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
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import CalendarIcon from '$icons/lucide/calendar';
|
|
3
|
+
import X from '$icons/lucide/x';
|
|
4
|
+
import { Button } from '../../shadcn/button';
|
|
5
|
+
import { Calendar } from '../../shadcn/calendar';
|
|
6
|
+
import { Input } from '../../shadcn/input';
|
|
7
|
+
import * as Popover from '../../shadcn/popover';
|
|
8
|
+
import { cn } from '../../shadcn/utils';
|
|
9
|
+
import { CalendarDate, parseAbsolute, type DateValue } from '@internationalized/date';
|
|
10
|
+
import { isSameDay, parseISO } from 'date-fns';
|
|
11
|
+
import { formatInTimeZone, fromZonedTime } from 'date-fns-tz';
|
|
12
|
+
|
|
13
|
+
type Props = {
|
|
14
|
+
value?: string; // ISO string
|
|
15
|
+
onChange?: (value: string | undefined) => void;
|
|
16
|
+
placeHolder?: string;
|
|
17
|
+
minValue?: string; // ISO string
|
|
18
|
+
maxValue?: string; // ISO string
|
|
19
|
+
required?: boolean;
|
|
20
|
+
timezone: string; // Required timezone prop
|
|
21
|
+
classes?: string;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* This is ignored if minValue or maxValue is not set. If both are set,
|
|
25
|
+
* this is similarly ignored.
|
|
26
|
+
*
|
|
27
|
+
* If true and minValue is set and the user sets the date to the same day as minValue
|
|
28
|
+
* but the time is before the time in minValue, the time will be set to the exact time
|
|
29
|
+
* of minValue.
|
|
30
|
+
*
|
|
31
|
+
* If true and maxValue is set and the user sets the date to the same day as maxValue
|
|
32
|
+
* but the time is after the time in maxValue, the time will be set to the exact time
|
|
33
|
+
* of maxValue.
|
|
34
|
+
*/
|
|
35
|
+
autoCorrectTimeForSameDay?: boolean;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
let { value = $bindable(), onChange, placeHolder, minValue, maxValue, required, timezone, classes, autoCorrectTimeForSameDay = false }: Props = $props();
|
|
39
|
+
|
|
40
|
+
// State for flashing red effect when auto-correction occurs
|
|
41
|
+
let isFlashingRed = $state(false);
|
|
42
|
+
|
|
43
|
+
// Helper function to trigger red flash effect
|
|
44
|
+
function triggerRedFlash() {
|
|
45
|
+
isFlashingRed = true;
|
|
46
|
+
setTimeout(() => {
|
|
47
|
+
isFlashingRed = false;
|
|
48
|
+
}, 600); // Flash for 600ms
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Convert ISO string to DateValue for the Calendar component
|
|
52
|
+
function isoToDateValue(isoString: string | undefined): DateValue | undefined {
|
|
53
|
+
if (!isoString) return undefined;
|
|
54
|
+
try {
|
|
55
|
+
return parseAbsolute(isoString, timezone);
|
|
56
|
+
} catch {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Convert ISO string to date-only DateValue for Calendar min/max (ignores time)
|
|
62
|
+
function isoToDateOnlyValue(isoString: string | undefined): DateValue | undefined {
|
|
63
|
+
if (!isoString) return undefined;
|
|
64
|
+
try {
|
|
65
|
+
const date = parseISO(isoString);
|
|
66
|
+
return new CalendarDate(date.getFullYear(), date.getMonth() + 1, date.getDate());
|
|
67
|
+
} catch {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Convert DateValue to ISO string
|
|
73
|
+
function dateValueToIso(dateValue: DateValue | undefined, hour: number = 0, minute: number = 0): string | undefined {
|
|
74
|
+
if (!dateValue) return undefined;
|
|
75
|
+
|
|
76
|
+
// Create a Date object in the specified timezone
|
|
77
|
+
const date = new Date(dateValue.year, dateValue.month - 1, dateValue.day, hour, minute);
|
|
78
|
+
|
|
79
|
+
// Convert to UTC and return ISO string
|
|
80
|
+
return fromZonedTime(date, timezone).toISOString();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// DATA FLOW EXPLANATION:
|
|
84
|
+
// 1. Main prop 'value' is an ISO string (what gets passed to parent)
|
|
85
|
+
// 2. Calendar component needs DateValue, so we use localDateValue as intermediate
|
|
86
|
+
// 3. When prop changes -> update localDateValue (effect below)
|
|
87
|
+
// 4. When user clicks calendar -> Calendar updates localDateValue via bind:value -> second effect detects this -> calls handleDateChange -> updates main value
|
|
88
|
+
|
|
89
|
+
// Create a local DateValue to track calendar changes
|
|
90
|
+
let localDateValue = $state<DateValue | undefined>(isoToDateValue(value));
|
|
91
|
+
|
|
92
|
+
// EFFECT 1: Prop -> Local (when parent updates the value prop)
|
|
93
|
+
$effect(() => {
|
|
94
|
+
localDateValue = isoToDateValue(value);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// EFFECT 2: Local -> Prop (when user interacts with calendar)
|
|
98
|
+
$effect(() => {
|
|
99
|
+
// Skip if localDateValue change was caused by the prop change above
|
|
100
|
+
if (localDateValue === isoToDateValue(value)) return;
|
|
101
|
+
|
|
102
|
+
// Call handleDateChange when localDateValue changes through calendar interaction
|
|
103
|
+
handleDateChange(localDateValue);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Time handling - derive from ISO value
|
|
107
|
+
let hours = $derived.by(() => {
|
|
108
|
+
if (!value) return 0;
|
|
109
|
+
const date = parseISO(value);
|
|
110
|
+
// Parse the time in the specified timezone
|
|
111
|
+
const timeStr = formatInTimeZone(date, timezone, 'H');
|
|
112
|
+
return parseInt(timeStr);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
let minutes = $derived.by(() => {
|
|
116
|
+
if (!value) return 0;
|
|
117
|
+
const date = parseISO(value);
|
|
118
|
+
const timeStr = formatInTimeZone(date, timezone, 'm');
|
|
119
|
+
return parseInt(timeStr);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
let isPM = $derived(hours >= 12);
|
|
123
|
+
|
|
124
|
+
// Format for display using your timezone approach
|
|
125
|
+
const displayFormatter = $derived.by(() => {
|
|
126
|
+
if (!value) return '';
|
|
127
|
+
const date = parseISO(value);
|
|
128
|
+
return formatInTimeZone(date, timezone, 'M/d/yy h:mm a');
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
function isTimeValid(isoString: string, hour: number, minute: number): boolean {
|
|
132
|
+
if (!minValue && !maxValue) return true;
|
|
133
|
+
|
|
134
|
+
const testDate = parseISO(isoString);
|
|
135
|
+
const testDateTime = new Date(testDate.getFullYear(), testDate.getMonth(), testDate.getDate(), hour, minute);
|
|
136
|
+
const testIso = fromZonedTime(testDateTime, timezone).toISOString();
|
|
137
|
+
|
|
138
|
+
if (minValue && testIso < minValue) return false;
|
|
139
|
+
if (maxValue && testIso > maxValue) return false;
|
|
140
|
+
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function handleTimeChange(type: 'hour' | 'minute', newValue: string) {
|
|
145
|
+
const num = parseInt(newValue) || 0;
|
|
146
|
+
let newHour = hours;
|
|
147
|
+
let newMinute = minutes;
|
|
148
|
+
|
|
149
|
+
if (type === 'hour') {
|
|
150
|
+
newHour = Math.max(0, Math.min(23, num));
|
|
151
|
+
} else {
|
|
152
|
+
newMinute = Math.max(0, Math.min(59, num));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// If no date is set, use today
|
|
156
|
+
let dateToUse = value ? parseISO(value) : new Date();
|
|
157
|
+
const newDateTime = new Date(dateToUse.getFullYear(), dateToUse.getMonth(), dateToUse.getDate(), newHour, newMinute);
|
|
158
|
+
let newIso = fromZonedTime(newDateTime, timezone).toISOString();
|
|
159
|
+
|
|
160
|
+
// Apply auto-correction if enabled and time is invalid
|
|
161
|
+
let autoCorrectionApplied = false;
|
|
162
|
+
if (!isTimeValid(newIso, newHour, newMinute) && autoCorrectTimeForSameDay && (minValue || maxValue) && !(minValue && maxValue)) {
|
|
163
|
+
const newDate = parseISO(newIso);
|
|
164
|
+
const originalIso = newIso;
|
|
165
|
+
|
|
166
|
+
// Case 1: minValue is set, same day, but time is before minValue
|
|
167
|
+
if (minValue && !maxValue) {
|
|
168
|
+
const minDateTime = parseISO(minValue);
|
|
169
|
+
if (isSameDay(newDate, minDateTime) && newDate < minDateTime) {
|
|
170
|
+
newIso = minValue;
|
|
171
|
+
autoCorrectionApplied = originalIso !== newIso;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Case 2: maxValue is set, same day, but time is after maxValue
|
|
176
|
+
if (maxValue && !minValue) {
|
|
177
|
+
const maxDateTime = parseISO(maxValue);
|
|
178
|
+
if (isSameDay(newDate, maxDateTime) && newDate > maxDateTime) {
|
|
179
|
+
newIso = maxValue;
|
|
180
|
+
autoCorrectionApplied = originalIso !== newIso;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Apply the change if it's now valid (either originally or after auto-correction)
|
|
186
|
+
if (isTimeValid(newIso, parseISO(newIso).getHours(), parseISO(newIso).getMinutes())) {
|
|
187
|
+
value = newIso;
|
|
188
|
+
onChange?.(newIso);
|
|
189
|
+
|
|
190
|
+
// Trigger red flash if auto-correction was applied
|
|
191
|
+
if (autoCorrectionApplied) {
|
|
192
|
+
triggerRedFlash();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function handleDateChange(newDate: DateValue | undefined) {
|
|
198
|
+
if (!newDate) {
|
|
199
|
+
if (required) return;
|
|
200
|
+
value = undefined;
|
|
201
|
+
onChange?.(undefined);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Preserve existing time or use current time
|
|
206
|
+
const currentHour = hours;
|
|
207
|
+
const currentMinute = minutes;
|
|
208
|
+
|
|
209
|
+
let newIso = dateValueToIso(newDate, currentHour, currentMinute);
|
|
210
|
+
|
|
211
|
+
if (newIso) {
|
|
212
|
+
let autoCorrectionApplied = false;
|
|
213
|
+
|
|
214
|
+
// Auto-correct time for same day if enabled and only one of min/max is set
|
|
215
|
+
if (autoCorrectTimeForSameDay && (minValue || maxValue) && !(minValue && maxValue)) {
|
|
216
|
+
const newDateTime = parseISO(newIso);
|
|
217
|
+
const originalIso = newIso;
|
|
218
|
+
|
|
219
|
+
// Case 1: minValue is set, same day, but time is before minValue
|
|
220
|
+
if (minValue && !maxValue) {
|
|
221
|
+
const minDateTime = parseISO(minValue);
|
|
222
|
+
if (isSameDay(newDateTime, minDateTime) && newDateTime < minDateTime) {
|
|
223
|
+
newIso = minValue;
|
|
224
|
+
autoCorrectionApplied = originalIso !== newIso;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Case 2: maxValue is set, same day, but time is after maxValue
|
|
229
|
+
if (maxValue && !minValue) {
|
|
230
|
+
const maxDateTime = parseISO(maxValue);
|
|
231
|
+
if (isSameDay(newDateTime, maxDateTime) && newDateTime > maxDateTime) {
|
|
232
|
+
newIso = maxValue;
|
|
233
|
+
autoCorrectionApplied = originalIso !== newIso;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Use normal validation if auto-correction didn't apply or wasn't enabled
|
|
239
|
+
if (isTimeValid(newIso, parseISO(newIso).getHours(), parseISO(newIso).getMinutes())) {
|
|
240
|
+
localDateValue = newDate;
|
|
241
|
+
value = newIso;
|
|
242
|
+
onChange?.(newIso);
|
|
243
|
+
|
|
244
|
+
// Trigger red flash if auto-correction was applied
|
|
245
|
+
if (autoCorrectionApplied) {
|
|
246
|
+
triggerRedFlash();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function handleClear(e: Event) {
|
|
253
|
+
e.stopPropagation();
|
|
254
|
+
localDateValue = undefined;
|
|
255
|
+
value = undefined;
|
|
256
|
+
onChange?.(undefined);
|
|
257
|
+
}
|
|
258
|
+
</script>
|
|
259
|
+
|
|
260
|
+
<Popover.Root>
|
|
261
|
+
<Popover.Trigger class={cn('justify-start text-left font-normal', !value && 'text-muted-foreground')}>
|
|
262
|
+
<div class={cn('relative')}>
|
|
263
|
+
<Button variant="outline" class={cn('justify-start text-left font-normal', !value && 'text-muted-foreground', classes)}>
|
|
264
|
+
<CalendarIcon class="h-5 w-5" />
|
|
265
|
+
{value ? displayFormatter : placeHolder || 'Pick a date/time'}
|
|
266
|
+
</Button>
|
|
267
|
+
{#if value && !required}
|
|
268
|
+
<button
|
|
269
|
+
type="button"
|
|
270
|
+
class="absolute top-1 right-2 h-7 hover:bg-muted rounded-sm text-muted-foreground hover:text-foreground"
|
|
271
|
+
onclick={handleClear}
|
|
272
|
+
onkeydown={(e) => e.key === 'Enter' && handleClear(e)}
|
|
273
|
+
>
|
|
274
|
+
<X class="h-4 w-4" />
|
|
275
|
+
</button>
|
|
276
|
+
{/if}
|
|
277
|
+
</div>
|
|
278
|
+
</Popover.Trigger>
|
|
279
|
+
<Popover.Content class="w-auto p-0">
|
|
280
|
+
<Calendar type="single" bind:value={localDateValue} minValue={isoToDateOnlyValue(minValue)} maxValue={isoToDateOnlyValue(maxValue)} preventDeselect={required} />
|
|
281
|
+
<div class="p-3 border-t border-border flex flex-col gap-2">
|
|
282
|
+
<div class="flex items-center gap-1">
|
|
283
|
+
<Input
|
|
284
|
+
type="number"
|
|
285
|
+
bind:value={
|
|
286
|
+
() => {
|
|
287
|
+
return hours === 0 ? 12 : hours > 12 ? hours - 12 : hours;
|
|
288
|
+
},
|
|
289
|
+
(newVal) => {
|
|
290
|
+
const newHour = newVal === 12 ? (isPM ? 12 : 0) : isPM ? newVal + 12 : newVal;
|
|
291
|
+
handleTimeChange('hour', newHour.toString());
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
min={1}
|
|
295
|
+
max={12}
|
|
296
|
+
class="w-16 {isFlashingRed ? 'text-destructive' : ''}"
|
|
297
|
+
/>
|
|
298
|
+
<span>:</span>
|
|
299
|
+
<Input
|
|
300
|
+
type="number"
|
|
301
|
+
bind:value={
|
|
302
|
+
() => minutes,
|
|
303
|
+
(newVal) => {
|
|
304
|
+
const newMinute = newVal === 60 ? 0 : newVal;
|
|
305
|
+
handleTimeChange('minute', newMinute.toString());
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
min={0}
|
|
309
|
+
max={59}
|
|
310
|
+
class="w-16 {isFlashingRed ? 'text-destructive' : ''}"
|
|
311
|
+
/>
|
|
312
|
+
<Button
|
|
313
|
+
variant="outline"
|
|
314
|
+
size="sm"
|
|
315
|
+
class="w-20"
|
|
316
|
+
onclick={() => {
|
|
317
|
+
const newHour = hours >= 12 ? hours - 12 : hours + 12;
|
|
318
|
+
handleTimeChange('hour', newHour.toString());
|
|
319
|
+
}}
|
|
320
|
+
>
|
|
321
|
+
{hours >= 12 ? 'PM' : 'AM'}
|
|
322
|
+
</Button>
|
|
323
|
+
</div>
|
|
324
|
+
{#if minValue}
|
|
325
|
+
<div class="text-xs transition-colors duration-200 {isFlashingRed ? 'text-destructive' : 'text-muted-foreground'}">
|
|
326
|
+
must be after {formatInTimeZone(parseISO(minValue), timezone, 'M/d/yy h:mm a')}
|
|
327
|
+
</div>
|
|
328
|
+
{/if}
|
|
329
|
+
{#if maxValue}
|
|
330
|
+
<div class="text-xs transition-colors duration-200 {isFlashingRed ? 'text-destructive' : 'text-muted-foreground'}">
|
|
331
|
+
must be before {formatInTimeZone(parseISO(maxValue), timezone, 'M/d/yy h:mm a')}
|
|
332
|
+
</div>
|
|
333
|
+
{/if}
|
|
334
|
+
</div>
|
|
335
|
+
</Popover.Content>
|
|
336
|
+
</Popover.Root>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as DateTimePicker } from './date-time-picker.svelte';
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Expandable Container Component
|
|
3
|
+
|
|
4
|
+
A versatile container component that can be expanded/collapsed and supports different use cases.
|
|
5
|
+
|
|
6
|
+
Supported Use Cases:
|
|
7
|
+
1. Default Use Case
|
|
8
|
+
- Basic expandable container with title and content
|
|
9
|
+
- Can be expanded/collapsed via chevron button
|
|
10
|
+
- Supports disabled state
|
|
11
|
+
|
|
12
|
+
2. Steps in Process Use Case
|
|
13
|
+
- Visualizes steps in a multi-step process
|
|
14
|
+
- Shows status indicators for each step:
|
|
15
|
+
- Green checkmark (✓) for completed steps
|
|
16
|
+
- Blue circle (○) for current active step
|
|
17
|
+
- Yellow dash (-) for future steps
|
|
18
|
+
- Requires stepsInProcess prop with:
|
|
19
|
+
- stepId: Current step identifier
|
|
20
|
+
- steps: Array of steps with their completion status
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
3. Button Use Case
|
|
24
|
+
- A button that can be used to expand/collapse the container
|
|
25
|
+
- The button is a chevron with a title that can be used to expand/collapse the container
|
|
26
|
+
- The button is a ghost button
|
|
27
|
+
|
|
28
|
+
Props:
|
|
29
|
+
- forceExpanded: boolean (optional) - Forces container to stay expanded
|
|
30
|
+
- title: string - Title text for the container
|
|
31
|
+
- disabled: boolean (optional) - Disables interaction with content
|
|
32
|
+
- children: Snippet - Content to display when expanded
|
|
33
|
+
- useCase: 'steps-in-process' | 'default' | 'button' - Determines component behavior
|
|
34
|
+
- stepsInProcess: StepsInProcess<any> - Required for 'steps-in-process' use case
|
|
35
|
+
-->
|
|
36
|
+
|
|
37
|
+
<script lang="ts">
|
|
38
|
+
import ArrowBigRight from '$icons/lucide/arrow-big-right';
|
|
39
|
+
import Check from '$icons/lucide/check';
|
|
40
|
+
import ChevronRight from '$icons/lucide/chevron-right';
|
|
41
|
+
import Circle from '$icons/lucide/circle';
|
|
42
|
+
import Minus from '$icons/lucide/minus';
|
|
43
|
+
import { Button } from '../../shadcn/button';
|
|
44
|
+
import type { Snippet } from 'svelte';
|
|
45
|
+
|
|
46
|
+
type UseCase = 'steps-in-process' | 'default' | 'button';
|
|
47
|
+
|
|
48
|
+
export interface StepModel<T> {
|
|
49
|
+
// The ID of the step
|
|
50
|
+
stepId: T;
|
|
51
|
+
|
|
52
|
+
// Whether the step has been completed
|
|
53
|
+
done: boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface StepsInProcess<T> {
|
|
57
|
+
// The ID of the current step this expandable container is representing
|
|
58
|
+
stepId: T;
|
|
59
|
+
|
|
60
|
+
// The steps that make up the process, in order
|
|
61
|
+
steps: StepModel<T>[];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
interface Props {
|
|
65
|
+
forceExpanded?: boolean;
|
|
66
|
+
title: string;
|
|
67
|
+
disabled?: boolean;
|
|
68
|
+
children?: Snippet<[]>;
|
|
69
|
+
useCase?: UseCase;
|
|
70
|
+
stepsInProcess?: StepsInProcess<any>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let { forceExpanded = false, title, disabled = false, children, useCase = 'default', stepsInProcess }: Props = $props();
|
|
74
|
+
|
|
75
|
+
let expanded = $state(false);
|
|
76
|
+
|
|
77
|
+
let statusObj = $derived.by(() => {
|
|
78
|
+
if (useCase === 'steps-in-process' && stepsInProcess) {
|
|
79
|
+
const currentStep = stepsInProcess.steps.find((step) => step.stepId === stepsInProcess.stepId);
|
|
80
|
+
const firstStepNotDone = stepsInProcess.steps.find((step) => !step.done);
|
|
81
|
+
if (currentStep?.done) {
|
|
82
|
+
// This step is done
|
|
83
|
+
return { iconColor: 'text-green-600', textColor: 'text-gray-600', icon: Check, titleIcon: undefined };
|
|
84
|
+
} else if (firstStepNotDone?.stepId === currentStep?.stepId) {
|
|
85
|
+
// This is the first step that hasn't been done
|
|
86
|
+
return {
|
|
87
|
+
iconColor: 'text-purple-600',
|
|
88
|
+
textColor: 'text-gray-600',
|
|
89
|
+
icon: Circle,
|
|
90
|
+
titleIcon: ArrowBigRight
|
|
91
|
+
};
|
|
92
|
+
} else {
|
|
93
|
+
// You can't do this step yet since it's after the current step
|
|
94
|
+
return { iconColor: 'text-yellow-600', textColor: 'text-gray-400', icon: Minus, titleIcon: undefined };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return undefined;
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
let forceExpandedComputed = $derived.by(() => {
|
|
102
|
+
if (useCase === 'steps-in-process' && stepsInProcess) {
|
|
103
|
+
const currentStep = stepsInProcess.steps.find((step) => step.stepId === stepsInProcess.stepId);
|
|
104
|
+
const firstStepNotDone = stepsInProcess.steps.find((step) => !step.done);
|
|
105
|
+
return currentStep?.stepId === firstStepNotDone?.stepId;
|
|
106
|
+
}
|
|
107
|
+
return forceExpanded;
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
$effect(() => {
|
|
111
|
+
const uc = useCase;
|
|
112
|
+
const sip = stepsInProcess;
|
|
113
|
+
if (uc === 'steps-in-process' && !sip) {
|
|
114
|
+
throw new Error('stepsInProcess is required for useCase "steps-in-process"');
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
</script>
|
|
118
|
+
|
|
119
|
+
{#if useCase === 'button'}
|
|
120
|
+
<Button variant="ghost" onclick={() => (expanded = !expanded)}>
|
|
121
|
+
<span class="font-medium">{title}</span>
|
|
122
|
+
<ChevronRight class="transition-transform duration-200 data-[state=open]:rotate-90" data-state={expanded || forceExpandedComputed ? 'open' : 'closed'} />
|
|
123
|
+
</Button>
|
|
124
|
+
{#if expanded || forceExpandedComputed}
|
|
125
|
+
<div class="p-4 {disabled ? 'opacity-60 pointer-events-none' : ''}">
|
|
126
|
+
{@render children?.()}
|
|
127
|
+
</div>
|
|
128
|
+
{/if}
|
|
129
|
+
{:else}
|
|
130
|
+
<div class="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden" data-state={expanded || forceExpandedComputed ? 'open' : 'closed'}>
|
|
131
|
+
<div class="flex items-center p-1 gap-3 pl-2 pr-2">
|
|
132
|
+
<div class="flex-grow flex items-center gap-1 {forceExpandedComputed ? 'h-8 pl-1' : ''}">
|
|
133
|
+
{#if !forceExpandedComputed}
|
|
134
|
+
<Button variant="ghost" class="p-1" onclick={() => (expanded = !expanded)}>
|
|
135
|
+
<ChevronRight class="transition-transform duration-200 data-[state=open]:rotate-90" data-state={expanded || forceExpandedComputed ? 'open' : 'closed'} />
|
|
136
|
+
</Button>
|
|
137
|
+
{:else if useCase === 'steps-in-process' && statusObj && statusObj.titleIcon}
|
|
138
|
+
<statusObj.titleIcon class="w-5 h-5 {statusObj.iconColor}" />
|
|
139
|
+
{/if}
|
|
140
|
+
|
|
141
|
+
<span class="font-medium {statusObj ? statusObj.textColor : ''}">{title}</span>
|
|
142
|
+
</div>
|
|
143
|
+
|
|
144
|
+
{#if useCase === 'steps-in-process' && statusObj}
|
|
145
|
+
<statusObj.icon class="w-5 h-5 {statusObj.iconColor}" />
|
|
146
|
+
{/if}
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
{#if expanded || forceExpandedComputed}
|
|
150
|
+
<div class="border-t border-gray-200 p-4 {disabled ? 'opacity-60 pointer-events-none' : ''}">
|
|
151
|
+
{@render children?.()}
|
|
152
|
+
</div>
|
|
153
|
+
{/if}
|
|
154
|
+
</div>
|
|
155
|
+
{/if}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as ExpandableContainer } from './expandable-container.svelte';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Pika UI Components - Non-conflicting exports
|
|
2
|
+
export * from './chip';
|
|
3
|
+
export * from './combobox';
|
|
4
|
+
export * from './confirm-dialog';
|
|
5
|
+
export * from './copy-button';
|
|
6
|
+
export * from './create-copy-link-button';
|
|
7
|
+
export * from './date-picker';
|
|
8
|
+
export * from './date-range-picker';
|
|
9
|
+
export * from './date-time-picker';
|
|
10
|
+
export * from './expandable-container';
|
|
11
|
+
export * from './markdown-editor';
|
|
12
|
+
export * from './permanent-toast';
|
|
13
|
+
export * from './pika-alert';
|
|
14
|
+
export * from './pika-badge';
|
|
15
|
+
export * from './pika-table';
|
|
16
|
+
export * from './popup-help';
|
|
17
|
+
export * from './simple-dropdown';
|
|
18
|
+
export * from './text-wave-shimmer';
|
|
19
|
+
export * from './tooltip-plus';
|
|
20
|
+
|
|
21
|
+
// Selective exports to avoid naming conflicts
|
|
22
|
+
// List component - renamed to avoid conflict with TabsList
|
|
23
|
+
export { List as PikaList, type ListMapping } from './list';
|
|
24
|
+
|
|
25
|
+
// Tabs component - only export aliased versions to avoid "Content" and "List" conflicts
|
|
26
|
+
export { Tabs, TabsContent, TabsList, TabsTrigger } from './pika-tabs';
|
|
27
|
+
|
|
28
|
+
// Slideout component - only export aliased versions to avoid "Content" conflict
|
|
29
|
+
export { Slideout, SlideoutContent, SlideoutPanel, SlideoutProvider, useSlideout } from './slideout';
|