From 99110de26102d0215addb868161e81fb11b30695 Mon Sep 17 00:00:00 2001 From: Derek Philip Au <22045002+derekphilipau@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:28:38 -0500 Subject: [PATCH 1/4] missing field name, agg styling --- components/search/search-agg.tsx | 8 ++++++-- dictionaries/lang/en.json | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/components/search/search-agg.tsx b/components/search/search-agg.tsx index c6a9aaf..74b9855 100644 --- a/components/search/search-agg.tsx +++ b/components/search/search-agg.tsx @@ -155,7 +155,9 @@ export function SearchAgg({ className="text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" > {option.key} - {option.doc_count ? ` (${option.doc_count})` : ''} + + {option.doc_count ? ` ${option.doc_count}` : ''} + ) @@ -184,7 +186,9 @@ export function SearchAgg({ className="text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" > {option.key} - {option.doc_count ? ` (${option.doc_count})` : ''} + + {option.doc_count ? ` ${option.doc_count}` : ''} + ) diff --git a/dictionaries/lang/en.json b/dictionaries/lang/en.json index ac7b1ab..1343728 100644 --- a/dictionaries/lang/en.json +++ b/dictionaries/lang/en.json @@ -89,7 +89,7 @@ "field.creditLine": "Credit Line", "field.exhibitions": "Exhibitions", "field.location": "Location", - "field.museumLocation": "Museum Location", + "field.museumLocation.name": "Museum Location", "field.rightsType": "Rights Statement", "field.dominantColors": "Dominant Colors", "field.primaryGeographicalLocation.continent": "Continent", From f93544b4a3b080ea83254f1a80fffb1e5e95c73c Mon Sep 17 00:00:00 2001 From: Derek Au Date: Thu, 28 Dec 2023 21:06:39 -0500 Subject: [PATCH 2/4] update shadcn/ui components --- app/globals.css | 82 ++- app/globals.css.old | 92 +++ components.json | 3 +- .../search/search-as-you-type-input.tsx | 2 +- components/ui/button.tsx | 2 +- components/ui/carousel.tsx | 257 +++++++++ components/ui/command.tsx | 2 +- components/ui/dialog-full-screen-local.tsx | 13 +- components/ui/dialog.tsx | 17 +- components/ui/popover.tsx | 4 +- components/ui/scroll-area.tsx | 2 +- components/ui/select.tsx | 45 +- components/ui/sheet.tsx | 12 +- components/ui/switch.tsx | 2 +- components/ui/textarea.tsx | 2 +- lib/utils.ts | 2 +- package-lock.json | 541 ++++++++++++++++-- package.json | 12 +- 18 files changed, 960 insertions(+), 132 deletions(-) create mode 100644 app/globals.css.old create mode 100644 components/ui/carousel.tsx diff --git a/app/globals.css b/app/globals.css index cccdc86..eae0917 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,85 +1,81 @@ @tailwind base; @tailwind components; @tailwind utilities; - + @layer base { :root { --background: 0 0% 100%; --foreground: 0 0% 3.9%; - - --muted: 0 0% 96.1%; - --muted-foreground: 0 0% 45.1%; - - --popover: 0 0% 100%; - --popover-foreground: 0 0% 3.9%; - + --card: 0 0% 100%; --card-foreground: 0 0% 3.9%; - - --border: 0 0% 89.8%; - --input: 0 0% 89.8%; - + + --popover: 0 0% 100%; + --popover-foreground: 0 0% 3.9%; + --primary: 0 0% 9%; --primary-foreground: 0 0% 98%; - + --secondary: 0 0% 96.1%; --secondary-foreground: 0 0% 9%; - + + --muted: 0 0% 96.1%; + --muted-foreground: 0 0% 45.1%; + --accent: 0 0% 96.1%; --accent-foreground: 0 0% 9%; - + --destructive: 0 84.2% 60.2%; --destructive-foreground: 0 0% 98%; - - --ring: 0 0% 63.9%; - + + --border: 0 0% 89.8%; + --input: 0 0% 89.8%; + --ring: 0 0% 3.9%; + --radius: 0.5rem; } - + .dark { --background: 0 0% 3.9%; --foreground: 0 0% 98%; - - --muted: 0 0% 14.9%; - --muted-foreground: 0 0% 63.9%; - - --popover: 0 0% 3.9%; - --popover-foreground: 0 0% 98%; - + --card: 0 0% 3.9%; --card-foreground: 0 0% 98%; - - --border: 0 0% 14.9%; - --input: 0 0% 14.9%; - + + --popover: 0 0% 3.9%; + --popover-foreground: 0 0% 98%; + --primary: 0 0% 98%; --primary-foreground: 0 0% 9%; - + --secondary: 0 0% 14.9%; --secondary-foreground: 0 0% 98%; - + + --muted: 0 0% 14.9%; + --muted-foreground: 0 0% 63.9%; + --accent: 0 0% 14.9%; --accent-foreground: 0 0% 98%; - + --destructive: 0 62.8% 30.6%; - --destructive-foreground: 0 85.7% 97.3%; - - --ring: 0 0% 14.9%; + --destructive-foreground: 0 0% 98%; + + --border: 0 0% 14.9%; + --input: 0 0% 14.9%; + --ring: 0 0% 83.1%; } } - + @layer base { * { @apply border-border; } - body { @apply bg-background text-foreground; - font-feature-settings: "rlig" 1, "calt" 1; - } - input[type="search"] { - -webkit-appearance: none !important; + input[type='search'] { + -webkit-appearance: none !important; + } } } @@ -87,4 +83,4 @@ .container { @apply px-4; } -} \ No newline at end of file +} diff --git a/app/globals.css.old b/app/globals.css.old new file mode 100644 index 0000000..193384b --- /dev/null +++ b/app/globals.css.old @@ -0,0 +1,92 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 0 0% 3.9%; + + --muted: 0 0% 96.1%; + --muted-foreground: 0 0% 45.1%; + + --popover: 0 0% 100%; + --popover-foreground: 0 0% 3.9%; + + --card: 0 0% 100%; + --card-foreground: 0 0% 3.9%; + + --border: 0 0% 89.8%; + --input: 0 0% 89.8%; + + --primary: 0 0% 9%; + --primary-foreground: 0 0% 98%; + + --secondary: 0 0% 96.1%; + --secondary-foreground: 0 0% 9%; + + --accent: 0 0% 96.1%; + --accent-foreground: 0 0% 9%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + + --ring: 0 0% 63.9%; + + --radius: 0.5rem; + } + + .dark { + --background: 0 0% 3.9%; + --foreground: 0 0% 98%; + + --muted: 0 0% 14.9%; + --muted-foreground: 0 0% 63.9%; + + --popover: 0 0% 3.9%; + --popover-foreground: 0 0% 98%; + + --card: 0 0% 3.9%; + --card-foreground: 0 0% 98%; + + --border: 0 0% 14.9%; + --input: 0 0% 14.9%; + + --primary: 0 0% 98%; + --primary-foreground: 0 0% 9%; + + --secondary: 0 0% 14.9%; + --secondary-foreground: 0 0% 98%; + + --accent: 0 0% 14.9%; + --accent-foreground: 0 0% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 85.7% 97.3%; + + --ring: 0 0% 14.9%; + } +} + +@layer base { + * { + @apply border-border; + } + + body { + @apply bg-background text-foreground; + font-feature-settings: + 'rlig' 1, + 'calt' 1; + } + + input[type='search'] { + -webkit-appearance: none !important; + } +} + +@media (max-width: 640px) { + .container { + @apply px-4; + } +} diff --git a/components.json b/components.json index 8ce3cc5..5ba5989 100644 --- a/components.json +++ b/components.json @@ -2,6 +2,7 @@ "$schema": "https://ui.shadcn.com/schema.json", "style": "default", "rsc": true, + "tsx": true, "tailwind": { "config": "tailwind.config.js", "css": "app/globals.css", @@ -12,4 +13,4 @@ "components": "@/components", "utils": "@/lib/utils" } -} \ No newline at end of file +} diff --git a/components/search/search-as-you-type-input.tsx b/components/search/search-as-you-type-input.tsx index f662614..10d57fe 100644 --- a/components/search/search-as-you-type-input.tsx +++ b/components/search/search-as-you-type-input.tsx @@ -17,7 +17,7 @@ import { Popover, PopoverAnchor, PopoverContent, -} from '@/components/ui/popover-local'; +} from '@/components/ui/popover'; interface SearchAsYouTypeInputProps { params?: SearchParams; diff --git a/components/ui/button.tsx b/components/ui/button.tsx index 62c0651..81e2e6e 100644 --- a/components/ui/button.tsx +++ b/components/ui/button.tsx @@ -5,7 +5,7 @@ import { cva, type VariantProps } from 'class-variance-authority'; import { cn } from '@/lib/utils'; const buttonVariants = cva( - 'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', + 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', { variants: { variant: { diff --git a/components/ui/carousel.tsx b/components/ui/carousel.tsx new file mode 100644 index 0000000..46dfca0 --- /dev/null +++ b/components/ui/carousel.tsx @@ -0,0 +1,257 @@ +import * as React from 'react'; +import useEmblaCarousel, { + type EmblaCarouselType as CarouselApi, + type EmblaOptionsType as CarouselOptions, + type EmblaPluginType as CarouselPlugin, +} from 'embla-carousel-react'; +import { ArrowLeft, ArrowRight } from 'lucide-react'; + +import { cn } from '@/lib/utils'; +import { Button } from '@/components/ui/button'; + +type CarouselProps = { + opts?: CarouselOptions; + plugins?: CarouselPlugin[]; + orientation?: 'horizontal' | 'vertical'; + setApi?: (api: CarouselApi) => void; +}; + +type CarouselContextProps = { + carouselRef: ReturnType[0]; + api: ReturnType[1]; + scrollPrev: () => void; + scrollNext: () => void; + canScrollPrev: boolean; + canScrollNext: boolean; +} & CarouselProps; + +const CarouselContext = React.createContext(null); + +function useCarousel() { + const context = React.useContext(CarouselContext); + + if (!context) { + throw new Error('useCarousel must be used within a '); + } + + return context; +} + +const Carousel = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & CarouselProps +>( + ( + { + orientation = 'horizontal', + opts, + setApi, + plugins, + className, + children, + ...props + }, + ref + ) => { + const [carouselRef, api] = useEmblaCarousel( + { + ...opts, + axis: orientation === 'horizontal' ? 'x' : 'y', + }, + plugins + ); + const [canScrollPrev, setCanScrollPrev] = React.useState(false); + const [canScrollNext, setCanScrollNext] = React.useState(false); + + const onSelect = React.useCallback((api: CarouselApi) => { + if (!api) { + return; + } + + setCanScrollPrev(api.canScrollPrev()); + setCanScrollNext(api.canScrollNext()); + }, []); + + const scrollPrev = React.useCallback(() => { + api?.scrollPrev(); + }, [api]); + + const scrollNext = React.useCallback(() => { + api?.scrollNext(); + }, [api]); + + const handleKeyDown = React.useCallback( + (event: React.KeyboardEvent) => { + if (event.key === 'ArrowLeft') { + event.preventDefault(); + scrollPrev(); + } else if (event.key === 'ArrowRight') { + event.preventDefault(); + scrollNext(); + } + }, + [scrollPrev, scrollNext] + ); + + React.useEffect(() => { + if (!api || !setApi) { + return; + } + + setApi(api); + }, [api, setApi]); + + React.useEffect(() => { + if (!api) { + return; + } + + onSelect(api); + api.on('reInit', onSelect); + api.on('select', onSelect); + + return () => { + api?.off('select', onSelect); + }; + }, [api, onSelect]); + + return ( + +
+ {children} +
+
+ ); + } +); +Carousel.displayName = 'Carousel'; + +const CarouselContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const { carouselRef, orientation } = useCarousel(); + + return ( +
+
+
+ ); +}); +CarouselContent.displayName = 'CarouselContent'; + +const CarouselItem = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const { orientation } = useCarousel(); + + return ( +
+ ); +}); +CarouselItem.displayName = 'CarouselItem'; + +const CarouselPrevious = React.forwardRef< + HTMLButtonElement, + React.ComponentProps +>(({ className, variant = 'outline', size = 'icon', ...props }, ref) => { + const { orientation, scrollPrev, canScrollPrev } = useCarousel(); + + return ( + + ); +}); +CarouselPrevious.displayName = 'CarouselPrevious'; + +const CarouselNext = React.forwardRef< + HTMLButtonElement, + React.ComponentProps +>(({ className, variant = 'outline', size = 'icon', ...props }, ref) => { + const { orientation, scrollNext, canScrollNext } = useCarousel(); + + return ( + + ); +}); +CarouselNext.displayName = 'CarouselNext'; + +export { + type CarouselApi, + Carousel, + CarouselContent, + CarouselItem, + CarouselPrevious, + CarouselNext, +}; diff --git a/components/ui/command.tsx b/components/ui/command.tsx index 24aaf74..15e2dc2 100644 --- a/components/ui/command.tsx +++ b/components/ui/command.tsx @@ -1,7 +1,7 @@ 'use client'; import * as React from 'react'; -import { DialogProps } from '@radix-ui/react-dialog'; +import { type DialogProps } from '@radix-ui/react-dialog'; import { Command as CommandPrimitive } from 'cmdk'; import { Search } from 'lucide-react'; diff --git a/components/ui/dialog-full-screen-local.tsx b/components/ui/dialog-full-screen-local.tsx index 2bb7a47..45c80c9 100644 --- a/components/ui/dialog-full-screen-local.tsx +++ b/components/ui/dialog-full-screen-local.tsx @@ -10,13 +10,9 @@ const Dialog = DialogPrimitive.Root; const DialogTrigger = DialogPrimitive.Trigger; -const DialogPortal = ({ - className, - ...props -}: DialogPrimitive.DialogPortalProps) => ( - -); -DialogPortal.displayName = DialogPrimitive.Portal.displayName; +const DialogPortal = DialogPrimitive.Portal; + +const DialogClose = DialogPrimitive.Close; const DialogOverlay = React.forwardRef< React.ElementRef, @@ -114,6 +110,9 @@ DialogDescription.displayName = DialogPrimitive.Description.displayName; export { Dialog, + DialogPortal, + DialogOverlay, + DialogClose, DialogTrigger, DialogContent, DialogHeader, diff --git a/components/ui/dialog.tsx b/components/ui/dialog.tsx index 90e8ab1..b552952 100644 --- a/components/ui/dialog.tsx +++ b/components/ui/dialog.tsx @@ -10,13 +10,9 @@ const Dialog = DialogPrimitive.Root; const DialogTrigger = DialogPrimitive.Trigger; -const DialogPortal = ({ - className, - ...props -}: DialogPrimitive.DialogPortalProps) => ( - -); -DialogPortal.displayName = DialogPrimitive.Portal.displayName; +const DialogPortal = DialogPrimitive.Portal; + +const DialogClose = DialogPrimitive.Close; const DialogOverlay = React.forwardRef< React.ElementRef, @@ -25,7 +21,7 @@ const DialogOverlay = React.forwardRef< , React.ComponentPropsWithoutRef @@ -28,4 +30,4 @@ const PopoverContent = React.forwardRef< )); PopoverContent.displayName = PopoverPrimitive.Content.displayName; -export { Popover, PopoverTrigger, PopoverContent }; +export { Popover, PopoverTrigger, PopoverAnchor, PopoverContent }; diff --git a/components/ui/scroll-area.tsx b/components/ui/scroll-area.tsx index 0a4654f..75c68fa 100644 --- a/components/ui/scroll-area.tsx +++ b/components/ui/scroll-area.tsx @@ -35,7 +35,7 @@ const ScrollBar = React.forwardRef< orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent p-[1px]', orientation === 'horizontal' && - 'h-2.5 border-t border-t-transparent p-[1px]', + 'h-2.5 flex-col border-t border-t-transparent p-[1px]', className )} {...props} diff --git a/components/ui/select.tsx b/components/ui/select.tsx index 313d5a7..9f3ef21 100644 --- a/components/ui/select.tsx +++ b/components/ui/select.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import * as SelectPrimitive from '@radix-ui/react-select'; -import { Check, ChevronDown } from 'lucide-react'; +import { Check, ChevronDown, ChevronUp } from 'lucide-react'; import { cn } from '@/lib/utils'; @@ -19,7 +19,7 @@ const SelectTrigger = React.forwardRef< span]:line-clamp-1', className )} {...props} @@ -32,6 +32,41 @@ const SelectTrigger = React.forwardRef< )); SelectTrigger.displayName = SelectPrimitive.Trigger.displayName; +const SelectScrollUpButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)); +SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName; + +const SelectScrollDownButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)); +SelectScrollDownButton.displayName = + SelectPrimitive.ScrollDownButton.displayName; + const SelectContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef @@ -40,7 +75,7 @@ const SelectContent = React.forwardRef< + {children} + )); @@ -118,4 +155,6 @@ export { SelectLabel, SelectItem, SelectSeparator, + SelectScrollUpButton, + SelectScrollDownButton, }; diff --git a/components/ui/sheet.tsx b/components/ui/sheet.tsx index af39011..257a927 100644 --- a/components/ui/sheet.tsx +++ b/components/ui/sheet.tsx @@ -13,13 +13,7 @@ const SheetTrigger = SheetPrimitive.Trigger; const SheetClose = SheetPrimitive.Close; -const SheetPortal = ({ - className, - ...props -}: SheetPrimitive.DialogPortalProps) => ( - -); -SheetPortal.displayName = SheetPrimitive.Portal.displayName; +const SheetPortal = SheetPrimitive.Portal; const SheetOverlay = React.forwardRef< React.ElementRef, @@ -27,7 +21,7 @@ const SheetOverlay = React.forwardRef< >(({ className, ...props }, ref) => ( (({ className, ...props }, ref) => ( ( return (