@ponti-studios/ui 2.0.1 → 3.0.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/README.md +36 -3
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/index.js +3 -0
- package/dist/components/data-display/accordion.d.ts +10 -0
- package/dist/components/data-display/accordion.js +53 -0
- package/{src/components/data-display/index.ts → dist/components/data-display/index.d.ts} +1 -10
- package/dist/components/data-display/index.js +8 -0
- package/dist/components/data-display/metric-card.d.ts +9 -0
- package/dist/components/data-display/metric-card.js +25 -0
- package/dist/components/data-display/sort-controls.d.ts +13 -0
- package/dist/components/data-display/sort-controls.js +57 -0
- package/dist/components/data-display/sort-row.d.ts +10 -0
- package/dist/components/data-display/sort-row.js +52 -0
- package/dist/components/data-display/table.d.ts +10 -0
- package/dist/components/data-display/table.js +57 -0
- package/dist/components/feedback/alert.d.ts +9 -0
- package/dist/components/feedback/alert.js +38 -0
- package/dist/components/feedback/empty-state.d.ts +18 -0
- package/dist/components/feedback/empty-state.js +36 -0
- package/{src/components/feedback/index.ts → dist/components/feedback/index.d.ts} +2 -0
- package/dist/components/feedback/index.js +7 -0
- package/dist/components/feedback/progress.d.ts +6 -0
- package/dist/components/feedback/progress.js +25 -0
- package/dist/components/feedback/skeleton.d.ts +2 -0
- package/dist/components/feedback/skeleton.js +11 -0
- package/dist/components/feedback/spinner.d.ts +14 -0
- package/dist/components/feedback/spinner.js +27 -0
- package/dist/components/feedback/update-guard.d.ts +13 -0
- package/dist/components/feedback/update-guard.js +38 -0
- package/dist/components/filters/active-filters-bar.d.ts +14 -0
- package/dist/components/filters/active-filters-bar.js +44 -0
- package/dist/components/filters/filter-chip.d.ts +11 -0
- package/dist/components/filters/filter-chip.js +33 -0
- package/dist/components/filters/filter-select.d.ts +17 -0
- package/dist/components/filters/filter-select.js +46 -0
- package/dist/components/filters/index.js +4 -0
- package/dist/components/forms/checkbox.d.ts +4 -0
- package/dist/components/forms/checkbox.js +24 -0
- package/dist/components/forms/date-month-select.d.ts +11 -0
- package/dist/components/forms/date-month-select.js +47 -0
- package/dist/components/forms/date-picker.d.ts +60 -0
- package/dist/components/forms/date-picker.js +193 -0
- package/dist/components/forms/date-utils.d.ts +14 -0
- package/dist/components/forms/date-utils.js +18 -0
- package/dist/components/forms/drop-zone.d.ts +42 -0
- package/dist/components/forms/drop-zone.js +184 -0
- package/{src/components/forms/index.ts → dist/components/forms/index.d.ts} +3 -9
- package/dist/components/forms/index.js +17 -0
- package/dist/components/forms/input.d.ts +3 -0
- package/dist/components/forms/input.js +15 -0
- package/dist/components/forms/label.d.ts +3 -0
- package/dist/components/forms/label.js +14 -0
- package/dist/components/forms/passkey-management.d.ts +14 -0
- package/dist/components/forms/passkey-management.js +132 -0
- package/dist/components/forms/radio-group.d.ts +6 -0
- package/dist/components/forms/radio-group.js +28 -0
- package/dist/components/forms/select.d.ts +18 -0
- package/dist/components/forms/select.js +103 -0
- package/dist/components/forms/slider.d.ts +9 -0
- package/dist/components/forms/slider.js +25 -0
- package/dist/components/forms/stepper.d.ts +15 -0
- package/dist/components/forms/stepper.js +41 -0
- package/dist/components/forms/switch.d.ts +6 -0
- package/dist/components/forms/switch.js +21 -0
- package/dist/components/forms/text-field.d.ts +15 -0
- package/dist/components/forms/text-field.js +46 -0
- package/dist/components/forms/text-field.types.d.ts +8 -0
- package/dist/components/forms/textarea.d.ts +3 -0
- package/dist/components/forms/textarea.js +14 -0
- package/dist/components/layout/index.js +5 -0
- package/dist/components/layout/particle-background.d.ts +19 -0
- package/dist/components/layout/particle-background.js +171 -0
- package/dist/components/layout/scroll-area.d.ts +9 -0
- package/dist/components/layout/scroll-area.js +35 -0
- package/dist/components/layout/section-intro.d.ts +12 -0
- package/dist/components/layout/section-intro.js +28 -0
- package/dist/components/layout/surface-panel.d.ts +7 -0
- package/dist/components/layout/surface-panel.js +11 -0
- package/dist/components/navigation/app-navigation.d.ts +67 -0
- package/dist/components/navigation/app-navigation.js +106 -0
- package/{src/components/navigation/index.ts → dist/components/navigation/index.d.ts} +1 -7
- package/dist/components/navigation/index.js +4 -0
- package/dist/components/navigation/pagination-controls.d.ts +7 -0
- package/dist/components/navigation/pagination-controls.js +50 -0
- package/dist/components/navigation/tabs.d.ts +7 -0
- package/dist/components/navigation/tabs.js +35 -0
- package/dist/components/overlays/bottom-sheet.d.ts +20 -0
- package/dist/components/overlays/bottom-sheet.js +101 -0
- package/dist/components/overlays/command.d.ts +29 -0
- package/dist/components/overlays/command.js +123 -0
- package/dist/components/overlays/dialog.d.ts +30 -0
- package/dist/components/overlays/dialog.js +105 -0
- package/dist/components/overlays/dropdown-menu.d.ts +29 -0
- package/dist/components/overlays/dropdown-menu.js +128 -0
- package/dist/components/overlays/index.d.ts +7 -0
- package/dist/components/overlays/index.js +8 -0
- package/dist/components/overlays/popover.d.ts +14 -0
- package/dist/components/overlays/popover.js +56 -0
- package/dist/components/overlays/sheet.d.ts +27 -0
- package/dist/components/overlays/sheet.js +81 -0
- package/dist/components/overlays/tooltip.d.ts +10 -0
- package/dist/components/overlays/tooltip.js +23 -0
- package/dist/components/primitives/avatar.d.ts +14 -0
- package/dist/components/primitives/avatar.js +72 -0
- package/dist/components/primitives/badge.d.ts +7 -0
- package/dist/components/primitives/badge.js +27 -0
- package/dist/components/primitives/button.d.ts +13 -0
- package/dist/components/primitives/button.js +113 -0
- package/{src/components/primitives/button.types.ts → dist/components/primitives/button.types.d.ts} +4 -6
- package/dist/components/primitives/card.d.ts +9 -0
- package/dist/components/primitives/card.js +56 -0
- package/{src/components/primitives/index.ts → dist/components/primitives/index.d.ts} +1 -9
- package/dist/components/primitives/index.js +7 -0
- package/dist/components/primitives/segmented-control.d.ts +20 -0
- package/dist/components/primitives/segmented-control.js +27 -0
- package/dist/components/primitives/separator.d.ts +4 -0
- package/dist/components/primitives/separator.js +16 -0
- package/dist/constants/chart-colors.d.ts +33 -0
- package/dist/constants/chart-colors.js +31 -0
- package/dist/hooks/index.js +9 -0
- package/{src/hooks/sort.types.ts → dist/hooks/sort.types.d.ts} +2 -4
- package/dist/hooks/use-api-client.d.ts +30 -0
- package/dist/hooks/use-api-client.js +106 -0
- package/dist/hooks/use-debounced-value.d.ts +1 -0
- package/dist/hooks/use-debounced-value.js +12 -0
- package/dist/hooks/use-derived-filter-state.d.ts +20 -0
- package/dist/hooks/use-derived-filter-state.js +39 -0
- package/dist/hooks/use-filter-state.d.ts +12 -0
- package/dist/hooks/use-filter-state.js +37 -0
- package/dist/hooks/use-media-query.d.ts +6 -0
- package/dist/hooks/use-media-query.js +27 -0
- package/dist/hooks/use-mobile.d.ts +1 -0
- package/dist/hooks/use-mobile.js +14 -0
- package/dist/hooks/use-sort.d.ts +11 -0
- package/dist/hooks/use-sort.js +14 -0
- package/{src/index.ts → dist/index.d.ts} +4 -32
- package/dist/index.js +15 -0
- package/dist/integrations/service-worker.d.ts +2 -0
- package/dist/integrations/service-worker.js +2 -0
- package/dist/lib/auth.d.ts +2 -0
- package/dist/lib/auth.js +7 -0
- package/dist/lib/clipboard.d.ts +1 -0
- package/dist/lib/clipboard.js +10 -0
- package/dist/lib/index.js +4 -0
- package/{src/lib/slot.tsx → dist/lib/slot.d.ts} +2 -15
- package/dist/lib/slot.js +14 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +8 -0
- package/dist/native/components.d.ts +41 -0
- package/dist/native/components.js +135 -0
- package/dist/native/index.js +3 -0
- package/dist/native/theme.d.ts +19 -0
- package/dist/native/theme.js +58 -0
- package/dist/styles/tokens/css-vars.d.ts +7 -0
- package/dist/styles/tokens/css-vars.js +5 -0
- package/dist/styles/tokens/generated/dark.colors.generated.d.ts +40 -0
- package/dist/styles/tokens/generated/dark.colors.generated.js +39 -0
- package/dist/styles/tokens/generated/foundations.generated.d.ts +323 -0
- package/dist/styles/tokens/generated/foundations.generated.js +453 -0
- package/dist/styles/tokens/generated/light.colors.generated.d.ts +40 -0
- package/dist/styles/tokens/generated/light.colors.generated.js +39 -0
- package/dist/styles/tokens/index.d.ts +317 -0
- package/dist/styles/tokens/index.js +14 -0
- package/dist/styles.css +1 -1
- package/dist/translations/en.d.ts +34 -0
- package/dist/translations/index.d.ts +39 -0
- package/dist/translations/ui-provider.d.ts +9 -0
- package/dist/translations/ui-provider.js +16 -0
- package/dist/types/upload.d.ts +36 -0
- package/package.json +50 -33
- package/src/components/data-display/accordion.stories.tsx +0 -57
- package/src/components/data-display/accordion.tsx +0 -86
- package/src/components/data-display/metric-card.stories.tsx +0 -48
- package/src/components/data-display/metric-card.tsx +0 -20
- package/src/components/data-display/sort-controls.stories.tsx +0 -45
- package/src/components/data-display/sort-controls.tsx +0 -96
- package/src/components/data-display/sort-row.tsx +0 -88
- package/src/components/data-display/table.stories.tsx +0 -75
- package/src/components/data-display/table.tsx +0 -80
- package/src/components/feedback/alert.stories.tsx +0 -51
- package/src/components/feedback/alert.tsx +0 -64
- package/src/components/feedback/empty-state.tsx +0 -76
- package/src/components/feedback/progress.stories.tsx +0 -54
- package/src/components/feedback/progress.tsx +0 -41
- package/src/components/feedback/skeleton.stories.tsx +0 -36
- package/src/components/feedback/skeleton.tsx +0 -7
- package/src/components/feedback/spinner.stories.tsx +0 -52
- package/src/components/feedback/spinner.tsx +0 -47
- package/src/components/feedback/update-guard.stories.tsx +0 -28
- package/src/components/feedback/update-guard.tsx +0 -57
- package/src/components/filters/active-filters-bar.stories.tsx +0 -114
- package/src/components/filters/active-filters-bar.tsx +0 -61
- package/src/components/filters/filter-chip.tsx +0 -57
- package/src/components/filters/filter-select.stories.tsx +0 -71
- package/src/components/filters/filter-select.tsx +0 -68
- package/src/components/forms/checkbox.stories.tsx +0 -35
- package/src/components/forms/checkbox.tsx +0 -38
- package/src/components/forms/date-month-select.stories.tsx +0 -26
- package/src/components/forms/date-month-select.tsx +0 -79
- package/src/components/forms/date-picker.stories.tsx +0 -188
- package/src/components/forms/date-picker.tsx +0 -303
- package/src/components/forms/date-utils.ts +0 -37
- package/src/components/forms/drop-zone.stories.tsx +0 -140
- package/src/components/forms/drop-zone.tsx +0 -298
- package/src/components/forms/input.stories.tsx +0 -47
- package/src/components/forms/input.tsx +0 -24
- package/src/components/forms/label.stories.tsx +0 -16
- package/src/components/forms/label.tsx +0 -25
- package/src/components/forms/passkey-management.stories.tsx +0 -85
- package/src/components/forms/passkey-management.tsx +0 -168
- package/src/components/forms/radio-group.stories.tsx +0 -46
- package/src/components/forms/radio-group.tsx +0 -44
- package/src/components/forms/select.stories.tsx +0 -207
- package/src/components/forms/select.tsx +0 -182
- package/src/components/forms/slider.stories.tsx +0 -70
- package/src/components/forms/slider.tsx +0 -50
- package/src/components/forms/stepper.stories.tsx +0 -111
- package/src/components/forms/stepper.tsx +0 -66
- package/src/components/forms/switch.stories.tsx +0 -144
- package/src/components/forms/switch.tsx +0 -39
- package/src/components/forms/text-field.stories.tsx +0 -87
- package/src/components/forms/text-field.tsx +0 -75
- package/src/components/forms/text-field.types.ts +0 -9
- package/src/components/forms/textarea.stories.tsx +0 -150
- package/src/components/forms/textarea.tsx +0 -22
- package/src/components/layout/particle-background.stories.tsx +0 -38
- package/src/components/layout/particle-background.tsx +0 -378
- package/src/components/layout/scroll-area.stories.tsx +0 -91
- package/src/components/layout/scroll-area.tsx +0 -79
- package/src/components/layout/section-intro.stories.tsx +0 -29
- package/src/components/layout/section-intro.tsx +0 -31
- package/src/components/layout/surface-panel.stories.tsx +0 -32
- package/src/components/layout/surface-panel.tsx +0 -23
- package/src/components/navigation/app-navigation.stories.tsx +0 -217
- package/src/components/navigation/app-navigation.tsx +0 -234
- package/src/components/navigation/pagination-controls.stories.tsx +0 -41
- package/src/components/navigation/pagination-controls.tsx +0 -46
- package/src/components/navigation/tabs.stories.tsx +0 -48
- package/src/components/navigation/tabs.tsx +0 -52
- package/src/components/overlays/bottom-sheet.stories.tsx +0 -52
- package/src/components/overlays/bottom-sheet.tsx +0 -179
- package/src/components/overlays/command.stories.tsx +0 -65
- package/src/components/overlays/command.tsx +0 -227
- package/src/components/overlays/dialog.stories.tsx +0 -148
- package/src/components/overlays/dialog.tsx +0 -203
- package/src/components/overlays/dropdown-menu.stories.tsx +0 -74
- package/src/components/overlays/dropdown-menu.tsx +0 -236
- package/src/components/overlays/index.ts +0 -56
- package/src/components/overlays/popover.stories.tsx +0 -51
- package/src/components/overlays/popover.tsx +0 -78
- package/src/components/overlays/sheet.stories.tsx +0 -68
- package/src/components/overlays/sheet.tsx +0 -155
- package/src/components/overlays/tooltip.stories.tsx +0 -29
- package/src/components/overlays/tooltip.tsx +0 -41
- package/src/components/primitives/avatar-placeholder.svg +0 -13
- package/src/components/primitives/avatar.stories.tsx +0 -72
- package/src/components/primitives/avatar.tsx +0 -136
- package/src/components/primitives/badge.stories.tsx +0 -43
- package/src/components/primitives/badge.tsx +0 -43
- package/src/components/primitives/button.stories.tsx +0 -113
- package/src/components/primitives/button.tsx +0 -131
- package/src/components/primitives/card.stories.tsx +0 -59
- package/src/components/primitives/card.tsx +0 -66
- package/src/components/primitives/segmented-control.stories.tsx +0 -54
- package/src/components/primitives/segmented-control.tsx +0 -73
- package/src/components/primitives/separator.stories.tsx +0 -34
- package/src/components/primitives/separator.tsx +0 -27
- package/src/constants/chart-colors.ts +0 -39
- package/src/env.d.ts +0 -9
- package/src/hooks/use-api-client.ts +0 -122
- package/src/hooks/use-debounced-value.ts +0 -12
- package/src/hooks/use-derived-filter-state.ts +0 -70
- package/src/hooks/use-filter-state.ts +0 -66
- package/src/hooks/use-media-query.ts +0 -69
- package/src/hooks/use-mobile.tsx +0 -19
- package/src/hooks/use-sort.ts +0 -20
- package/src/lib/auth.ts +0 -5
- package/src/lib/clipboard.ts +0 -8
- package/src/lib/utils.ts +0 -6
- package/src/native/components.tsx +0 -198
- package/src/native/theme.tsx +0 -69
- package/src/storybook/controls.ts +0 -117
- package/src/storybook/options.ts +0 -52
- package/src/styles/build.ts +0 -1
- package/src/styles/index.css +0 -423
- package/src/styles/nokia.css +0 -36
- package/src/styles/package.css +0 -3
- package/src/styles/tokens/chart-colors.stories.tsx +0 -189
- package/src/styles/tokens/color-systems.stories.tsx +0 -190
- package/src/styles/tokens/css-vars.ts +0 -15
- package/src/styles/tokens/generated/dark-class.css +0 -39
- package/src/styles/tokens/generated/dark.colors.generated.ts +0 -39
- package/src/styles/tokens/generated/dark.css +0 -39
- package/src/styles/tokens/generated/foundations.css +0 -149
- package/src/styles/tokens/generated/foundations.generated.ts +0 -454
- package/src/styles/tokens/generated/light.colors.generated.ts +0 -39
- package/src/styles/tokens/generated/light.css +0 -39
- package/src/styles/tokens/index.ts +0 -70
- package/src/styles/tokens/layout.stories.tsx +0 -50
- package/src/styles/tokens/scripts/check-foundations.mjs +0 -126
- package/src/styles/tokens/scripts/check-source.mjs +0 -53
- package/src/styles/tokens/source/dark.tokens.json +0 -138
- package/src/styles/tokens/source/foundations.tokens.json +0 -344
- package/src/styles/tokens/source/light.tokens.json +0 -138
- package/src/styles/tokens/style-dictionary.dark-class.json +0 -16
- package/src/styles/tokens/style-dictionary.dark-storybook.json +0 -16
- package/src/styles/tokens/style-dictionary.dark.json +0 -21
- package/src/styles/tokens/style-dictionary.foundations.json +0 -21
- package/src/styles/tokens/style-dictionary.light-storybook.json +0 -16
- package/src/styles/tokens/style-dictionary.light.json +0 -21
- package/src/styles/tokens/typography.stories.tsx +0 -157
- package/src/translations/en.ts +0 -34
- package/src/translations/index.ts +0 -32
- package/src/types/upload.ts +0 -42
- /package/{src/components/filters/index.ts → dist/components/filters/index.d.ts} +0 -0
- /package/{src/components/layout/index.ts → dist/components/layout/index.d.ts} +0 -0
- /package/{src/hooks/index.ts → dist/hooks/index.d.ts} +0 -0
- /package/{src/lib/index.ts → dist/lib/index.d.ts} +0 -0
- /package/{src/native/index.ts → dist/native/index.d.ts} +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useUiText as e } from "../../translations/ui-provider.js";
|
|
3
|
+
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
4
|
+
import { LucideRefreshCcw as r, LucideX as i } from "lucide-react";
|
|
5
|
+
//#region src/components/feedback/update-guard.tsx
|
|
6
|
+
function a({ needRefresh: a, onRefresh: o, onDismiss: s, copyText: c = "New content available", refreshText: l = "Refresh" }) {
|
|
7
|
+
let u = e("dialog.close", "Close");
|
|
8
|
+
return a ? /* @__PURE__ */ t("output", {
|
|
9
|
+
"aria-live": "polite",
|
|
10
|
+
"aria-atomic": "true",
|
|
11
|
+
className: "fixed inset-x-0 bottom-0 z-50 flex justify-center px-4",
|
|
12
|
+
children: /* @__PURE__ */ n("div", {
|
|
13
|
+
className: "border-border bg-card flex items-center gap-3 rounded-md border px-4 py-2",
|
|
14
|
+
children: [
|
|
15
|
+
/* @__PURE__ */ t("span", {
|
|
16
|
+
className: "text-foreground text-sm",
|
|
17
|
+
children: c
|
|
18
|
+
}),
|
|
19
|
+
/* @__PURE__ */ t("button", {
|
|
20
|
+
type: "button",
|
|
21
|
+
"aria-label": l,
|
|
22
|
+
onClick: o,
|
|
23
|
+
className: "text-accent-text font-semibold border-muted-foreground rounded-md border px-2 py-1 hover:bg-accent hover:text-accent-foreground",
|
|
24
|
+
children: /* @__PURE__ */ t(r, { className: "size-4" })
|
|
25
|
+
}),
|
|
26
|
+
s ? /* @__PURE__ */ t("button", {
|
|
27
|
+
"aria-label": u,
|
|
28
|
+
type: "button",
|
|
29
|
+
onClick: s,
|
|
30
|
+
className: "text-accent-text font-semibold border-muted-foreground rounded-md border px-2 py-1 hover:bg-accent hover:text-accent-foreground",
|
|
31
|
+
children: /* @__PURE__ */ t(i, { className: "size-4" })
|
|
32
|
+
}) : null
|
|
33
|
+
]
|
|
34
|
+
})
|
|
35
|
+
}) : null;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { a as UpdateGuard };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ActiveFilter {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
onRemove: () => void;
|
|
5
|
+
onClick?: () => void;
|
|
6
|
+
variant?: "filter" | "sort";
|
|
7
|
+
direction?: "asc" | "desc";
|
|
8
|
+
}
|
|
9
|
+
export interface ActiveFiltersBarProps {
|
|
10
|
+
filters: ActiveFilter[];
|
|
11
|
+
className?: string;
|
|
12
|
+
onClearAll?: () => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function ActiveFiltersBar({ filters, className, onClearAll }: ActiveFiltersBarProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import { useUiText as t } from "../../translations/ui-provider.js";
|
|
4
|
+
import { FilterChip as n } from "./filter-chip.js";
|
|
5
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
6
|
+
import { X as a } from "lucide-react";
|
|
7
|
+
//#region src/components/filters/active-filters-bar.tsx
|
|
8
|
+
function o({ filters: o, className: s, onClearAll: c }) {
|
|
9
|
+
let l = t("filters.clearAll", "Clear all");
|
|
10
|
+
return o.length === 0 ? null : /* @__PURE__ */ i("div", {
|
|
11
|
+
className: e("flex w-full items-center h-10 gap-2 rounded-lg border border-border pr-0", s),
|
|
12
|
+
children: [
|
|
13
|
+
/* @__PURE__ */ r("span", {
|
|
14
|
+
className: "text-muted-foreground shrink-0 self-stretch flex items-center text-sm border-r px-4",
|
|
15
|
+
children: "Filters"
|
|
16
|
+
}),
|
|
17
|
+
/* @__PURE__ */ r("ul", {
|
|
18
|
+
className: "flex flex-1 min-w-0 items-center gap-2 overflow-x-auto scroll-fade-x pl-4 py-1.5",
|
|
19
|
+
children: o.map((e) => /* @__PURE__ */ r("li", {
|
|
20
|
+
className: "shrink-0",
|
|
21
|
+
children: /* @__PURE__ */ r(n, {
|
|
22
|
+
label: e.label,
|
|
23
|
+
onRemove: e.onRemove,
|
|
24
|
+
onClick: e.onClick,
|
|
25
|
+
variant: e.variant === "sort" ? "sort" : "default",
|
|
26
|
+
direction: e.direction
|
|
27
|
+
})
|
|
28
|
+
}, e.id))
|
|
29
|
+
}),
|
|
30
|
+
c ? /* @__PURE__ */ r("button", {
|
|
31
|
+
type: "button",
|
|
32
|
+
onClick: c,
|
|
33
|
+
className: "hover:bg-muted text-muted-foreground hover:text-foreground focus-visible:ring-ring inline-flex shrink-0 items-center justify-center self-stretch aspect-square rounded-r-lg border-l border-border transition-colors focus-visible:ring-2 focus-visible:outline-none",
|
|
34
|
+
"aria-label": l,
|
|
35
|
+
children: /* @__PURE__ */ r(a, {
|
|
36
|
+
className: "size-4",
|
|
37
|
+
"aria-hidden": !0
|
|
38
|
+
})
|
|
39
|
+
}) : null
|
|
40
|
+
]
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { o as ActiveFiltersBar };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export interface FilterChipProps {
|
|
3
|
+
label: ReactNode;
|
|
4
|
+
onRemove: () => void;
|
|
5
|
+
onClick?: () => void;
|
|
6
|
+
className?: string;
|
|
7
|
+
variant?: "default" | "sort";
|
|
8
|
+
direction?: "asc" | "desc";
|
|
9
|
+
role?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function FilterChip({ label, onRemove, onClick, className, variant, direction, role, }: FilterChipProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import { useUiText as t } from "../../translations/ui-provider.js";
|
|
4
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
5
|
+
import { ArrowDown as i, ArrowUp as a, X as o } from "lucide-react";
|
|
6
|
+
//#region src/components/filters/filter-chip.tsx
|
|
7
|
+
function s({ label: s, onRemove: c, onClick: l, className: u, variant: d = "default", direction: f, role: p }) {
|
|
8
|
+
let m = t("filterChip.remove", "Remove filter"), h = d === "sort", g = f === "asc" ? a : f === "desc" ? i : null;
|
|
9
|
+
return /* @__PURE__ */ r("span", {
|
|
10
|
+
role: p,
|
|
11
|
+
"aria-label": typeof s == "string" ? `${s} filter` : "filter",
|
|
12
|
+
className: e("border-border bg-secondary text-secondary-foreground inline-flex items-center rounded-full border text-xs font-medium", h && "border-dashed", u),
|
|
13
|
+
children: [/* @__PURE__ */ r("button", {
|
|
14
|
+
type: "button",
|
|
15
|
+
disabled: !l,
|
|
16
|
+
className: "focus-visible:ring-ring inline-flex items-center rounded-full px-3 transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-default",
|
|
17
|
+
onClick: l,
|
|
18
|
+
children: [h && g ? /* @__PURE__ */ n(g, { className: "mr-1 size-4" }) : null, s]
|
|
19
|
+
}), /* @__PURE__ */ n("button", {
|
|
20
|
+
type: "button",
|
|
21
|
+
"data-slot": "filter-chip-remove",
|
|
22
|
+
className: "text-muted-foreground hover:text-foreground focus-visible:ring-ring mr-0.5 flex size-6 items-center justify-center rounded-full transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none",
|
|
23
|
+
onClick: c,
|
|
24
|
+
"aria-label": `${m}: ${typeof s == "string" ? s : "selected filter"}`,
|
|
25
|
+
children: /* @__PURE__ */ n(o, {
|
|
26
|
+
className: "size-4",
|
|
27
|
+
"aria-hidden": !0
|
|
28
|
+
})
|
|
29
|
+
})]
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { s as FilterChip };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface FilterSelectOption {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
}
|
|
5
|
+
export interface FilterSelectProps {
|
|
6
|
+
value: string | null;
|
|
7
|
+
onChange: (value: string | null) => void;
|
|
8
|
+
options: FilterSelectOption[];
|
|
9
|
+
label: string;
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
isLoading?: boolean;
|
|
13
|
+
emptyLabel?: string;
|
|
14
|
+
className?: string;
|
|
15
|
+
id?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function FilterSelect({ label, value, options, onChange, placeholder, disabled, isLoading, emptyLabel, className, id, }: FilterSelectProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import { useUiText as t } from "../../translations/ui-provider.js";
|
|
4
|
+
import { Spinner as n } from "../feedback/spinner.js";
|
|
5
|
+
import { Select as r, SelectContent as i, SelectItem as a, SelectTrigger as o, SelectValue as s } from "../forms/select.js";
|
|
6
|
+
import { useId as c, useMemo as l } from "react";
|
|
7
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
8
|
+
//#region src/components/filters/filter-select.tsx
|
|
9
|
+
function f({ label: f, value: p, options: m, onChange: h, placeholder: g = "All", disabled: _ = !1, isLoading: v = !1, emptyLabel: y, className: b, id: x }) {
|
|
10
|
+
let S = t("filterSelect.empty", "No options available"), C = y ?? S, w = c(), T = x ?? w, E = l(() => [{
|
|
11
|
+
value: null,
|
|
12
|
+
label: g
|
|
13
|
+
}, ...m], [m, g]);
|
|
14
|
+
return /* @__PURE__ */ d("div", {
|
|
15
|
+
className: e("space-y-2 min-w-36", b),
|
|
16
|
+
children: [/* @__PURE__ */ u("label", {
|
|
17
|
+
htmlFor: T,
|
|
18
|
+
children: f
|
|
19
|
+
}), /* @__PURE__ */ d(r, {
|
|
20
|
+
value: p,
|
|
21
|
+
onValueChange: h,
|
|
22
|
+
items: E,
|
|
23
|
+
children: [/* @__PURE__ */ u(o, {
|
|
24
|
+
id: T,
|
|
25
|
+
disabled: _,
|
|
26
|
+
"aria-label": f,
|
|
27
|
+
className: "w-full",
|
|
28
|
+
children: /* @__PURE__ */ u(s, { placeholder: g })
|
|
29
|
+
}), /* @__PURE__ */ d(i, {
|
|
30
|
+
className: "bg-background max-h-[250px] min-w-36 overflow-y-auto",
|
|
31
|
+
children: [/* @__PURE__ */ u(a, { children: g }), v ? /* @__PURE__ */ u(n, {
|
|
32
|
+
presentation: "centered",
|
|
33
|
+
size: "sm"
|
|
34
|
+
}) : m.length === 0 ? /* @__PURE__ */ u("div", {
|
|
35
|
+
className: "text-muted-foreground px-2 py-1.5 text-sm",
|
|
36
|
+
children: C
|
|
37
|
+
}) : m.map((e) => /* @__PURE__ */ u(a, {
|
|
38
|
+
value: e.value,
|
|
39
|
+
children: e.label
|
|
40
|
+
}, e.value))]
|
|
41
|
+
})]
|
|
42
|
+
})]
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { f as FilterSelect };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import "react";
|
|
4
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
5
|
+
import { CheckIcon as n, MinusIcon as r } from "lucide-react";
|
|
6
|
+
import { Checkbox as i } from "@base-ui/react/checkbox";
|
|
7
|
+
//#region src/components/forms/checkbox.tsx
|
|
8
|
+
function a({ className: a, ...o }) {
|
|
9
|
+
return /* @__PURE__ */ t(i.Root, {
|
|
10
|
+
"data-slot": "checkbox",
|
|
11
|
+
className: e("border-input bg-background aria-checked:bg-primary aria-checked:text-primary-foreground aria-checked:border-primary focus-visible:outline-ring size-4 shrink-0 rounded-[4px] border transition-colors focus-visible:outline-2 focus-visible:outline-offset-2", "aria-[checked=mixed]:bg-primary aria-[checked=mixed]:text-primary-foreground aria-[checked=mixed]:border-primary", "data-disabled:pointer-events-none data-disabled:opacity-50", a),
|
|
12
|
+
...o,
|
|
13
|
+
children: /* @__PURE__ */ t(i.Indicator, {
|
|
14
|
+
"data-slot": "checkbox-indicator",
|
|
15
|
+
className: "flex items-center justify-center text-current transition-none",
|
|
16
|
+
render: (e, i) => /* @__PURE__ */ t("span", {
|
|
17
|
+
...e,
|
|
18
|
+
children: i.indeterminate ? /* @__PURE__ */ t(r, { className: "size-3" }) : /* @__PURE__ */ t(n, { className: "size-3" })
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { a as Checkbox };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface DateMonthSelectProps {
|
|
2
|
+
selectedMonthYear: string;
|
|
3
|
+
onMonthChange: (value: string) => void;
|
|
4
|
+
monthsBack?: number;
|
|
5
|
+
className?: string;
|
|
6
|
+
placeholder?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Select a `YYYY-MM` month from the last `monthsBack` months. */
|
|
9
|
+
export declare function DateMonthSelect({ selectedMonthYear, onMonthChange, monthsBack, className, placeholder, }: DateMonthSelectProps): import("react").JSX.Element;
|
|
10
|
+
/** Current month in `YYYY-MM` format. */
|
|
11
|
+
export declare const getCurrentMonthYear: () => string;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import { Select as t, SelectContent as n, SelectItem as r, SelectTrigger as i, SelectValue as a } from "./select.js";
|
|
4
|
+
import { useMemo as o } from "react";
|
|
5
|
+
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
6
|
+
import { Calendar as l } from "lucide-react";
|
|
7
|
+
//#region src/components/forms/date-month-select.tsx
|
|
8
|
+
function u({ selectedMonthYear: u, onMonthChange: d, monthsBack: f = 12, className: p = "w-[200px]", placeholder: m = "Select month" }) {
|
|
9
|
+
let h = o(() => {
|
|
10
|
+
let e = [], t = /* @__PURE__ */ new Date();
|
|
11
|
+
for (let n = 0; n < f; n++) {
|
|
12
|
+
let r = new Date(t.getFullYear(), t.getMonth() - n, 1), i = r.getFullYear(), a = (r.getMonth() + 1).toString().padStart(2, "0");
|
|
13
|
+
e.push({
|
|
14
|
+
value: `${i}-${a}`,
|
|
15
|
+
label: r.toLocaleString("default", {
|
|
16
|
+
month: "long",
|
|
17
|
+
year: "numeric"
|
|
18
|
+
})
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return e;
|
|
22
|
+
}, [f]);
|
|
23
|
+
return /* @__PURE__ */ c("div", {
|
|
24
|
+
className: "flex items-center",
|
|
25
|
+
children: [/* @__PURE__ */ s("div", {
|
|
26
|
+
className: "border-border bg-background text-foreground flex size-10 items-center justify-center rounded-l-xl border",
|
|
27
|
+
children: /* @__PURE__ */ s(l, { className: "size-4" })
|
|
28
|
+
}), /* @__PURE__ */ c(t, {
|
|
29
|
+
value: u,
|
|
30
|
+
onValueChange: (e) => e != null && d(e),
|
|
31
|
+
children: [/* @__PURE__ */ s(i, {
|
|
32
|
+
className: e("border-border bg-background text-foreground min-h-10 max-h-10 rounded-l-none rounded-r-xl border-l-0", p),
|
|
33
|
+
"aria-label": m,
|
|
34
|
+
children: /* @__PURE__ */ s(a, { placeholder: m })
|
|
35
|
+
}), /* @__PURE__ */ s(n, { children: h.map((e) => /* @__PURE__ */ s(r, {
|
|
36
|
+
value: e.value,
|
|
37
|
+
children: e.label
|
|
38
|
+
}, e.value)) })]
|
|
39
|
+
})]
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
var d = () => {
|
|
43
|
+
let e = /* @__PURE__ */ new Date();
|
|
44
|
+
return `${e.getFullYear()}-${(e.getMonth() + 1).toString().padStart(2, "0")}`;
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
47
|
+
export { u as DateMonthSelect, d as getCurrentMonthYear };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface DateRangeValue {
|
|
2
|
+
from?: Date | string | null;
|
|
3
|
+
to?: Date | string | null;
|
|
4
|
+
}
|
|
5
|
+
interface DatePickerBaseProps {
|
|
6
|
+
label?: string;
|
|
7
|
+
helpText?: string;
|
|
8
|
+
error?: string;
|
|
9
|
+
id?: string;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
required?: boolean;
|
|
12
|
+
className?: string;
|
|
13
|
+
/** Earliest selectable date, "YYYY-MM-DD". */
|
|
14
|
+
min?: string;
|
|
15
|
+
/** Latest selectable date, "YYYY-MM-DD". */
|
|
16
|
+
max?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface SingleDatePickerProps extends DatePickerBaseProps {
|
|
19
|
+
mode?: "single";
|
|
20
|
+
/** Form field name — the native input submits "YYYY-MM-DD". */
|
|
21
|
+
name?: string;
|
|
22
|
+
value?: Date | string | null;
|
|
23
|
+
defaultValue?: Date | string | null;
|
|
24
|
+
onValueChange?: (value: string | null) => void;
|
|
25
|
+
}
|
|
26
|
+
export interface RangeDatePickerProps extends DatePickerBaseProps {
|
|
27
|
+
mode: "range";
|
|
28
|
+
/** Form field name for the range start — submits "YYYY-MM-DD". */
|
|
29
|
+
startName?: string;
|
|
30
|
+
/** Form field name for the range end — submits "YYYY-MM-DD". */
|
|
31
|
+
endName?: string;
|
|
32
|
+
value?: DateRangeValue;
|
|
33
|
+
defaultValue?: DateRangeValue;
|
|
34
|
+
onValueChange?: (value: {
|
|
35
|
+
from: string | null;
|
|
36
|
+
to: string | null;
|
|
37
|
+
}) => void;
|
|
38
|
+
fromLabel?: string;
|
|
39
|
+
toLabel?: string;
|
|
40
|
+
}
|
|
41
|
+
export type DatePickerProps = SingleDatePickerProps | RangeDatePickerProps;
|
|
42
|
+
/**
|
|
43
|
+
* DatePicker — native date inputs styled to the design system. The browser
|
|
44
|
+
* owns the picker UI (calendar on desktop, wheel on iOS, etc.) so there is no
|
|
45
|
+
* popover, calendar grid, or positioning layer in the bundle. Both a single
|
|
46
|
+
* date (`name`) and a range (`startName` + `endName`) are supported; the
|
|
47
|
+
* native inputs submit "YYYY-MM-DD" local date strings directly.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* <DatePicker name="startDate" defaultValue="2020-01-15" label="Start date" />
|
|
51
|
+
* <DatePicker
|
|
52
|
+
* mode="range"
|
|
53
|
+
* startName="startDate"
|
|
54
|
+
* endName="endDate"
|
|
55
|
+
* defaultValue={{ from: "2020-01-15", to: "2020-06-30" }}
|
|
56
|
+
* label="Active period"
|
|
57
|
+
* />
|
|
58
|
+
*/
|
|
59
|
+
declare function DatePicker(props: DatePickerProps): import("react").JSX.Element;
|
|
60
|
+
export { DatePicker };
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import { useUiText as t } from "../../translations/ui-provider.js";
|
|
4
|
+
import { formatDateInput as n } from "./date-utils.js";
|
|
5
|
+
import { useId as r, useRef as i, useState as a } from "react";
|
|
6
|
+
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
7
|
+
import { CalendarIcon as c } from "lucide-react";
|
|
8
|
+
//#region src/components/forms/date-picker.tsx
|
|
9
|
+
var l = "text-foreground text-sm font-medium", u = "after:text-destructive-text after:ml-0.5 after:content-['*']", d = "text-muted-foreground text-xs font-medium", f = "bg-background text-foreground border-input h-10 w-full min-w-0 appearance-none border px-3 py-1 text-sm transition-colors [&::-webkit-calendar-picker-indicator]:appearance-none [&::-webkit-calendar-picker-indicator]:opacity-0 placeholder:text-muted-foreground focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-destructive/20 aria-invalid:border-destructive";
|
|
10
|
+
function p({ inputRef: e, disabled: t, ariaLabel: n }) {
|
|
11
|
+
return /* @__PURE__ */ o("button", {
|
|
12
|
+
type: "button",
|
|
13
|
+
"data-slot": "date-picker-icon",
|
|
14
|
+
"aria-label": n,
|
|
15
|
+
disabled: t,
|
|
16
|
+
onClick: () => {
|
|
17
|
+
let t = e.current;
|
|
18
|
+
if (t) try {
|
|
19
|
+
t.showPicker?.();
|
|
20
|
+
} catch {
|
|
21
|
+
t.focus();
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
className: "border-input bg-background text-foreground focus-visible:outline-ring flex size-10 shrink-0 items-center justify-center rounded-l-xl border focus-visible:outline-2 focus-visible:outline-offset-2",
|
|
25
|
+
children: /* @__PURE__ */ o(c, {
|
|
26
|
+
className: "size-4",
|
|
27
|
+
"aria-hidden": !0
|
|
28
|
+
})
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function m({ id: c, name: d, label: m, helpText: h, error: g, className: _, disabled: v, required: y, min: b, max: x, value: S, defaultValue: C, onValueChange: w }) {
|
|
32
|
+
let T = t("datePicker.open", "Open date picker"), E = r(), D = c ?? E, O = `${D}-description`, k = `${D}-error`, A = i(null), j = S !== void 0, [M, N] = a(() => n(j ? S : C)), P = (j ? n(S) : M) || "";
|
|
33
|
+
function F(e) {
|
|
34
|
+
let t = e.target.value || null;
|
|
35
|
+
j || N(t ?? ""), w?.(t);
|
|
36
|
+
}
|
|
37
|
+
return /* @__PURE__ */ s("div", {
|
|
38
|
+
className: e("flex flex-col gap-1.5", _),
|
|
39
|
+
children: [
|
|
40
|
+
m ? /* @__PURE__ */ o("label", {
|
|
41
|
+
htmlFor: D,
|
|
42
|
+
className: e(l, y && u),
|
|
43
|
+
children: m
|
|
44
|
+
}) : null,
|
|
45
|
+
/* @__PURE__ */ s("div", {
|
|
46
|
+
className: "flex w-full items-center",
|
|
47
|
+
children: [/* @__PURE__ */ o(p, {
|
|
48
|
+
inputRef: A,
|
|
49
|
+
disabled: v,
|
|
50
|
+
ariaLabel: T
|
|
51
|
+
}), /* @__PURE__ */ o("input", {
|
|
52
|
+
ref: A,
|
|
53
|
+
id: D,
|
|
54
|
+
name: d,
|
|
55
|
+
type: "date",
|
|
56
|
+
value: j ? P : void 0,
|
|
57
|
+
defaultValue: j ? void 0 : P,
|
|
58
|
+
onChange: F,
|
|
59
|
+
disabled: v,
|
|
60
|
+
required: y,
|
|
61
|
+
min: b,
|
|
62
|
+
max: x,
|
|
63
|
+
"aria-invalid": g ? !0 : void 0,
|
|
64
|
+
"aria-describedby": g ? k : h ? O : void 0,
|
|
65
|
+
className: e(f, "rounded-l-none rounded-r-xl border-l-0")
|
|
66
|
+
})]
|
|
67
|
+
}),
|
|
68
|
+
g ? /* @__PURE__ */ o("p", {
|
|
69
|
+
id: k,
|
|
70
|
+
role: "alert",
|
|
71
|
+
className: "text-destructive-text text-sm",
|
|
72
|
+
children: g
|
|
73
|
+
}) : h ? /* @__PURE__ */ o("p", {
|
|
74
|
+
id: O,
|
|
75
|
+
className: "text-muted-foreground text-sm",
|
|
76
|
+
children: h
|
|
77
|
+
}) : null
|
|
78
|
+
]
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function h({ id: t, label: c, helpText: m, error: h, className: g, disabled: _, required: v, min: y, max: b, startName: x, endName: S, value: C, defaultValue: w, onValueChange: T, fromLabel: E = "From", toLabel: D = "To" }) {
|
|
82
|
+
let O = r(), k = t ?? O, A = `${k}-to`, j = `${k}-description`, M = `${k}-error`, N = i(null), P = i(null), F = C !== void 0, [I, L] = a(() => {
|
|
83
|
+
let e = F ? C : w;
|
|
84
|
+
return {
|
|
85
|
+
from: n(e?.from),
|
|
86
|
+
to: n(e?.to)
|
|
87
|
+
};
|
|
88
|
+
}), R = (F ? n(C?.from) : I.from) || "", z = (F ? n(C?.to) : I.to) || "";
|
|
89
|
+
function B(e) {
|
|
90
|
+
return (t) => {
|
|
91
|
+
let n = t.target.value || null, r = e === "from" ? {
|
|
92
|
+
from: n,
|
|
93
|
+
to: z
|
|
94
|
+
} : {
|
|
95
|
+
from: R,
|
|
96
|
+
to: n
|
|
97
|
+
};
|
|
98
|
+
F || L({
|
|
99
|
+
from: r.from ?? "",
|
|
100
|
+
to: r.to ?? ""
|
|
101
|
+
}), T?.({
|
|
102
|
+
from: r.from,
|
|
103
|
+
to: r.to
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return /* @__PURE__ */ s("div", {
|
|
108
|
+
className: e("flex flex-col gap-1.5", g),
|
|
109
|
+
children: [
|
|
110
|
+
c ? /* @__PURE__ */ o("span", {
|
|
111
|
+
className: e(l, v && u),
|
|
112
|
+
children: c
|
|
113
|
+
}) : null,
|
|
114
|
+
/* @__PURE__ */ s("div", {
|
|
115
|
+
className: "grid gap-3 sm:grid-cols-2",
|
|
116
|
+
children: [/* @__PURE__ */ s("div", {
|
|
117
|
+
className: "flex min-w-0 flex-col gap-1",
|
|
118
|
+
children: [/* @__PURE__ */ o("label", {
|
|
119
|
+
htmlFor: k,
|
|
120
|
+
className: d,
|
|
121
|
+
children: E
|
|
122
|
+
}), /* @__PURE__ */ s("div", {
|
|
123
|
+
className: "flex w-full items-center",
|
|
124
|
+
children: [/* @__PURE__ */ o(p, {
|
|
125
|
+
inputRef: N,
|
|
126
|
+
disabled: _,
|
|
127
|
+
ariaLabel: E
|
|
128
|
+
}), /* @__PURE__ */ o("input", {
|
|
129
|
+
ref: N,
|
|
130
|
+
id: k,
|
|
131
|
+
name: x,
|
|
132
|
+
type: "date",
|
|
133
|
+
value: F ? R : void 0,
|
|
134
|
+
defaultValue: F ? void 0 : R,
|
|
135
|
+
onChange: B("from"),
|
|
136
|
+
disabled: _,
|
|
137
|
+
required: v,
|
|
138
|
+
min: y,
|
|
139
|
+
max: z || b || void 0,
|
|
140
|
+
"aria-invalid": h ? !0 : void 0,
|
|
141
|
+
"aria-describedby": h ? M : m ? j : void 0,
|
|
142
|
+
className: e(f, "rounded-l-none rounded-r-xl border-l-0")
|
|
143
|
+
})]
|
|
144
|
+
})]
|
|
145
|
+
}), /* @__PURE__ */ s("div", {
|
|
146
|
+
className: "flex min-w-0 flex-col gap-1",
|
|
147
|
+
children: [/* @__PURE__ */ o("label", {
|
|
148
|
+
htmlFor: A,
|
|
149
|
+
className: d,
|
|
150
|
+
children: D
|
|
151
|
+
}), /* @__PURE__ */ s("div", {
|
|
152
|
+
className: "flex w-full items-center",
|
|
153
|
+
children: [/* @__PURE__ */ o(p, {
|
|
154
|
+
inputRef: P,
|
|
155
|
+
disabled: _,
|
|
156
|
+
ariaLabel: D
|
|
157
|
+
}), /* @__PURE__ */ o("input", {
|
|
158
|
+
ref: P,
|
|
159
|
+
id: A,
|
|
160
|
+
name: S,
|
|
161
|
+
type: "date",
|
|
162
|
+
value: F ? z : void 0,
|
|
163
|
+
defaultValue: F ? void 0 : z,
|
|
164
|
+
onChange: B("to"),
|
|
165
|
+
disabled: _,
|
|
166
|
+
required: v,
|
|
167
|
+
min: R || y || void 0,
|
|
168
|
+
max: b,
|
|
169
|
+
"aria-invalid": h ? !0 : void 0,
|
|
170
|
+
"aria-describedby": h ? M : m ? j : void 0,
|
|
171
|
+
className: e(f, "rounded-l-none rounded-r-xl border-l-0")
|
|
172
|
+
})]
|
|
173
|
+
})]
|
|
174
|
+
})]
|
|
175
|
+
}),
|
|
176
|
+
h ? /* @__PURE__ */ o("p", {
|
|
177
|
+
id: M,
|
|
178
|
+
role: "alert",
|
|
179
|
+
className: "text-destructive-text text-sm",
|
|
180
|
+
children: h
|
|
181
|
+
}) : m ? /* @__PURE__ */ o("p", {
|
|
182
|
+
id: j,
|
|
183
|
+
className: "text-muted-foreground text-sm",
|
|
184
|
+
children: m
|
|
185
|
+
}) : null
|
|
186
|
+
]
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
function g(e) {
|
|
190
|
+
return e.mode === "range" ? /* @__PURE__ */ o(h, { ...e }) : /* @__PURE__ */ o(m, { ...e });
|
|
191
|
+
}
|
|
192
|
+
//#endregion
|
|
193
|
+
export { g as DatePicker };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a date-only string ("YYYY-MM-DD") as a local calendar day instead of
|
|
3
|
+
* UTC midnight, so negative-UTC-offset timezones don't render the previous day.
|
|
4
|
+
* Accepts a `Date` (returned as-is when valid) and returns `undefined` for
|
|
5
|
+
* null/undefined/invalid input.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseDateInput(value: Date | string | null | undefined): Date | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Serialize a date to its "YYYY-MM-DD" form using local components, so the
|
|
10
|
+
* value round-trips without a UTC shift. Returns "" for invalid input.
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatDateInput(value: Date | string | null | undefined): string;
|
|
13
|
+
/** Today's date as a "YYYY-MM-DD" local string. */
|
|
14
|
+
export declare function todayDateInput(): string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/components/forms/date-utils.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
if (!e) return;
|
|
4
|
+
if (e instanceof Date) return Number.isNaN(e.getTime()) ? void 0 : e;
|
|
5
|
+
let [t, n, r] = e.split("-").map(Number);
|
|
6
|
+
if (!t || !n || !r) return;
|
|
7
|
+
let i = /* @__PURE__ */ new Date(0);
|
|
8
|
+
return i.setFullYear(t, n - 1, r), Number.isNaN(i.getTime()) ? void 0 : i;
|
|
9
|
+
}
|
|
10
|
+
function t(t) {
|
|
11
|
+
let n = e(t);
|
|
12
|
+
return n ? `${String(n.getFullYear()).padStart(4, "0")}-${String(n.getMonth() + 1).padStart(2, "0")}-${String(n.getDate()).padStart(2, "0")}` : "";
|
|
13
|
+
}
|
|
14
|
+
function n() {
|
|
15
|
+
return t(/* @__PURE__ */ new Date());
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { t as formatDateInput, e as parseDateInput, n as todayDateInput };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export type DropZoneStatus = "empty" | "armed" | "busy" | "failed";
|
|
3
|
+
export type DropZoneFileInfo = {
|
|
4
|
+
name: string;
|
|
5
|
+
size: number;
|
|
6
|
+
};
|
|
7
|
+
export type DropZoneProps = {
|
|
8
|
+
status: DropZoneStatus;
|
|
9
|
+
/** Selected file metadata for armed / busy / failed (with file retained). */
|
|
10
|
+
file?: DropZoneFileInfo | null;
|
|
11
|
+
error?: string | null;
|
|
12
|
+
notice?: string | null;
|
|
13
|
+
/** File input accept attribute, e.g. `.pdf,application/pdf`. */
|
|
14
|
+
accept?: string;
|
|
15
|
+
multiple?: boolean;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
className?: string;
|
|
18
|
+
/** Empty idle copy */
|
|
19
|
+
emptyLabel?: ReactNode;
|
|
20
|
+
emptyHint?: ReactNode;
|
|
21
|
+
draggingLabel?: ReactNode;
|
|
22
|
+
/** Busy copy */
|
|
23
|
+
busyLabel?: ReactNode;
|
|
24
|
+
busyDescription?: ReactNode;
|
|
25
|
+
/** Action labels — parent owns domain language */
|
|
26
|
+
submitLabel?: string;
|
|
27
|
+
retryLabel?: string;
|
|
28
|
+
clearLabel?: string;
|
|
29
|
+
cancelLabel?: string;
|
|
30
|
+
/** Extra content under error (e.g. sign-in link). */
|
|
31
|
+
failedActions?: ReactNode;
|
|
32
|
+
onFiles: (files: File[]) => void;
|
|
33
|
+
onSubmit?: () => void;
|
|
34
|
+
onClear?: () => void;
|
|
35
|
+
onCancel?: () => void;
|
|
36
|
+
onRetry?: () => void;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Generic file drop surface. Parent owns validation, network, and domain copy.
|
|
40
|
+
* Modes: empty | armed | busy | failed, plus an internal drag overlay.
|
|
41
|
+
*/
|
|
42
|
+
export declare function DropZone({ status, file, error, notice, accept, multiple, disabled, className, emptyLabel, emptyHint, draggingLabel, busyLabel, busyDescription, submitLabel, retryLabel, clearLabel, cancelLabel, failedActions, onFiles, onSubmit, onClear, onCancel, onRetry, }: DropZoneProps): import("react").JSX.Element;
|