From 3fd683b6eeeab26822de4a3a7cff1952b2b956b2 Mon Sep 17 00:00:00 2001 From: Neshura Date: Wed, 6 Dec 2023 21:00:46 +0100 Subject: [PATCH] Add shadcn UI --- .../ui/avatar/avatar-fallback.svelte | 19 ++++++ .../components/ui/avatar/avatar-image.svelte | 18 ++++++ src/lib/components/ui/avatar/avatar.svelte | 21 +++++++ src/lib/components/ui/avatar/index.ts | 13 ++++ src/lib/components/ui/button/button.svelte | 25 ++++++++ src/lib/components/ui/button/index.ts | 52 ++++++++++++++++ .../dropdown-menu-checkbox-item.svelte | 35 +++++++++++ .../dropdown-menu-content.svelte | 26 ++++++++ .../dropdown-menu/dropdown-menu-item.svelte | 31 ++++++++++ .../dropdown-menu/dropdown-menu-label.svelte | 19 ++++++ .../dropdown-menu-radio-group.svelte | 11 ++++ .../dropdown-menu-radio-item.svelte | 35 +++++++++++ .../dropdown-menu-separator.svelte | 14 +++++ .../dropdown-menu-shortcut.svelte | 16 +++++ .../dropdown-menu-sub-content.svelte | 29 +++++++++ .../dropdown-menu-sub-trigger.svelte | 32 ++++++++++ src/lib/components/ui/dropdown-menu/index.ts | 48 ++++++++++++++ src/lib/components/ui/menubar/index.ts | 52 ++++++++++++++++ .../ui/menubar/menubar-checkbox-item.svelte | 33 ++++++++++ .../ui/menubar/menubar-content.svelte | 28 +++++++++ .../components/ui/menubar/menubar-item.svelte | 31 ++++++++++ .../ui/menubar/menubar-label.svelte | 18 ++++++ .../ui/menubar/menubar-radio-item.svelte | 34 ++++++++++ .../ui/menubar/menubar-separator.svelte | 13 ++++ .../ui/menubar/menubar-shortcut.svelte | 18 ++++++ .../ui/menubar/menubar-sub-content.svelte | 25 ++++++++ .../ui/menubar/menubar-sub-trigger.svelte | 32 ++++++++++ .../ui/menubar/menubar-trigger.svelte | 23 +++++++ src/lib/components/ui/menubar/menubar.svelte | 18 ++++++ src/lib/components/ui/separator/index.ts | 7 +++ .../components/ui/separator/separator.svelte | 22 +++++++ src/lib/utils.ts | 62 +++++++++++++++++++ 32 files changed, 860 insertions(+) create mode 100644 src/lib/components/ui/avatar/avatar-fallback.svelte create mode 100644 src/lib/components/ui/avatar/avatar-image.svelte create mode 100644 src/lib/components/ui/avatar/avatar.svelte create mode 100644 src/lib/components/ui/avatar/index.ts create mode 100644 src/lib/components/ui/button/button.svelte create mode 100644 src/lib/components/ui/button/index.ts create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte create mode 100644 src/lib/components/ui/dropdown-menu/index.ts create mode 100644 src/lib/components/ui/menubar/index.ts create mode 100644 src/lib/components/ui/menubar/menubar-checkbox-item.svelte create mode 100644 src/lib/components/ui/menubar/menubar-content.svelte create mode 100644 src/lib/components/ui/menubar/menubar-item.svelte create mode 100644 src/lib/components/ui/menubar/menubar-label.svelte create mode 100644 src/lib/components/ui/menubar/menubar-radio-item.svelte create mode 100644 src/lib/components/ui/menubar/menubar-separator.svelte create mode 100644 src/lib/components/ui/menubar/menubar-shortcut.svelte create mode 100644 src/lib/components/ui/menubar/menubar-sub-content.svelte create mode 100644 src/lib/components/ui/menubar/menubar-sub-trigger.svelte create mode 100644 src/lib/components/ui/menubar/menubar-trigger.svelte create mode 100644 src/lib/components/ui/menubar/menubar.svelte create mode 100644 src/lib/components/ui/separator/index.ts create mode 100644 src/lib/components/ui/separator/separator.svelte create mode 100644 src/lib/utils.ts diff --git a/src/lib/components/ui/avatar/avatar-fallback.svelte b/src/lib/components/ui/avatar/avatar-fallback.svelte new file mode 100644 index 0000000..3b9b24c --- /dev/null +++ b/src/lib/components/ui/avatar/avatar-fallback.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/src/lib/components/ui/avatar/avatar-image.svelte b/src/lib/components/ui/avatar/avatar-image.svelte new file mode 100644 index 0000000..27b0e7d --- /dev/null +++ b/src/lib/components/ui/avatar/avatar-image.svelte @@ -0,0 +1,18 @@ + + + diff --git a/src/lib/components/ui/avatar/avatar.svelte b/src/lib/components/ui/avatar/avatar.svelte new file mode 100644 index 0000000..b8a6ee1 --- /dev/null +++ b/src/lib/components/ui/avatar/avatar.svelte @@ -0,0 +1,21 @@ + + + + + diff --git a/src/lib/components/ui/avatar/index.ts b/src/lib/components/ui/avatar/index.ts new file mode 100644 index 0000000..b08c780 --- /dev/null +++ b/src/lib/components/ui/avatar/index.ts @@ -0,0 +1,13 @@ +import Root from "./avatar.svelte"; +import Image from "./avatar-image.svelte"; +import Fallback from "./avatar-fallback.svelte"; + +export { + Root, + Image, + Fallback, + // + Root as Avatar, + Image as AvatarImage, + Fallback as AvatarFallback +}; diff --git a/src/lib/components/ui/button/button.svelte b/src/lib/components/ui/button/button.svelte new file mode 100644 index 0000000..a128f14 --- /dev/null +++ b/src/lib/components/ui/button/button.svelte @@ -0,0 +1,25 @@ + + + + + diff --git a/src/lib/components/ui/button/index.ts b/src/lib/components/ui/button/index.ts new file mode 100644 index 0000000..9787e3e --- /dev/null +++ b/src/lib/components/ui/button/index.ts @@ -0,0 +1,52 @@ +import type { Button as ButtonPrimitive } from "bits-ui"; +import { tv, type VariantProps } from "tailwind-variants"; +import Root from "./button.svelte"; + +const buttonVariants = tv({ + base: "inline-flex items-center justify-center rounded-md text-sm font-medium whitespace-nowrap transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50", + variants: { + variant: { + default: + "bg-primary text-primary-foreground shadow hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90", + outline: + "border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline" + }, + size: { + default: "h-9 px-4 py-2", + sm: "h-8 rounded-md px-3 text-xs", + lg: "h-10 rounded-md px-8", + icon: "h-9 w-9" + } + }, + defaultVariants: { + variant: "default", + size: "default" + } +}); + +type Variant = VariantProps["variant"]; +type Size = VariantProps["size"]; + +type Props = ButtonPrimitive.Props & { + variant?: Variant; + size?: Size; +}; + +type Events = ButtonPrimitive.Events; + +export { + Root, + type Props, + type Events, + // + Root as Button, + type Props as ButtonProps, + type Events as ButtonEvents, + buttonVariants +}; diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 0000000..727dbd5 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,35 @@ + + + + + + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..3d09fe9 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,26 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..aaf9d71 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,31 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..a7fb3c4 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte new file mode 100644 index 0000000..1c74ae1 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte @@ -0,0 +1,11 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..e518364 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,35 @@ + + + + + + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..775f8fe --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,14 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..caf24ad --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,16 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..eec9bfa --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,29 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..d3a5ad3 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,32 @@ + + + + + + diff --git a/src/lib/components/ui/dropdown-menu/index.ts b/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..313213a --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,48 @@ +import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; +import Item from "./dropdown-menu-item.svelte"; +import Label from "./dropdown-menu-label.svelte"; +import Content from "./dropdown-menu-content.svelte"; +import Shortcut from "./dropdown-menu-shortcut.svelte"; +import RadioItem from "./dropdown-menu-radio-item.svelte"; +import Separator from "./dropdown-menu-separator.svelte"; +import RadioGroup from "./dropdown-menu-radio-group.svelte"; +import SubContent from "./dropdown-menu-sub-content.svelte"; +import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; +import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; + +const Sub = DropdownMenuPrimitive.Sub; +const Root = DropdownMenuPrimitive.Root; +const Trigger = DropdownMenuPrimitive.Trigger; +const Group = DropdownMenuPrimitive.Group; + +export { + Sub, + Root, + Item, + Label, + Group, + Trigger, + Content, + Shortcut, + Separator, + RadioItem, + SubContent, + SubTrigger, + RadioGroup, + CheckboxItem, + // + Root as DropdownMenu, + Sub as DropdownMenuSub, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + Group as DropdownMenuGroup, + Content as DropdownMenuContent, + Trigger as DropdownMenuTrigger, + Shortcut as DropdownMenuShortcut, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + RadioGroup as DropdownMenuRadioGroup, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + CheckboxItem as DropdownMenuCheckboxItem +}; diff --git a/src/lib/components/ui/menubar/index.ts b/src/lib/components/ui/menubar/index.ts new file mode 100644 index 0000000..733ab08 --- /dev/null +++ b/src/lib/components/ui/menubar/index.ts @@ -0,0 +1,52 @@ +import { Menubar as MenubarPrimitive } from "bits-ui"; + +import Root from "./menubar.svelte"; +import CheckboxItem from "./menubar-checkbox-item.svelte"; +import Content from "./menubar-content.svelte"; +import Item from "./menubar-item.svelte"; +import Label from "./menubar-label.svelte"; +import RadioItem from "./menubar-radio-item.svelte"; +import Separator from "./menubar-separator.svelte"; +import Shortcut from "./menubar-shortcut.svelte"; +import SubContent from "./menubar-sub-content.svelte"; +import SubTrigger from "./menubar-sub-trigger.svelte"; +import Trigger from "./menubar-trigger.svelte"; + +const Menu = MenubarPrimitive.Menu; +const Group = MenubarPrimitive.Group; +const Sub = MenubarPrimitive.Sub; +const RadioGroup = MenubarPrimitive.RadioGroup; + +export { + Root, + CheckboxItem, + Content, + Item, + Label, + RadioItem, + Separator, + Shortcut, + SubContent, + SubTrigger, + Trigger, + Menu, + Group, + Sub, + RadioGroup, + // + Root as Menubar, + CheckboxItem as MenubarCheckboxItem, + Content as MenubarContent, + Item as MenubarItem, + Label as MenubarLabel, + RadioItem as MenubarRadioItem, + Separator as MenubarSeparator, + Shortcut as MenubarShortcut, + SubContent as MenubarSubContent, + SubTrigger as MenubarSubTrigger, + Trigger as MenubarTrigger, + Menu as MenubarMenu, + Group as MenubarGroup, + Sub as MenubarSub, + RadioGroup as MenubarRadioGroup +}; diff --git a/src/lib/components/ui/menubar/menubar-checkbox-item.svelte b/src/lib/components/ui/menubar/menubar-checkbox-item.svelte new file mode 100644 index 0000000..a98439a --- /dev/null +++ b/src/lib/components/ui/menubar/menubar-checkbox-item.svelte @@ -0,0 +1,33 @@ + + + + + + + + + + diff --git a/src/lib/components/ui/menubar/menubar-content.svelte b/src/lib/components/ui/menubar/menubar-content.svelte new file mode 100644 index 0000000..20f61c7 --- /dev/null +++ b/src/lib/components/ui/menubar/menubar-content.svelte @@ -0,0 +1,28 @@ + + + + + diff --git a/src/lib/components/ui/menubar/menubar-item.svelte b/src/lib/components/ui/menubar/menubar-item.svelte new file mode 100644 index 0000000..53af5c1 --- /dev/null +++ b/src/lib/components/ui/menubar/menubar-item.svelte @@ -0,0 +1,31 @@ + + + + + diff --git a/src/lib/components/ui/menubar/menubar-label.svelte b/src/lib/components/ui/menubar/menubar-label.svelte new file mode 100644 index 0000000..710619f --- /dev/null +++ b/src/lib/components/ui/menubar/menubar-label.svelte @@ -0,0 +1,18 @@ + + + + + diff --git a/src/lib/components/ui/menubar/menubar-radio-item.svelte b/src/lib/components/ui/menubar/menubar-radio-item.svelte new file mode 100644 index 0000000..bf1e2d3 --- /dev/null +++ b/src/lib/components/ui/menubar/menubar-radio-item.svelte @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/src/lib/components/ui/menubar/menubar-separator.svelte b/src/lib/components/ui/menubar/menubar-separator.svelte new file mode 100644 index 0000000..90851d6 --- /dev/null +++ b/src/lib/components/ui/menubar/menubar-separator.svelte @@ -0,0 +1,13 @@ + + + diff --git a/src/lib/components/ui/menubar/menubar-shortcut.svelte b/src/lib/components/ui/menubar/menubar-shortcut.svelte new file mode 100644 index 0000000..82309a0 --- /dev/null +++ b/src/lib/components/ui/menubar/menubar-shortcut.svelte @@ -0,0 +1,18 @@ + + + + + diff --git a/src/lib/components/ui/menubar/menubar-sub-content.svelte b/src/lib/components/ui/menubar/menubar-sub-content.svelte new file mode 100644 index 0000000..287b756 --- /dev/null +++ b/src/lib/components/ui/menubar/menubar-sub-content.svelte @@ -0,0 +1,25 @@ + + + + + diff --git a/src/lib/components/ui/menubar/menubar-sub-trigger.svelte b/src/lib/components/ui/menubar/menubar-sub-trigger.svelte new file mode 100644 index 0000000..329ee24 --- /dev/null +++ b/src/lib/components/ui/menubar/menubar-sub-trigger.svelte @@ -0,0 +1,32 @@ + + + + + + diff --git a/src/lib/components/ui/menubar/menubar-trigger.svelte b/src/lib/components/ui/menubar/menubar-trigger.svelte new file mode 100644 index 0000000..c6dfe97 --- /dev/null +++ b/src/lib/components/ui/menubar/menubar-trigger.svelte @@ -0,0 +1,23 @@ + + + + + diff --git a/src/lib/components/ui/menubar/menubar.svelte b/src/lib/components/ui/menubar/menubar.svelte new file mode 100644 index 0000000..4ed491a --- /dev/null +++ b/src/lib/components/ui/menubar/menubar.svelte @@ -0,0 +1,18 @@ + + + + + diff --git a/src/lib/components/ui/separator/index.ts b/src/lib/components/ui/separator/index.ts new file mode 100644 index 0000000..dbfb139 --- /dev/null +++ b/src/lib/components/ui/separator/index.ts @@ -0,0 +1,7 @@ +import Root from "./separator.svelte"; + +export { + Root, + // + Root as Separator +}; diff --git a/src/lib/components/ui/separator/separator.svelte b/src/lib/components/ui/separator/separator.svelte new file mode 100644 index 0000000..bf9127a --- /dev/null +++ b/src/lib/components/ui/separator/separator.svelte @@ -0,0 +1,22 @@ + + + diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..230a1fb --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,62 @@ +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; +import { cubicOut } from "svelte/easing"; +import type { TransitionConfig } from "svelte/transition"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} + +type FlyAndScaleParams = { + y?: number; + x?: number; + start?: number; + duration?: number; +}; + +export const flyAndScale = ( + node: Element, + params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 } +): TransitionConfig => { + const style = getComputedStyle(node); + const transform = style.transform === "none" ? "" : style.transform; + + const scaleConversion = ( + valueA: number, + scaleA: [number, number], + scaleB: [number, number] + ) => { + const [minA, maxA] = scaleA; + const [minB, maxB] = scaleB; + + const percentage = (valueA - minA) / (maxA - minA); + const valueB = percentage * (maxB - minB) + minB; + + return valueB; + }; + + const styleToString = ( + style: Record + ): string => { + return Object.keys(style).reduce((str, key) => { + if (style[key] === undefined) return str; + return str + `${key}:${style[key]};`; + }, ""); + }; + + return { + duration: params.duration ?? 200, + delay: 0, + css: (t) => { + const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0]); + const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0]); + const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1]); + + return styleToString({ + transform: `${transform} translate3d(${x}px, ${y}px, 0) scale(${scale})`, + opacity: t + }); + }, + easing: cubicOut + }; +}; \ No newline at end of file