@modern-admin/ui 0.1.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/dist/components/accordion.d.ts +7 -0
- package/dist/components/accordion.d.ts.map +1 -0
- package/dist/components/accordion.jsx +19 -0
- package/dist/components/accordion.jsx.map +1 -0
- package/dist/components/alert-dialog.d.ts +22 -0
- package/dist/components/alert-dialog.d.ts.map +1 -0
- package/dist/components/alert-dialog.jsx +27 -0
- package/dist/components/alert-dialog.jsx.map +1 -0
- package/dist/components/audit-timeline.d.ts +24 -0
- package/dist/components/audit-timeline.d.ts.map +1 -0
- package/dist/components/audit-timeline.jsx +60 -0
- package/dist/components/audit-timeline.jsx.map +1 -0
- package/dist/components/avatar.d.ts +6 -0
- package/dist/components/avatar.d.ts.map +1 -0
- package/dist/components/avatar.jsx +10 -0
- package/dist/components/avatar.jsx.map +1 -0
- package/dist/components/badge.d.ts +10 -0
- package/dist/components/badge.d.ts.map +1 -0
- package/dist/components/badge.jsx +19 -0
- package/dist/components/badge.jsx.map +1 -0
- package/dist/components/breadcrumb.d.ts +17 -0
- package/dist/components/breadcrumb.d.ts.map +1 -0
- package/dist/components/breadcrumb.jsx +27 -0
- package/dist/components/breadcrumb.jsx.map +1 -0
- package/dist/components/button.d.ts +12 -0
- package/dist/components/button.d.ts.map +1 -0
- package/dist/components/button.jsx +37 -0
- package/dist/components/button.jsx.map +1 -0
- package/dist/components/calendar.d.ts +9 -0
- package/dist/components/calendar.d.ts.map +1 -0
- package/dist/components/calendar.jsx +102 -0
- package/dist/components/calendar.jsx.map +1 -0
- package/dist/components/card.d.ts +8 -0
- package/dist/components/card.d.ts.map +1 -0
- package/dist/components/card.jsx +18 -0
- package/dist/components/card.jsx.map +1 -0
- package/dist/components/chart.d.ts +97 -0
- package/dist/components/chart.d.ts.map +1 -0
- package/dist/components/chart.jsx +233 -0
- package/dist/components/chart.jsx.map +1 -0
- package/dist/components/checkbox.d.ts +4 -0
- package/dist/components/checkbox.d.ts.map +1 -0
- package/dist/components/checkbox.jsx +11 -0
- package/dist/components/checkbox.jsx.map +1 -0
- package/dist/components/combobox.d.ts +46 -0
- package/dist/components/combobox.d.ts.map +1 -0
- package/dist/components/combobox.jsx +145 -0
- package/dist/components/combobox.jsx.map +1 -0
- package/dist/components/command.d.ts +80 -0
- package/dist/components/command.d.ts.map +1 -0
- package/dist/components/command.jsx +32 -0
- package/dist/components/command.jsx.map +1 -0
- package/dist/components/date-picker.d.ts +24 -0
- package/dist/components/date-picker.d.ts.map +1 -0
- package/dist/components/date-picker.jsx +149 -0
- package/dist/components/date-picker.jsx.map +1 -0
- package/dist/components/date-range-input.d.ts +22 -0
- package/dist/components/date-range-input.d.ts.map +1 -0
- package/dist/components/date-range-input.jsx +202 -0
- package/dist/components/date-range-input.jsx.map +1 -0
- package/dist/components/dialog.d.ts +19 -0
- package/dist/components/dialog.d.ts.map +1 -0
- package/dist/components/dialog.jsx +30 -0
- package/dist/components/dialog.jsx.map +1 -0
- package/dist/components/diff-view.d.ts +24 -0
- package/dist/components/diff-view.d.ts.map +1 -0
- package/dist/components/diff-view.jsx +69 -0
- package/dist/components/diff-view.jsx.map +1 -0
- package/dist/components/dropdown-menu.d.ts +27 -0
- package/dist/components/dropdown-menu.d.ts.map +1 -0
- package/dist/components/dropdown-menu.jsx +48 -0
- package/dist/components/dropdown-menu.jsx.map +1 -0
- package/dist/components/empty.d.ts +15 -0
- package/dist/components/empty.d.ts.map +1 -0
- package/dist/components/empty.jsx +27 -0
- package/dist/components/empty.jsx.map +1 -0
- package/dist/components/field.d.ts +23 -0
- package/dist/components/field.d.ts.map +1 -0
- package/dist/components/field.jsx +60 -0
- package/dist/components/field.jsx.map +1 -0
- package/dist/components/file-input.d.ts +50 -0
- package/dist/components/file-input.d.ts.map +1 -0
- package/dist/components/file-input.jsx +104 -0
- package/dist/components/file-input.jsx.map +1 -0
- package/dist/components/form.d.ts +20 -0
- package/dist/components/form.d.ts.map +1 -0
- package/dist/components/form.jsx +66 -0
- package/dist/components/form.jsx.map +1 -0
- package/dist/components/info-tooltip.d.ts +11 -0
- package/dist/components/info-tooltip.d.ts.map +1 -0
- package/dist/components/info-tooltip.jsx +17 -0
- package/dist/components/info-tooltip.jsx.map +1 -0
- package/dist/components/input.d.ts +13 -0
- package/dist/components/input.d.ts.map +1 -0
- package/dist/components/input.jsx +19 -0
- package/dist/components/input.jsx.map +1 -0
- package/dist/components/json-editor.d.ts +23 -0
- package/dist/components/json-editor.d.ts.map +1 -0
- package/dist/components/json-editor.jsx +143 -0
- package/dist/components/json-editor.jsx.map +1 -0
- package/dist/components/kbd.d.ts +15 -0
- package/dist/components/kbd.d.ts.map +1 -0
- package/dist/components/kbd.jsx +23 -0
- package/dist/components/kbd.jsx.map +1 -0
- package/dist/components/key-value-editor.d.ts +92 -0
- package/dist/components/key-value-editor.d.ts.map +1 -0
- package/dist/components/key-value-editor.jsx +187 -0
- package/dist/components/key-value-editor.jsx.map +1 -0
- package/dist/components/keyboard-shortcuts-help.d.ts +17 -0
- package/dist/components/keyboard-shortcuts-help.d.ts.map +1 -0
- package/dist/components/keyboard-shortcuts-help.jsx +97 -0
- package/dist/components/keyboard-shortcuts-help.jsx.map +1 -0
- package/dist/components/label.d.ts +5 -0
- package/dist/components/label.d.ts.map +1 -0
- package/dist/components/label.jsx +8 -0
- package/dist/components/label.jsx.map +1 -0
- package/dist/components/media-preview.d.ts +30 -0
- package/dist/components/media-preview.d.ts.map +1 -0
- package/dist/components/media-preview.jsx +189 -0
- package/dist/components/media-preview.jsx.map +1 -0
- package/dist/components/multi-file-input.d.ts +76 -0
- package/dist/components/multi-file-input.d.ts.map +1 -0
- package/dist/components/multi-file-input.jsx +131 -0
- package/dist/components/multi-file-input.jsx.map +1 -0
- package/dist/components/password-input.d.ts +10 -0
- package/dist/components/password-input.d.ts.map +1 -0
- package/dist/components/password-input.jsx +18 -0
- package/dist/components/password-input.jsx.map +1 -0
- package/dist/components/popover.d.ts +7 -0
- package/dist/components/popover.d.ts.map +1 -0
- package/dist/components/popover.jsx +11 -0
- package/dist/components/popover.jsx.map +1 -0
- package/dist/components/revision-timeline.d.ts +30 -0
- package/dist/components/revision-timeline.d.ts.map +1 -0
- package/dist/components/revision-timeline.jsx +42 -0
- package/dist/components/revision-timeline.jsx.map +1 -0
- package/dist/components/richtext-editor.d.ts +43 -0
- package/dist/components/richtext-editor.d.ts.map +1 -0
- package/dist/components/richtext-editor.jsx +319 -0
- package/dist/components/richtext-editor.jsx.map +1 -0
- package/dist/components/richtext-mode.d.ts +23 -0
- package/dist/components/richtext-mode.d.ts.map +1 -0
- package/dist/components/richtext-mode.js +36 -0
- package/dist/components/richtext-mode.js.map +1 -0
- package/dist/components/richtext-render.d.ts +8 -0
- package/dist/components/richtext-render.d.ts.map +1 -0
- package/dist/components/richtext-render.jsx +33 -0
- package/dist/components/richtext-render.jsx.map +1 -0
- package/dist/components/richtext-sync.d.ts +37 -0
- package/dist/components/richtext-sync.d.ts.map +1 -0
- package/dist/components/richtext-sync.js +46 -0
- package/dist/components/richtext-sync.js.map +1 -0
- package/dist/components/scroll-area.d.ts +5 -0
- package/dist/components/scroll-area.d.ts.map +1 -0
- package/dist/components/scroll-area.jsx +16 -0
- package/dist/components/scroll-area.jsx.map +1 -0
- package/dist/components/select.d.ts +36 -0
- package/dist/components/select.d.ts.map +1 -0
- package/dist/components/select.jsx +87 -0
- package/dist/components/select.jsx.map +1 -0
- package/dist/components/separator.d.ts +4 -0
- package/dist/components/separator.d.ts.map +1 -0
- package/dist/components/separator.jsx +6 -0
- package/dist/components/separator.jsx.map +1 -0
- package/dist/components/sheet.d.ts +29 -0
- package/dist/components/sheet.d.ts.map +1 -0
- package/dist/components/sheet.jsx +44 -0
- package/dist/components/sheet.jsx.map +1 -0
- package/dist/components/sidebar.d.ts +70 -0
- package/dist/components/sidebar.d.ts.map +1 -0
- package/dist/components/sidebar.jsx +245 -0
- package/dist/components/sidebar.jsx.map +1 -0
- package/dist/components/skeleton.d.ts +3 -0
- package/dist/components/skeleton.d.ts.map +1 -0
- package/dist/components/skeleton.jsx +6 -0
- package/dist/components/skeleton.jsx.map +1 -0
- package/dist/components/sonner.d.ts +6 -0
- package/dist/components/sonner.d.ts.map +1 -0
- package/dist/components/sonner.jsx +29 -0
- package/dist/components/sonner.jsx.map +1 -0
- package/dist/components/switch.d.ts +4 -0
- package/dist/components/switch.d.ts.map +1 -0
- package/dist/components/switch.jsx +8 -0
- package/dist/components/switch.jsx.map +1 -0
- package/dist/components/table.d.ts +10 -0
- package/dist/components/table.d.ts.map +1 -0
- package/dist/components/table.jsx +21 -0
- package/dist/components/table.jsx.map +1 -0
- package/dist/components/tabs.d.ts +7 -0
- package/dist/components/tabs.d.ts.map +1 -0
- package/dist/components/tabs.jsx +14 -0
- package/dist/components/tabs.jsx.map +1 -0
- package/dist/components/textarea.d.ts +4 -0
- package/dist/components/textarea.d.ts.map +1 -0
- package/dist/components/textarea.jsx +5 -0
- package/dist/components/textarea.jsx.map +1 -0
- package/dist/components/tooltip.d.ts +7 -0
- package/dist/components/tooltip.d.ts.map +1 -0
- package/dist/components/tooltip.jsx +11 -0
- package/dist/components/tooltip.jsx.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/theme.d.ts +11 -0
- package/dist/lib/theme.d.ts.map +1 -0
- package/dist/lib/theme.js +44 -0
- package/dist/lib/theme.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +6 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/styles.css +242 -0
- package/package.json +85 -0
- package/src/components/accordion.tsx +48 -0
- package/src/components/alert-dialog.tsx +113 -0
- package/src/components/audit-timeline.tsx +102 -0
- package/src/components/avatar.tsx +42 -0
- package/src/components/badge.tsx +34 -0
- package/src/components/breadcrumb.tsx +99 -0
- package/src/components/button.tsx +58 -0
- package/src/components/calendar.tsx +176 -0
- package/src/components/card.tsx +60 -0
- package/src/components/chart.tsx +558 -0
- package/src/components/checkbox.tsx +23 -0
- package/src/components/combobox.tsx +264 -0
- package/src/components/command.tsx +120 -0
- package/src/components/date-picker.tsx +221 -0
- package/src/components/date-range-input.tsx +295 -0
- package/src/components/dialog.tsx +94 -0
- package/src/components/diff-view.tsx +182 -0
- package/src/components/dropdown-menu.tsx +165 -0
- package/src/components/empty.tsx +100 -0
- package/src/components/field.tsx +168 -0
- package/src/components/file-input.tsx +233 -0
- package/src/components/form.tsx +152 -0
- package/src/components/info-tooltip.tsx +40 -0
- package/src/components/input.tsx +55 -0
- package/src/components/json-editor.tsx +210 -0
- package/src/components/kbd.tsx +35 -0
- package/src/components/key-value-editor.tsx +423 -0
- package/src/components/keyboard-shortcuts-help.tsx +136 -0
- package/src/components/label.tsx +16 -0
- package/src/components/media-preview.tsx +278 -0
- package/src/components/multi-file-input.tsx +315 -0
- package/src/components/password-input.tsx +50 -0
- package/src/components/popover.tsx +26 -0
- package/src/components/revision-timeline.tsx +93 -0
- package/src/components/richtext-editor.tsx +624 -0
- package/src/components/richtext-mode.ts +39 -0
- package/src/components/richtext-render.tsx +51 -0
- package/src/components/richtext-sync.ts +57 -0
- package/src/components/scroll-area.tsx +41 -0
- package/src/components/select.tsx +200 -0
- package/src/components/separator.tsx +21 -0
- package/src/components/sheet.tsx +109 -0
- package/src/components/sidebar.tsx +660 -0
- package/src/components/skeleton.tsx +9 -0
- package/src/components/sonner.tsx +45 -0
- package/src/components/switch.tsx +24 -0
- package/src/components/table.tsx +93 -0
- package/src/components/tabs.tsx +57 -0
- package/src/components/textarea.tsx +18 -0
- package/src/components/tooltip.tsx +25 -0
- package/src/index.ts +342 -0
- package/src/lib/theme.ts +45 -0
- package/src/lib/utils.ts +6 -0
- package/src/styles.css +242 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Dialog } from './dialog.js';
|
|
3
|
+
export declare const Command: React.ForwardRefExoticComponent<Omit<{
|
|
4
|
+
children?: React.ReactNode;
|
|
5
|
+
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
6
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
7
|
+
} & {
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & {
|
|
10
|
+
label?: string;
|
|
11
|
+
shouldFilter?: boolean;
|
|
12
|
+
filter?: (value: string, search: string, keywords?: string[]) => number;
|
|
13
|
+
defaultValue?: string;
|
|
14
|
+
value?: string;
|
|
15
|
+
onValueChange?: (value: string) => void;
|
|
16
|
+
loop?: boolean;
|
|
17
|
+
disablePointerSelection?: boolean;
|
|
18
|
+
vimBindings?: boolean;
|
|
19
|
+
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
20
|
+
export declare const CommandDialog: ({ children, ...props }: React.ComponentProps<typeof Dialog>) => React.ReactElement;
|
|
21
|
+
export declare const CommandInput: React.ForwardRefExoticComponent<Omit<Omit<Pick<Pick<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "key" | keyof React.InputHTMLAttributes<HTMLInputElement>> & {
|
|
22
|
+
ref?: React.Ref<HTMLInputElement>;
|
|
23
|
+
} & {
|
|
24
|
+
asChild?: boolean;
|
|
25
|
+
}, "key" | "asChild" | keyof React.InputHTMLAttributes<HTMLInputElement>>, "onChange" | "value" | "type"> & {
|
|
26
|
+
value?: string;
|
|
27
|
+
onValueChange?: (search: string) => void;
|
|
28
|
+
} & React.RefAttributes<HTMLInputElement>, "ref"> & React.RefAttributes<HTMLInputElement>>;
|
|
29
|
+
export declare const CommandList: React.ForwardRefExoticComponent<Omit<{
|
|
30
|
+
children?: React.ReactNode;
|
|
31
|
+
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
32
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
33
|
+
} & {
|
|
34
|
+
asChild?: boolean;
|
|
35
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & {
|
|
36
|
+
label?: string;
|
|
37
|
+
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
38
|
+
export declare const CommandEmpty: React.ForwardRefExoticComponent<Omit<{
|
|
39
|
+
children?: React.ReactNode;
|
|
40
|
+
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
41
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
42
|
+
} & {
|
|
43
|
+
asChild?: boolean;
|
|
44
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
45
|
+
export declare const CommandGroup: React.ForwardRefExoticComponent<Omit<{
|
|
46
|
+
children?: React.ReactNode;
|
|
47
|
+
} & Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
48
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
49
|
+
} & {
|
|
50
|
+
asChild?: boolean;
|
|
51
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild">, "heading" | "value"> & {
|
|
52
|
+
heading?: React.ReactNode;
|
|
53
|
+
value?: string;
|
|
54
|
+
forceMount?: boolean;
|
|
55
|
+
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
56
|
+
export declare const CommandSeparator: React.ForwardRefExoticComponent<Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
57
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
58
|
+
} & {
|
|
59
|
+
asChild?: boolean;
|
|
60
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & {
|
|
61
|
+
alwaysRender?: boolean;
|
|
62
|
+
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
63
|
+
export declare const CommandItem: React.ForwardRefExoticComponent<Omit<{
|
|
64
|
+
children?: React.ReactNode;
|
|
65
|
+
} & Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
66
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
67
|
+
} & {
|
|
68
|
+
asChild?: boolean;
|
|
69
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild">, "onSelect" | "disabled" | "value"> & {
|
|
70
|
+
disabled?: boolean;
|
|
71
|
+
onSelect?: (value: string) => void;
|
|
72
|
+
value?: string;
|
|
73
|
+
keywords?: string[];
|
|
74
|
+
forceMount?: boolean;
|
|
75
|
+
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
76
|
+
export declare const CommandShortcut: {
|
|
77
|
+
({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>): React.ReactElement;
|
|
78
|
+
displayName: string;
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/components/command.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,OAAO,EAAE,MAAM,EAAiB,MAAM,aAAa,CAAA;AAEnD,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;sFAYlB,CAAA;AAGF,eAAO,MAAM,aAAa,GAAI,wBAG3B,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,KAAG,KAAK,CAAC,YAQ9C,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;0FAevB,CAAA;AAGF,eAAO,MAAM,WAAW;;;;;;;;sFAStB,CAAA;AAGF,eAAO,MAAM,YAAY;;;;;;uJAKvB,CAAA;AAGF,eAAO,MAAM,YAAY;;;;;;;;;;sFAYvB,CAAA;AAGF,eAAO,MAAM,gBAAgB;;;;;;sFAK3B,CAAA;AAGF,eAAO,MAAM,WAAW;;;;;;;;;;;;sFAYtB,CAAA;AAGF,eAAO,MAAM,eAAe;8BAGzB,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,GAAG,KAAK,CAAC,YAAY;;CAK5D,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Command as CommandPrimitive } from 'cmdk';
|
|
3
|
+
import { Search } from 'lucide-react';
|
|
4
|
+
import { cn } from '../lib/utils.js';
|
|
5
|
+
import { Dialog, DialogContent } from './dialog.js';
|
|
6
|
+
export const Command = React.forwardRef(({ className, ...props }, ref) => (<CommandPrimitive ref={ref} className={cn('flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground', className)} {...props}/>));
|
|
7
|
+
Command.displayName = CommandPrimitive.displayName;
|
|
8
|
+
export const CommandDialog = ({ children, ...props }) => (<Dialog {...props}>
|
|
9
|
+
<DialogContent className="overflow-hidden p-0 shadow-lg">
|
|
10
|
+
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
|
11
|
+
{children}
|
|
12
|
+
</Command>
|
|
13
|
+
</DialogContent>
|
|
14
|
+
</Dialog>);
|
|
15
|
+
export const CommandInput = React.forwardRef(({ className, ...props }, ref) => (<div className="flex items-center border-b border-border px-3" cmdk-input-wrapper="">
|
|
16
|
+
<Search className="mr-2 h-4 w-4 shrink-0 opacity-50"/>
|
|
17
|
+
<CommandPrimitive.Input ref={ref} className={cn('flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50', className)} {...props}/>
|
|
18
|
+
</div>));
|
|
19
|
+
CommandInput.displayName = CommandPrimitive.Input.displayName;
|
|
20
|
+
export const CommandList = React.forwardRef(({ className, ...props }, ref) => (<CommandPrimitive.List ref={ref} className={cn('max-h-[300px] overflow-y-auto overflow-x-hidden', className)} {...props}/>));
|
|
21
|
+
CommandList.displayName = CommandPrimitive.List.displayName;
|
|
22
|
+
export const CommandEmpty = React.forwardRef((props, ref) => (<CommandPrimitive.Empty ref={ref} className="py-6 text-center text-sm" {...props}/>));
|
|
23
|
+
CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
|
|
24
|
+
export const CommandGroup = React.forwardRef(({ className, ...props }, ref) => (<CommandPrimitive.Group ref={ref} className={cn('overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground', className)} {...props}/>));
|
|
25
|
+
CommandGroup.displayName = CommandPrimitive.Group.displayName;
|
|
26
|
+
export const CommandSeparator = React.forwardRef(({ className, ...props }, ref) => (<CommandPrimitive.Separator ref={ref} className={cn('-mx-1 h-px bg-border/40', className)} {...props}/>));
|
|
27
|
+
CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
|
|
28
|
+
export const CommandItem = React.forwardRef(({ className, ...props }, ref) => (<CommandPrimitive.Item ref={ref} className={cn('relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', className)} {...props}/>));
|
|
29
|
+
CommandItem.displayName = CommandPrimitive.Item.displayName;
|
|
30
|
+
export const CommandShortcut = ({ className, ...props }) => (<span className={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)} {...props}/>);
|
|
31
|
+
CommandShortcut.displayName = 'CommandShortcut';
|
|
32
|
+
//# sourceMappingURL=command.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.jsx","sourceRoot":"","sources":["../../src/components/command.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type DatePickerMode = 'date' | 'datetime';
|
|
3
|
+
export interface DatePickerProps {
|
|
4
|
+
value: string | null | undefined;
|
|
5
|
+
onChange(next: string): void;
|
|
6
|
+
mode?: DatePickerMode;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
/** Applied to the outer wrapper div (controls width, etc.). */
|
|
10
|
+
className?: string;
|
|
11
|
+
/** Applied to the inner text Input — use to override height / font size. */
|
|
12
|
+
inputClassName?: string;
|
|
13
|
+
/** ARIA label forwarded to the trigger input (mobile users / screen readers). */
|
|
14
|
+
ariaLabel?: string;
|
|
15
|
+
/** ARIA label for the calendar icon button. Default: "Open calendar". */
|
|
16
|
+
openCalendarLabel?: string;
|
|
17
|
+
/** Label for the time input shown in datetime mode. Default: "Time". */
|
|
18
|
+
timeLabel?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function DatePicker({ value, onChange, mode, disabled, placeholder, className, inputClassName, ariaLabel, openCalendarLabel, timeLabel, }: DatePickerProps): React.ReactElement;
|
|
21
|
+
export declare namespace DatePicker {
|
|
22
|
+
var displayName: string;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=date-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../src/components/date-picker.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAS9B,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,CAAA;AAEhD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA2CD,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,IAAa,EACb,QAAQ,EACR,WAAW,EACX,SAAS,EACT,cAAc,EACd,SAAS,EACT,iBAAmC,EACnC,SAAkB,GACnB,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CAiItC;yBA5Ie,UAAU"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// Popover-driven date / datetime input. Single picker handles both modes:
|
|
2
|
+
// pass `mode="datetime"` to surface an HH:MM time input below the calendar.
|
|
3
|
+
//
|
|
4
|
+
// Value is an ISO-ish string (`yyyy-MM-dd` for dates, `yyyy-MM-ddTHH:mm` for
|
|
5
|
+
// datetime — same shape <input type="date">/<input type="datetime-local">
|
|
6
|
+
// produce, so callers can stay format-stable). The trigger is a real text
|
|
7
|
+
// input so users can also type the date manually; clicks on the trailing
|
|
8
|
+
// calendar icon open the popover with the inline picker.
|
|
9
|
+
import * as React from 'react';
|
|
10
|
+
import { format, isValid, parse, parseISO } from 'date-fns';
|
|
11
|
+
import { Calendar as CalendarIcon } from 'lucide-react';
|
|
12
|
+
import { cn } from '../lib/utils.js';
|
|
13
|
+
import { Button } from './button.js';
|
|
14
|
+
import { Calendar } from './calendar.js';
|
|
15
|
+
import { Input } from './input.js';
|
|
16
|
+
import { Popover, PopoverContent, PopoverTrigger } from './popover.js';
|
|
17
|
+
const DATE_FMT = 'yyyy-MM-dd';
|
|
18
|
+
const DATETIME_FMT = "yyyy-MM-dd'T'HH:mm";
|
|
19
|
+
// Friendlier display format for the datetime input — space instead of `T`.
|
|
20
|
+
const DATETIME_DISPLAY_FMT = 'yyyy-MM-dd HH:mm';
|
|
21
|
+
function parseValue(value) {
|
|
22
|
+
if (!value)
|
|
23
|
+
return undefined;
|
|
24
|
+
const direct = value.length <= 10 ? parse(value, DATE_FMT, new Date()) : parseISO(value);
|
|
25
|
+
return Number.isNaN(direct.getTime()) ? undefined : direct;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Try to parse a manually-typed string in any of the supported shapes.
|
|
29
|
+
* Returns `undefined` on blank, `null` on invalid (non-blank) input so the
|
|
30
|
+
* caller can distinguish "cleared" from "typo".
|
|
31
|
+
*/
|
|
32
|
+
function parseTyped(raw, mode) {
|
|
33
|
+
const trimmed = raw.trim();
|
|
34
|
+
if (trimmed === '')
|
|
35
|
+
return undefined;
|
|
36
|
+
const candidates = mode === 'datetime'
|
|
37
|
+
? [DATETIME_FMT, DATETIME_DISPLAY_FMT, "yyyy-MM-dd'T'HH:mm:ss", DATE_FMT]
|
|
38
|
+
: [DATE_FMT];
|
|
39
|
+
for (const fmt of candidates) {
|
|
40
|
+
const parsed = parse(trimmed, fmt, new Date());
|
|
41
|
+
if (isValid(parsed))
|
|
42
|
+
return parsed;
|
|
43
|
+
}
|
|
44
|
+
// Last resort: ISO with timezone, etc.
|
|
45
|
+
const iso = parseISO(trimmed);
|
|
46
|
+
return isValid(iso) ? iso : null;
|
|
47
|
+
}
|
|
48
|
+
function formatForInput(date, mode) {
|
|
49
|
+
if (!date)
|
|
50
|
+
return '';
|
|
51
|
+
return format(date, mode === 'datetime' ? DATETIME_DISPLAY_FMT : DATE_FMT);
|
|
52
|
+
}
|
|
53
|
+
function formatForApi(date, mode) {
|
|
54
|
+
return format(date, mode === 'datetime' ? DATETIME_FMT : DATE_FMT);
|
|
55
|
+
}
|
|
56
|
+
export function DatePicker({ value, onChange, mode = 'date', disabled, placeholder, className, inputClassName, ariaLabel, openCalendarLabel = 'Open calendar', timeLabel = 'Time', }) {
|
|
57
|
+
const [open, setOpen] = React.useState(false);
|
|
58
|
+
const date = parseValue(value);
|
|
59
|
+
// Local draft for the text input — keeps user typing intact even when
|
|
60
|
+
// intermediate strings don't yet parse.
|
|
61
|
+
const [draft, setDraft] = React.useState(() => formatForInput(date, mode));
|
|
62
|
+
// Re-sync draft whenever the canonical value changes from outside (e.g.
|
|
63
|
+
// calendar selection or form reset). Compare via formatted shape so a noop
|
|
64
|
+
// update doesn't clobber what the user is typing.
|
|
65
|
+
const lastFormatted = React.useRef(formatForInput(date, mode));
|
|
66
|
+
React.useEffect(() => {
|
|
67
|
+
const next = formatForInput(date, mode);
|
|
68
|
+
if (next !== lastFormatted.current) {
|
|
69
|
+
lastFormatted.current = next;
|
|
70
|
+
setDraft(next);
|
|
71
|
+
}
|
|
72
|
+
}, [value, mode]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
73
|
+
const time = date ? format(date, 'HH:mm') : '00:00';
|
|
74
|
+
const commitDate = (next) => {
|
|
75
|
+
if (!next) {
|
|
76
|
+
lastFormatted.current = '';
|
|
77
|
+
setDraft('');
|
|
78
|
+
onChange('');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (mode === 'datetime') {
|
|
82
|
+
const [h, m] = time.split(':').map(Number);
|
|
83
|
+
next.setHours(h ?? 0, m ?? 0, 0, 0);
|
|
84
|
+
}
|
|
85
|
+
const formatted = formatForInput(next, mode);
|
|
86
|
+
lastFormatted.current = formatted;
|
|
87
|
+
setDraft(formatted);
|
|
88
|
+
onChange(formatForApi(next, mode));
|
|
89
|
+
};
|
|
90
|
+
const setTime = (raw) => {
|
|
91
|
+
if (!date)
|
|
92
|
+
return;
|
|
93
|
+
const [h, m] = raw.split(':').map(Number);
|
|
94
|
+
const next = new Date(date);
|
|
95
|
+
next.setHours(h ?? 0, m ?? 0, 0, 0);
|
|
96
|
+
const formatted = formatForInput(next, mode);
|
|
97
|
+
lastFormatted.current = formatted;
|
|
98
|
+
setDraft(formatted);
|
|
99
|
+
onChange(formatForApi(next, mode));
|
|
100
|
+
};
|
|
101
|
+
const handleInputChange = (e) => {
|
|
102
|
+
const text = e.target.value;
|
|
103
|
+
setDraft(text);
|
|
104
|
+
const parsed = parseTyped(text, mode);
|
|
105
|
+
if (parsed === undefined) {
|
|
106
|
+
// cleared
|
|
107
|
+
lastFormatted.current = '';
|
|
108
|
+
onChange('');
|
|
109
|
+
}
|
|
110
|
+
else if (parsed) {
|
|
111
|
+
lastFormatted.current = formatForInput(parsed, mode);
|
|
112
|
+
onChange(formatForApi(parsed, mode));
|
|
113
|
+
}
|
|
114
|
+
// parsed === null → keep draft, don't fire onChange yet
|
|
115
|
+
};
|
|
116
|
+
const handleInputBlur = () => {
|
|
117
|
+
// On blur, if the draft is invalid, snap back to the canonical value.
|
|
118
|
+
const parsed = parseTyped(draft, mode);
|
|
119
|
+
if (parsed === null) {
|
|
120
|
+
const restored = formatForInput(date, mode);
|
|
121
|
+
lastFormatted.current = restored;
|
|
122
|
+
setDraft(restored);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const inputPlaceholder = placeholder ?? (mode === 'datetime' ? 'YYYY-MM-DD HH:MM' : 'YYYY-MM-DD');
|
|
126
|
+
return (<Popover open={open} onOpenChange={setOpen}>
|
|
127
|
+
<div className={cn('relative w-full', className)}>
|
|
128
|
+
<Input type="text" inputMode="numeric" value={draft} onChange={handleInputChange} onBlur={handleInputBlur} placeholder={inputPlaceholder} disabled={disabled} aria-label={ariaLabel} className={cn(inputClassName, 'pr-10')}/>
|
|
129
|
+
<PopoverTrigger asChild>
|
|
130
|
+
<Button type="button" variant="ghost" size="icon" disabled={disabled} aria-label={openCalendarLabel} className="absolute right-1 top-1/2 size-8 -translate-y-1/2 text-muted-foreground hover:text-foreground">
|
|
131
|
+
<CalendarIcon className="size-4"/>
|
|
132
|
+
</Button>
|
|
133
|
+
</PopoverTrigger>
|
|
134
|
+
</div>
|
|
135
|
+
<PopoverContent className="w-auto p-0" align="start">
|
|
136
|
+
<Calendar mode="single" selected={date} defaultMonth={date} onSelect={(d) => {
|
|
137
|
+
commitDate(d);
|
|
138
|
+
if (mode === 'date')
|
|
139
|
+
setOpen(false);
|
|
140
|
+
}} autoFocus/>
|
|
141
|
+
{mode === 'datetime' && (<div className="flex items-center gap-2 border-t p-3">
|
|
142
|
+
<span className="text-xs text-muted-foreground">{timeLabel}</span>
|
|
143
|
+
<Input type="time" value={time} disabled={!date} onChange={(e) => setTime(e.target.value)} className="h-8 w-32"/>
|
|
144
|
+
</div>)}
|
|
145
|
+
</PopoverContent>
|
|
146
|
+
</Popover>);
|
|
147
|
+
}
|
|
148
|
+
DatePicker.displayName = 'DatePicker';
|
|
149
|
+
//# sourceMappingURL=date-picker.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-picker.jsx","sourceRoot":"","sources":["../../src/components/date-picker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface DateRangeInputLabels {
|
|
3
|
+
/** Shown in the trigger when nothing is selected. */
|
|
4
|
+
placeholder?: string;
|
|
5
|
+
/** "Apply" button inside the popover footer. */
|
|
6
|
+
apply?: string;
|
|
7
|
+
/** "Clear" button inside the popover footer + aria-label for the inline X. */
|
|
8
|
+
clear?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface DateRangeInputProps {
|
|
11
|
+
from: string | null | undefined;
|
|
12
|
+
to: string | null | undefined;
|
|
13
|
+
onChange(from: string, to: string): void;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
className?: string;
|
|
16
|
+
labels?: DateRangeInputLabels;
|
|
17
|
+
}
|
|
18
|
+
export declare function DateRangeInput({ from, to, onChange, disabled, className, labels, }: DateRangeInputProps): React.ReactElement;
|
|
19
|
+
export declare namespace DateRangeInput {
|
|
20
|
+
var displayName: string;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=date-range-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-range-input.d.ts","sourceRoot":"","sources":["../../src/components/date-range-input.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAkB9B,MAAM,WAAW,oBAAoB;IACnC,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAC/B,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,oBAAoB,CAAA;CAC9B;AAED,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,EAAE,EACF,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,MAAW,GACZ,EAAE,mBAAmB,GAAG,KAAK,CAAC,YAAY,CAoO1C;yBA3Oe,cAAc"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// Popover-driven date-range picker.
|
|
2
|
+
// A single trigger button shows the selected range (or placeholder);
|
|
3
|
+
// clicking opens a popover with a two-month Calendar in range mode.
|
|
4
|
+
// On narrow screens the calendar collapses to a single month.
|
|
5
|
+
//
|
|
6
|
+
// UX notes:
|
|
7
|
+
// - The picker NEVER auto-closes on date selection — the user confirms
|
|
8
|
+
// explicitly via the "Apply" button. This prevents the "first click
|
|
9
|
+
// closes the picker" bug that occurs when a partial pending range
|
|
10
|
+
// (from without to) is in state and the next click completes it.
|
|
11
|
+
// - "Clear" inside the popover empties the range and closes.
|
|
12
|
+
// - The X inline in the trigger clears directly without opening the picker.
|
|
13
|
+
// - On open: only a COMPLETE committed range (both ends) is mirrored into
|
|
14
|
+
// the calendar state so the user can edit from a known baseline.
|
|
15
|
+
// A committed partial range (from only) resets to blank to avoid
|
|
16
|
+
// accidentally completing it on the first click.
|
|
17
|
+
// - Escape / click-outside discards in-progress selection and reverts to
|
|
18
|
+
// the last committed range.
|
|
19
|
+
//
|
|
20
|
+
// i18n-unaware by design: all visible strings are passed via `labels`.
|
|
21
|
+
import * as React from 'react';
|
|
22
|
+
import { addMonths, format, isSameMonth, isValid, parse, parseISO, startOfMonth } from 'date-fns';
|
|
23
|
+
import { CalendarRange, X } from 'lucide-react';
|
|
24
|
+
import { cn } from '../lib/utils.js';
|
|
25
|
+
import { Button } from './button.js';
|
|
26
|
+
import { Calendar } from './calendar.js';
|
|
27
|
+
import { Popover, PopoverContent, PopoverTrigger } from './popover.js';
|
|
28
|
+
const DATE_FMT = 'yyyy-MM-dd';
|
|
29
|
+
const DISPLAY_FMT = 'MMM d, yyyy';
|
|
30
|
+
function parseDate(value) {
|
|
31
|
+
if (!value)
|
|
32
|
+
return undefined;
|
|
33
|
+
const d = value.length <= 10 ? parse(value, DATE_FMT, new Date()) : parseISO(value);
|
|
34
|
+
return isValid(d) ? d : undefined;
|
|
35
|
+
}
|
|
36
|
+
export function DateRangeInput({ from, to, onChange, disabled, className, labels = {}, }) {
|
|
37
|
+
const placeholder = labels.placeholder ?? 'Select date range';
|
|
38
|
+
const applyLabel = labels.apply ?? 'Apply';
|
|
39
|
+
const clearLabel = labels.clear ?? 'Clear';
|
|
40
|
+
const [open, setOpen] = React.useState(false);
|
|
41
|
+
// Calendar selection in progress. Committed to onChange only via Apply.
|
|
42
|
+
const [pending, setPending] = React.useState(() => {
|
|
43
|
+
const f = parseDate(from);
|
|
44
|
+
const t = parseDate(to);
|
|
45
|
+
// Only restore a complete range on init — partial ranges start fresh.
|
|
46
|
+
return f && t ? { from: f, to: t } : undefined;
|
|
47
|
+
});
|
|
48
|
+
// Keep pending in sync when props change externally (e.g. programmatic reset).
|
|
49
|
+
React.useEffect(() => {
|
|
50
|
+
const f = parseDate(from);
|
|
51
|
+
const t = parseDate(to);
|
|
52
|
+
setPending(f ?? t ? { from: f, to: t } : undefined);
|
|
53
|
+
}, [from, to]);
|
|
54
|
+
// Number of calendar months — 1 on narrow, 2 on wide viewports.
|
|
55
|
+
const [months, setMonths] = React.useState(() => typeof window !== 'undefined' && window.innerWidth >= 640 ? 2 : 1);
|
|
56
|
+
React.useEffect(() => {
|
|
57
|
+
const mq = window.matchMedia('(min-width: 640px)');
|
|
58
|
+
const handle = (e) => setMonths(e.matches ? 2 : 1);
|
|
59
|
+
setMonths(mq.matches ? 2 : 1);
|
|
60
|
+
mq.addEventListener('change', handle);
|
|
61
|
+
return () => mq.removeEventListener('change', handle);
|
|
62
|
+
}, []);
|
|
63
|
+
// Independent navigation for the two-panel layout. Each panel keeps its
|
|
64
|
+
// own visible month; the dropdowns on the right are constrained to
|
|
65
|
+
// months >= left (and the left to months <= right) so the panels can
|
|
66
|
+
// never cross over. State is (re)initialised from the committed range
|
|
67
|
+
// every time the popover opens (see `handleOpenChange`).
|
|
68
|
+
const [leftMonth, setLeftMonth] = React.useState(() => {
|
|
69
|
+
const f = parseDate(from);
|
|
70
|
+
return startOfMonth(f ?? new Date());
|
|
71
|
+
});
|
|
72
|
+
const [rightMonth, setRightMonth] = React.useState(() => {
|
|
73
|
+
const f = parseDate(from);
|
|
74
|
+
const t = parseDate(to);
|
|
75
|
+
const left = startOfMonth(f ?? new Date());
|
|
76
|
+
return t && !isSameMonth(left, t) ? startOfMonth(t) : addMonths(left, 1);
|
|
77
|
+
});
|
|
78
|
+
const handleOpenChange = (next) => {
|
|
79
|
+
if (next) {
|
|
80
|
+
// On open: only restore a COMPLETE committed range so the user sees
|
|
81
|
+
// their previous selection as a starting point. A partial range
|
|
82
|
+
// (from without to) is intentionally dropped — carrying it over
|
|
83
|
+
// would cause the very next calendar click to "complete" the range
|
|
84
|
+
// and trigger an immediate commit + close.
|
|
85
|
+
const f = parseDate(from);
|
|
86
|
+
const t = parseDate(to);
|
|
87
|
+
setPending(f && t ? { from: f, to: t } : undefined);
|
|
88
|
+
// Re-derive panel navigation from the committed range so reopening
|
|
89
|
+
// always lands the user on the months they were last looking at —
|
|
90
|
+
// independently for the left and right panels.
|
|
91
|
+
const left = startOfMonth(f ?? new Date());
|
|
92
|
+
const right = t && !isSameMonth(left, t)
|
|
93
|
+
? startOfMonth(t)
|
|
94
|
+
: addMonths(left, 1);
|
|
95
|
+
setLeftMonth(left);
|
|
96
|
+
setRightMonth(right);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// Closed without Apply (Escape / outside click) — discard in-progress
|
|
100
|
+
// selection and revert to the last committed values.
|
|
101
|
+
const f = parseDate(from);
|
|
102
|
+
const t = parseDate(to);
|
|
103
|
+
setPending(f ?? t ? { from: f, to: t } : undefined);
|
|
104
|
+
}
|
|
105
|
+
setOpen(next);
|
|
106
|
+
};
|
|
107
|
+
// Navigation guards. The right panel can never cross above the left's
|
|
108
|
+
// month, and the left can never cross above the right's. If a user
|
|
109
|
+
// navigates the LEFT forward past the right (via the prev/next arrow
|
|
110
|
+
// when the dropdown bounds don't disable it), push the right one month
|
|
111
|
+
// ahead; symmetric for the right going below the left.
|
|
112
|
+
const handleLeftMonthChange = (next) => {
|
|
113
|
+
setLeftMonth(next);
|
|
114
|
+
if (!isSameMonth(next, rightMonth) && next > rightMonth) {
|
|
115
|
+
setRightMonth(addMonths(next, 1));
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const handleRightMonthChange = (next) => {
|
|
119
|
+
setRightMonth(next);
|
|
120
|
+
if (!isSameMonth(next, leftMonth) && next < leftMonth) {
|
|
121
|
+
setLeftMonth(addMonths(next, -1));
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
// Update the in-progress selection; never auto-commit.
|
|
125
|
+
const handleSelect = (range) => {
|
|
126
|
+
setPending(range);
|
|
127
|
+
};
|
|
128
|
+
// Commit whatever is pending (at minimum a start date) and close.
|
|
129
|
+
const handleApply = () => {
|
|
130
|
+
if (pending?.from) {
|
|
131
|
+
onChange(format(pending.from, DATE_FMT), pending.to ? format(pending.to, DATE_FMT) : '');
|
|
132
|
+
}
|
|
133
|
+
setOpen(false);
|
|
134
|
+
};
|
|
135
|
+
// Clear inside the popover: empty the committed range and close.
|
|
136
|
+
const handleClearPopover = () => {
|
|
137
|
+
setPending(undefined);
|
|
138
|
+
onChange('', '');
|
|
139
|
+
setOpen(false);
|
|
140
|
+
};
|
|
141
|
+
// Inline X on the trigger: clear committed range without opening the picker.
|
|
142
|
+
const handleClearInline = (e) => {
|
|
143
|
+
e.stopPropagation();
|
|
144
|
+
setPending(undefined);
|
|
145
|
+
onChange('', '');
|
|
146
|
+
};
|
|
147
|
+
const fromDate = parseDate(from);
|
|
148
|
+
const toDate = parseDate(to);
|
|
149
|
+
const hasValue = !!(from || to);
|
|
150
|
+
const displayText = hasValue
|
|
151
|
+
? [
|
|
152
|
+
fromDate ? format(fromDate, DISPLAY_FMT) : '…',
|
|
153
|
+
toDate ? format(toDate, DISPLAY_FMT) : '…',
|
|
154
|
+
].join(' – ')
|
|
155
|
+
: null;
|
|
156
|
+
return (<Popover open={open} onOpenChange={handleOpenChange}>
|
|
157
|
+
<PopoverTrigger asChild>
|
|
158
|
+
<Button type="button" variant="outline" disabled={disabled} className={cn('h-9 w-full justify-start gap-2 px-3 font-normal', !hasValue && 'text-muted-foreground', className)}>
|
|
159
|
+
<CalendarRange className="size-4 shrink-0 opacity-60"/>
|
|
160
|
+
<span className="flex-1 truncate text-left text-sm">
|
|
161
|
+
{displayText ?? placeholder}
|
|
162
|
+
</span>
|
|
163
|
+
{hasValue && (<span role="button" tabIndex={0} aria-label={clearLabel} onClick={handleClearInline} onKeyDown={(e) => {
|
|
164
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
165
|
+
handleClearInline(e);
|
|
166
|
+
}
|
|
167
|
+
}} className="ml-1 rounded-sm p-0.5 opacity-50 hover:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring">
|
|
168
|
+
<X className="size-3.5"/>
|
|
169
|
+
</span>)}
|
|
170
|
+
</Button>
|
|
171
|
+
</PopoverTrigger>
|
|
172
|
+
<PopoverContent className="w-auto p-0" align="start">
|
|
173
|
+
{months === 2 ? (
|
|
174
|
+
// Two-panel layout: each Calendar is a fully independent single-
|
|
175
|
+
// month instance with its own controlled `month` state. The left
|
|
176
|
+
// panel's dropdowns can't reach past the right panel's month
|
|
177
|
+
// (and vice versa) thanks to the shared start/end-month bounds.
|
|
178
|
+
// Range selection still spans both panels because they share
|
|
179
|
+
// the same `selected` + `onSelect`.
|
|
180
|
+
<div className="flex flex-col sm:flex-row">
|
|
181
|
+
<Calendar mode="range" selected={pending} onSelect={handleSelect} numberOfMonths={1} month={leftMonth} onMonthChange={handleLeftMonthChange} endMonth={rightMonth} autoFocus/>
|
|
182
|
+
<Calendar mode="range" selected={pending} onSelect={handleSelect} numberOfMonths={1} month={rightMonth} onMonthChange={handleRightMonthChange} startMonth={leftMonth}/>
|
|
183
|
+
</div>) : (<Calendar mode="range" selected={pending} onSelect={handleSelect} numberOfMonths={1}
|
|
184
|
+
// react-day-picker doesn't auto-navigate to the selected range on
|
|
185
|
+
// mount — it stays on today's month. The popover re-mounts the
|
|
186
|
+
// Calendar each time it opens, so deriving `defaultMonth` from
|
|
187
|
+
// the (already-restored) pending range puts the user back where
|
|
188
|
+
// they left off without controlling navigation explicitly.
|
|
189
|
+
defaultMonth={pending?.from ?? pending?.to ?? undefined} autoFocus/>)}
|
|
190
|
+
<div className="flex items-center justify-between border-t border-border px-3 py-2">
|
|
191
|
+
<Button variant="ghost" size="sm" onClick={handleClearPopover}>
|
|
192
|
+
{clearLabel}
|
|
193
|
+
</Button>
|
|
194
|
+
<Button size="sm" onClick={handleApply} disabled={!pending?.from}>
|
|
195
|
+
{applyLabel}
|
|
196
|
+
</Button>
|
|
197
|
+
</div>
|
|
198
|
+
</PopoverContent>
|
|
199
|
+
</Popover>);
|
|
200
|
+
}
|
|
201
|
+
DateRangeInput.displayName = 'DateRangeInput';
|
|
202
|
+
//# sourceMappingURL=date-range-input.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-range-input.jsx","sourceRoot":"","sources":["../../src/components/date-range-input.tsx"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,qEAAqE;AACrE,oEAAoE;AACpE,8DAA8D;AAC9D,EAAE;AACF,YAAY;AACZ,uEAAuE;AACvE,sEAAsE;AACtE,oEAAoE;AACpE,mEAAmE;AACnE,6DAA6D;AAC7D,4EAA4E;AAC5E,0EAA0E;AAC1E,mEAAmE;AACnE,mEAAmE;AACnE,mDAAmD;AACnD,yEAAyE;AACzE,8BAA8B;AAC9B,EAAE;AACF,uEAAuE;AAEvE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACjG,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAEtE,MAAM,QAAQ,GAAG,YAAY,CAAA;AAC7B,MAAM,WAAW,GAAG,aAAa,CAAA;AAEjC,SAAS,SAAS,CAAC,KAAgC;IACjD,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAA;IAC5B,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnF,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACnC,CAAC;AAoBD,MAAM,UAAU,cAAc,CAAC,EAC7B,IAAI,EACJ,EAAE,EACF,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,MAAM,GAAG,EAAE,GACS;IACpB,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,mBAAmB,CAAA;IAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,IAAI,OAAO,CAAA;IAC1C,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,IAAI,OAAO,CAAA;IAE1C,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE7C,wEAAwE;IACxE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAwB,GAAG,EAAE;QACvE,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QACzB,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;QACvB,sEAAsE;QACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;IAChD,CAAC,CAAC,CAAA;IAEF,+EAA+E;IAC/E,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QACzB,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;QACvB,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IACrD,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;IAEd,gEAAgE;IAChE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,CAC9C,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAClE,CAAA;IACD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAA;QAClD,MAAM,MAAM,GAAG,CAAC,CAAsB,EAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC7E,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC7B,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QACrC,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IACvD,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,wEAAwE;IACxE,mEAAmE;IACnE,qEAAqE;IACrE,sEAAsE;IACtE,yDAAyD;IACzD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAO,GAAG,EAAE;QAC1D,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QACzB,OAAO,YAAY,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAO,GAAG,EAAE;QAC5D,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QACzB,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;QACvB,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAA;QAC1C,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAC1E,CAAC,CAAC,CAAA;IAEF,MAAM,gBAAgB,GAAG,CAAC,IAAa,EAAQ,EAAE;QAC/C,IAAI,IAAI,EAAE,CAAC;YACT,oEAAoE;YACpE,gEAAgE;YAChE,gEAAgE;YAChE,mEAAmE;YACnE,2CAA2C;YAC3C,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;YACzB,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;YACvB,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;YACnD,mEAAmE;YACnE,kEAAkE;YAClE,+CAA+C;YAC/C,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAA;YAC1C,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;gBACtC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;gBACjB,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;YACtB,YAAY,CAAC,IAAI,CAAC,CAAA;YAClB,aAAa,CAAC,KAAK,CAAC,CAAA;QACtB,CAAC;aAAM,CAAC;YACN,sEAAsE;YACtE,qDAAqD;YACrD,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;YACzB,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;YACvB,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QACrD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAA;IACf,CAAC,CAAA;IAED,sEAAsE;IACtE,mEAAmE;IACnE,qEAAqE;IACrE,uEAAuE;IACvE,uDAAuD;IACvD,MAAM,qBAAqB,GAAG,CAAC,IAAU,EAAQ,EAAE;QACjD,YAAY,CAAC,IAAI,CAAC,CAAA;QAClB,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,IAAI,GAAG,UAAU,EAAE,CAAC;YACxD,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QACnC,CAAC;IACH,CAAC,CAAA;IACD,MAAM,sBAAsB,GAAG,CAAC,IAAU,EAAQ,EAAE;QAClD,aAAa,CAAC,IAAI,CAAC,CAAA;QACnB,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,GAAG,SAAS,EAAE,CAAC;YACtD,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QACnC,CAAC;IACH,CAAC,CAAA;IAED,uDAAuD;IACvD,MAAM,YAAY,GAAG,CAAC,KAA4B,EAAQ,EAAE;QAC1D,UAAU,CAAC,KAAK,CAAC,CAAA;IACnB,CAAC,CAAA;IAED,kEAAkE;IAClE,MAAM,WAAW,GAAG,GAAS,EAAE;QAC7B,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;YAClB,QAAQ,CACN,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,EAC9B,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAC/C,CAAA;QACH,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,CAAA;IAChB,CAAC,CAAA;IAED,iEAAiE;IACjE,MAAM,kBAAkB,GAAG,GAAS,EAAE;QACpC,UAAU,CAAC,SAAS,CAAC,CAAA;QACrB,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;QAChB,OAAO,CAAC,KAAK,CAAC,CAAA;IAChB,CAAC,CAAA;IAED,6EAA6E;IAC7E,MAAM,iBAAiB,GAAG,CAAC,CAAmB,EAAQ,EAAE;QACtD,CAAC,CAAC,eAAe,EAAE,CAAA;QACnB,UAAU,CAAC,SAAS,CAAC,CAAA;QACrB,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAClB,CAAC,CAAA;IAED,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;IAChC,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;IAC5B,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;IAE/B,MAAM,WAAW,GAAG,QAAQ;QAC1B,CAAC,CAAC;YACA,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG;YAC9C,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG;SAC3C,CAAC,IAAI,CAAC,KAAK,CAAC;QACb,CAAC,CAAC,IAAI,CAAA;IAER,OAAO,CACL,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,gBAAgB,CAAC,CAClD;MAAA,CAAC,cAAc,CAAC,OAAO,CACrB;QAAA,CAAC,MAAM,CACL,IAAI,CAAC,QAAQ,CACb,OAAO,CAAC,SAAS,CACjB,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,SAAS,CAAC,CAAC,EAAE,CACX,iDAAiD,EACjD,CAAC,QAAQ,IAAI,uBAAuB,EACpC,SAAS,CACV,CAAC,CAEF;UAAA,CAAC,aAAa,CAAC,SAAS,CAAC,4BAA4B,EACrD;UAAA,CAAC,IAAI,CAAC,SAAS,CAAC,mCAAmC,CACjD;YAAA,CAAC,WAAW,IAAI,WAAW,CAC7B;UAAA,EAAE,IAAI,CACN;UAAA,CAAC,QAAQ,IAAI,CACX,CAAC,IAAI,CACH,IAAI,CAAC,QAAQ,CACb,QAAQ,CAAC,CAAC,CAAC,CAAC,CACZ,UAAU,CAAC,CAAC,UAAU,CAAC,CACvB,OAAO,CAAC,CAAC,iBAAiB,CAAC,CAC3B,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE;gBACf,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;oBACvC,iBAAiB,CAAC,CAAgC,CAAC,CAAA;gBACrD,CAAC;YACH,CAAC,CAAC,CACF,SAAS,CAAC,4HAA4H,CAEtI;cAAA,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,EACzB;YAAA,EAAE,IAAI,CAAC,CACR,CACH;QAAA,EAAE,MAAM,CACV;MAAA,EAAE,cAAc,CAChB;MAAA,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAClD;QAAA,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;QACd,iEAAiE;QACjE,iEAAiE;QACjE,6DAA6D;QAC7D,gEAAgE;QAChE,6DAA6D;QAC7D,oCAAoC;QACpC,CAAC,GAAG,CAAC,SAAS,CAAC,2BAA2B,CACxC;YAAA,CAAC,QAAQ,CACP,IAAI,CAAC,OAAO,CACZ,QAAQ,CAAC,CAAC,OAAO,CAAC,CAClB,QAAQ,CAAC,CAAC,YAAY,CAAC,CACvB,cAAc,CAAC,CAAC,CAAC,CAAC,CAClB,KAAK,CAAC,CAAC,SAAS,CAAC,CACjB,aAAa,CAAC,CAAC,qBAAqB,CAAC,CACrC,QAAQ,CAAC,CAAC,UAAU,CAAC,CACrB,SAAS,EAEX;YAAA,CAAC,QAAQ,CACP,IAAI,CAAC,OAAO,CACZ,QAAQ,CAAC,CAAC,OAAO,CAAC,CAClB,QAAQ,CAAC,CAAC,YAAY,CAAC,CACvB,cAAc,CAAC,CAAC,CAAC,CAAC,CAClB,KAAK,CAAC,CAAC,UAAU,CAAC,CAClB,aAAa,CAAC,CAAC,sBAAsB,CAAC,CACtC,UAAU,CAAC,CAAC,SAAS,CAAC,EAE1B;UAAA,EAAE,GAAG,CAAC,CACP,CAAC,CAAC,CAAC,CACF,CAAC,QAAQ,CACP,IAAI,CAAC,OAAO,CACZ,QAAQ,CAAC,CAAC,OAAO,CAAC,CAClB,QAAQ,CAAC,CAAC,YAAY,CAAC,CACvB,cAAc,CAAC,CAAC,CAAC,CAAC;QAClB,kEAAkE;QAClE,+DAA+D;QAC/D,+DAA+D;QAC/D,gEAAgE;QAChE,2DAA2D;QAC3D,YAAY,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,EAAE,IAAI,SAAS,CAAC,CACxD,SAAS,EACT,CACH,CACD;QAAA,CAAC,GAAG,CAAC,SAAS,CAAC,oEAAoE,CACjF;UAAA,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,kBAAkB,CAAC,CAC5D;YAAA,CAAC,UAAU,CACb;UAAA,EAAE,MAAM,CACR;UAAA,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAC/D;YAAA,CAAC,UAAU,CACb;UAAA,EAAE,MAAM,CACV;QAAA,EAAE,GAAG,CACP;MAAA,EAAE,cAAc,CAClB;IAAA,EAAE,OAAO,CAAC,CACX,CAAA;AACH,CAAC;AAED,cAAc,CAAC,WAAW,GAAG,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
3
|
+
export declare const Dialog: React.FC<DialogPrimitive.DialogProps>;
|
|
4
|
+
export declare const DialogTrigger: React.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
5
|
+
export declare const DialogPortal: React.FC<DialogPrimitive.DialogPortalProps>;
|
|
6
|
+
export declare const DialogClose: React.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
|
|
7
|
+
export declare const DialogOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
8
|
+
export declare const DialogContent: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
9
|
+
export declare const DialogHeader: {
|
|
10
|
+
({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.ReactElement;
|
|
11
|
+
displayName: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const DialogFooter: {
|
|
14
|
+
({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.ReactElement;
|
|
15
|
+
displayName: string;
|
|
16
|
+
};
|
|
17
|
+
export declare const DialogTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
|
|
18
|
+
export declare const DialogDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
|
|
19
|
+
//# sourceMappingURL=dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/components/dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAA;AAIzD,eAAO,MAAM,MAAM,uCAAuB,CAAA;AAC1C,eAAO,MAAM,aAAa,8GAA0B,CAAA;AACpD,eAAO,MAAM,YAAY,6CAAyB,CAAA;AAClD,eAAO,MAAM,WAAW,4GAAwB,CAAA;AAEhD,eAAO,MAAM,aAAa,8JAYxB,CAAA;AAGF,eAAO,MAAM,aAAa,8JAqBxB,CAAA;AAGF,eAAO,MAAM,YAAY;8BAGtB,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG,KAAK,CAAC,YAAY;;CAK3D,CAAA;AAGD,eAAO,MAAM,YAAY;8BAGtB,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG,KAAK,CAAC,YAAY;;CAK3D,CAAA;AAGD,eAAO,MAAM,WAAW,oKAStB,CAAA;AAGF,eAAO,MAAM,iBAAiB,8KAS5B,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
3
|
+
import { X } from 'lucide-react';
|
|
4
|
+
import { cn } from '../lib/utils.js';
|
|
5
|
+
export const Dialog = DialogPrimitive.Root;
|
|
6
|
+
export const DialogTrigger = DialogPrimitive.Trigger;
|
|
7
|
+
export const DialogPortal = DialogPrimitive.Portal;
|
|
8
|
+
export const DialogClose = DialogPrimitive.Close;
|
|
9
|
+
export const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (<DialogPrimitive.Overlay ref={ref} className={cn('fixed inset-0 z-50 bg-black/60 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', className)} {...props}/>));
|
|
10
|
+
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
11
|
+
export const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => (<DialogPortal>
|
|
12
|
+
<DialogOverlay />
|
|
13
|
+
<DialogPrimitive.Content ref={ref} className={cn('fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 sm:rounded-lg', className)} {...props}>
|
|
14
|
+
{children}
|
|
15
|
+
<DialogPrimitive.Close className="absolute right-4 top-4 cursor-pointer rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
|
16
|
+
<X className="h-4 w-4"/>
|
|
17
|
+
<span className="sr-only">Close</span>
|
|
18
|
+
</DialogPrimitive.Close>
|
|
19
|
+
</DialogPrimitive.Content>
|
|
20
|
+
</DialogPortal>));
|
|
21
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
22
|
+
export const DialogHeader = ({ className, ...props }) => (<div className={cn('flex flex-col gap-1.5 text-center sm:text-left', className)} {...props}/>);
|
|
23
|
+
DialogHeader.displayName = 'DialogHeader';
|
|
24
|
+
export const DialogFooter = ({ className, ...props }) => (<div className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-2', className)} {...props}/>);
|
|
25
|
+
DialogFooter.displayName = 'DialogFooter';
|
|
26
|
+
export const DialogTitle = React.forwardRef(({ className, ...props }, ref) => (<DialogPrimitive.Title ref={ref} className={cn('text-lg font-semibold leading-none tracking-tight', className)} {...props}/>));
|
|
27
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
28
|
+
export const DialogDescription = React.forwardRef(({ className, ...props }, ref) => (<DialogPrimitive.Description ref={ref} className={cn('text-sm text-muted-foreground', className)} {...props}/>));
|
|
29
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
30
|
+
//# sourceMappingURL=dialog.jsx.map
|