From f0144a2361f189f6e21ac539992a52525fc1cdae Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 11:42:43 +0000 Subject: [PATCH] ui: add shadcn-svelte foundation and theming Set up shadcn-svelte components and adopt its design-token system as the base for modernizing the UI. Switch dark mode from the data-theme attribute to the .dark class so shadcn primitives theme correctly. - add components.json, $lib alias (tsconfig + vite), cn() util - install shadcn primitives under src/lib/components/ui - rewrite index.css with shadcn tokens (zinc + brand teal accent) - keep legacy utility/class aliases as a transitional shim - toggle .dark class from theme store in App.svelte Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01UmuGqwNBJNEAMaWsdCDqUC --- ui-svelte/components.json | 17 + ui-svelte/package-lock.json | 320 +++++++++++++++++- ui-svelte/package.json | 11 +- ui-svelte/src/App.svelte | 2 +- ui-svelte/src/index.css | 270 +++++++++------ .../src/lib/components/ui/badge/badge.svelte | 49 +++ .../src/lib/components/ui/badge/index.ts | 2 + .../lib/components/ui/button/button.svelte | 82 +++++ .../src/lib/components/ui/button/index.ts | 17 + .../lib/components/ui/card/card-action.svelte | 23 ++ .../components/ui/card/card-content.svelte | 20 ++ .../ui/card/card-description.svelte | 20 ++ .../lib/components/ui/card/card-footer.svelte | 20 ++ .../lib/components/ui/card/card-header.svelte | 23 ++ .../lib/components/ui/card/card-title.svelte | 20 ++ .../src/lib/components/ui/card/card.svelte | 22 ++ ui-svelte/src/lib/components/ui/card/index.ts | 25 ++ .../components/ui/dialog/dialog-close.svelte | 11 + .../ui/dialog/dialog-content.svelte | 48 +++ .../ui/dialog/dialog-description.svelte | 17 + .../components/ui/dialog/dialog-footer.svelte | 32 ++ .../components/ui/dialog/dialog-header.svelte | 20 ++ .../ui/dialog/dialog-overlay.svelte | 17 + .../components/ui/dialog/dialog-portal.svelte | 7 + .../components/ui/dialog/dialog-title.svelte | 17 + .../ui/dialog/dialog-trigger.svelte | 11 + .../lib/components/ui/dialog/dialog.svelte | 7 + .../src/lib/components/ui/dialog/index.ts | 34 ++ .../dropdown-menu-checkbox-group.svelte | 16 + .../dropdown-menu-checkbox-item.svelte | 44 +++ .../dropdown-menu-content.svelte | 31 ++ .../dropdown-menu-group-heading.svelte | 22 ++ .../dropdown-menu/dropdown-menu-group.svelte | 7 + .../dropdown-menu/dropdown-menu-item.svelte | 27 ++ .../dropdown-menu/dropdown-menu-label.svelte | 24 ++ .../dropdown-menu/dropdown-menu-portal.svelte | 7 + .../dropdown-menu-radio-group.svelte | 16 + .../dropdown-menu-radio-item.svelte | 34 ++ .../dropdown-menu-separator.svelte | 17 + .../dropdown-menu-shortcut.svelte | 20 ++ .../dropdown-menu-sub-content.svelte | 17 + .../dropdown-menu-sub-trigger.svelte | 29 ++ .../ui/dropdown-menu/dropdown-menu-sub.svelte | 7 + .../dropdown-menu-trigger.svelte | 7 + .../ui/dropdown-menu/dropdown-menu.svelte | 7 + .../lib/components/ui/dropdown-menu/index.ts | 54 +++ .../src/lib/components/ui/input/index.ts | 7 + .../src/lib/components/ui/input/input.svelte | 48 +++ .../src/lib/components/ui/label/index.ts | 7 + .../src/lib/components/ui/label/label.svelte | 20 ++ .../src/lib/components/ui/resizable/index.ts | 13 + .../ui/resizable/resizable-handle.svelte | 27 ++ .../ui/resizable/resizable-pane-group.svelte | 24 ++ .../lib/components/ui/scroll-area/index.ts | 10 + .../scroll-area/scroll-area-scrollbar.svelte | 30 ++ .../ui/scroll-area/scroll-area.svelte | 43 +++ .../src/lib/components/ui/select/index.ts | 37 ++ .../ui/select/select-content.svelte | 45 +++ .../ui/select/select-group-heading.svelte | 21 ++ .../components/ui/select/select-group.svelte | 17 + .../components/ui/select/select-item.svelte | 40 +++ .../components/ui/select/select-label.svelte | 20 ++ .../components/ui/select/select-portal.svelte | 7 + .../select/select-scroll-down-button.svelte | 20 ++ .../ui/select/select-scroll-up-button.svelte | 20 ++ .../ui/select/select-separator.svelte | 18 + .../ui/select/select-trigger.svelte | 29 ++ .../lib/components/ui/select/select.svelte | 11 + .../src/lib/components/ui/separator/index.ts | 7 + .../components/ui/separator/separator.svelte | 23 ++ .../src/lib/components/ui/sheet/index.ts | 34 ++ .../components/ui/sheet/sheet-close.svelte | 7 + .../components/ui/sheet/sheet-content.svelte | 55 +++ .../ui/sheet/sheet-description.svelte | 17 + .../components/ui/sheet/sheet-footer.svelte | 20 ++ .../components/ui/sheet/sheet-header.svelte | 20 ++ .../components/ui/sheet/sheet-overlay.svelte | 17 + .../components/ui/sheet/sheet-portal.svelte | 7 + .../components/ui/sheet/sheet-title.svelte | 17 + .../components/ui/sheet/sheet-trigger.svelte | 7 + .../src/lib/components/ui/sheet/sheet.svelte | 7 + .../lib/components/ui/sidebar/constants.ts | 6 + .../components/ui/sidebar/context.svelte.ts | 81 +++++ .../src/lib/components/ui/sidebar/index.ts | 75 ++++ .../ui/sidebar/sidebar-content.svelte | 24 ++ .../ui/sidebar/sidebar-footer.svelte | 21 ++ .../ui/sidebar/sidebar-group-action.svelte | 33 ++ .../ui/sidebar/sidebar-group-content.svelte | 21 ++ .../ui/sidebar/sidebar-group-label.svelte | 33 ++ .../ui/sidebar/sidebar-group.svelte | 21 ++ .../ui/sidebar/sidebar-header.svelte | 21 ++ .../ui/sidebar/sidebar-input.svelte | 21 ++ .../ui/sidebar/sidebar-inset.svelte | 20 ++ .../ui/sidebar/sidebar-menu-action.svelte | 37 ++ .../ui/sidebar/sidebar-menu-badge.svelte | 24 ++ .../ui/sidebar/sidebar-menu-button.svelte | 102 ++++++ .../ui/sidebar/sidebar-menu-item.svelte | 21 ++ .../ui/sidebar/sidebar-menu-skeleton.svelte | 36 ++ .../ui/sidebar/sidebar-menu-sub-button.svelte | 39 +++ .../ui/sidebar/sidebar-menu-sub-item.svelte | 21 ++ .../ui/sidebar/sidebar-menu-sub.svelte | 21 ++ .../components/ui/sidebar/sidebar-menu.svelte | 21 ++ .../ui/sidebar/sidebar-provider.svelte | 53 +++ .../components/ui/sidebar/sidebar-rail.svelte | 36 ++ .../ui/sidebar/sidebar-separator.svelte | 19 ++ .../ui/sidebar/sidebar-trigger.svelte | 36 ++ .../lib/components/ui/sidebar/sidebar.svelte | 108 ++++++ .../src/lib/components/ui/skeleton/index.ts | 7 + .../components/ui/skeleton/skeleton.svelte | 17 + .../src/lib/components/ui/switch/index.ts | 7 + .../lib/components/ui/switch/switch.svelte | 31 ++ .../src/lib/components/ui/table/index.ts | 28 ++ .../lib/components/ui/table/table-body.svelte | 15 + .../components/ui/table/table-caption.svelte | 20 ++ .../lib/components/ui/table/table-cell.svelte | 15 + .../components/ui/table/table-footer.svelte | 20 ++ .../lib/components/ui/table/table-head.svelte | 15 + .../components/ui/table/table-header.svelte | 20 ++ .../lib/components/ui/table/table-row.svelte | 15 + .../src/lib/components/ui/table/table.svelte | 17 + ui-svelte/src/lib/components/ui/tabs/index.ts | 18 + .../components/ui/tabs/tabs-content.svelte | 17 + .../lib/components/ui/tabs/tabs-list.svelte | 40 +++ .../components/ui/tabs/tabs-trigger.svelte | 23 ++ .../src/lib/components/ui/tabs/tabs.svelte | 19 ++ .../src/lib/components/ui/textarea/index.ts | 7 + .../components/ui/textarea/textarea.svelte | 23 ++ .../lib/components/ui/toggle-group/index.ts | 10 + .../ui/toggle-group/toggle-group-item.svelte | 35 ++ .../ui/toggle-group/toggle-group.svelte | 75 ++++ .../src/lib/components/ui/toggle/index.ts | 13 + .../lib/components/ui/toggle/toggle.svelte | 51 +++ .../src/lib/components/ui/tooltip/index.ts | 19 ++ .../ui/tooltip/tooltip-content.svelte | 52 +++ .../ui/tooltip/tooltip-portal.svelte | 7 + .../ui/tooltip/tooltip-provider.svelte | 7 + .../ui/tooltip/tooltip-trigger.svelte | 7 + .../lib/components/ui/tooltip/tooltip.svelte | 7 + ui-svelte/src/lib/hooks/is-mobile.svelte.ts | 9 + ui-svelte/src/lib/utils.ts | 13 + ui-svelte/tsconfig.json | 7 +- ui-svelte/vite.config.ts | 6 + 142 files changed, 3842 insertions(+), 103 deletions(-) create mode 100644 ui-svelte/components.json create mode 100644 ui-svelte/src/lib/components/ui/badge/badge.svelte create mode 100644 ui-svelte/src/lib/components/ui/badge/index.ts create mode 100644 ui-svelte/src/lib/components/ui/button/button.svelte create mode 100644 ui-svelte/src/lib/components/ui/button/index.ts create mode 100644 ui-svelte/src/lib/components/ui/card/card-action.svelte create mode 100644 ui-svelte/src/lib/components/ui/card/card-content.svelte create mode 100644 ui-svelte/src/lib/components/ui/card/card-description.svelte create mode 100644 ui-svelte/src/lib/components/ui/card/card-footer.svelte create mode 100644 ui-svelte/src/lib/components/ui/card/card-header.svelte create mode 100644 ui-svelte/src/lib/components/ui/card/card-title.svelte create mode 100644 ui-svelte/src/lib/components/ui/card/card.svelte create mode 100644 ui-svelte/src/lib/components/ui/card/index.ts create mode 100644 ui-svelte/src/lib/components/ui/dialog/dialog-close.svelte create mode 100644 ui-svelte/src/lib/components/ui/dialog/dialog-content.svelte create mode 100644 ui-svelte/src/lib/components/ui/dialog/dialog-description.svelte create mode 100644 ui-svelte/src/lib/components/ui/dialog/dialog-footer.svelte create mode 100644 ui-svelte/src/lib/components/ui/dialog/dialog-header.svelte create mode 100644 ui-svelte/src/lib/components/ui/dialog/dialog-overlay.svelte create mode 100644 ui-svelte/src/lib/components/ui/dialog/dialog-portal.svelte create mode 100644 ui-svelte/src/lib/components/ui/dialog/dialog-title.svelte create mode 100644 ui-svelte/src/lib/components/ui/dialog/dialog-trigger.svelte create mode 100644 ui-svelte/src/lib/components/ui/dialog/dialog.svelte create mode 100644 ui-svelte/src/lib/components/ui/dialog/index.ts create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte create mode 100644 ui-svelte/src/lib/components/ui/dropdown-menu/index.ts create mode 100644 ui-svelte/src/lib/components/ui/input/index.ts create mode 100644 ui-svelte/src/lib/components/ui/input/input.svelte create mode 100644 ui-svelte/src/lib/components/ui/label/index.ts create mode 100644 ui-svelte/src/lib/components/ui/label/label.svelte create mode 100644 ui-svelte/src/lib/components/ui/resizable/index.ts create mode 100644 ui-svelte/src/lib/components/ui/resizable/resizable-handle.svelte create mode 100644 ui-svelte/src/lib/components/ui/resizable/resizable-pane-group.svelte create mode 100644 ui-svelte/src/lib/components/ui/scroll-area/index.ts create mode 100644 ui-svelte/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte create mode 100644 ui-svelte/src/lib/components/ui/scroll-area/scroll-area.svelte create mode 100644 ui-svelte/src/lib/components/ui/select/index.ts create mode 100644 ui-svelte/src/lib/components/ui/select/select-content.svelte create mode 100644 ui-svelte/src/lib/components/ui/select/select-group-heading.svelte create mode 100644 ui-svelte/src/lib/components/ui/select/select-group.svelte create mode 100644 ui-svelte/src/lib/components/ui/select/select-item.svelte create mode 100644 ui-svelte/src/lib/components/ui/select/select-label.svelte create mode 100644 ui-svelte/src/lib/components/ui/select/select-portal.svelte create mode 100644 ui-svelte/src/lib/components/ui/select/select-scroll-down-button.svelte create mode 100644 ui-svelte/src/lib/components/ui/select/select-scroll-up-button.svelte create mode 100644 ui-svelte/src/lib/components/ui/select/select-separator.svelte create mode 100644 ui-svelte/src/lib/components/ui/select/select-trigger.svelte create mode 100644 ui-svelte/src/lib/components/ui/select/select.svelte create mode 100644 ui-svelte/src/lib/components/ui/separator/index.ts create mode 100644 ui-svelte/src/lib/components/ui/separator/separator.svelte create mode 100644 ui-svelte/src/lib/components/ui/sheet/index.ts create mode 100644 ui-svelte/src/lib/components/ui/sheet/sheet-close.svelte create mode 100644 ui-svelte/src/lib/components/ui/sheet/sheet-content.svelte create mode 100644 ui-svelte/src/lib/components/ui/sheet/sheet-description.svelte create mode 100644 ui-svelte/src/lib/components/ui/sheet/sheet-footer.svelte create mode 100644 ui-svelte/src/lib/components/ui/sheet/sheet-header.svelte create mode 100644 ui-svelte/src/lib/components/ui/sheet/sheet-overlay.svelte create mode 100644 ui-svelte/src/lib/components/ui/sheet/sheet-portal.svelte create mode 100644 ui-svelte/src/lib/components/ui/sheet/sheet-title.svelte create mode 100644 ui-svelte/src/lib/components/ui/sheet/sheet-trigger.svelte create mode 100644 ui-svelte/src/lib/components/ui/sheet/sheet.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/constants.ts create mode 100644 ui-svelte/src/lib/components/ui/sidebar/context.svelte.ts create mode 100644 ui-svelte/src/lib/components/ui/sidebar/index.ts create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-content.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-footer.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-group-action.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-group-content.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-group-label.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-group.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-header.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-input.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-inset.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-action.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-button.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-item.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-menu.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-provider.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-rail.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-separator.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar-trigger.svelte create mode 100644 ui-svelte/src/lib/components/ui/sidebar/sidebar.svelte create mode 100644 ui-svelte/src/lib/components/ui/skeleton/index.ts create mode 100644 ui-svelte/src/lib/components/ui/skeleton/skeleton.svelte create mode 100644 ui-svelte/src/lib/components/ui/switch/index.ts create mode 100644 ui-svelte/src/lib/components/ui/switch/switch.svelte create mode 100644 ui-svelte/src/lib/components/ui/table/index.ts create mode 100644 ui-svelte/src/lib/components/ui/table/table-body.svelte create mode 100644 ui-svelte/src/lib/components/ui/table/table-caption.svelte create mode 100644 ui-svelte/src/lib/components/ui/table/table-cell.svelte create mode 100644 ui-svelte/src/lib/components/ui/table/table-footer.svelte create mode 100644 ui-svelte/src/lib/components/ui/table/table-head.svelte create mode 100644 ui-svelte/src/lib/components/ui/table/table-header.svelte create mode 100644 ui-svelte/src/lib/components/ui/table/table-row.svelte create mode 100644 ui-svelte/src/lib/components/ui/table/table.svelte create mode 100644 ui-svelte/src/lib/components/ui/tabs/index.ts create mode 100644 ui-svelte/src/lib/components/ui/tabs/tabs-content.svelte create mode 100644 ui-svelte/src/lib/components/ui/tabs/tabs-list.svelte create mode 100644 ui-svelte/src/lib/components/ui/tabs/tabs-trigger.svelte create mode 100644 ui-svelte/src/lib/components/ui/tabs/tabs.svelte create mode 100644 ui-svelte/src/lib/components/ui/textarea/index.ts create mode 100644 ui-svelte/src/lib/components/ui/textarea/textarea.svelte create mode 100644 ui-svelte/src/lib/components/ui/toggle-group/index.ts create mode 100644 ui-svelte/src/lib/components/ui/toggle-group/toggle-group-item.svelte create mode 100644 ui-svelte/src/lib/components/ui/toggle-group/toggle-group.svelte create mode 100644 ui-svelte/src/lib/components/ui/toggle/index.ts create mode 100644 ui-svelte/src/lib/components/ui/toggle/toggle.svelte create mode 100644 ui-svelte/src/lib/components/ui/tooltip/index.ts create mode 100644 ui-svelte/src/lib/components/ui/tooltip/tooltip-content.svelte create mode 100644 ui-svelte/src/lib/components/ui/tooltip/tooltip-portal.svelte create mode 100644 ui-svelte/src/lib/components/ui/tooltip/tooltip-provider.svelte create mode 100644 ui-svelte/src/lib/components/ui/tooltip/tooltip-trigger.svelte create mode 100644 ui-svelte/src/lib/components/ui/tooltip/tooltip.svelte create mode 100644 ui-svelte/src/lib/hooks/is-mobile.svelte.ts create mode 100644 ui-svelte/src/lib/utils.ts diff --git a/ui-svelte/components.json b/ui-svelte/components.json new file mode 100644 index 00000000..8bc41972 --- /dev/null +++ b/ui-svelte/components.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://shadcn-svelte.com/schema.json", + "tailwind": { + "css": "src/index.css", + "baseColor": "zinc" + }, + "aliases": { + "components": "$lib/components", + "utils": "$lib/utils", + "ui": "$lib/components/ui", + "hooks": "$lib/hooks", + "lib": "$lib" + }, + "typescript": true, + "registry": "https://shadcn-svelte.com/registry", + "iconLibrary": "lucide" +} diff --git a/ui-svelte/package-lock.json b/ui-svelte/package-lock.json index 01fc2229..09fa5323 100644 --- a/ui-svelte/package-lock.json +++ b/ui-svelte/package-lock.json @@ -23,14 +23,23 @@ "unist-util-visit": "^5.1.0" }, "devDependencies": { + "@internationalized/date": "^3.12.2", + "@lucide/svelte": "^1.21.0", "@sveltejs/vite-plugin-svelte": "^7.0.0", "@tailwindcss/vite": "^4.1.8", "@tsconfig/svelte": "^5.0.4", "@types/hast": "^3.0.4", "@types/node": "^25.1.0", + "bits-ui": "^2.18.1", + "clsx": "^2.1.1", + "paneforge": "^1.0.2", + "shadcn-svelte": "^1.3.0", "svelte": "^5.46.4", "svelte-check": "^4.1.4", + "tailwind-merge": "^3.6.0", + "tailwind-variants": "^3.2.2", "tailwindcss": "^4.1.8", + "tw-animate-css": "^1.4.0", "typescript": "~5.8.3", "vite": "^8.0.0", "vite-plugin-compression2": "^2.5.1", @@ -71,6 +80,44 @@ "tslib": "^2.4.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", + "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", + "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.5", + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", + "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@internationalized/date": { + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.12.2.tgz", + "integrity": "sha512-FY1Y+H64NDs+HAF6omlnWxm3mEpfgaCSWtL5l551ZZfImA+kGjPFgrnJrGjH6lfmLL0g8Z/mBu1R3kufeCp6Jw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -127,6 +174,16 @@ "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", "license": "MIT" }, + "node_modules/@lucide/svelte": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-1.21.0.tgz", + "integrity": "sha512-MEv//A7Jv3kHukZowv/DWp1MAtUzJKYwtJsmnQ7X98lCgtac3z3NbaToDl3Q6jO3gS9sougFpcD+t+YuxOkRMw==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "svelte": "^5" + } + }, "node_modules/@napi-rs/wasm-runtime": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz", @@ -480,6 +537,16 @@ "vite": "^8.0.0-beta.7 || ^8.0.0" } }, + "node_modules/@swc/helpers": { + "version": "0.5.23", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", + "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, "node_modules/@tailwindcss/node": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", @@ -1053,6 +1120,31 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/bits-ui": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.18.1.tgz", + "integrity": "sha512-KkemzKFH4T3gt3H+P86JcnAWExjByv/6vlwjm/BoCwTPHu03yiCdxbghdJLvFReQTe0acCAiRcKfmixxD6XvlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.1", + "@floating-ui/dom": "^1.7.1", + "esm-env": "^1.1.2", + "runed": "^0.35.1", + "svelte-toolbelt": "^0.10.6", + "tabbable": "^6.2.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/huntabyte" + }, + "peerDependencies": { + "@internationalized/date": "^3.8.1", + "svelte": "^5.33.0" + } + }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", @@ -1555,6 +1647,13 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "dev": true, + "license": "MIT" + }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -1890,6 +1989,16 @@ "svelte": "^3 || ^4 || ^5.0.0-next.42" } }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -2756,6 +2865,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "dev": true, + "license": "MIT" + }, "node_modules/obug": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", @@ -2767,6 +2883,74 @@ ], "license": "MIT" }, + "node_modules/paneforge": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/paneforge/-/paneforge-1.0.2.tgz", + "integrity": "sha512-KzmIXQH1wCfwZ4RsMohD/IUtEjVhteR+c+ulb/CHYJHX8SuDXoJmChtsc/Xs5Wl8NHS4L5Q7cxL8MG40gSU1bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "runed": "^0.23.4", + "svelte-toolbelt": "^0.9.2" + }, + "peerDependencies": { + "svelte": "^5.29.0" + } + }, + "node_modules/paneforge/node_modules/runed": { + "version": "0.23.4", + "resolved": "https://registry.npmjs.org/runed/-/runed-0.23.4.tgz", + "integrity": "sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/huntabyte", + "https://github.com/sponsors/tglide" + ], + "dependencies": { + "esm-env": "^1.0.0" + }, + "peerDependencies": { + "svelte": "^5.7.0" + } + }, + "node_modules/paneforge/node_modules/svelte-toolbelt": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.9.3.tgz", + "integrity": "sha512-HCSWxCtVmv+c6g1ACb8LTwHVbDqLKJvHpo6J8TaqwUme2hj9ATJCpjCPNISR1OCq2Q4U1KT41if9ON0isINQZw==", + "dev": true, + "funding": [ + "https://github.com/sponsors/huntabyte" + ], + "dependencies": { + "clsx": "^2.1.1", + "runed": "^0.29.0", + "style-to-object": "^1.0.8" + }, + "engines": { + "node": ">=18", + "pnpm": ">=8.7.0" + }, + "peerDependencies": { + "svelte": "^5.30.2" + } + }, + "node_modules/paneforge/node_modules/svelte-toolbelt/node_modules/runed": { + "version": "0.29.2", + "resolved": "https://registry.npmjs.org/runed/-/runed-0.29.2.tgz", + "integrity": "sha512-0cq6cA6sYGZwl/FvVqjx9YN+1xEBu9sDDyuWdDW1yWX7JF2wmvmVKfH+hVCZs+csW+P3ARH92MjI3H9QTagOQA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/huntabyte", + "https://github.com/sponsors/tglide" + ], + "license": "MIT", + "dependencies": { + "esm-env": "^1.0.0" + }, + "peerDependencies": { + "svelte": "^5.7.0" + } + }, "node_modules/parse5": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", @@ -3018,6 +3202,31 @@ "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" } }, + "node_modules/runed": { + "version": "0.35.1", + "resolved": "https://registry.npmjs.org/runed/-/runed-0.35.1.tgz", + "integrity": "sha512-2F4Q/FZzbeJTFdIS/PuOoPRSm92sA2LhzTnv6FXhCoENb3huf5+fDuNOg1LNvGOouy3u/225qxmuJvcV3IZK5Q==", + "dev": true, + "funding": [ + "https://github.com/sponsors/huntabyte", + "https://github.com/sponsors/tglide" + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3", + "esm-env": "^1.0.0", + "lz-string": "^1.5.0" + }, + "peerDependencies": { + "@sveltejs/kit": "^2.21.0", + "svelte": "^5.7.0" + }, + "peerDependenciesMeta": { + "@sveltejs/kit": { + "optional": true + } + } + }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -3031,6 +3240,35 @@ "node": ">=6" } }, + "node_modules/shadcn-svelte": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/shadcn-svelte/-/shadcn-svelte-1.3.0.tgz", + "integrity": "sha512-Pd4ICWTkTks/b2YU4c9vF2XsX1x5HFPRl5bKszS1LcnWS83x+7T4WiIvbWz8Qh9knkcGZ+SCz1+Dmhdq+AYooA==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^14.0.0", + "node-fetch-native": "^1.6.4", + "postcss": "^8.5.5", + "tailwind-merge": "^3.0.0" + }, + "bin": { + "shadcn-svelte": "dist/index.mjs" + }, + "peerDependencies": { + "svelte": "^5.0.0" + } + }, + "node_modules/shadcn-svelte/node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -3086,6 +3324,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, "node_modules/svelte": { "version": "5.55.7", "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.55.7.tgz", @@ -3150,6 +3398,65 @@ "url": "https://github.com/sponsors/ItalyPaleAle" } }, + "node_modules/svelte-toolbelt": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.10.6.tgz", + "integrity": "sha512-YWuX+RE+CnWYx09yseAe4ZVMM7e7GRFZM6OYWpBKOb++s+SQ8RBIMMe+Bs/CznBMc0QPLjr+vDBxTAkozXsFXQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/huntabyte" + ], + "dependencies": { + "clsx": "^2.1.1", + "runed": "^0.35.1", + "style-to-object": "^1.0.8" + }, + "engines": { + "node": ">=18", + "pnpm": ">=8.7.0" + }, + "peerDependencies": { + "svelte": "^5.30.2" + } + }, + "node_modules/tabbable": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.5.0.tgz", + "integrity": "sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tailwind-merge": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", + "integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwind-variants": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-3.2.2.tgz", + "integrity": "sha512-Mi4kHeMTLvKlM98XPnK+7HoBPmf4gygdFmqQPaDivc3DpYS6aIY6KiG/PgThrGvii5YZJqRsPz0aPyhoFzmZgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.x", + "pnpm": ">=7.x" + }, + "peerDependencies": { + "tailwind-merge": ">=3.0.0", + "tailwindcss": "*" + }, + "peerDependenciesMeta": { + "tailwind-merge": { + "optional": true + } + } + }, "node_modules/tailwindcss": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", @@ -3247,8 +3554,17 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "license": "0BSD", - "optional": true + "license": "0BSD" + }, + "node_modules/tw-animate-css": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } }, "node_modules/typescript": { "version": "5.8.3", diff --git a/ui-svelte/package.json b/ui-svelte/package.json index efedc65b..2e73a344 100644 --- a/ui-svelte/package.json +++ b/ui-svelte/package.json @@ -12,20 +12,30 @@ "test:watch": "vitest" }, "devDependencies": { + "@internationalized/date": "^3.12.2", + "@lucide/svelte": "^1.21.0", "@sveltejs/vite-plugin-svelte": "^7.0.0", "@tailwindcss/vite": "^4.1.8", "@tsconfig/svelte": "^5.0.4", "@types/hast": "^3.0.4", "@types/node": "^25.1.0", + "bits-ui": "^2.18.1", + "clsx": "^2.1.1", + "paneforge": "^1.0.2", + "shadcn-svelte": "^1.3.0", "svelte": "^5.46.4", "svelte-check": "^4.1.4", + "tailwind-merge": "^3.6.0", + "tailwind-variants": "^3.2.2", "tailwindcss": "^4.1.8", + "tw-animate-css": "^1.4.0", "typescript": "~5.8.3", "vite": "^8.0.0", "vite-plugin-compression2": "^2.5.1", "vitest": "^4.1.0" }, "dependencies": { + "chart.js": "4.5.1", "highlight.js": "^11.11.1", "katex": "^0.16.28", "lucide-svelte": "^0.563.0", @@ -35,7 +45,6 @@ "remark-math": "^6.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", - "chart.js": "4.5.1", "svelte-spa-router": "^4.0.1", "unified": "^11.0.5", "unist-util-visit": "^5.1.0" diff --git a/ui-svelte/src/App.svelte b/ui-svelte/src/App.svelte index df2dc1a0..2e0d2620 100644 --- a/ui-svelte/src/App.svelte +++ b/ui-svelte/src/App.svelte @@ -27,7 +27,7 @@ } $effect(() => { - document.documentElement.setAttribute("data-theme", $isDarkMode ? "dark" : "light"); + document.documentElement.classList.toggle("dark", $isDarkMode); }); $effect(() => { diff --git a/ui-svelte/src/index.css b/ui-svelte/src/index.css index 1f833519..82ebd7dd 100644 --- a/ui-svelte/src/index.css +++ b/ui-svelte/src/index.css @@ -1,100 +1,184 @@ @import "tailwindcss"; +@import "tw-animate-css"; @import "katex/dist/katex.min.css"; -@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *)); -@theme { - --color-background: rgba(252, 252, 249, 1); - --color-surface: rgba(255, 255, 253, 1); +@custom-variant dark (&:is(.dark *)); - /* text colors */ - --color-txtmain: rgba(19, 52, 59, 1); - --color-txtsecondary: rgba(98, 108, 113, 1); - --color-navlink-active: rgba(245, 245, 245, 1); +:root { + --radius: 0.625rem; - --color-primary: rgba(50, 184, 198, 1); + /* shadcn base palette (zinc) */ + --background: oklch(1 0 0); + --foreground: oklch(0.141 0.005 285.823); + --card: oklch(1 0 0); + --card-foreground: oklch(0.141 0.005 285.823); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.141 0.005 285.823); - --color-primary-hover: rgba(29, 116, 128, 1); - --color-primary-active: rgba(26, 104, 115, 1); - --color-secondary: rgba(94, 82, 64, 0.12); - --color-secondary-hover: rgba(94, 82, 64, 0.2); - --color-secondary-active: rgba(94, 82, 64, 0.25); - --color-border: rgba(94, 82, 64, 0.3); - --color-btn-primary-text: rgba(252, 252, 249, 1); - --color-card-border: rgba(94, 82, 64, 0.12); - --color-card-border-inner: rgba(94, 82, 64, 0.12); - --color-error: rgba(192, 21, 47, 1); - --color-success: rgba(33, 128, 141, 1); - --color-warning: rgb(244, 155, 0); - --color-info: rgba(98, 108, 113, 1); - --color-focus-ring: rgba(33, 128, 141, 0.4); - --color-select-caret: rgba(19, 52, 59, 0.8); - --color-btn-border: rgba(94, 82, 64, 0.7); + /* brand accent: llama-swap teal */ + --primary: rgb(50 184 198); + --primary-foreground: oklch(0.985 0 0); + + --secondary: oklch(0.967 0.001 286.375); + --secondary-foreground: oklch(0.21 0.006 285.885); + --muted: oklch(0.967 0.001 286.375); + --muted-foreground: oklch(0.552 0.016 285.938); + --accent: oklch(0.967 0.001 286.375); + --accent-foreground: oklch(0.21 0.006 285.885); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.92 0.004 286.32); + --input: oklch(0.92 0.004 286.32); + --ring: rgb(50 184 198); + + --chart-1: rgb(50 184 198); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.141 0.005 285.823); + --sidebar-primary: rgb(50 184 198); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.967 0.001 286.375); + --sidebar-accent-foreground: oklch(0.21 0.006 285.885); + --sidebar-border: oklch(0.92 0.004 286.32); + --sidebar-ring: rgb(50 184 198); + + /* semantic status colors (shared light/dark-aware below) */ + --success: oklch(0.6 0.118 184.704); + --warning: oklch(0.769 0.17 70.08); + --info: oklch(0.552 0.016 285.938); } -@layer theme { - /* over ride theme for dark mode */ - [data-theme="dark"] { - --color-background: rgba(31, 33, 33, 1); - --color-surface: rgba(38, 40, 40, 1); - /* text colors */ - --color-txtmain: rgba(245, 245, 245, 1); - --color-txtsecondary: rgba(167, 169, 169, 0.7); +.dark { + --background: oklch(0.141 0.005 285.823); + --foreground: oklch(0.985 0 0); + --card: oklch(0.21 0.006 285.885); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.21 0.006 285.885); + --popover-foreground: oklch(0.985 0 0); - --color-navlink-active: rgba(245, 245, 245, 1); + /* brand accent: deeper teal for dark surfaces */ + --primary: rgb(45 166 178); + --primary-foreground: oklch(0.141 0.005 285.823); - --color-primary: rgba(33, 128, 141, 1); - --color-primary-hover: rgba(45, 166, 178, 1); - --color-primary-active: rgba(41, 150, 161, 1); - --color-secondary: rgba(119, 124, 124, 0.15); - --color-secondary-hover: rgba(119, 124, 124, 0.25); - --color-secondary-active: rgba(119, 124, 124, 0.3); - --color-border: rgba(119, 124, 124, 0.3); - --color-error: rgba(255, 84, 89, 1); - --color-success: rgba(50, 184, 198, 1); - --color-warning: rgb(244, 155, 0); - --color-info: rgba(167, 169, 169, 1); - --color-focus-ring: rgba(50, 184, 198, 0.4); - --color-btn-primary-text: rgba(19, 52, 59, 1); - --color-card-border: rgba(119, 124, 124, 0.2); - --color-card-border-inner: rgba(119, 124, 124, 0.15); - --shadow-inset-sm: inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 -1px 0 rgba(0, 0, 0, 0.15); - --button-border-secondary: rgba(119, 124, 124, 0.2); - } + --secondary: oklch(0.274 0.006 286.033); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.274 0.006 286.033); + --muted-foreground: oklch(0.705 0.015 286.067); + --accent: oklch(0.274 0.006 286.033); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: rgb(50 184 198); + + --chart-1: rgb(50 184 198); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + + --sidebar: oklch(0.21 0.006 285.885); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: rgb(50 184 198); + --sidebar-primary-foreground: oklch(0.141 0.005 285.823); + --sidebar-accent: oklch(0.274 0.006 286.033); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: rgb(50 184 198); + + --success: oklch(0.696 0.17 162.48); + --warning: oklch(0.769 0.17 70.08); + --info: oklch(0.705 0.015 286.067); +} + +@theme inline { + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); + + --color-success: var(--success); + --color-warning: var(--warning); + --color-info: var(--info); + --color-error: var(--destructive); + + /* legacy aliases (transitional — removed as views migrate) */ + --color-surface: var(--card); + --color-txtmain: var(--foreground); + --color-txtsecondary: var(--muted-foreground); + --color-navlink-active: var(--primary-foreground); + --color-card-border: var(--border); + --color-card-border-inner: var(--border); + --color-btn-border: var(--border); + --color-btn-primary-text: var(--primary-foreground); } @layer base { + * { + @apply border-border outline-ring/50; + } + body { - /* example of how colors using theme colors*/ - @apply bg-background text-txtmain; + @apply bg-background text-foreground; } h1 { - @apply text-4xl text-txtmain font-bold pb-4; + @apply text-3xl font-bold tracking-tight pb-4; } h2 { - @apply text-3xl text-txtmain font-bold pb-4; + @apply text-2xl font-bold tracking-tight pb-4; } h3 { - @apply text-2xl text-txtmain font-bold pb-4; + @apply text-xl font-semibold tracking-tight pb-4; } h4 { - @apply text-xl text-txtmain font-bold pb-4; + @apply text-lg font-semibold pb-4; } h5 { - @apply text-lg text-txtmain font-bold pb-4; + @apply text-base font-semibold pb-4; } h6 { - @apply text-base text-txtmain font-bold pb-4; + @apply text-sm font-semibold pb-4; } } -/* define CSS classes here for specific types of components */ +/* Transitional component classes — kept until all views move to shadcn primitives. */ @layer components { - .container { - @apply px-4; - } - - /* Tables */ table th { @apply p-2 font-semibold; } @@ -102,77 +186,67 @@ @apply p-2; } - /* Navigation Header */ - .navlink { - @apply text-txtsecondary hover:bg-secondary hover:text-txtmain rounded-lg p-2; + @apply text-muted-foreground hover:bg-accent hover:text-foreground rounded-lg p-2; } .navlink.active { - @apply bg-primary text-navlink-active; + @apply bg-primary text-primary-foreground; } - /* Card component */ .card { - @apply bg-surface rounded-lg border border-card-border shadow-sm overflow-hidden p-4; + @apply bg-card text-card-foreground rounded-xl border shadow-sm overflow-hidden p-4; } - - .card:hover { - @apply shadow-md; - } - .card__body { @apply p-4; } - .card__header, .card__footer { - @apply p-4 border-b border-card-border-inner; + @apply p-4 border-b; } - /* Status Badges */ .status { - @apply inline-block px-2 py-1 text-xs font-medium rounded-lg; + @apply inline-flex items-center px-2 py-0.5 text-xs font-medium rounded-md; } - .status--ready { @apply bg-success/10 text-success; } - .status--starting, .status--stopping, .status--queued { @apply bg-warning/10 text-warning; } - .status--stopped { - @apply bg-error/10 text-error; + @apply bg-destructive/10 text-destructive; } - /* Buttons */ .btn { - @apply bg-surface py-2 px-4 text-sm rounded-md border transition-colors duration-200 border-btn-border; + @apply bg-background py-2 px-4 text-sm rounded-md border transition-colors duration-200; } - .btn:hover { - cursor: pointer; + @apply bg-muted cursor-pointer; } - .btn--sm { @apply px-2 py-0.5 text-xs; } - .btn:disabled { @apply opacity-50 cursor-not-allowed; } } -@layer utilities { - .ml-2 { - margin-left: 0.5rem; - } +@utility activity-link { + background: linear-gradient(90deg, #6366f1, #8b5cf6, #a855f7, #8b5cf6, #6366f1); + background-size: 200% 100%; + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + animation: gradient-shift 2s linear infinite; +} - .my-8 { - margin-top: 2rem; - margin-bottom: 2rem; +@keyframes gradient-shift { + 0% { + background-position: 0% 50%; + } + 100% { + background-position: 200% 50%; } } diff --git a/ui-svelte/src/lib/components/ui/badge/badge.svelte b/ui-svelte/src/lib/components/ui/badge/badge.svelte new file mode 100644 index 00000000..51bbc23e --- /dev/null +++ b/ui-svelte/src/lib/components/ui/badge/badge.svelte @@ -0,0 +1,49 @@ + + + + + + {@render children?.()} + diff --git a/ui-svelte/src/lib/components/ui/badge/index.ts b/ui-svelte/src/lib/components/ui/badge/index.ts new file mode 100644 index 00000000..64e0aa9b --- /dev/null +++ b/ui-svelte/src/lib/components/ui/badge/index.ts @@ -0,0 +1,2 @@ +export { default as Badge } from "./badge.svelte"; +export { badgeVariants, type BadgeVariant } from "./badge.svelte"; diff --git a/ui-svelte/src/lib/components/ui/button/button.svelte b/ui-svelte/src/lib/components/ui/button/button.svelte new file mode 100644 index 00000000..89cedcb7 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/button/button.svelte @@ -0,0 +1,82 @@ + + + + +{#if href} + + {@render children?.()} + +{:else} + +{/if} diff --git a/ui-svelte/src/lib/components/ui/button/index.ts b/ui-svelte/src/lib/components/ui/button/index.ts new file mode 100644 index 00000000..fb585d76 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/button/index.ts @@ -0,0 +1,17 @@ +import Root, { + type ButtonProps, + type ButtonSize, + type ButtonVariant, + buttonVariants, +} from "./button.svelte"; + +export { + Root, + type ButtonProps as Props, + // + Root as Button, + buttonVariants, + type ButtonProps, + type ButtonSize, + type ButtonVariant, +}; diff --git a/ui-svelte/src/lib/components/ui/card/card-action.svelte b/ui-svelte/src/lib/components/ui/card/card-action.svelte new file mode 100644 index 00000000..7c48844a --- /dev/null +++ b/ui-svelte/src/lib/components/ui/card/card-action.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/card/card-content.svelte b/ui-svelte/src/lib/components/ui/card/card-content.svelte new file mode 100644 index 00000000..4f60ee3a --- /dev/null +++ b/ui-svelte/src/lib/components/ui/card/card-content.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/card/card-description.svelte b/ui-svelte/src/lib/components/ui/card/card-description.svelte new file mode 100644 index 00000000..9b20ac70 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/card/card-description.svelte @@ -0,0 +1,20 @@ + + +

