pika-ux 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/dist/icon-generator/generate-icon-ts-indices.js +78 -0
- package/dist/shadcn-postinstall/index.js +114 -0
- package/package.json +102 -0
- package/readme.md +50 -0
- package/scripts/setup.js +100 -0
- package/src/App.svelte +51 -0
- package/src/app.css +349 -0
- package/src/icons/ci/index.d.ts +5009 -0
- package/src/icons/lucide/index.d.ts +11274 -0
- package/src/index.ts +23 -0
- package/src/lib/docsite/Navigation.svelte +77 -0
- package/src/lib/docsite/pages/Colors.svelte +35 -0
- package/src/lib/docsite/pages/Components.svelte +50 -0
- package/src/lib/docsite/pages/GettingStarted.svelte +21 -0
- package/src/lib/docsite/pages/Icons.svelte +22 -0
- package/src/lib/docsite/pages/components/Button.svelte +40 -0
- package/src/main.ts +9 -0
- package/src/pika/chip/chip.svelte +95 -0
- package/src/pika/chip/index.ts +1 -0
- package/src/pika/combobox/combobox-types.ts +5 -0
- package/src/pika/combobox/combobox.svelte +221 -0
- package/src/pika/combobox/index.ts +2 -0
- package/src/pika/confirm-dialog/confirm-dialog.svelte +48 -0
- package/src/pika/confirm-dialog/index.ts +1 -0
- package/src/pika/copy-button/copy-button.svelte +134 -0
- package/src/pika/copy-button/index.ts +1 -0
- package/src/pika/create-copy-link-button/create-copy-link-button.svelte +133 -0
- package/src/pika/create-copy-link-button/index.ts +1 -0
- package/src/pika/date-picker/date-picker.svelte +33 -0
- package/src/pika/date-picker/index.ts +1 -0
- package/src/pika/date-range-picker/date-range-picker.svelte +48 -0
- package/src/pika/date-range-picker/index.ts +1 -0
- package/src/pika/date-time-picker/date-time-picker.svelte +336 -0
- package/src/pika/date-time-picker/index.ts +1 -0
- package/src/pika/expandable-container/expandable-container.svelte +155 -0
- package/src/pika/expandable-container/index.ts +1 -0
- package/src/pika/index.ts +29 -0
- package/src/pika/list/index.ts +2 -0
- package/src/pika/list/list-types.ts +5 -0
- package/src/pika/list/list.svelte +349 -0
- package/src/pika/markdown-editor/github.scss +87 -0
- package/src/pika/markdown-editor/index.ts +1 -0
- package/src/pika/markdown-editor/markdown-editor.svelte +44 -0
- package/src/pika/permanent-toast/index.ts +1 -0
- package/src/pika/permanent-toast/permanent-toast.svelte +47 -0
- package/src/pika/pika-alert/index.ts +1 -0
- package/src/pika/pika-alert/pika-alert.svelte +53 -0
- package/src/pika/pika-badge/index.ts +1 -0
- package/src/pika/pika-badge/pika-badge.svelte +61 -0
- package/src/pika/pika-table/index.ts +7 -0
- package/src/pika/pika-table/pika-table-cell.svelte +9 -0
- package/src/pika/pika-table/pika-table-checkbox.svelte +8 -0
- package/src/pika/pika-table/pika-table-column-header.svelte +88 -0
- package/src/pika/pika-table/pika-table-faceted-filter.svelte +109 -0
- package/src/pika/pika-table/pika-table-pagination.svelte +95 -0
- package/src/pika/pika-table/pika-table-row-actions.svelte +58 -0
- package/src/pika/pika-table/pika-table-toolbar.svelte +88 -0
- package/src/pika/pika-table/pika-table-view-options.svelte +35 -0
- package/src/pika/pika-table/pika-table.svelte +295 -0
- package/src/pika/pika-table/types.ts +106 -0
- package/src/pika/pika-tabs/index.ts +18 -0
- package/src/pika/pika-tabs/tabs-content.svelte +16 -0
- package/src/pika/pika-tabs/tabs-list.svelte +12 -0
- package/src/pika/pika-tabs/tabs-trigger.svelte +23 -0
- package/src/pika/popup-help/index.ts +1 -0
- package/src/pika/popup-help/popup-help.svelte +33 -0
- package/src/pika/simple-dropdown/index.ts +2 -0
- package/src/pika/simple-dropdown/simple-dropdown-types.ts +5 -0
- package/src/pika/simple-dropdown/simple-dropdown.svelte +288 -0
- package/src/pika/slideout/constants.ts +5 -0
- package/src/pika/slideout/context.svelte.ts +110 -0
- package/src/pika/slideout/index.ts +19 -0
- package/src/pika/slideout/slideout-content.svelte +36 -0
- package/src/pika/slideout/slideout-panel.svelte +126 -0
- package/src/pika/slideout/slideout-provider.svelte +49 -0
- package/src/pika/slideout/slideout-rail.svelte.die +69 -0
- package/src/pika/slideout/slideout.svelte +33 -0
- package/src/pika/slideout/slideout.svelte.old +113 -0
- package/src/pika/text-wave-shimmer/index.ts +1 -0
- package/src/pika/text-wave-shimmer/text-wave-shimmer.svelte +43 -0
- package/src/pika/tooltip-plus/index.ts +1 -0
- package/src/pika/tooltip-plus/tooltip-plus.svelte +42 -0
- package/src/shadcn/.DS_Store +0 -0
- package/src/shadcn/alert/alert-description.svelte +11 -0
- package/src/shadcn/alert/alert-title.svelte +24 -0
- package/src/shadcn/alert/alert.svelte +39 -0
- package/src/shadcn/alert/index.ts +14 -0
- package/src/shadcn/avatar/avatar-fallback.svelte +13 -0
- package/src/shadcn/avatar/avatar-image.svelte +13 -0
- package/src/shadcn/avatar/avatar.svelte +19 -0
- package/src/shadcn/avatar/index.ts +13 -0
- package/src/shadcn/badge/badge.svelte +48 -0
- package/src/shadcn/badge/index.ts +2 -0
- package/src/shadcn/breadcrumb/breadcrumb-ellipsis.svelte +12 -0
- package/src/shadcn/breadcrumb/breadcrumb-item.svelte +20 -0
- package/src/shadcn/breadcrumb/breadcrumb-link.svelte +31 -0
- package/src/shadcn/breadcrumb/breadcrumb-list.svelte +20 -0
- package/src/shadcn/breadcrumb/breadcrumb-page.svelte +23 -0
- package/src/shadcn/breadcrumb/breadcrumb-separator.svelte +15 -0
- package/src/shadcn/breadcrumb/breadcrumb.svelte +15 -0
- package/src/shadcn/breadcrumb/index.ts +25 -0
- package/src/shadcn/button/button.svelte +81 -0
- package/src/shadcn/button/index.ts +17 -0
- package/src/shadcn/calendar/calendar-caption.svelte +76 -0
- package/src/shadcn/calendar/calendar-cell.svelte +19 -0
- package/src/shadcn/calendar/calendar-day.svelte +31 -0
- package/src/shadcn/calendar/calendar-grid-body.svelte +12 -0
- package/src/shadcn/calendar/calendar-grid-head.svelte +12 -0
- package/src/shadcn/calendar/calendar-grid-row.svelte +12 -0
- package/src/shadcn/calendar/calendar-grid.svelte +16 -0
- package/src/shadcn/calendar/calendar-head-cell.svelte +16 -0
- package/src/shadcn/calendar/calendar-header.svelte +16 -0
- package/src/shadcn/calendar/calendar-heading.svelte +12 -0
- package/src/shadcn/calendar/calendar-month-select.svelte +25 -0
- package/src/shadcn/calendar/calendar-month.svelte +15 -0
- package/src/shadcn/calendar/calendar-months.svelte +20 -0
- package/src/shadcn/calendar/calendar-nav.svelte +19 -0
- package/src/shadcn/calendar/calendar-next-button.svelte +19 -0
- package/src/shadcn/calendar/calendar-prev-button.svelte +19 -0
- package/src/shadcn/calendar/calendar-year-select.svelte +25 -0
- package/src/shadcn/calendar/calendar.svelte +61 -0
- package/src/shadcn/calendar/index.ts +30 -0
- package/src/shadcn/card/card-content.svelte +16 -0
- package/src/shadcn/card/card-description.svelte +16 -0
- package/src/shadcn/card/card-footer.svelte +16 -0
- package/src/shadcn/card/card-header.svelte +16 -0
- package/src/shadcn/card/card-title.svelte +25 -0
- package/src/shadcn/card/card.svelte +20 -0
- package/src/shadcn/card/index.ts +22 -0
- package/src/shadcn/carousel/carousel-content.svelte +39 -0
- package/src/shadcn/carousel/carousel-item.svelte +26 -0
- package/src/shadcn/carousel/carousel-next.svelte +30 -0
- package/src/shadcn/carousel/carousel-previous.svelte +30 -0
- package/src/shadcn/carousel/carousel.svelte +88 -0
- package/src/shadcn/carousel/context.ts +51 -0
- package/src/shadcn/carousel/index.ts +19 -0
- package/src/shadcn/checkbox/checkbox.svelte +36 -0
- package/src/shadcn/checkbox/index.ts +6 -0
- package/src/shadcn/collapsible/collapsible-content.svelte +7 -0
- package/src/shadcn/collapsible/collapsible-trigger.svelte +7 -0
- package/src/shadcn/collapsible/collapsible.svelte +11 -0
- package/src/shadcn/collapsible/index.ts +13 -0
- package/src/shadcn/command/command-dialog.svelte +40 -0
- package/src/shadcn/command/command-empty.svelte +13 -0
- package/src/shadcn/command/command-group.svelte +30 -0
- package/src/shadcn/command/command-input.svelte +21 -0
- package/src/shadcn/command/command-item.svelte +16 -0
- package/src/shadcn/command/command-link-item.svelte +16 -0
- package/src/shadcn/command/command-list.svelte +13 -0
- package/src/shadcn/command/command-separator.svelte +13 -0
- package/src/shadcn/command/command-shortcut.svelte +20 -0
- package/src/shadcn/command/command.svelte +19 -0
- package/src/shadcn/command/index.ts +40 -0
- package/src/shadcn/data-table/data-table.svelte.ts +141 -0
- package/src/shadcn/data-table/flex-render.svelte +36 -0
- package/src/shadcn/data-table/index.ts +3 -0
- package/src/shadcn/data-table/render-helpers.ts +111 -0
- package/src/shadcn/dialog/dialog-close.svelte +7 -0
- package/src/shadcn/dialog/dialog-content.svelte +43 -0
- package/src/shadcn/dialog/dialog-description.svelte +13 -0
- package/src/shadcn/dialog/dialog-footer.svelte +20 -0
- package/src/shadcn/dialog/dialog-header.svelte +20 -0
- package/src/shadcn/dialog/dialog-overlay.svelte +16 -0
- package/src/shadcn/dialog/dialog-title.svelte +13 -0
- package/src/shadcn/dialog/dialog-trigger.svelte +7 -0
- package/src/shadcn/dialog/index.ts +37 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-checkbox-item.svelte +41 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-content.svelte +27 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-group.svelte +7 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-item.svelte +27 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-label.svelte +24 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-radio-item.svelte +26 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-separator.svelte +13 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-shortcut.svelte +20 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-sub-content.svelte +16 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
- package/src/shadcn/dropdown-menu/index.ts +49 -0
- package/src/shadcn/index.ts +40 -0
- package/src/shadcn/input/index.ts +7 -0
- package/src/shadcn/input/input.svelte +51 -0
- package/src/shadcn/is-mobile.svelte.ts +9 -0
- package/src/shadcn/label/index.ts +7 -0
- package/src/shadcn/label/label.svelte +16 -0
- package/src/shadcn/popover/index.ts +17 -0
- package/src/shadcn/popover/popover-content.svelte +29 -0
- package/src/shadcn/popover/popover-trigger.svelte +8 -0
- package/src/shadcn/radio-group/index.ts +10 -0
- package/src/shadcn/radio-group/radio-group-item.svelte +25 -0
- package/src/shadcn/radio-group/radio-group.svelte +19 -0
- package/src/shadcn/range-calendar/index.ts +30 -0
- package/src/shadcn/range-calendar/range-calendar-cell.svelte +19 -0
- package/src/shadcn/range-calendar/range-calendar-day.svelte +35 -0
- package/src/shadcn/range-calendar/range-calendar-grid-body.svelte +12 -0
- package/src/shadcn/range-calendar/range-calendar-grid-head.svelte +12 -0
- package/src/shadcn/range-calendar/range-calendar-grid-row.svelte +12 -0
- package/src/shadcn/range-calendar/range-calendar-grid.svelte +16 -0
- package/src/shadcn/range-calendar/range-calendar-head-cell.svelte +16 -0
- package/src/shadcn/range-calendar/range-calendar-header.svelte +16 -0
- package/src/shadcn/range-calendar/range-calendar-heading.svelte +16 -0
- package/src/shadcn/range-calendar/range-calendar-months.svelte +20 -0
- package/src/shadcn/range-calendar/range-calendar-next-button.svelte +18 -0
- package/src/shadcn/range-calendar/range-calendar-prev-button.svelte +18 -0
- package/src/shadcn/range-calendar/range-calendar.svelte +57 -0
- package/src/shadcn/resizable/index.ts +13 -0
- package/src/shadcn/resizable/resizable-handle.svelte +30 -0
- package/src/shadcn/resizable/resizable-pane-group.svelte +22 -0
- package/src/shadcn/scroll-area/index.ts +10 -0
- package/src/shadcn/scroll-area/scroll-area-scrollbar.svelte +28 -0
- package/src/shadcn/scroll-area/scroll-area.svelte +35 -0
- package/src/shadcn/select/index.ts +37 -0
- package/src/shadcn/select/select-content.svelte +38 -0
- package/src/shadcn/select/select-group-heading.svelte +21 -0
- package/src/shadcn/select/select-group.svelte +7 -0
- package/src/shadcn/select/select-item.svelte +31 -0
- package/src/shadcn/select/select-label.svelte +20 -0
- package/src/shadcn/select/select-scroll-down-button.svelte +11 -0
- package/src/shadcn/select/select-scroll-up-button.svelte +11 -0
- package/src/shadcn/select/select-separator.svelte +14 -0
- package/src/shadcn/select/select-trigger.svelte +30 -0
- package/src/shadcn/separator/index.ts +7 -0
- package/src/shadcn/separator/separator.svelte +16 -0
- package/src/shadcn/sheet/index.ts +36 -0
- package/src/shadcn/sheet/sheet-close.svelte +7 -0
- package/src/shadcn/sheet/sheet-content.svelte +66 -0
- package/src/shadcn/sheet/sheet-description.svelte +13 -0
- package/src/shadcn/sheet/sheet-footer.svelte +15 -0
- package/src/shadcn/sheet/sheet-header.svelte +15 -0
- package/src/shadcn/sheet/sheet-overlay.svelte +16 -0
- package/src/shadcn/sheet/sheet-title.svelte +13 -0
- package/src/shadcn/sheet/sheet-trigger.svelte +7 -0
- package/src/shadcn/sidebar/constants.ts +6 -0
- package/src/shadcn/sidebar/context.svelte.ts +80 -0
- package/src/shadcn/sidebar/index.ts +75 -0
- package/src/shadcn/sidebar/sidebar-content.svelte +24 -0
- package/src/shadcn/sidebar/sidebar-footer.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-group-action.svelte +36 -0
- package/src/shadcn/sidebar/sidebar-group-content.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-group-label.svelte +34 -0
- package/src/shadcn/sidebar/sidebar-group.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-header.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-input.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-inset.svelte +24 -0
- package/src/shadcn/sidebar/sidebar-menu-action.svelte +43 -0
- package/src/shadcn/sidebar/sidebar-menu-badge.svelte +29 -0
- package/src/shadcn/sidebar/sidebar-menu-button.svelte +101 -0
- package/src/shadcn/sidebar/sidebar-menu-item.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-menu-skeleton.svelte +36 -0
- package/src/shadcn/sidebar/sidebar-menu-sub-button.svelte +43 -0
- package/src/shadcn/sidebar/sidebar-menu-sub-item.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-menu-sub.svelte +25 -0
- package/src/shadcn/sidebar/sidebar-menu.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-provider.svelte +46 -0
- package/src/shadcn/sidebar/sidebar-rail.svelte +36 -0
- package/src/shadcn/sidebar/sidebar-separator.svelte +15 -0
- package/src/shadcn/sidebar/sidebar-trigger.svelte +35 -0
- package/src/shadcn/sidebar/sidebar.svelte +94 -0
- package/src/shadcn/skeleton/index.ts +7 -0
- package/src/shadcn/skeleton/skeleton.svelte +17 -0
- package/src/shadcn/slider/index.ts +7 -0
- package/src/shadcn/slider/slider.svelte +44 -0
- package/src/shadcn/sonner/index.ts +1 -0
- package/src/shadcn/sonner/sonner.svelte +13 -0
- package/src/shadcn/switch/index.ts +7 -0
- package/src/shadcn/switch/switch.svelte +27 -0
- package/src/shadcn/table/index.ts +28 -0
- package/src/shadcn/table/table-body.svelte +15 -0
- package/src/shadcn/table/table-caption.svelte +20 -0
- package/src/shadcn/table/table-cell.svelte +20 -0
- package/src/shadcn/table/table-footer.svelte +20 -0
- package/src/shadcn/table/table-head.svelte +23 -0
- package/src/shadcn/table/table-header.svelte +15 -0
- package/src/shadcn/table/table-row.svelte +23 -0
- package/src/shadcn/table/table.svelte +17 -0
- package/src/shadcn/tabs/index.ts +18 -0
- package/src/shadcn/tabs/tabs-content.svelte +21 -0
- package/src/shadcn/tabs/tabs-list.svelte +19 -0
- package/src/shadcn/tabs/tabs-trigger.svelte +21 -0
- package/src/shadcn/textarea/index.ts +7 -0
- package/src/shadcn/textarea/textarea.svelte +22 -0
- package/src/shadcn/toggle/index.ts +13 -0
- package/src/shadcn/toggle/toggle.svelte +51 -0
- package/src/shadcn/toggle-group/index.ts +10 -0
- package/src/shadcn/toggle-group/toggle-group-item.svelte +30 -0
- package/src/shadcn/toggle-group/toggle-group.svelte +41 -0
- package/src/shadcn/tooltip/index.ts +21 -0
- package/src/shadcn/tooltip/tooltip-content.svelte +47 -0
- package/src/shadcn/tooltip/tooltip-trigger.svelte +7 -0
- package/src/shadcn/utils.ts +14 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pika-ux package
|
|
3
|
+
*
|
|
4
|
+
* This package contains UI components for the Pika project, including both custom Pika components
|
|
5
|
+
* and shadcn/ui components adapted for Svelte.
|
|
6
|
+
*
|
|
7
|
+
* You can import specific component collections:
|
|
8
|
+
* import { Button, Card } from 'pika-ux/shadcn';
|
|
9
|
+
* import { Chip, PikaAlert } from 'pika-ux/pika';
|
|
10
|
+
*
|
|
11
|
+
* Or import individual components:
|
|
12
|
+
* import { Button } from 'pika-ux/shadcn/button';
|
|
13
|
+
* import { Chip } from 'pika-ux/pika/chip';
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const packageInfo = {
|
|
17
|
+
name: 'pika-ux',
|
|
18
|
+
description: 'UI Components library for the Pika project'
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Re-export all components for convenience
|
|
22
|
+
export * from './pika';
|
|
23
|
+
export * from './shadcn';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import * as Sidebar from '../../shadcn/sidebar/index.js';
|
|
3
|
+
|
|
4
|
+
// Props interface
|
|
5
|
+
interface NavigationProps {
|
|
6
|
+
currentPage: string;
|
|
7
|
+
onNavigate: (page: string) => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Props
|
|
11
|
+
let { currentPage, onNavigate }: NavigationProps = $props();
|
|
12
|
+
|
|
13
|
+
const navigationItems = [
|
|
14
|
+
{ id: 'getting-started', label: 'Getting Started', icon: '📚' },
|
|
15
|
+
{ id: 'icons', label: 'Icons', icon: '✨' },
|
|
16
|
+
{ id: 'colors', label: 'Colors', icon: '🎨' },
|
|
17
|
+
{
|
|
18
|
+
id: 'components',
|
|
19
|
+
label: 'Components',
|
|
20
|
+
icon: '🧩',
|
|
21
|
+
children: [{ id: 'components/button', label: 'Button', icon: '🔘' }]
|
|
22
|
+
}
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
function handleNavigate(pageId: string) {
|
|
26
|
+
onNavigate(pageId);
|
|
27
|
+
}
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<Sidebar.Provider>
|
|
31
|
+
<Sidebar.Sidebar variant="inset" class="border-r">
|
|
32
|
+
<Sidebar.SidebarHeader class="border-b px-6 py-4">
|
|
33
|
+
<h2 class="text-lg font-semibold text-foreground">pika-ux</h2>
|
|
34
|
+
<p class="text-sm text-muted-foreground">Component Documentation</p>
|
|
35
|
+
</Sidebar.SidebarHeader>
|
|
36
|
+
|
|
37
|
+
<Sidebar.SidebarContent class="px-3 py-4">
|
|
38
|
+
<Sidebar.SidebarGroup>
|
|
39
|
+
<Sidebar.SidebarMenu>
|
|
40
|
+
{#each navigationItems as item}
|
|
41
|
+
<Sidebar.SidebarMenuItem>
|
|
42
|
+
<Sidebar.SidebarMenuButton
|
|
43
|
+
onclick={() => handleNavigate(item.id)}
|
|
44
|
+
class="w-full justify-start {currentPage === item.id || (item.children && item.children.some((child) => currentPage === child.id))
|
|
45
|
+
? 'bg-sidebar-accent text-sidebar-accent-foreground'
|
|
46
|
+
: ''}"
|
|
47
|
+
>
|
|
48
|
+
<span class="mr-2">{item.icon}</span>
|
|
49
|
+
{item.label}
|
|
50
|
+
</Sidebar.SidebarMenuButton>
|
|
51
|
+
|
|
52
|
+
{#if item.children}
|
|
53
|
+
<Sidebar.SidebarMenuSub class="ml-4 mt-1">
|
|
54
|
+
{#each item.children as child}
|
|
55
|
+
<Sidebar.SidebarMenuSubItem>
|
|
56
|
+
<Sidebar.SidebarMenuSubButton
|
|
57
|
+
onclick={() => handleNavigate(child.id)}
|
|
58
|
+
class="w-full justify-start {currentPage === child.id ? 'bg-sidebar-accent text-sidebar-accent-foreground' : ''}"
|
|
59
|
+
>
|
|
60
|
+
<span class="mr-2">{child.icon}</span>
|
|
61
|
+
{child.label}
|
|
62
|
+
</Sidebar.SidebarMenuSubButton>
|
|
63
|
+
</Sidebar.SidebarMenuSubItem>
|
|
64
|
+
{/each}
|
|
65
|
+
</Sidebar.SidebarMenuSub>
|
|
66
|
+
{/if}
|
|
67
|
+
</Sidebar.SidebarMenuItem>
|
|
68
|
+
{/each}
|
|
69
|
+
</Sidebar.SidebarMenu>
|
|
70
|
+
</Sidebar.SidebarGroup>
|
|
71
|
+
</Sidebar.SidebarContent>
|
|
72
|
+
|
|
73
|
+
<!-- <Sidebar.SidebarFooter class="border-t px-6 py-4">
|
|
74
|
+
<p class="text-xs text-muted-foreground">Built with Svelte 5</p>
|
|
75
|
+
</Sidebar.SidebarFooter> -->
|
|
76
|
+
</Sidebar.Sidebar>
|
|
77
|
+
</Sidebar.Provider>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// TODO: Add color palette examples and documentation
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<div class="max-w-4xl mx-auto p-6">
|
|
6
|
+
<h1 class="text-4xl font-bold text-foreground mb-6">Colors</h1>
|
|
7
|
+
|
|
8
|
+
<div class="prose prose-slate dark:prose-invert max-w-none">
|
|
9
|
+
<p class="text-lg text-muted-foreground mb-8">Design system colors with light and dark mode support.</p>
|
|
10
|
+
|
|
11
|
+
<div class="grid gap-6">
|
|
12
|
+
<!-- Preview of existing color system -->
|
|
13
|
+
<div class="bg-card border border-border rounded-lg p-6">
|
|
14
|
+
<h3 class="text-lg font-semibold mb-4">Core Colors</h3>
|
|
15
|
+
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
16
|
+
<div class="p-4 bg-primary text-primary-foreground rounded-lg text-center text-sm">Primary</div>
|
|
17
|
+
<div class="p-4 bg-secondary text-secondary-foreground rounded-lg text-center text-sm">Secondary</div>
|
|
18
|
+
<div class="p-4 bg-accent text-accent-foreground rounded-lg text-center text-sm">Accent</div>
|
|
19
|
+
<div class="p-4 bg-muted text-muted-foreground rounded-lg text-center text-sm">Muted</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<div class="bg-card border border-border rounded-lg p-6">
|
|
24
|
+
<h2 class="text-xl font-semibold mb-4">TODO: Complete Color Documentation</h2>
|
|
25
|
+
<ul class="space-y-2 text-muted-foreground">
|
|
26
|
+
<li>• Full color palette showcase</li>
|
|
27
|
+
<li>• Custom color variables (gold, blueish, etc.)</li>
|
|
28
|
+
<li>• Usage guidelines</li>
|
|
29
|
+
<li>• Dark mode variants</li>
|
|
30
|
+
<li>• CSS variable reference</li>
|
|
31
|
+
</ul>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// TODO: Add component overview and categories
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<div class="max-w-4xl mx-auto p-6">
|
|
6
|
+
<h1 class="text-4xl font-bold text-foreground mb-6">Components</h1>
|
|
7
|
+
|
|
8
|
+
<div class="prose prose-slate dark:prose-invert max-w-none">
|
|
9
|
+
<p class="text-lg text-muted-foreground mb-8">A comprehensive collection of Svelte components for modern web applications.</p>
|
|
10
|
+
|
|
11
|
+
<div class="grid gap-6">
|
|
12
|
+
<div class="bg-card border border-border rounded-lg p-6">
|
|
13
|
+
<h2 class="text-xl font-semibold mb-4">shadcn/ui Components</h2>
|
|
14
|
+
<p class="text-muted-foreground mb-4">Battle-tested components from shadcn/ui, adapted for Svelte.</p>
|
|
15
|
+
<div class="grid grid-cols-2 md:grid-cols-3 gap-2 text-sm">
|
|
16
|
+
<span class="bg-muted px-2 py-1 rounded">Button</span>
|
|
17
|
+
<span class="bg-muted px-2 py-1 rounded">Card</span>
|
|
18
|
+
<span class="bg-muted px-2 py-1 rounded">Dialog</span>
|
|
19
|
+
<span class="bg-muted px-2 py-1 rounded">Input</span>
|
|
20
|
+
<span class="bg-muted px-2 py-1 rounded">Sidebar</span>
|
|
21
|
+
<span class="bg-muted px-2 py-1 rounded">+ 30 more</span>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="bg-card border border-border rounded-lg p-6">
|
|
26
|
+
<h2 class="text-xl font-semibold mb-4">Pika Components</h2>
|
|
27
|
+
<p class="text-muted-foreground mb-4">Custom components built specifically for enhanced productivity.</p>
|
|
28
|
+
<div class="grid grid-cols-2 md:grid-cols-3 gap-2 text-sm">
|
|
29
|
+
<span class="bg-muted px-2 py-1 rounded">Pika Alert</span>
|
|
30
|
+
<span class="bg-muted px-2 py-1 rounded">Date Picker</span>
|
|
31
|
+
<span class="bg-muted px-2 py-1 rounded">Popup Help</span>
|
|
32
|
+
<span class="bg-muted px-2 py-1 rounded">Slideout</span>
|
|
33
|
+
<span class="bg-muted px-2 py-1 rounded">Pika Table</span>
|
|
34
|
+
<span class="bg-muted px-2 py-1 rounded">+ 20 more</span>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div class="bg-card border border-border rounded-lg p-6">
|
|
39
|
+
<h2 class="text-xl font-semibold mb-4">TODO: Complete Component Documentation</h2>
|
|
40
|
+
<ul class="space-y-2 text-muted-foreground">
|
|
41
|
+
<li>• Individual component pages</li>
|
|
42
|
+
<li>• Live examples and code</li>
|
|
43
|
+
<li>• Props and API documentation</li>
|
|
44
|
+
<li>• Usage guidelines</li>
|
|
45
|
+
<li>• Accessibility notes</li>
|
|
46
|
+
</ul>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// TODO: Add getting started content
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<div class="max-w-4xl mx-auto p-6">
|
|
6
|
+
<h1 class="text-4xl font-bold text-foreground mb-6">Getting Started</h1>
|
|
7
|
+
|
|
8
|
+
<div class="prose prose-slate dark:prose-invert max-w-none">
|
|
9
|
+
<p class="text-lg text-muted-foreground mb-8">Welcome to pika-ux - a modern Svelte component library built for productivity.</p>
|
|
10
|
+
|
|
11
|
+
<div class="bg-card border border-border rounded-lg p-6">
|
|
12
|
+
<h2 class="text-xl font-semibold mb-4">TODO: Getting Started Content</h2>
|
|
13
|
+
<ul class="space-y-2 text-muted-foreground">
|
|
14
|
+
<li>• Installation instructions</li>
|
|
15
|
+
<li>• Basic setup guide</li>
|
|
16
|
+
<li>• Quick start examples</li>
|
|
17
|
+
<li>• Configuration options</li>
|
|
18
|
+
</ul>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// TODO: Add icon examples and documentation
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<div class="max-w-4xl mx-auto p-6">
|
|
6
|
+
<h1 class="text-4xl font-bold text-foreground mb-6">Icons</h1>
|
|
7
|
+
|
|
8
|
+
<div class="prose prose-slate dark:prose-invert max-w-none">
|
|
9
|
+
<p class="text-lg text-muted-foreground mb-8">Icon system powered by unplugin-icons with Lucide and CI icon sets.</p>
|
|
10
|
+
|
|
11
|
+
<div class="bg-card border border-border rounded-lg p-6">
|
|
12
|
+
<h2 class="text-xl font-semibold mb-4">TODO: Icon Documentation</h2>
|
|
13
|
+
<ul class="space-y-2 text-muted-foreground">
|
|
14
|
+
<li>• Icon usage examples</li>
|
|
15
|
+
<li>• Available icon sets (Lucide, CI)</li>
|
|
16
|
+
<li>• Import patterns</li>
|
|
17
|
+
<li>• Size and styling options</li>
|
|
18
|
+
<li>• Icon component wrapper</li>
|
|
19
|
+
</ul>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Button from '../../../../shadcn/button/button.svelte';
|
|
3
|
+
// TODO: Add complete Button documentation and examples
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<div class="max-w-4xl mx-auto p-6">
|
|
7
|
+
<h1 class="text-4xl font-bold text-foreground mb-6">Button</h1>
|
|
8
|
+
|
|
9
|
+
<div class="prose prose-slate dark:prose-invert max-w-none">
|
|
10
|
+
<p class="text-lg text-muted-foreground mb-8">A versatile button component with multiple variants and sizes.</p>
|
|
11
|
+
|
|
12
|
+
<div class="grid gap-6">
|
|
13
|
+
<!-- Quick Preview -->
|
|
14
|
+
<div class="bg-card border border-border rounded-lg p-6">
|
|
15
|
+
<h3 class="text-lg font-semibold mb-4">Preview</h3>
|
|
16
|
+
<div class="flex gap-4 flex-wrap">
|
|
17
|
+
<Button>Default</Button>
|
|
18
|
+
<Button variant="secondary">Secondary</Button>
|
|
19
|
+
<Button variant="destructive">Destructive</Button>
|
|
20
|
+
<Button variant="outline">Outline</Button>
|
|
21
|
+
<Button variant="ghost">Ghost</Button>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="bg-card border border-border rounded-lg p-6">
|
|
26
|
+
<h2 class="text-xl font-semibold mb-4">TODO: Complete Button Documentation</h2>
|
|
27
|
+
<ul class="space-y-2 text-muted-foreground">
|
|
28
|
+
<li>• All variant examples (default, secondary, destructive, outline, ghost, link)</li>
|
|
29
|
+
<li>• Size variations (sm, default, lg, icon)</li>
|
|
30
|
+
<li>• Usage with icons</li>
|
|
31
|
+
<li>• Loading states</li>
|
|
32
|
+
<li>• Disabled states</li>
|
|
33
|
+
<li>• Props API reference</li>
|
|
34
|
+
<li>• Code examples</li>
|
|
35
|
+
<li>• Accessibility guidelines</li>
|
|
36
|
+
</ul>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
package/src/main.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import X from '$icons/lucide/x';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
children: Snippet;
|
|
7
|
+
onclick?: () => void;
|
|
8
|
+
showHover?: boolean;
|
|
9
|
+
ondelete?: () => void;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
deleteLabel?: string;
|
|
12
|
+
size?: 'sm' | 'md' | 'lg';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
children,
|
|
17
|
+
ondelete,
|
|
18
|
+
showHover = true,
|
|
19
|
+
onclick,
|
|
20
|
+
disabled = false,
|
|
21
|
+
deleteLabel = 'Remove item',
|
|
22
|
+
size = 'md',
|
|
23
|
+
}: Props = $props();
|
|
24
|
+
|
|
25
|
+
function handleDelete() {
|
|
26
|
+
if (!disabled && ondelete) {
|
|
27
|
+
ondelete();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function handleClick() {
|
|
32
|
+
if (!disabled && onclick) {
|
|
33
|
+
onclick();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function handleKeydown(event: KeyboardEvent) {
|
|
38
|
+
if (!disabled && onclick && (event.key === 'Enter' || event.key === ' ')) {
|
|
39
|
+
event.preventDefault();
|
|
40
|
+
onclick();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Shared classes for both interactive and non-interactive states
|
|
45
|
+
const baseClasses =
|
|
46
|
+
'inline-flex items-center gap-1 px-3 py-1 rounded-full border border-gray-200 bg-white text-sm font-medium';
|
|
47
|
+
|
|
48
|
+
// Dynamic classes that apply to both states
|
|
49
|
+
const dynamicClasses = $derived(
|
|
50
|
+
[
|
|
51
|
+
size === 'sm' ? 'text-xs' : '',
|
|
52
|
+
size === 'md' ? 'text-sm' : '',
|
|
53
|
+
size === 'lg' ? 'text-base' : '',
|
|
54
|
+
disabled ? 'opacity-50 cursor-not-allowed' : '',
|
|
55
|
+
]
|
|
56
|
+
.filter(Boolean)
|
|
57
|
+
.join(' ')
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Interactive-specific classes
|
|
61
|
+
const interactiveClasses = $derived((onclick || showHover) && !disabled ? 'hover:bg-gray-50 cursor-pointer' : '');
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
{#snippet chipContent()}
|
|
65
|
+
{@render children()}
|
|
66
|
+
{#if ondelete}
|
|
67
|
+
<button
|
|
68
|
+
type="button"
|
|
69
|
+
class="ml-1 inline-flex items-center justify-center w-4 h-4 rounded-full hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-300"
|
|
70
|
+
class:hover:bg-gray-100={!disabled}
|
|
71
|
+
class:cursor-not-allowed={disabled}
|
|
72
|
+
onclick={handleDelete}
|
|
73
|
+
{disabled}
|
|
74
|
+
aria-label={deleteLabel}
|
|
75
|
+
>
|
|
76
|
+
<X class="w-3 h-3" />
|
|
77
|
+
</button>
|
|
78
|
+
{/if}
|
|
79
|
+
{/snippet}
|
|
80
|
+
|
|
81
|
+
{#if onclick}
|
|
82
|
+
<div
|
|
83
|
+
class="{baseClasses} {dynamicClasses} {interactiveClasses}"
|
|
84
|
+
onclick={handleClick}
|
|
85
|
+
onkeydown={handleKeydown}
|
|
86
|
+
role="button"
|
|
87
|
+
tabindex={disabled ? -1 : 0}
|
|
88
|
+
>
|
|
89
|
+
{@render chipContent()}
|
|
90
|
+
</div>
|
|
91
|
+
{:else}
|
|
92
|
+
<div class="{baseClasses} {dynamicClasses} {interactiveClasses}">
|
|
93
|
+
{@render chipContent()}
|
|
94
|
+
</div>
|
|
95
|
+
{/if}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Chip } from './chip.svelte';
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
<script lang="ts" generics="T">
|
|
2
|
+
import Check from '$icons/lucide/check';
|
|
3
|
+
import ChevronsUpDown from '$icons/lucide/chevrons-up-down';
|
|
4
|
+
import X from '$icons/lucide/x';
|
|
5
|
+
import { Button } from '../../shadcn/button';
|
|
6
|
+
import * as Command from '../../shadcn/command';
|
|
7
|
+
import * as Popover from '../../shadcn/popover';
|
|
8
|
+
import { cn } from '../../shadcn/utils';
|
|
9
|
+
import indefinite from 'indefinite';
|
|
10
|
+
import plur from 'plur';
|
|
11
|
+
import { tick } from 'svelte';
|
|
12
|
+
import type { ComboboxMapping } from './combobox-types';
|
|
13
|
+
|
|
14
|
+
let {
|
|
15
|
+
value = $bindable(),
|
|
16
|
+
mapping,
|
|
17
|
+
options,
|
|
18
|
+
optionTypeName = 'option',
|
|
19
|
+
// We will figure out the plural form of the data type name using the plur library if not provided
|
|
20
|
+
optionTypeNamePlural,
|
|
21
|
+
onValueChanged,
|
|
22
|
+
onSearchValueChanged,
|
|
23
|
+
debounceSearchMs = 300,
|
|
24
|
+
popupWidthClasses = '',
|
|
25
|
+
wrapperClasses = 'w-[200px]',
|
|
26
|
+
buttonClasses = '',
|
|
27
|
+
minCharactersForSearch = 3,
|
|
28
|
+
loading = false,
|
|
29
|
+
showValueInListEntries = false,
|
|
30
|
+
disabled = false,
|
|
31
|
+
allowClear = false,
|
|
32
|
+
inputPlaceholder
|
|
33
|
+
}: {
|
|
34
|
+
value: T | undefined;
|
|
35
|
+
mapping: ComboboxMapping<T>;
|
|
36
|
+
options: T[] | undefined;
|
|
37
|
+
inputPlaceholder?: string;
|
|
38
|
+
searchPlaceholder?: string;
|
|
39
|
+
onValueChanged?: (value: T) => void;
|
|
40
|
+
onSearchValueChanged?: (value: string) => void;
|
|
41
|
+
debounceSearchMs?: number;
|
|
42
|
+
popupWidthClasses?: string;
|
|
43
|
+
wrapperClasses?: string;
|
|
44
|
+
buttonClasses?: string;
|
|
45
|
+
// This is the name of the type of data in the combobox that a user will understand
|
|
46
|
+
optionTypeName?: string;
|
|
47
|
+
optionTypeNamePlural?: string;
|
|
48
|
+
minCharactersForSearch?: number;
|
|
49
|
+
loading?: boolean;
|
|
50
|
+
showValueInListEntries?: boolean;
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
allowClear?: boolean;
|
|
53
|
+
} = $props();
|
|
54
|
+
|
|
55
|
+
$effect(() => {
|
|
56
|
+
// Throw an exception if there is an options array and if all values are not unique
|
|
57
|
+
if (options && options.length > 0 && new Set(options.map((opt) => getValue(opt))).size !== options.length) {
|
|
58
|
+
throw new Error(`All values in the options (returned from your mappings.getValue fn) array must be unique: ${JSON.stringify(options)}`);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const getValue = (item: T) => mapping.value(item);
|
|
63
|
+
const getLabel = (item: T) => mapping.label(item);
|
|
64
|
+
const getSecondaryLabel = (item: T) => mapping.secondaryLabel?.(item);
|
|
65
|
+
|
|
66
|
+
const plurarFormOfOptionTypeName = $derived(optionTypeNamePlural ?? plur(optionTypeName));
|
|
67
|
+
const optionTypeNamePrecededByArticle = $derived(indefinite(optionTypeName));
|
|
68
|
+
const selectAnOptionText = $derived(inputPlaceholder ?? `Select ${optionTypeNamePrecededByArticle}...`);
|
|
69
|
+
let open = $state(false);
|
|
70
|
+
let triggerRef = $state<HTMLButtonElement>(null!);
|
|
71
|
+
let searchDebounceTimeout = $state<ReturnType<typeof setTimeout> | undefined>();
|
|
72
|
+
let searchValue = $state('');
|
|
73
|
+
let labelIsEmpty = $derived(!value);
|
|
74
|
+
let labelToDisplayInButton = $derived(value ? getLabel(value) : selectAnOptionText);
|
|
75
|
+
|
|
76
|
+
// Add the current value to the options if it's not already in the options
|
|
77
|
+
const normalizedOptions = $derived(options ? [...options] : []);
|
|
78
|
+
|
|
79
|
+
// Only show options if we meet the minimum search criteria
|
|
80
|
+
const visibleOptions = $derived.by(() => {
|
|
81
|
+
if (loading) {
|
|
82
|
+
return []; // Don't show any options if we are loading
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Only show options if we have enough characters to search
|
|
86
|
+
if (searchValue.length < minCharactersForSearch) {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
return normalizedOptions;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// We want to refocus the trigger button when the user selects
|
|
93
|
+
// an item from the list so users can continue navigating the
|
|
94
|
+
// rest of the form with the keyboard.
|
|
95
|
+
function closeAndFocusTrigger() {
|
|
96
|
+
open = false;
|
|
97
|
+
tick().then(() => {
|
|
98
|
+
triggerRef.focus();
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
</script>
|
|
102
|
+
|
|
103
|
+
<div class="flex items-center ${wrapperClasses} gap-2">
|
|
104
|
+
<Popover.Root bind:open>
|
|
105
|
+
<Popover.Trigger bind:ref={triggerRef} class="flex-1">
|
|
106
|
+
{#snippet child({ props })}
|
|
107
|
+
<Button variant="outline" class={`flex items-center justify-between w-full ${buttonClasses}`} {...props} role="combobox" aria-expanded={open} {disabled}>
|
|
108
|
+
<span class={cn('flex-1 text-left truncate', labelIsEmpty && 'text-muted-foreground')}>
|
|
109
|
+
{labelToDisplayInButton}
|
|
110
|
+
</span>
|
|
111
|
+
<ChevronsUpDown class="ml-2 shrink-0 opacity-50" />
|
|
112
|
+
</Button>
|
|
113
|
+
{/snippet}
|
|
114
|
+
</Popover.Trigger>
|
|
115
|
+
<Popover.Content class={`p-0 ${popupWidthClasses}`}>
|
|
116
|
+
<Command.Root shouldFilter={false}>
|
|
117
|
+
<Command.Input
|
|
118
|
+
bind:value={searchValue}
|
|
119
|
+
oninput={(e: Event) => {
|
|
120
|
+
if (onSearchValueChanged) {
|
|
121
|
+
const val = (e.target as HTMLInputElement).value;
|
|
122
|
+
|
|
123
|
+
// Always clear existing timeout
|
|
124
|
+
if (searchDebounceTimeout) {
|
|
125
|
+
clearTimeout(searchDebounceTimeout);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Only make server call if we meet minimum characters
|
|
129
|
+
if (val.length >= minCharactersForSearch) {
|
|
130
|
+
// Set new timeout
|
|
131
|
+
searchDebounceTimeout = setTimeout(() => {
|
|
132
|
+
onSearchValueChanged((e.target as HTMLInputElement).value);
|
|
133
|
+
}, debounceSearchMs);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}}
|
|
137
|
+
placeholder="Search {plurarFormOfOptionTypeName}..."
|
|
138
|
+
class="h-9"
|
|
139
|
+
/>
|
|
140
|
+
<Command.List>
|
|
141
|
+
{#if loading}
|
|
142
|
+
<Command.Loading>
|
|
143
|
+
<div class="flex items-center justify-center py-6 text-sm text-muted-foreground">
|
|
144
|
+
<div class="flex items-center gap-2">
|
|
145
|
+
<div class="h-4 w-4 animate-spin rounded-full border-2 border-muted-foreground border-t-transparent"></div>
|
|
146
|
+
Searching {plurarFormOfOptionTypeName}...
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</Command.Loading>
|
|
150
|
+
{:else}
|
|
151
|
+
<Command.Empty>
|
|
152
|
+
{#if searchValue.length > 0 && searchValue.length < minCharactersForSearch}
|
|
153
|
+
Enter at least {minCharactersForSearch} characters to search.
|
|
154
|
+
{:else}
|
|
155
|
+
No {optionTypeName} found.
|
|
156
|
+
{/if}
|
|
157
|
+
</Command.Empty>
|
|
158
|
+
{/if}
|
|
159
|
+
<Command.Group value={plurarFormOfOptionTypeName}>
|
|
160
|
+
{#key visibleOptions}
|
|
161
|
+
{#each visibleOptions as option (getValue(option))}
|
|
162
|
+
<Command.Item
|
|
163
|
+
value={getValue(option)}
|
|
164
|
+
onSelect={() => {
|
|
165
|
+
if (!value || getValue(value) !== getValue(option)) {
|
|
166
|
+
value = option;
|
|
167
|
+
if (onValueChanged) onValueChanged(value);
|
|
168
|
+
}
|
|
169
|
+
closeAndFocusTrigger();
|
|
170
|
+
}}
|
|
171
|
+
class={cn('flex items-start gap-2 px-2 py-2', (getSecondaryLabel(option) || showValueInListEntries) && 'py-2.5 min-h-[3rem]')}
|
|
172
|
+
>
|
|
173
|
+
<Check class={cn('mt-1 flex-shrink-0', (!value || getValue(value) !== getValue(option)) && 'text-transparent')} />
|
|
174
|
+
<div class="flex-1 min-w-0">
|
|
175
|
+
<!-- Primary label -->
|
|
176
|
+
<div class="font-medium text-sm leading-tight truncate">
|
|
177
|
+
{getLabel(option)}
|
|
178
|
+
</div>
|
|
179
|
+
|
|
180
|
+
<!-- Secondary and tertiary info in a row -->
|
|
181
|
+
{#if getSecondaryLabel(option) || showValueInListEntries}
|
|
182
|
+
<div class="flex items-center gap-2 mt-0.5">
|
|
183
|
+
{#if getSecondaryLabel(option)}
|
|
184
|
+
<span class="text-xs text-muted-foreground truncate flex-shrink-0">
|
|
185
|
+
{getSecondaryLabel(option)}
|
|
186
|
+
</span>
|
|
187
|
+
{/if}
|
|
188
|
+
{#if showValueInListEntries}
|
|
189
|
+
<!-- Separator dot if we have both secondary label and value -->
|
|
190
|
+
{#if getSecondaryLabel(option)}
|
|
191
|
+
<span class="text-xs text-muted-foreground/50">•</span>
|
|
192
|
+
{/if}
|
|
193
|
+
<span class="text-xs text-muted-foreground/70 font-mono truncate">
|
|
194
|
+
{getValue(option)}
|
|
195
|
+
</span>
|
|
196
|
+
{/if}
|
|
197
|
+
</div>
|
|
198
|
+
{/if}
|
|
199
|
+
</div>
|
|
200
|
+
</Command.Item>
|
|
201
|
+
{/each}
|
|
202
|
+
{/key}
|
|
203
|
+
</Command.Group>
|
|
204
|
+
</Command.List>
|
|
205
|
+
</Command.Root>
|
|
206
|
+
</Popover.Content>
|
|
207
|
+
</Popover.Root>
|
|
208
|
+
{#if allowClear && !disabled}
|
|
209
|
+
<Button
|
|
210
|
+
variant="ghost"
|
|
211
|
+
size="icon"
|
|
212
|
+
class="h-4 w-4 text-muted-foreground "
|
|
213
|
+
onclick={() => {
|
|
214
|
+
value = undefined;
|
|
215
|
+
if (onValueChanged) onValueChanged(undefined as T);
|
|
216
|
+
}}
|
|
217
|
+
>
|
|
218
|
+
<X />
|
|
219
|
+
</Button>
|
|
220
|
+
{/if}
|
|
221
|
+
</div>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Button } from '../../shadcn/button';
|
|
3
|
+
import * as Dialog from '../../shadcn/dialog';
|
|
4
|
+
let {
|
|
5
|
+
open = $bindable(false),
|
|
6
|
+
message: confirmQuestion,
|
|
7
|
+
onyes,
|
|
8
|
+
title,
|
|
9
|
+
yesBtnTitle,
|
|
10
|
+
noBtnTitle,
|
|
11
|
+
onno,
|
|
12
|
+
onclose
|
|
13
|
+
}: {
|
|
14
|
+
open: boolean;
|
|
15
|
+
message: string;
|
|
16
|
+
title?: string;
|
|
17
|
+
yesBtnTitle?: string;
|
|
18
|
+
noBtnTitle?: string;
|
|
19
|
+
|
|
20
|
+
onyes: () => void;
|
|
21
|
+
onno?: () => void;
|
|
22
|
+
onclose?: () => void;
|
|
23
|
+
} = $props();
|
|
24
|
+
|
|
25
|
+
let noCallback =
|
|
26
|
+
onno ??
|
|
27
|
+
(() => {
|
|
28
|
+
open = false;
|
|
29
|
+
});
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<Dialog.Root
|
|
33
|
+
bind:open
|
|
34
|
+
onOpenChange={() => {
|
|
35
|
+
if (!open && onclose) {
|
|
36
|
+
onclose();
|
|
37
|
+
}
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
<Dialog.Content>
|
|
41
|
+
<Dialog.Title>{title ?? 'Confirm'}</Dialog.Title>
|
|
42
|
+
{confirmQuestion}
|
|
43
|
+
<Dialog.Footer>
|
|
44
|
+
<Button variant="default" onclick={onyes}>{yesBtnTitle ?? 'Confirm'}</Button>
|
|
45
|
+
<Button variant="outline" onclick={noCallback}>{noBtnTitle ?? 'Cancel'}</Button>
|
|
46
|
+
</Dialog.Footer>
|
|
47
|
+
</Dialog.Content>
|
|
48
|
+
</Dialog.Root>
|