+ {@render children?.()} +

diff --git a/ui-svelte/src/lib/components/ui/card/card-footer.svelte b/ui-svelte/src/lib/components/ui/card/card-footer.svelte new file mode 100644 index 00000000..1efff6d9 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/card/card-footer.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/card/card-header.svelte b/ui-svelte/src/lib/components/ui/card/card-header.svelte new file mode 100644 index 00000000..7eb69e12 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/card/card-header.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/card/card-title.svelte b/ui-svelte/src/lib/components/ui/card/card-title.svelte new file mode 100644 index 00000000..1523fc52 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/card/card-title.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/card/card.svelte b/ui-svelte/src/lib/components/ui/card/card.svelte new file mode 100644 index 00000000..2b4f81af --- /dev/null +++ b/ui-svelte/src/lib/components/ui/card/card.svelte @@ -0,0 +1,22 @@ + + +
img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col", className)} + {...restProps} +> + {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/card/index.ts b/ui-svelte/src/lib/components/ui/card/index.ts new file mode 100644 index 00000000..4d3fce48 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/card/index.ts @@ -0,0 +1,25 @@ +import Root from "./card.svelte"; +import Content from "./card-content.svelte"; +import Description from "./card-description.svelte"; +import Footer from "./card-footer.svelte"; +import Header from "./card-header.svelte"; +import Title from "./card-title.svelte"; +import Action from "./card-action.svelte"; + +export { + Root, + Content, + Description, + Footer, + Header, + Title, + Action, + // + Root as Card, + Content as CardContent, + Description as CardDescription, + Footer as CardFooter, + Header as CardHeader, + Title as CardTitle, + Action as CardAction, +}; diff --git a/ui-svelte/src/lib/components/ui/dialog/dialog-close.svelte b/ui-svelte/src/lib/components/ui/dialog/dialog-close.svelte new file mode 100644 index 00000000..de68f2f0 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dialog/dialog-close.svelte @@ -0,0 +1,11 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dialog/dialog-content.svelte b/ui-svelte/src/lib/components/ui/dialog/dialog-content.svelte new file mode 100644 index 00000000..c0551ee3 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dialog/dialog-content.svelte @@ -0,0 +1,48 @@ + + + + + + {@render children?.()} + {#if showCloseButton} + + {#snippet child({ props })} + + {/snippet} + + {/if} + + diff --git a/ui-svelte/src/lib/components/ui/dialog/dialog-description.svelte b/ui-svelte/src/lib/components/ui/dialog/dialog-description.svelte new file mode 100644 index 00000000..0102d910 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dialog/dialog-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dialog/dialog-footer.svelte b/ui-svelte/src/lib/components/ui/dialog/dialog-footer.svelte new file mode 100644 index 00000000..e23160ae --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dialog/dialog-footer.svelte @@ -0,0 +1,32 @@ + + +
+ {@render children?.()} + {#if showCloseButton} + + {#snippet child({ props })} + + {/snippet} + + {/if} +
diff --git a/ui-svelte/src/lib/components/ui/dialog/dialog-header.svelte b/ui-svelte/src/lib/components/ui/dialog/dialog-header.svelte new file mode 100644 index 00000000..c3ce8a24 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dialog/dialog-header.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/dialog/dialog-overlay.svelte b/ui-svelte/src/lib/components/ui/dialog/dialog-overlay.svelte new file mode 100644 index 00000000..19f69f05 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dialog/dialog-overlay.svelte @@ -0,0 +1,17 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dialog/dialog-portal.svelte b/ui-svelte/src/lib/components/ui/dialog/dialog-portal.svelte new file mode 100644 index 00000000..ccfa79ca --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dialog/dialog-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dialog/dialog-title.svelte b/ui-svelte/src/lib/components/ui/dialog/dialog-title.svelte new file mode 100644 index 00000000..6ff1a4a5 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dialog/dialog-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dialog/dialog-trigger.svelte b/ui-svelte/src/lib/components/ui/dialog/dialog-trigger.svelte new file mode 100644 index 00000000..589ee0c3 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dialog/dialog-trigger.svelte @@ -0,0 +1,11 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dialog/dialog.svelte b/ui-svelte/src/lib/components/ui/dialog/dialog.svelte new file mode 100644 index 00000000..211672c6 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dialog/dialog.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dialog/index.ts b/ui-svelte/src/lib/components/ui/dialog/index.ts new file mode 100644 index 00000000..076cef52 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dialog/index.ts @@ -0,0 +1,34 @@ +import Root from "./dialog.svelte"; +import Portal from "./dialog-portal.svelte"; +import Title from "./dialog-title.svelte"; +import Footer from "./dialog-footer.svelte"; +import Header from "./dialog-header.svelte"; +import Overlay from "./dialog-overlay.svelte"; +import Content from "./dialog-content.svelte"; +import Description from "./dialog-description.svelte"; +import Trigger from "./dialog-trigger.svelte"; +import Close from "./dialog-close.svelte"; + +export { + Root, + Title, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + Close, + // + Root as Dialog, + Title as DialogTitle, + Portal as DialogPortal, + Footer as DialogFooter, + Header as DialogHeader, + Trigger as DialogTrigger, + Overlay as DialogOverlay, + Content as DialogContent, + Description as DialogDescription, + Close as DialogClose, +}; diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte new file mode 100644 index 00000000..e0e19718 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 00000000..a81b48d0 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,44 @@ + + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else if checked} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 00000000..261a5b08 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,31 @@ + + + + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte new file mode 100644 index 00000000..433540fd --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte @@ -0,0 +1,22 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte new file mode 100644 index 00000000..aca1f7bd --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 00000000..c425190d --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,27 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 00000000..e0c534fe --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,24 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte new file mode 100644 index 00000000..274cfef7 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte new file mode 100644 index 00000000..189aef40 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 00000000..c8aa07b1 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,34 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 00000000..90f1b6f1 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 00000000..ed7cc85a --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 00000000..b5750d4d --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,17 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 00000000..fab0275d --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte new file mode 100644 index 00000000..f0445813 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte new file mode 100644 index 00000000..cb053444 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte new file mode 100644 index 00000000..cb4bc621 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/dropdown-menu/index.ts b/ui-svelte/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 00000000..7850c6a3 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,54 @@ +import Root from "./dropdown-menu.svelte"; +import Sub from "./dropdown-menu-sub.svelte"; +import CheckboxGroup from "./dropdown-menu-checkbox-group.svelte"; +import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; +import Content from "./dropdown-menu-content.svelte"; +import Group from "./dropdown-menu-group.svelte"; +import Item from "./dropdown-menu-item.svelte"; +import Label from "./dropdown-menu-label.svelte"; +import RadioGroup from "./dropdown-menu-radio-group.svelte"; +import RadioItem from "./dropdown-menu-radio-item.svelte"; +import Separator from "./dropdown-menu-separator.svelte"; +import Shortcut from "./dropdown-menu-shortcut.svelte"; +import Trigger from "./dropdown-menu-trigger.svelte"; +import SubContent from "./dropdown-menu-sub-content.svelte"; +import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; +import GroupHeading from "./dropdown-menu-group-heading.svelte"; +import Portal from "./dropdown-menu-portal.svelte"; + +export { + CheckboxGroup, + CheckboxItem, + Content, + Portal, + Root as DropdownMenu, + CheckboxGroup as DropdownMenuCheckboxGroup, + CheckboxItem as DropdownMenuCheckboxItem, + Content as DropdownMenuContent, + Portal as DropdownMenuPortal, + Group as DropdownMenuGroup, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + RadioGroup as DropdownMenuRadioGroup, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + Shortcut as DropdownMenuShortcut, + Sub as DropdownMenuSub, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + Trigger as DropdownMenuTrigger, + GroupHeading as DropdownMenuGroupHeading, + Group, + GroupHeading, + Item, + Label, + RadioGroup, + RadioItem, + Root, + Separator, + Shortcut, + Sub, + SubContent, + SubTrigger, + Trigger, +}; diff --git a/ui-svelte/src/lib/components/ui/input/index.ts b/ui-svelte/src/lib/components/ui/input/index.ts new file mode 100644 index 00000000..f47b6d3f --- /dev/null +++ b/ui-svelte/src/lib/components/ui/input/index.ts @@ -0,0 +1,7 @@ +import Root from "./input.svelte"; + +export { + Root, + // + Root as Input, +}; diff --git a/ui-svelte/src/lib/components/ui/input/input.svelte b/ui-svelte/src/lib/components/ui/input/input.svelte new file mode 100644 index 00000000..fe7db38f --- /dev/null +++ b/ui-svelte/src/lib/components/ui/input/input.svelte @@ -0,0 +1,48 @@ + + +{#if type === "file"} + +{:else} + +{/if} diff --git a/ui-svelte/src/lib/components/ui/label/index.ts b/ui-svelte/src/lib/components/ui/label/index.ts new file mode 100644 index 00000000..8bfca0b3 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/label/index.ts @@ -0,0 +1,7 @@ +import Root from "./label.svelte"; + +export { + Root, + // + Root as Label, +}; diff --git a/ui-svelte/src/lib/components/ui/label/label.svelte b/ui-svelte/src/lib/components/ui/label/label.svelte new file mode 100644 index 00000000..d5e30863 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/label/label.svelte @@ -0,0 +1,20 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/resizable/index.ts b/ui-svelte/src/lib/components/ui/resizable/index.ts new file mode 100644 index 00000000..2e37f114 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/resizable/index.ts @@ -0,0 +1,13 @@ +import { Pane } from "paneforge"; +import Handle from "./resizable-handle.svelte"; +import PaneGroup from "./resizable-pane-group.svelte"; + +export { + PaneGroup, + Pane, + Handle, + // + PaneGroup as ResizablePaneGroup, + Pane as ResizablePane, + Handle as ResizableHandle, +}; diff --git a/ui-svelte/src/lib/components/ui/resizable/resizable-handle.svelte b/ui-svelte/src/lib/components/ui/resizable/resizable-handle.svelte new file mode 100644 index 00000000..4650600a --- /dev/null +++ b/ui-svelte/src/lib/components/ui/resizable/resizable-handle.svelte @@ -0,0 +1,27 @@ + + +div]:rotate-90", + className + )} + {...restProps} +> + {#if withHandle} +
+ {/if} +
diff --git a/ui-svelte/src/lib/components/ui/resizable/resizable-pane-group.svelte b/ui-svelte/src/lib/components/ui/resizable/resizable-pane-group.svelte new file mode 100644 index 00000000..4b1801da --- /dev/null +++ b/ui-svelte/src/lib/components/ui/resizable/resizable-pane-group.svelte @@ -0,0 +1,24 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/scroll-area/index.ts b/ui-svelte/src/lib/components/ui/scroll-area/index.ts new file mode 100644 index 00000000..e86a25b2 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/scroll-area/index.ts @@ -0,0 +1,10 @@ +import Scrollbar from "./scroll-area-scrollbar.svelte"; +import Root from "./scroll-area.svelte"; + +export { + Root, + Scrollbar, + //, + Root as ScrollArea, + Scrollbar as ScrollAreaScrollbar, +}; diff --git a/ui-svelte/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte b/ui-svelte/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte new file mode 100644 index 00000000..b9518f36 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte @@ -0,0 +1,30 @@ + + + + {@render children?.()} + + diff --git a/ui-svelte/src/lib/components/ui/scroll-area/scroll-area.svelte b/ui-svelte/src/lib/components/ui/scroll-area/scroll-area.svelte new file mode 100644 index 00000000..d4d96d0f --- /dev/null +++ b/ui-svelte/src/lib/components/ui/scroll-area/scroll-area.svelte @@ -0,0 +1,43 @@ + + + + + {@render children?.()} + + {#if orientation === "vertical" || orientation === "both"} + + {/if} + {#if orientation === "horizontal" || orientation === "both"} + + {/if} + + diff --git a/ui-svelte/src/lib/components/ui/select/index.ts b/ui-svelte/src/lib/components/ui/select/index.ts new file mode 100644 index 00000000..4dec358b --- /dev/null +++ b/ui-svelte/src/lib/components/ui/select/index.ts @@ -0,0 +1,37 @@ +import Root from "./select.svelte"; +import Group from "./select-group.svelte"; +import Label from "./select-label.svelte"; +import Item from "./select-item.svelte"; +import Content from "./select-content.svelte"; +import Trigger from "./select-trigger.svelte"; +import Separator from "./select-separator.svelte"; +import ScrollDownButton from "./select-scroll-down-button.svelte"; +import ScrollUpButton from "./select-scroll-up-button.svelte"; +import GroupHeading from "./select-group-heading.svelte"; +import Portal from "./select-portal.svelte"; + +export { + Root, + Group, + Label, + Item, + Content, + Trigger, + Separator, + ScrollDownButton, + ScrollUpButton, + GroupHeading, + Portal, + // + Root as Select, + Group as SelectGroup, + Label as SelectLabel, + Item as SelectItem, + Content as SelectContent, + Trigger as SelectTrigger, + Separator as SelectSeparator, + ScrollDownButton as SelectScrollDownButton, + ScrollUpButton as SelectScrollUpButton, + GroupHeading as SelectGroupHeading, + Portal as SelectPortal, +}; diff --git a/ui-svelte/src/lib/components/ui/select/select-content.svelte b/ui-svelte/src/lib/components/ui/select/select-content.svelte new file mode 100644 index 00000000..bb1e2ac2 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/select/select-content.svelte @@ -0,0 +1,45 @@ + + + + + + + {@render children?.()} + + + + diff --git a/ui-svelte/src/lib/components/ui/select/select-group-heading.svelte b/ui-svelte/src/lib/components/ui/select/select-group-heading.svelte new file mode 100644 index 00000000..1fab5f00 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/select/select-group-heading.svelte @@ -0,0 +1,21 @@ + + + + {@render children?.()} + diff --git a/ui-svelte/src/lib/components/ui/select/select-group.svelte b/ui-svelte/src/lib/components/ui/select/select-group.svelte new file mode 100644 index 00000000..f666cb22 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/select/select-group.svelte @@ -0,0 +1,17 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/select/select-item.svelte b/ui-svelte/src/lib/components/ui/select/select-item.svelte new file mode 100644 index 00000000..e4a53d29 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/select/select-item.svelte @@ -0,0 +1,40 @@ + + + + {#snippet children({ selected, highlighted })} + + {#if selected} + + {/if} + + + {#if childrenProp} + {@render childrenProp({ selected, highlighted })} + {:else} + {label || value} + {/if} + + {/snippet} + diff --git a/ui-svelte/src/lib/components/ui/select/select-label.svelte b/ui-svelte/src/lib/components/ui/select/select-label.svelte new file mode 100644 index 00000000..69bcfdfe --- /dev/null +++ b/ui-svelte/src/lib/components/ui/select/select-label.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/select/select-portal.svelte b/ui-svelte/src/lib/components/ui/select/select-portal.svelte new file mode 100644 index 00000000..424bcddc --- /dev/null +++ b/ui-svelte/src/lib/components/ui/select/select-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/select/select-scroll-down-button.svelte b/ui-svelte/src/lib/components/ui/select/select-scroll-down-button.svelte new file mode 100644 index 00000000..94f41cdd --- /dev/null +++ b/ui-svelte/src/lib/components/ui/select/select-scroll-down-button.svelte @@ -0,0 +1,20 @@ + + + + + diff --git a/ui-svelte/src/lib/components/ui/select/select-scroll-up-button.svelte b/ui-svelte/src/lib/components/ui/select/select-scroll-up-button.svelte new file mode 100644 index 00000000..035ea094 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/select/select-scroll-up-button.svelte @@ -0,0 +1,20 @@ + + + + + diff --git a/ui-svelte/src/lib/components/ui/select/select-separator.svelte b/ui-svelte/src/lib/components/ui/select/select-separator.svelte new file mode 100644 index 00000000..3b24bab6 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/select/select-separator.svelte @@ -0,0 +1,18 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/select/select-trigger.svelte b/ui-svelte/src/lib/components/ui/select/select-trigger.svelte new file mode 100644 index 00000000..03d06d0f --- /dev/null +++ b/ui-svelte/src/lib/components/ui/select/select-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/ui-svelte/src/lib/components/ui/select/select.svelte b/ui-svelte/src/lib/components/ui/select/select.svelte new file mode 100644 index 00000000..05eb6634 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/select/select.svelte @@ -0,0 +1,11 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/separator/index.ts b/ui-svelte/src/lib/components/ui/separator/index.ts new file mode 100644 index 00000000..82442d2c --- /dev/null +++ b/ui-svelte/src/lib/components/ui/separator/index.ts @@ -0,0 +1,7 @@ +import Root from "./separator.svelte"; + +export { + Root, + // + Root as Separator, +}; diff --git a/ui-svelte/src/lib/components/ui/separator/separator.svelte b/ui-svelte/src/lib/components/ui/separator/separator.svelte new file mode 100644 index 00000000..5fd8a429 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/separator/separator.svelte @@ -0,0 +1,23 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/sheet/index.ts b/ui-svelte/src/lib/components/ui/sheet/index.ts new file mode 100644 index 00000000..28d7da1c --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sheet/index.ts @@ -0,0 +1,34 @@ +import Root from "./sheet.svelte"; +import Portal from "./sheet-portal.svelte"; +import Trigger from "./sheet-trigger.svelte"; +import Close from "./sheet-close.svelte"; +import Overlay from "./sheet-overlay.svelte"; +import Content from "./sheet-content.svelte"; +import Header from "./sheet-header.svelte"; +import Footer from "./sheet-footer.svelte"; +import Title from "./sheet-title.svelte"; +import Description from "./sheet-description.svelte"; + +export { + Root, + Close, + Trigger, + Portal, + Overlay, + Content, + Header, + Footer, + Title, + Description, + // + Root as Sheet, + Close as SheetClose, + Trigger as SheetTrigger, + Portal as SheetPortal, + Overlay as SheetOverlay, + Content as SheetContent, + Header as SheetHeader, + Footer as SheetFooter, + Title as SheetTitle, + Description as SheetDescription, +}; diff --git a/ui-svelte/src/lib/components/ui/sheet/sheet-close.svelte b/ui-svelte/src/lib/components/ui/sheet/sheet-close.svelte new file mode 100644 index 00000000..ae382c12 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sheet/sheet-close.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/sheet/sheet-content.svelte b/ui-svelte/src/lib/components/ui/sheet/sheet-content.svelte new file mode 100644 index 00000000..20957dcc --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sheet/sheet-content.svelte @@ -0,0 +1,55 @@ + + + + + + + + {@render children?.()} + {#if showCloseButton} + + {#snippet child({ props })} + + {/snippet} + + {/if} + + diff --git a/ui-svelte/src/lib/components/ui/sheet/sheet-description.svelte b/ui-svelte/src/lib/components/ui/sheet/sheet-description.svelte new file mode 100644 index 00000000..333b17a7 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sheet/sheet-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/sheet/sheet-footer.svelte b/ui-svelte/src/lib/components/ui/sheet/sheet-footer.svelte new file mode 100644 index 00000000..ad9e07bb --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sheet/sheet-footer.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/sheet/sheet-header.svelte b/ui-svelte/src/lib/components/ui/sheet/sheet-header.svelte new file mode 100644 index 00000000..504465f9 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sheet/sheet-header.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/sheet/sheet-overlay.svelte b/ui-svelte/src/lib/components/ui/sheet/sheet-overlay.svelte new file mode 100644 index 00000000..8d338474 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sheet/sheet-overlay.svelte @@ -0,0 +1,17 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/sheet/sheet-portal.svelte b/ui-svelte/src/lib/components/ui/sheet/sheet-portal.svelte new file mode 100644 index 00000000..f3085a3c --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sheet/sheet-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/sheet/sheet-title.svelte b/ui-svelte/src/lib/components/ui/sheet/sheet-title.svelte new file mode 100644 index 00000000..10c17178 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sheet/sheet-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/sheet/sheet-trigger.svelte b/ui-svelte/src/lib/components/ui/sheet/sheet-trigger.svelte new file mode 100644 index 00000000..e266975f --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sheet/sheet-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/sheet/sheet.svelte b/ui-svelte/src/lib/components/ui/sheet/sheet.svelte new file mode 100644 index 00000000..5bf97839 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sheet/sheet.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/sidebar/constants.ts b/ui-svelte/src/lib/components/ui/sidebar/constants.ts new file mode 100644 index 00000000..1347e83c --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/constants.ts @@ -0,0 +1,6 @@ +export const SIDEBAR_COOKIE_NAME = "sidebar_state"; +export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; +export const SIDEBAR_WIDTH = "16rem"; +export const SIDEBAR_WIDTH_MOBILE = "18rem"; +export const SIDEBAR_WIDTH_ICON = "3rem"; +export const SIDEBAR_KEYBOARD_SHORTCUT = "b"; diff --git a/ui-svelte/src/lib/components/ui/sidebar/context.svelte.ts b/ui-svelte/src/lib/components/ui/sidebar/context.svelte.ts new file mode 100644 index 00000000..15248ada --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/context.svelte.ts @@ -0,0 +1,81 @@ +import { IsMobile } from "$lib/hooks/is-mobile.svelte.js"; +import { getContext, setContext } from "svelte"; +import { SIDEBAR_KEYBOARD_SHORTCUT } from "./constants.js"; + +type Getter = () => T; + +export type SidebarStateProps = { + /** + * A getter function that returns the current open state of the sidebar. + * We use a getter function here to support `bind:open` on the `Sidebar.Provider` + * component. + */ + open: Getter; + + /** + * A function that sets the open state of the sidebar. To support `bind:open`, we need + * a source of truth for changing the open state to ensure it will be synced throughout + * the sub-components and any `bind:` references. + */ + setOpen: (open: boolean) => void; +}; + +class SidebarState { + readonly props: SidebarStateProps; + open = $derived.by(() => this.props.open()); + openMobile = $state(false); + setOpen: SidebarStateProps["setOpen"]; + #isMobile: IsMobile; + state = $derived.by(() => (this.open ? "expanded" : "collapsed")); + + constructor(props: SidebarStateProps) { + this.setOpen = props.setOpen; + this.#isMobile = new IsMobile(); + this.props = props; + } + + // Convenience getter for checking if the sidebar is mobile + // without this, we would need to use `sidebar.isMobile.current` everywhere + get isMobile() { + return this.#isMobile.current; + } + + // Event handler to apply to the `` + handleShortcutKeydown = (e: KeyboardEvent) => { + if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) { + e.preventDefault(); + this.toggle(); + } + }; + + setOpenMobile = (value: boolean) => { + this.openMobile = value; + }; + + toggle = () => { + return this.#isMobile.current + ? (this.openMobile = !this.openMobile) + : this.setOpen(!this.open); + }; +} + +const SYMBOL_KEY = "scn-sidebar"; + +/** + * Instantiates a new `SidebarState` instance and sets it in the context. + * + * @param props The constructor props for the `SidebarState` class. + * @returns The `SidebarState` instance. + */ +export function setSidebar(props: SidebarStateProps): SidebarState { + return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props)); +} + +/** + * Retrieves the `SidebarState` instance from the context. This is a class instance, + * so you cannot destructure it. + * @returns The `SidebarState` instance. + */ +export function useSidebar(): SidebarState { + return getContext(Symbol.for(SYMBOL_KEY)); +} diff --git a/ui-svelte/src/lib/components/ui/sidebar/index.ts b/ui-svelte/src/lib/components/ui/sidebar/index.ts new file mode 100644 index 00000000..318a3417 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/index.ts @@ -0,0 +1,75 @@ +import { useSidebar } from "./context.svelte.js"; +import Content from "./sidebar-content.svelte"; +import Footer from "./sidebar-footer.svelte"; +import GroupAction from "./sidebar-group-action.svelte"; +import GroupContent from "./sidebar-group-content.svelte"; +import GroupLabel from "./sidebar-group-label.svelte"; +import Group from "./sidebar-group.svelte"; +import Header from "./sidebar-header.svelte"; +import Input from "./sidebar-input.svelte"; +import Inset from "./sidebar-inset.svelte"; +import MenuAction from "./sidebar-menu-action.svelte"; +import MenuBadge from "./sidebar-menu-badge.svelte"; +import MenuButton from "./sidebar-menu-button.svelte"; +import MenuItem from "./sidebar-menu-item.svelte"; +import MenuSkeleton from "./sidebar-menu-skeleton.svelte"; +import MenuSubButton from "./sidebar-menu-sub-button.svelte"; +import MenuSubItem from "./sidebar-menu-sub-item.svelte"; +import MenuSub from "./sidebar-menu-sub.svelte"; +import Menu from "./sidebar-menu.svelte"; +import Provider from "./sidebar-provider.svelte"; +import Rail from "./sidebar-rail.svelte"; +import Separator from "./sidebar-separator.svelte"; +import Trigger from "./sidebar-trigger.svelte"; +import Root from "./sidebar.svelte"; + +export { + Content, + Footer, + Group, + GroupAction, + GroupContent, + GroupLabel, + Header, + Input, + Inset, + Menu, + MenuAction, + MenuBadge, + MenuButton, + MenuItem, + MenuSkeleton, + MenuSub, + MenuSubButton, + MenuSubItem, + Provider, + Rail, + Root, + Separator, + // + Root as Sidebar, + Content as SidebarContent, + Footer as SidebarFooter, + Group as SidebarGroup, + GroupAction as SidebarGroupAction, + GroupContent as SidebarGroupContent, + GroupLabel as SidebarGroupLabel, + Header as SidebarHeader, + Input as SidebarInput, + Inset as SidebarInset, + Menu as SidebarMenu, + MenuAction as SidebarMenuAction, + MenuBadge as SidebarMenuBadge, + MenuButton as SidebarMenuButton, + MenuItem as SidebarMenuItem, + MenuSkeleton as SidebarMenuSkeleton, + MenuSub as SidebarMenuSub, + MenuSubButton as SidebarMenuSubButton, + MenuSubItem as SidebarMenuSubItem, + Provider as SidebarProvider, + Rail as SidebarRail, + Separator as SidebarSeparator, + Trigger as SidebarTrigger, + Trigger, + useSidebar, +}; diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-content.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-content.svelte new file mode 100644 index 00000000..2a8d7ea0 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-content.svelte @@ -0,0 +1,24 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-footer.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-footer.svelte new file mode 100644 index 00000000..496c6c0b --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-footer.svelte @@ -0,0 +1,21 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-group-action.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-group-action.svelte new file mode 100644 index 00000000..1d07b978 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-group-action.svelte @@ -0,0 +1,33 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + +{/if} diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-group-content.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-group-content.svelte new file mode 100644 index 00000000..7835b0e3 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-group-content.svelte @@ -0,0 +1,21 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-group-label.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-group-label.svelte new file mode 100644 index 00000000..518216c2 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-group-label.svelte @@ -0,0 +1,33 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} +
+ {@render children?.()} +
+{/if} diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-group.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-group.svelte new file mode 100644 index 00000000..b5880d7c --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-group.svelte @@ -0,0 +1,21 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-header.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-header.svelte new file mode 100644 index 00000000..b54754ac --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-header.svelte @@ -0,0 +1,21 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-input.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-input.svelte new file mode 100644 index 00000000..19b36660 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-input.svelte @@ -0,0 +1,21 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-inset.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-inset.svelte new file mode 100644 index 00000000..19a787cb --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-inset.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-action.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-action.svelte new file mode 100644 index 00000000..26c81ed6 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-action.svelte @@ -0,0 +1,37 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + +{/if} diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte new file mode 100644 index 00000000..6cecdb41 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte @@ -0,0 +1,24 @@ + + +
+ {@render children?.()} +
diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-button.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-button.svelte new file mode 100644 index 00000000..e0c9c25e --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-button.svelte @@ -0,0 +1,102 @@ + + + + +{#snippet Button({ props }: { props?: Record })} + {@const mergedProps = mergeProps(buttonProps, props)} + {#if child} + {@render child({ props: mergedProps })} + {:else} + + {/if} +{/snippet} + +{#if !tooltipContent} + {@render Button({})} +{:else} + + + {#snippet child({ props })} + {@render Button({ props })} + {/snippet} + + + +{/if} diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-item.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-item.svelte new file mode 100644 index 00000000..4db44532 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-item.svelte @@ -0,0 +1,21 @@ + + +
  • + {@render children?.()} +
  • diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte new file mode 100644 index 00000000..1e1249bf --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte @@ -0,0 +1,36 @@ + + +
    + {#if showIcon} + + {/if} + + {@render children?.()} +
    diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte new file mode 100644 index 00000000..09ff228f --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte @@ -0,0 +1,39 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + + {@render children?.()} + +{/if} diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte new file mode 100644 index 00000000..681d0f1d --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte @@ -0,0 +1,21 @@ + + +
  • + {@render children?.()} +
  • diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte new file mode 100644 index 00000000..29614ee1 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte @@ -0,0 +1,21 @@ + + +
      + {@render children?.()} +
    diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu.svelte new file mode 100644 index 00000000..a8cdefd7 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-menu.svelte @@ -0,0 +1,21 @@ + + +
      + {@render children?.()} +
    diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-provider.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-provider.svelte new file mode 100644 index 00000000..5b0d0aa2 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-provider.svelte @@ -0,0 +1,53 @@ + + + + + +
    + {@render children?.()} +
    +
    diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-rail.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-rail.svelte new file mode 100644 index 00000000..f65c8698 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-rail.svelte @@ -0,0 +1,36 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-separator.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-separator.svelte new file mode 100644 index 00000000..18d791bd --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-separator.svelte @@ -0,0 +1,19 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar-trigger.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar-trigger.svelte new file mode 100644 index 00000000..dd2dc503 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar-trigger.svelte @@ -0,0 +1,36 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/sidebar/sidebar.svelte b/ui-svelte/src/lib/components/ui/sidebar/sidebar.svelte new file mode 100644 index 00000000..9c90d4f8 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/sidebar/sidebar.svelte @@ -0,0 +1,108 @@ + + +{#if collapsible === "none"} +
    + {@render children?.()} +
    +{:else if sidebar.isMobile} + sidebar.openMobile, (v) => sidebar.setOpenMobile(v)} + {...restProps} + > + button]:hidden", + className + )} + style="--sidebar-width: {SIDEBAR_WIDTH_MOBILE};" + {side} + > + + Sidebar + Displays the mobile sidebar. + +
    + {@render children?.()} +
    +
    +
    +{:else} + +{/if} diff --git a/ui-svelte/src/lib/components/ui/skeleton/index.ts b/ui-svelte/src/lib/components/ui/skeleton/index.ts new file mode 100644 index 00000000..186db219 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/skeleton/index.ts @@ -0,0 +1,7 @@ +import Root from "./skeleton.svelte"; + +export { + Root, + // + Root as Skeleton, +}; diff --git a/ui-svelte/src/lib/components/ui/skeleton/skeleton.svelte b/ui-svelte/src/lib/components/ui/skeleton/skeleton.svelte new file mode 100644 index 00000000..1a940eee --- /dev/null +++ b/ui-svelte/src/lib/components/ui/skeleton/skeleton.svelte @@ -0,0 +1,17 @@ + + +
    diff --git a/ui-svelte/src/lib/components/ui/switch/index.ts b/ui-svelte/src/lib/components/ui/switch/index.ts new file mode 100644 index 00000000..f5533db7 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/switch/index.ts @@ -0,0 +1,7 @@ +import Root from "./switch.svelte"; + +export { + Root, + // + Root as Switch, +}; diff --git a/ui-svelte/src/lib/components/ui/switch/switch.svelte b/ui-svelte/src/lib/components/ui/switch/switch.svelte new file mode 100644 index 00000000..6aa57d5b --- /dev/null +++ b/ui-svelte/src/lib/components/ui/switch/switch.svelte @@ -0,0 +1,31 @@ + + + + + diff --git a/ui-svelte/src/lib/components/ui/table/index.ts b/ui-svelte/src/lib/components/ui/table/index.ts new file mode 100644 index 00000000..14695c81 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/table/index.ts @@ -0,0 +1,28 @@ +import Root from "./table.svelte"; +import Body from "./table-body.svelte"; +import Caption from "./table-caption.svelte"; +import Cell from "./table-cell.svelte"; +import Footer from "./table-footer.svelte"; +import Head from "./table-head.svelte"; +import Header from "./table-header.svelte"; +import Row from "./table-row.svelte"; + +export { + Root, + Body, + Caption, + Cell, + Footer, + Head, + Header, + Row, + // + Root as Table, + Body as TableBody, + Caption as TableCaption, + Cell as TableCell, + Footer as TableFooter, + Head as TableHead, + Header as TableHeader, + Row as TableRow, +}; diff --git a/ui-svelte/src/lib/components/ui/table/table-body.svelte b/ui-svelte/src/lib/components/ui/table/table-body.svelte new file mode 100644 index 00000000..935feae7 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/table/table-body.svelte @@ -0,0 +1,15 @@ + + + + {@render children?.()} + diff --git a/ui-svelte/src/lib/components/ui/table/table-caption.svelte b/ui-svelte/src/lib/components/ui/table/table-caption.svelte new file mode 100644 index 00000000..4696cff5 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/table/table-caption.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/ui-svelte/src/lib/components/ui/table/table-cell.svelte b/ui-svelte/src/lib/components/ui/table/table-cell.svelte new file mode 100644 index 00000000..a998bf68 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/table/table-cell.svelte @@ -0,0 +1,15 @@ + + + + {@render children?.()} + diff --git a/ui-svelte/src/lib/components/ui/table/table-footer.svelte b/ui-svelte/src/lib/components/ui/table/table-footer.svelte new file mode 100644 index 00000000..b9b14ebf --- /dev/null +++ b/ui-svelte/src/lib/components/ui/table/table-footer.svelte @@ -0,0 +1,20 @@ + + +tr]:last:border-b-0", className)} + {...restProps} +> + {@render children?.()} + diff --git a/ui-svelte/src/lib/components/ui/table/table-head.svelte b/ui-svelte/src/lib/components/ui/table/table-head.svelte new file mode 100644 index 00000000..267c4e08 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/table/table-head.svelte @@ -0,0 +1,15 @@ + + + + {@render children?.()} + diff --git a/ui-svelte/src/lib/components/ui/table/table-header.svelte b/ui-svelte/src/lib/components/ui/table/table-header.svelte new file mode 100644 index 00000000..f47d2597 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/table/table-header.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/ui-svelte/src/lib/components/ui/table/table-row.svelte b/ui-svelte/src/lib/components/ui/table/table-row.svelte new file mode 100644 index 00000000..90b4e2a2 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/table/table-row.svelte @@ -0,0 +1,15 @@ + + + + {@render children?.()} + diff --git a/ui-svelte/src/lib/components/ui/table/table.svelte b/ui-svelte/src/lib/components/ui/table/table.svelte new file mode 100644 index 00000000..d95a02ea --- /dev/null +++ b/ui-svelte/src/lib/components/ui/table/table.svelte @@ -0,0 +1,17 @@ + + +
    + + {@render children?.()} +
    +
    diff --git a/ui-svelte/src/lib/components/ui/tabs/index.ts b/ui-svelte/src/lib/components/ui/tabs/index.ts new file mode 100644 index 00000000..31267e58 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/tabs/index.ts @@ -0,0 +1,18 @@ +import Root from "./tabs.svelte"; +import Content from "./tabs-content.svelte"; +import List, { tabsListVariants, type TabsListVariant } from "./tabs-list.svelte"; +import Trigger from "./tabs-trigger.svelte"; + +export { + Root, + Content, + List, + Trigger, + tabsListVariants, + type TabsListVariant, + // + Root as Tabs, + Content as TabsContent, + List as TabsList, + Trigger as TabsTrigger, +}; diff --git a/ui-svelte/src/lib/components/ui/tabs/tabs-content.svelte b/ui-svelte/src/lib/components/ui/tabs/tabs-content.svelte new file mode 100644 index 00000000..394ab3e8 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/tabs/tabs-content.svelte @@ -0,0 +1,17 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/tabs/tabs-list.svelte b/ui-svelte/src/lib/components/ui/tabs/tabs-list.svelte new file mode 100644 index 00000000..18dce00a --- /dev/null +++ b/ui-svelte/src/lib/components/ui/tabs/tabs-list.svelte @@ -0,0 +1,40 @@ + + + + + diff --git a/ui-svelte/src/lib/components/ui/tabs/tabs-trigger.svelte b/ui-svelte/src/lib/components/ui/tabs/tabs-trigger.svelte new file mode 100644 index 00000000..8a0be4ae --- /dev/null +++ b/ui-svelte/src/lib/components/ui/tabs/tabs-trigger.svelte @@ -0,0 +1,23 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/tabs/tabs.svelte b/ui-svelte/src/lib/components/ui/tabs/tabs.svelte new file mode 100644 index 00000000..bfb900db --- /dev/null +++ b/ui-svelte/src/lib/components/ui/tabs/tabs.svelte @@ -0,0 +1,19 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/textarea/index.ts b/ui-svelte/src/lib/components/ui/textarea/index.ts new file mode 100644 index 00000000..ace797a8 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/textarea/index.ts @@ -0,0 +1,7 @@ +import Root from "./textarea.svelte"; + +export { + Root, + // + Root as Textarea, +}; diff --git a/ui-svelte/src/lib/components/ui/textarea/textarea.svelte b/ui-svelte/src/lib/components/ui/textarea/textarea.svelte new file mode 100644 index 00000000..2e779ff6 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/textarea/textarea.svelte @@ -0,0 +1,23 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/toggle-group/index.ts b/ui-svelte/src/lib/components/ui/toggle-group/index.ts new file mode 100644 index 00000000..12b14b96 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/toggle-group/index.ts @@ -0,0 +1,10 @@ +import Root from "./toggle-group.svelte"; +import Item from "./toggle-group-item.svelte"; + +export { + Root, + Item, + // + Root as ToggleGroup, + Item as ToggleGroupItem, +}; diff --git a/ui-svelte/src/lib/components/ui/toggle-group/toggle-group-item.svelte b/ui-svelte/src/lib/components/ui/toggle-group/toggle-group-item.svelte new file mode 100644 index 00000000..f685ae31 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/toggle-group/toggle-group-item.svelte @@ -0,0 +1,35 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/toggle-group/toggle-group.svelte b/ui-svelte/src/lib/components/ui/toggle-group/toggle-group.svelte new file mode 100644 index 00000000..98b062bb --- /dev/null +++ b/ui-svelte/src/lib/components/ui/toggle-group/toggle-group.svelte @@ -0,0 +1,75 @@ + + + + + + diff --git a/ui-svelte/src/lib/components/ui/toggle/index.ts b/ui-svelte/src/lib/components/ui/toggle/index.ts new file mode 100644 index 00000000..8cb2936f --- /dev/null +++ b/ui-svelte/src/lib/components/ui/toggle/index.ts @@ -0,0 +1,13 @@ +import Root from "./toggle.svelte"; +export { + toggleVariants, + type ToggleSize, + type ToggleVariant, + type ToggleVariants, +} from "./toggle.svelte"; + +export { + Root, + // + Root as Toggle, +}; diff --git a/ui-svelte/src/lib/components/ui/toggle/toggle.svelte b/ui-svelte/src/lib/components/ui/toggle/toggle.svelte new file mode 100644 index 00000000..8e50317e --- /dev/null +++ b/ui-svelte/src/lib/components/ui/toggle/toggle.svelte @@ -0,0 +1,51 @@ + + + + + diff --git a/ui-svelte/src/lib/components/ui/tooltip/index.ts b/ui-svelte/src/lib/components/ui/tooltip/index.ts new file mode 100644 index 00000000..17186042 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/tooltip/index.ts @@ -0,0 +1,19 @@ +import Root from "./tooltip.svelte"; +import Trigger from "./tooltip-trigger.svelte"; +import Content from "./tooltip-content.svelte"; +import Provider from "./tooltip-provider.svelte"; +import Portal from "./tooltip-portal.svelte"; + +export { + Root, + Trigger, + Content, + Provider, + Portal, + // + Root as Tooltip, + Content as TooltipContent, + Trigger as TooltipTrigger, + Provider as TooltipProvider, + Portal as TooltipPortal, +}; diff --git a/ui-svelte/src/lib/components/ui/tooltip/tooltip-content.svelte b/ui-svelte/src/lib/components/ui/tooltip/tooltip-content.svelte new file mode 100644 index 00000000..0cf06949 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/tooltip/tooltip-content.svelte @@ -0,0 +1,52 @@ + + + + + {@render children?.()} + + {#snippet child({ props })} +
    + {/snippet} +
    +
    +
    diff --git a/ui-svelte/src/lib/components/ui/tooltip/tooltip-portal.svelte b/ui-svelte/src/lib/components/ui/tooltip/tooltip-portal.svelte new file mode 100644 index 00000000..d234f7d7 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/tooltip/tooltip-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/tooltip/tooltip-provider.svelte b/ui-svelte/src/lib/components/ui/tooltip/tooltip-provider.svelte new file mode 100644 index 00000000..6dba9a67 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/tooltip/tooltip-provider.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/tooltip/tooltip-trigger.svelte b/ui-svelte/src/lib/components/ui/tooltip/tooltip-trigger.svelte new file mode 100644 index 00000000..c4b21fc7 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/tooltip/tooltip-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/components/ui/tooltip/tooltip.svelte b/ui-svelte/src/lib/components/ui/tooltip/tooltip.svelte new file mode 100644 index 00000000..03c9a3d9 --- /dev/null +++ b/ui-svelte/src/lib/components/ui/tooltip/tooltip.svelte @@ -0,0 +1,7 @@ + + + diff --git a/ui-svelte/src/lib/hooks/is-mobile.svelte.ts b/ui-svelte/src/lib/hooks/is-mobile.svelte.ts new file mode 100644 index 00000000..4829c00b --- /dev/null +++ b/ui-svelte/src/lib/hooks/is-mobile.svelte.ts @@ -0,0 +1,9 @@ +import { MediaQuery } from "svelte/reactivity"; + +const DEFAULT_MOBILE_BREAKPOINT = 768; + +export class IsMobile extends MediaQuery { + constructor(breakpoint: number = DEFAULT_MOBILE_BREAKPOINT) { + super(`max-width: ${breakpoint - 1}px`); + } +} diff --git a/ui-svelte/src/lib/utils.ts b/ui-svelte/src/lib/utils.ts new file mode 100644 index 00000000..55b3a918 --- /dev/null +++ b/ui-svelte/src/lib/utils.ts @@ -0,0 +1,13 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type WithoutChild = T extends { child?: any } ? Omit : T; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type WithoutChildren = T extends { children?: any } ? Omit : T; +export type WithoutChildrenOrChild = WithoutChildren>; +export type WithElementRef = T & { ref?: U | null }; diff --git a/ui-svelte/tsconfig.json b/ui-svelte/tsconfig.json index 80fb577b..0d590bbf 100644 --- a/ui-svelte/tsconfig.json +++ b/ui-svelte/tsconfig.json @@ -14,7 +14,12 @@ "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, - "verbatimModuleSyntax": true + "verbatimModuleSyntax": true, + "baseUrl": ".", + "paths": { + "$lib": ["./src/lib"], + "$lib/*": ["./src/lib/*"] + } }, "include": ["src/**/*.ts", "src/**/*.svelte"] } diff --git a/ui-svelte/vite.config.ts b/ui-svelte/vite.config.ts index e2ac6b36..adc03eea 100644 --- a/ui-svelte/vite.config.ts +++ b/ui-svelte/vite.config.ts @@ -2,6 +2,7 @@ import { defineConfig } from "vite"; import { svelte } from "@sveltejs/vite-plugin-svelte"; import tailwindcss from "@tailwindcss/vite"; import { compression } from "vite-plugin-compression2"; +import path from "node:path"; // https://vite.dev/config/ export default defineConfig({ @@ -21,6 +22,11 @@ export default defineConfig({ }), ], base: "/ui/", + resolve: { + alias: { + $lib: path.resolve(__dirname, "./src/lib"), + }, + }, build: { outDir: "../internal/server/ui_dist", assetsDir: "assets",