@craftzbay/ui 0.9.0 → 0.11.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 +82 -10
- package/dist-lib/__tests__/helpers/color.d.ts +9 -0
- package/dist-lib/__tests__/helpers/theme.d.ts +18 -0
- package/dist-lib/components/ui/Accordion.js +71 -0
- package/dist-lib/components/ui/Accordion.js.map +1 -0
- package/dist-lib/components/ui/Alert.d.ts +17 -1
- package/dist-lib/components/ui/Alert.js +79 -0
- package/dist-lib/components/ui/Alert.js.map +1 -0
- package/dist-lib/components/ui/Avatar.d.ts +3 -3
- package/dist-lib/components/ui/Avatar.js +94 -0
- package/dist-lib/components/ui/Avatar.js.map +1 -0
- package/dist-lib/components/ui/Badge.d.ts +4 -2
- package/dist-lib/components/ui/Badge.js +76 -0
- package/dist-lib/components/ui/Badge.js.map +1 -0
- package/dist-lib/components/ui/Breadcrumbs.d.ts +2 -0
- package/dist-lib/components/ui/Breadcrumbs.js +52 -0
- package/dist-lib/components/ui/Breadcrumbs.js.map +1 -0
- package/dist-lib/components/ui/Button.d.ts +6 -4
- package/dist-lib/components/ui/Button.js +131 -0
- package/dist-lib/components/ui/Button.js.map +1 -0
- package/dist-lib/components/ui/Calendar.d.ts +7 -1
- package/dist-lib/components/ui/Calendar.js +139 -0
- package/dist-lib/components/ui/Calendar.js.map +1 -0
- package/dist-lib/components/ui/Card.d.ts +3 -1
- package/dist-lib/components/ui/Card.js +97 -0
- package/dist-lib/components/ui/Card.js.map +1 -0
- package/dist-lib/components/ui/Carousel.d.ts +11 -7
- package/dist-lib/components/ui/Carousel.js +174 -0
- package/dist-lib/components/ui/Carousel.js.map +1 -0
- package/dist-lib/components/ui/Chart.d.ts +68 -7
- package/dist-lib/components/ui/Chart.js +487 -0
- package/dist-lib/components/ui/Chart.js.map +1 -0
- package/dist-lib/components/ui/Checkbox.js +70 -0
- package/dist-lib/components/ui/Checkbox.js.map +1 -0
- package/dist-lib/components/ui/Combobox.d.ts +9 -0
- package/dist-lib/components/ui/Combobox.js +195 -0
- package/dist-lib/components/ui/Combobox.js.map +1 -0
- package/dist-lib/components/ui/CommandPalette.d.ts +9 -6
- package/dist-lib/components/ui/CommandPalette.js +179 -0
- package/dist-lib/components/ui/CommandPalette.js.map +1 -0
- package/dist-lib/components/ui/ContextMenu.d.ts +7 -2
- package/dist-lib/components/ui/ContextMenu.js +165 -0
- package/dist-lib/components/ui/ContextMenu.js.map +1 -0
- package/dist-lib/components/ui/DataGrid.d.ts +17 -4
- package/dist-lib/components/ui/DataGrid.js +99 -0
- package/dist-lib/components/ui/DataGrid.js.map +1 -0
- package/dist-lib/components/ui/DatePicker.d.ts +16 -13
- package/dist-lib/components/ui/DatePicker.js +193 -0
- package/dist-lib/components/ui/DatePicker.js.map +1 -0
- package/dist-lib/components/ui/DesignSystemProvider.d.ts +102 -41
- package/dist-lib/components/ui/DesignSystemProvider.js +135 -0
- package/dist-lib/components/ui/DesignSystemProvider.js.map +1 -0
- package/dist-lib/components/ui/Dialog.d.ts +19 -4
- package/dist-lib/components/ui/Dialog.js +165 -0
- package/dist-lib/components/ui/Dialog.js.map +1 -0
- package/dist-lib/components/ui/Drawer.d.ts +23 -2
- package/dist-lib/components/ui/Drawer.js +132 -0
- package/dist-lib/components/ui/Drawer.js.map +1 -0
- package/dist-lib/components/ui/DropdownMenu.js +169 -0
- package/dist-lib/components/ui/DropdownMenu.js.map +1 -0
- package/dist-lib/components/ui/EmptyState.d.ts +2 -0
- package/dist-lib/components/ui/EmptyState.js +46 -0
- package/dist-lib/components/ui/EmptyState.js.map +1 -0
- package/dist-lib/components/ui/ErrorState.d.ts +13 -2
- package/dist-lib/components/ui/ErrorState.js +69 -0
- package/dist-lib/components/ui/ErrorState.js.map +1 -0
- package/dist-lib/components/ui/FileUpload.d.ts +3 -0
- package/dist-lib/components/ui/FileUpload.js +111 -0
- package/dist-lib/components/ui/FileUpload.js.map +1 -0
- package/dist-lib/components/ui/Form.d.ts +16 -2
- package/dist-lib/components/ui/Form.js +131 -0
- package/dist-lib/components/ui/Form.js.map +1 -0
- package/dist-lib/components/ui/Icon.d.ts +1 -1
- package/dist-lib/components/ui/Icon.js +32 -0
- package/dist-lib/components/ui/Icon.js.map +1 -0
- package/dist-lib/components/ui/IconButton.d.ts +3 -3
- package/dist-lib/components/ui/IconButton.js +64 -0
- package/dist-lib/components/ui/IconButton.js.map +1 -0
- package/dist-lib/components/ui/Input.d.ts +9 -4
- package/dist-lib/components/ui/Input.js +149 -0
- package/dist-lib/components/ui/Input.js.map +1 -0
- package/dist-lib/components/ui/Kbd.js +24 -0
- package/dist-lib/components/ui/Kbd.js.map +1 -0
- package/dist-lib/components/ui/MultiSelect.d.ts +3 -1
- package/dist-lib/components/ui/MultiSelect.js +210 -0
- package/dist-lib/components/ui/MultiSelect.js.map +1 -0
- package/dist-lib/components/ui/Pagination.d.ts +23 -0
- package/dist-lib/components/ui/Pagination.js +153 -0
- package/dist-lib/components/ui/Pagination.js.map +1 -0
- package/dist-lib/components/ui/Popover.js +35 -0
- package/dist-lib/components/ui/Popover.js.map +1 -0
- package/dist-lib/components/ui/Progress.d.ts +3 -3
- package/dist-lib/components/ui/Progress.js +100 -0
- package/dist-lib/components/ui/Progress.js.map +1 -0
- package/dist-lib/components/ui/RadioGroup.d.ts +1 -1
- package/dist-lib/components/ui/RadioGroup.js +81 -0
- package/dist-lib/components/ui/RadioGroup.js.map +1 -0
- package/dist-lib/components/ui/RelativeTime.d.ts +19 -0
- package/dist-lib/components/ui/RelativeTime.js +31 -0
- package/dist-lib/components/ui/RelativeTime.js.map +1 -0
- package/dist-lib/components/ui/ScrollArea.d.ts +9 -1
- package/dist-lib/components/ui/ScrollArea.js +60 -0
- package/dist-lib/components/ui/ScrollArea.js.map +1 -0
- package/dist-lib/components/ui/Select.d.ts +6 -1
- package/dist-lib/components/ui/Select.js +139 -0
- package/dist-lib/components/ui/Select.js.map +1 -0
- package/dist-lib/components/ui/Separator.js +26 -0
- package/dist-lib/components/ui/Separator.js.map +1 -0
- package/dist-lib/components/ui/Sheet.d.ts +10 -1
- package/dist-lib/components/ui/Sheet.js +136 -0
- package/dist-lib/components/ui/Sheet.js.map +1 -0
- package/dist-lib/components/ui/Sidebar.d.ts +29 -14
- package/dist-lib/components/ui/Sidebar.js +212 -0
- package/dist-lib/components/ui/Sidebar.js.map +1 -0
- package/dist-lib/components/ui/Skeleton.d.ts +13 -2
- package/dist-lib/components/ui/Skeleton.js +29 -0
- package/dist-lib/components/ui/Skeleton.js.map +1 -0
- package/dist-lib/components/ui/Slider.js +64 -0
- package/dist-lib/components/ui/Slider.js.map +1 -0
- package/dist-lib/components/ui/Snackbar.d.ts +1 -1
- package/dist-lib/components/ui/Snackbar.js +57 -0
- package/dist-lib/components/ui/Snackbar.js.map +1 -0
- package/dist-lib/components/ui/Spinner.js +54 -0
- package/dist-lib/components/ui/Spinner.js.map +1 -0
- package/dist-lib/components/ui/Stepper.d.ts +6 -0
- package/dist-lib/components/ui/Stepper.js +111 -0
- package/dist-lib/components/ui/Stepper.js.map +1 -0
- package/dist-lib/components/ui/Switch.js +80 -0
- package/dist-lib/components/ui/Switch.js.map +1 -0
- package/dist-lib/components/ui/Table.d.ts +41 -5
- package/dist-lib/components/ui/Table.js +179 -0
- package/dist-lib/components/ui/Table.js.map +1 -0
- package/dist-lib/components/ui/Tabs.d.ts +1 -1
- package/dist-lib/components/ui/Tabs.js +91 -0
- package/dist-lib/components/ui/Tabs.js.map +1 -0
- package/dist-lib/components/ui/TagInput.d.ts +17 -2
- package/dist-lib/components/ui/TagInput.js +111 -0
- package/dist-lib/components/ui/TagInput.js.map +1 -0
- package/dist-lib/components/ui/Textarea.js +88 -0
- package/dist-lib/components/ui/Textarea.js.map +1 -0
- package/dist-lib/components/ui/Timeline.d.ts +16 -6
- package/dist-lib/components/ui/Timeline.js +56 -0
- package/dist-lib/components/ui/Timeline.js.map +1 -0
- package/dist-lib/components/ui/Toast.d.ts +1 -1
- package/dist-lib/components/ui/Toast.js +158 -0
- package/dist-lib/components/ui/Toast.js.map +1 -0
- package/dist-lib/components/ui/Tooltip.d.ts +4 -1
- package/dist-lib/components/ui/Tooltip.js +60 -0
- package/dist-lib/components/ui/Tooltip.js.map +1 -0
- package/dist-lib/components/ui/TopNav.d.ts +7 -3
- package/dist-lib/components/ui/TopNav.js +62 -0
- package/dist-lib/components/ui/TopNav.js.map +1 -0
- package/dist-lib/components/ui/Tree.d.ts +34 -7
- package/dist-lib/components/ui/Tree.js +170 -0
- package/dist-lib/components/ui/Tree.js.map +1 -0
- package/dist-lib/hooks/use-debounce.d.ts +19 -0
- package/dist-lib/hooks/use-debounce.js +36 -0
- package/dist-lib/hooks/use-debounce.js.map +1 -0
- package/dist-lib/hooks/use-delayed-loading.d.ts +21 -0
- package/dist-lib/hooks/use-delayed-loading.js +20 -0
- package/dist-lib/hooks/use-delayed-loading.js.map +1 -0
- package/dist-lib/hooks/use-field-ids.d.ts +30 -0
- package/dist-lib/hooks/use-field-ids.js +18 -0
- package/dist-lib/hooks/use-field-ids.js.map +1 -0
- package/dist-lib/hooks/use-media-query.d.ts +3 -1
- package/dist-lib/hooks/use-media-query.js +22 -0
- package/dist-lib/hooks/use-media-query.js.map +1 -0
- package/dist-lib/hooks/use-modifier-key.d.ts +13 -0
- package/dist-lib/hooks/use-modifier-key.js +19 -0
- package/dist-lib/hooks/use-modifier-key.js.map +1 -0
- package/dist-lib/hooks/use-strings.d.ts +5 -0
- package/dist-lib/hooks/use-strings.js +12 -0
- package/dist-lib/hooks/use-strings.js.map +1 -0
- package/dist-lib/hooks/use-toast.d.ts +7 -2
- package/dist-lib/hooks/use-toast.js +67 -0
- package/dist-lib/hooks/use-toast.js.map +1 -0
- package/dist-lib/icon.d.ts +8 -0
- package/dist-lib/icon.js +7 -0
- package/dist-lib/icon.js.map +1 -0
- package/dist-lib/icons/index.d.ts +80 -88
- package/dist-lib/icons/index.js +163 -0
- package/dist-lib/icons/index.js.map +1 -0
- package/dist-lib/illustrations/index.d.ts +1 -0
- package/dist-lib/illustrations/index.js +114 -0
- package/dist-lib/illustrations/index.js.map +1 -0
- package/dist-lib/index.d.ts +68 -59
- package/dist-lib/index.js +288 -4530
- package/dist-lib/index.js.map +1 -1
- package/dist-lib/lib/format.d.ts +65 -0
- package/dist-lib/lib/format.js +95 -0
- package/dist-lib/lib/format.js.map +1 -0
- package/dist-lib/lib/return-focus.d.ts +11 -0
- package/dist-lib/lib/return-focus.js +12 -0
- package/dist-lib/lib/return-focus.js.map +1 -0
- package/dist-lib/lib/strings.d.ts +190 -0
- package/dist-lib/lib/strings.js +141 -0
- package/dist-lib/lib/strings.js.map +1 -0
- package/dist-lib/lib/strings.mn.d.ts +3 -0
- package/dist-lib/lib/strings.mn.js +115 -0
- package/dist-lib/lib/strings.mn.js.map +1 -0
- package/dist-lib/lib/utils.d.ts +0 -1
- package/dist-lib/lib/utils.js +10 -0
- package/dist-lib/lib/utils.js.map +1 -0
- package/dist-lib/styles.css +1 -1
- package/dist-lib/theme.css +840 -0
- package/package.json +38 -8
- package/dist-lib/index.cjs +0 -8
- package/dist-lib/index.cjs.map +0 -1
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as l, jsx as a } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef as u } from "react";
|
|
4
|
+
import * as t from "@radix-ui/react-context-menu";
|
|
5
|
+
import { Check as m, Circle as x, ChevronRight as p } from "../../icons/index.js";
|
|
6
|
+
import { cn as r } from "../../lib/utils.js";
|
|
7
|
+
const w = t.Root, T = t.Trigger, j = t.Group, C = t.Portal, G = t.Sub, L = t.RadioGroup, i = r(
|
|
8
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-foreground outline-none",
|
|
9
|
+
"data-[highlighted]:bg-background-muted data-[highlighted]:text-foreground",
|
|
10
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
11
|
+
"transition-colors duration-[var(--duration-fast)]"
|
|
12
|
+
), g = u(function({ className: e, inset: n, children: o, ...d }, c) {
|
|
13
|
+
return /* @__PURE__ */ l(
|
|
14
|
+
t.SubTrigger,
|
|
15
|
+
{
|
|
16
|
+
ref: c,
|
|
17
|
+
className: r(
|
|
18
|
+
i,
|
|
19
|
+
"data-[state=open]:bg-background-muted",
|
|
20
|
+
n && "pl-8",
|
|
21
|
+
e
|
|
22
|
+
),
|
|
23
|
+
...d,
|
|
24
|
+
children: [
|
|
25
|
+
o,
|
|
26
|
+
/* @__PURE__ */ a(p, { className: "text-foreground-subtle ml-auto size-4", "aria-hidden": !0 })
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
g.displayName = "ContextMenuSubTrigger";
|
|
32
|
+
const f = u(function({ className: e, ...n }, o) {
|
|
33
|
+
return /* @__PURE__ */ a(
|
|
34
|
+
t.SubContent,
|
|
35
|
+
{
|
|
36
|
+
ref: o,
|
|
37
|
+
className: r(
|
|
38
|
+
"border-border bg-popover text-popover-foreground z-[var(--z-popover)] min-w-[8rem] overflow-hidden rounded-lg border p-1 shadow-md",
|
|
39
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
40
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
41
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
42
|
+
e
|
|
43
|
+
),
|
|
44
|
+
...n
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
f.displayName = "ContextMenuSubContent";
|
|
49
|
+
const b = u(function({ className: e, ...n }, o) {
|
|
50
|
+
return /* @__PURE__ */ a(C, { children: /* @__PURE__ */ a(
|
|
51
|
+
t.Content,
|
|
52
|
+
{
|
|
53
|
+
ref: o,
|
|
54
|
+
className: r(
|
|
55
|
+
"border-border bg-popover text-popover-foreground z-[var(--z-popover)] min-w-[12rem] overflow-hidden rounded-lg border p-1 shadow-md",
|
|
56
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
57
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
58
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
59
|
+
e
|
|
60
|
+
),
|
|
61
|
+
...n
|
|
62
|
+
}
|
|
63
|
+
) });
|
|
64
|
+
});
|
|
65
|
+
b.displayName = "ContextMenuContent";
|
|
66
|
+
const h = u(function({ className: e, inset: n, destructive: o, ...d }, c) {
|
|
67
|
+
return /* @__PURE__ */ a(
|
|
68
|
+
t.Item,
|
|
69
|
+
{
|
|
70
|
+
ref: c,
|
|
71
|
+
className: r(
|
|
72
|
+
i,
|
|
73
|
+
n && "pl-8",
|
|
74
|
+
o && "text-danger-text data-[highlighted]:bg-danger-soft data-[highlighted]:text-danger-text",
|
|
75
|
+
e
|
|
76
|
+
),
|
|
77
|
+
...d
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
h.displayName = "ContextMenuItem";
|
|
82
|
+
const M = u(function({ className: e, children: n, ...o }, d) {
|
|
83
|
+
return /* @__PURE__ */ l(
|
|
84
|
+
t.CheckboxItem,
|
|
85
|
+
{
|
|
86
|
+
ref: d,
|
|
87
|
+
className: r(i, "pl-8", e),
|
|
88
|
+
...o,
|
|
89
|
+
children: [
|
|
90
|
+
/* @__PURE__ */ a("span", { className: "absolute left-2 flex size-4 items-center justify-center", children: /* @__PURE__ */ a(t.ItemIndicator, { children: /* @__PURE__ */ a(m, { className: "text-accent size-4", "aria-hidden": !0 }) }) }),
|
|
91
|
+
n
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
});
|
|
96
|
+
M.displayName = "ContextMenuCheckboxItem";
|
|
97
|
+
const N = u(function({ className: e, children: n, ...o }, d) {
|
|
98
|
+
return /* @__PURE__ */ l(
|
|
99
|
+
t.RadioItem,
|
|
100
|
+
{
|
|
101
|
+
ref: d,
|
|
102
|
+
className: r(i, "pl-8", e),
|
|
103
|
+
...o,
|
|
104
|
+
children: [
|
|
105
|
+
/* @__PURE__ */ a("span", { className: "absolute left-2 flex size-4 items-center justify-center", children: /* @__PURE__ */ a(t.ItemIndicator, { children: /* @__PURE__ */ a(x, { className: "fill-accent text-accent size-2", "aria-hidden": !0 }) }) }),
|
|
106
|
+
n
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
N.displayName = "ContextMenuRadioItem";
|
|
112
|
+
const I = u(function({ className: e, inset: n, ...o }, d) {
|
|
113
|
+
return /* @__PURE__ */ a(
|
|
114
|
+
t.Label,
|
|
115
|
+
{
|
|
116
|
+
ref: d,
|
|
117
|
+
className: r(
|
|
118
|
+
"text-foreground-subtle px-2 py-1.5 text-xs font-medium",
|
|
119
|
+
n && "pl-8",
|
|
120
|
+
e
|
|
121
|
+
),
|
|
122
|
+
...o
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
I.displayName = "ContextMenuLabel";
|
|
127
|
+
const S = u(function({ className: e, ...n }, o) {
|
|
128
|
+
return /* @__PURE__ */ a(
|
|
129
|
+
t.Separator,
|
|
130
|
+
{
|
|
131
|
+
ref: o,
|
|
132
|
+
className: r("bg-border -mx-1 my-1 h-px", e),
|
|
133
|
+
...n
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
S.displayName = "ContextMenuSeparator";
|
|
138
|
+
function v({ className: s, ...e }) {
|
|
139
|
+
return /* @__PURE__ */ a(
|
|
140
|
+
"span",
|
|
141
|
+
{
|
|
142
|
+
className: r("text-foreground-subtle ml-auto font-mono text-xs tracking-widest", s),
|
|
143
|
+
...e
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
v.displayName = "ContextMenuShortcut";
|
|
148
|
+
export {
|
|
149
|
+
w as ContextMenu,
|
|
150
|
+
M as ContextMenuCheckboxItem,
|
|
151
|
+
b as ContextMenuContent,
|
|
152
|
+
j as ContextMenuGroup,
|
|
153
|
+
h as ContextMenuItem,
|
|
154
|
+
I as ContextMenuLabel,
|
|
155
|
+
C as ContextMenuPortal,
|
|
156
|
+
L as ContextMenuRadioGroup,
|
|
157
|
+
N as ContextMenuRadioItem,
|
|
158
|
+
S as ContextMenuSeparator,
|
|
159
|
+
v as ContextMenuShortcut,
|
|
160
|
+
G as ContextMenuSub,
|
|
161
|
+
f as ContextMenuSubContent,
|
|
162
|
+
g as ContextMenuSubTrigger,
|
|
163
|
+
T as ContextMenuTrigger
|
|
164
|
+
};
|
|
165
|
+
//# sourceMappingURL=ContextMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextMenu.js","sources":["../../../src/components/ui/ContextMenu.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type HTMLAttributes,\n} from 'react';\nimport * as ContextMenuPrimitive from '@radix-ui/react-context-menu';\nimport { Check, ChevronRight, Circle } from '@/icons';\nimport { cn } from '@/lib/utils';\n\n/**\n * Right-click (or two-finger tap) menu. Visual surface mirrors DropdownMenu\n * for consistency.\n *\n * @example\n * <ContextMenu>\n * <ContextMenuTrigger asChild>\n * <div className=\"grid h-32 place-items-center rounded-lg border border-border\">\n * Right-click me\n * </div>\n * </ContextMenuTrigger>\n * <ContextMenuContent>\n * <ContextMenuItem>Open</ContextMenuItem>\n * <ContextMenuSeparator />\n * <ContextMenuItem destructive>Delete</ContextMenuItem>\n * </ContextMenuContent>\n * </ContextMenu>\n *\n * @do Mirror DropdownMenu items for the same surface — users expect the same\n * operations from both.\n * @dont Hide critical actions behind right-click — they must also exist in\n * a visible button or menu.\n */\nexport const ContextMenu = ContextMenuPrimitive.Root;\nexport const ContextMenuTrigger = ContextMenuPrimitive.Trigger;\nexport const ContextMenuGroup = ContextMenuPrimitive.Group;\nexport const ContextMenuPortal = ContextMenuPrimitive.Portal;\nexport const ContextMenuSub = ContextMenuPrimitive.Sub;\nexport const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;\n\nconst itemClasses = cn(\n 'relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-foreground outline-none',\n 'data-[highlighted]:bg-background-muted data-[highlighted]:text-foreground',\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n 'transition-colors duration-[var(--duration-fast)]',\n);\n\nexport const ContextMenuSubTrigger = forwardRef<\n ElementRef<typeof ContextMenuPrimitive.SubTrigger>,\n ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & { inset?: boolean }\n>(function ContextMenuSubTrigger({ className, inset, children, ...props }, ref) {\n return (\n <ContextMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n itemClasses,\n 'data-[state=open]:bg-background-muted',\n inset && 'pl-8',\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRight className=\"text-foreground-subtle ml-auto size-4\" aria-hidden />\n </ContextMenuPrimitive.SubTrigger>\n );\n});\nContextMenuSubTrigger.displayName = 'ContextMenuSubTrigger';\n\nexport const ContextMenuSubContent = forwardRef<\n ElementRef<typeof ContextMenuPrimitive.SubContent>,\n ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubContent>\n>(function ContextMenuSubContent({ className, ...props }, ref) {\n return (\n <ContextMenuPrimitive.SubContent\n ref={ref}\n className={cn(\n 'border-border bg-popover text-popover-foreground z-[var(--z-popover)] min-w-[8rem] overflow-hidden rounded-lg border p-1 shadow-md',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n className,\n )}\n {...props}\n />\n );\n});\nContextMenuSubContent.displayName = 'ContextMenuSubContent';\n\nexport const ContextMenuContent = forwardRef<\n ElementRef<typeof ContextMenuPrimitive.Content>,\n ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>\n>(function ContextMenuContent({ className, ...props }, ref) {\n return (\n <ContextMenuPortal>\n <ContextMenuPrimitive.Content\n ref={ref}\n className={cn(\n 'border-border bg-popover text-popover-foreground z-[var(--z-popover)] min-w-[12rem] overflow-hidden rounded-lg border p-1 shadow-md',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n className,\n )}\n {...props}\n />\n </ContextMenuPortal>\n );\n});\nContextMenuContent.displayName = 'ContextMenuContent';\n\nexport const ContextMenuItem = forwardRef<\n ElementRef<typeof ContextMenuPrimitive.Item>,\n ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {\n inset?: boolean;\n destructive?: boolean;\n }\n>(function ContextMenuItem({ className, inset, destructive, ...props }, ref) {\n return (\n <ContextMenuPrimitive.Item\n ref={ref}\n className={cn(\n itemClasses,\n inset && 'pl-8',\n destructive &&\n 'text-danger-text data-[highlighted]:bg-danger-soft data-[highlighted]:text-danger-text',\n className,\n )}\n {...props}\n />\n );\n});\nContextMenuItem.displayName = 'ContextMenuItem';\n\nexport const ContextMenuCheckboxItem = forwardRef<\n ElementRef<typeof ContextMenuPrimitive.CheckboxItem>,\n ComponentPropsWithoutRef<typeof ContextMenuPrimitive.CheckboxItem>\n>(function ContextMenuCheckboxItem({ className, children, ...props }, ref) {\n return (\n <ContextMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(itemClasses, 'pl-8', className)}\n {...props}\n >\n <span className=\"absolute left-2 flex size-4 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <Check className=\"text-accent size-4\" aria-hidden />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.CheckboxItem>\n );\n});\nContextMenuCheckboxItem.displayName = 'ContextMenuCheckboxItem';\n\nexport const ContextMenuRadioItem = forwardRef<\n ElementRef<typeof ContextMenuPrimitive.RadioItem>,\n ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioItem>\n>(function ContextMenuRadioItem({ className, children, ...props }, ref) {\n return (\n <ContextMenuPrimitive.RadioItem\n ref={ref}\n className={cn(itemClasses, 'pl-8', className)}\n {...props}\n >\n <span className=\"absolute left-2 flex size-4 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <Circle className=\"fill-accent text-accent size-2\" aria-hidden />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.RadioItem>\n );\n});\nContextMenuRadioItem.displayName = 'ContextMenuRadioItem';\n\nexport const ContextMenuLabel = forwardRef<\n ElementRef<typeof ContextMenuPrimitive.Label>,\n ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & { inset?: boolean }\n>(function ContextMenuLabel({ className, inset, ...props }, ref) {\n return (\n <ContextMenuPrimitive.Label\n ref={ref}\n className={cn(\n 'text-foreground-subtle px-2 py-1.5 text-xs font-medium',\n inset && 'pl-8',\n className,\n )}\n {...props}\n />\n );\n});\nContextMenuLabel.displayName = 'ContextMenuLabel';\n\nexport const ContextMenuSeparator = forwardRef<\n ElementRef<typeof ContextMenuPrimitive.Separator>,\n ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>\n>(function ContextMenuSeparator({ className, ...props }, ref) {\n return (\n <ContextMenuPrimitive.Separator\n ref={ref}\n className={cn('bg-border -mx-1 my-1 h-px', className)}\n {...props}\n />\n );\n});\nContextMenuSeparator.displayName = 'ContextMenuSeparator';\n\nexport function ContextMenuShortcut({ className, ...props }: HTMLAttributes<HTMLSpanElement>) {\n return (\n <span\n className={cn('text-foreground-subtle ml-auto font-mono text-xs tracking-widest', className)}\n {...props}\n />\n );\n}\nContextMenuShortcut.displayName = 'ContextMenuShortcut';\n"],"names":["ContextMenu","ContextMenuPrimitive","ContextMenuTrigger","ContextMenuGroup","ContextMenuPortal","ContextMenuSub","ContextMenuRadioGroup","itemClasses","cn","ContextMenuSubTrigger","forwardRef","className","inset","children","props","ref","jsxs","jsx","ChevronRight","ContextMenuSubContent","ContextMenuContent","ContextMenuItem","destructive","ContextMenuCheckboxItem","Check","ContextMenuRadioItem","Circle","ContextMenuLabel","ContextMenuSeparator","ContextMenuShortcut"],"mappings":";;;;;;AAmCO,MAAMA,IAAcC,EAAqB,MACnCC,IAAqBD,EAAqB,SAC1CE,IAAmBF,EAAqB,OACxCG,IAAoBH,EAAqB,QACzCI,IAAiBJ,EAAqB,KACtCK,IAAwBL,EAAqB,YAEpDM,IAAcC;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEaC,IAAwBC,EAGnC,SAA+B,EAAE,WAAAC,GAAW,OAAAC,GAAO,UAAAC,GAAU,GAAGC,EAAA,GAASC,GAAK;AAC9E,SACE,gBAAAC;AAAA,IAACf,EAAqB;AAAA,IAArB;AAAA,MACC,KAAAc;AAAA,MACA,WAAWP;AAAA,QACTD;AAAA,QACA;AAAA,QACAK,KAAS;AAAA,QACTD;AAAA,MAAA;AAAA,MAED,GAAGG;AAAA,MAEH,UAAA;AAAA,QAAAD;AAAA,QACD,gBAAAI,EAACC,GAAA,EAAa,WAAU,yCAAwC,eAAW,GAAA,CAAC;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGlF,CAAC;AACDT,EAAsB,cAAc;AAE7B,MAAMU,IAAwBT,EAGnC,SAA+B,EAAE,WAAAC,GAAW,GAAGG,EAAA,GAASC,GAAK;AAC7D,SACE,gBAAAE;AAAA,IAAChB,EAAqB;AAAA,IAArB;AAAA,MACC,KAAAc;AAAA,MACA,WAAWP;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAG;AAAA,MAAA;AAAA,MAED,GAAGG;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDK,EAAsB,cAAc;AAE7B,MAAMC,IAAqBV,EAGhC,SAA4B,EAAE,WAAAC,GAAW,GAAGG,EAAA,GAASC,GAAK;AAC1D,2BACGX,GAAA,EACC,UAAA,gBAAAa;AAAA,IAAChB,EAAqB;AAAA,IAArB;AAAA,MACC,KAAAc;AAAA,MACA,WAAWP;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAG;AAAA,MAAA;AAAA,MAED,GAAGG;AAAA,IAAA;AAAA,EAAA,GAER;AAEJ,CAAC;AACDM,EAAmB,cAAc;AAE1B,MAAMC,IAAkBX,EAM7B,SAAyB,EAAE,WAAAC,GAAW,OAAAC,GAAO,aAAAU,GAAa,GAAGR,EAAA,GAASC,GAAK;AAC3E,SACE,gBAAAE;AAAA,IAAChB,EAAqB;AAAA,IAArB;AAAA,MACC,KAAAc;AAAA,MACA,WAAWP;AAAA,QACTD;AAAA,QACAK,KAAS;AAAA,QACTU,KACE;AAAA,QACFX;AAAA,MAAA;AAAA,MAED,GAAGG;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDO,EAAgB,cAAc;AAEvB,MAAME,IAA0Bb,EAGrC,SAAiC,EAAE,WAAAC,GAAW,UAAAE,GAAU,GAAGC,EAAA,GAASC,GAAK;AACzE,SACE,gBAAAC;AAAA,IAACf,EAAqB;AAAA,IAArB;AAAA,MACC,KAAAc;AAAA,MACA,WAAWP,EAAGD,GAAa,QAAQI,CAAS;AAAA,MAC3C,GAAGG;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAG,EAAC,QAAA,EAAK,WAAU,2DACd,UAAA,gBAAAA,EAAChB,EAAqB,eAArB,EACC,UAAA,gBAAAgB,EAACO,GAAA,EAAM,WAAU,sBAAqB,eAAW,GAAA,CAAC,GACpD,GACF;AAAA,QACCX;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP,CAAC;AACDU,EAAwB,cAAc;AAE/B,MAAME,IAAuBf,EAGlC,SAA8B,EAAE,WAAAC,GAAW,UAAAE,GAAU,GAAGC,EAAA,GAASC,GAAK;AACtE,SACE,gBAAAC;AAAA,IAACf,EAAqB;AAAA,IAArB;AAAA,MACC,KAAAc;AAAA,MACA,WAAWP,EAAGD,GAAa,QAAQI,CAAS;AAAA,MAC3C,GAAGG;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAG,EAAC,QAAA,EAAK,WAAU,2DACd,UAAA,gBAAAA,EAAChB,EAAqB,eAArB,EACC,UAAA,gBAAAgB,EAACS,GAAA,EAAO,WAAU,kCAAiC,eAAW,GAAA,CAAC,GACjE,GACF;AAAA,QACCb;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP,CAAC;AACDY,EAAqB,cAAc;AAE5B,MAAME,IAAmBjB,EAG9B,SAA0B,EAAE,WAAAC,GAAW,OAAAC,GAAO,GAAGE,EAAA,GAASC,GAAK;AAC/D,SACE,gBAAAE;AAAA,IAAChB,EAAqB;AAAA,IAArB;AAAA,MACC,KAAAc;AAAA,MACA,WAAWP;AAAA,QACT;AAAA,QACAI,KAAS;AAAA,QACTD;AAAA,MAAA;AAAA,MAED,GAAGG;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDa,EAAiB,cAAc;AAExB,MAAMC,IAAuBlB,EAGlC,SAA8B,EAAE,WAAAC,GAAW,GAAGG,EAAA,GAASC,GAAK;AAC5D,SACE,gBAAAE;AAAA,IAAChB,EAAqB;AAAA,IAArB;AAAA,MACC,KAAAc;AAAA,MACA,WAAWP,EAAG,6BAA6BG,CAAS;AAAA,MACnD,GAAGG;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDc,EAAqB,cAAc;AAE5B,SAASC,EAAoB,EAAE,WAAAlB,GAAW,GAAGG,KAA0C;AAC5F,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWT,EAAG,oEAAoEG,CAAS;AAAA,MAC1F,GAAGG;AAAA,IAAA;AAAA,EAAA;AAGV;AACAe,EAAoB,cAAc;"}
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
export interface DataGridColumn<TRow> {
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Stable key used for visibility, sort, and React lists. Autocompletes
|
|
5
|
+
* row fields; any string is allowed for computed columns (with `cell`).
|
|
6
|
+
*/
|
|
7
|
+
key: (keyof TRow & string) | (string & {});
|
|
5
8
|
/** Header label. */
|
|
6
9
|
header: ReactNode;
|
|
7
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Render the cell. Defaults to the value at `row[key]`: `Date` →
|
|
12
|
+
* `formatDate` (yyyy-MM-dd HH:mm), primitives as-is, other objects via
|
|
13
|
+
* `String()`.
|
|
14
|
+
*/
|
|
8
15
|
cell?: (row: TRow) => ReactNode;
|
|
9
16
|
/** Cell width — passed to `<col>` so the grid keeps shape during loading. */
|
|
10
17
|
width?: string;
|
|
@@ -36,6 +43,12 @@ export interface DataGridProps<TRow extends {
|
|
|
36
43
|
};
|
|
37
44
|
/** Empty-state node when no rows are visible. */
|
|
38
45
|
emptyState?: ReactNode;
|
|
46
|
+
/**
|
|
47
|
+
* Controlled column visibility: `{ [key]: boolean }` (missing = visible).
|
|
48
|
+
* Omit for internal state. At least one column always stays visible.
|
|
49
|
+
*/
|
|
50
|
+
columnVisibility?: Record<string, boolean>;
|
|
51
|
+
onColumnVisibilityChange?: (next: Record<string, boolean>) => void;
|
|
39
52
|
className?: string;
|
|
40
53
|
}
|
|
41
54
|
/**
|
|
@@ -63,4 +76,4 @@ export interface DataGridProps<TRow extends {
|
|
|
63
76
|
*/
|
|
64
77
|
export declare function DataGrid<TRow extends {
|
|
65
78
|
id: string | number;
|
|
66
|
-
}>({ columns, rows, loading, sort, onSortChange, filter, emptyState, className, }: DataGridProps<TRow>): import("react/jsx-runtime").JSX.Element;
|
|
79
|
+
}>({ columns, rows, loading, sort, onSortChange, filter, emptyState, columnVisibility, onColumnVisibilityChange, className, }: DataGridProps<TRow>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as d, jsx as r } from "react/jsx-runtime";
|
|
3
|
+
import { useState as M, useMemo as T, isValidElement as G } from "react";
|
|
4
|
+
import { Settings as C } from "../../icons/index.js";
|
|
5
|
+
import { cn as j } from "../../lib/utils.js";
|
|
6
|
+
import { formatDate as v } from "../../lib/format.js";
|
|
7
|
+
import { useStrings as I } from "../../hooks/use-strings.js";
|
|
8
|
+
import { DropdownMenu as H, DropdownMenuTrigger as R, DropdownMenuContent as B, DropdownMenuLabel as L, DropdownMenuSeparator as V, DropdownMenuCheckboxItem as A } from "./DropdownMenu.js";
|
|
9
|
+
import { IconButton as E } from "./IconButton.js";
|
|
10
|
+
import { Input as K } from "./Input.js";
|
|
11
|
+
import { Table as P, TableHeader as _, TableRow as m, TableSortHeader as $, TableHead as q, TableBody as z, TableCell as p } from "./Table.js";
|
|
12
|
+
import { Skeleton as F } from "./Skeleton.js";
|
|
13
|
+
function J(t, s) {
|
|
14
|
+
return t == null || t === "" ? /* @__PURE__ */ r("span", { "aria-label": s, className: "text-foreground-subtle", children: "—" }) : t instanceof Date ? v(t) : typeof t == "object" ? G(t) ? t : String(t) : t;
|
|
15
|
+
}
|
|
16
|
+
function ae({
|
|
17
|
+
columns: t,
|
|
18
|
+
rows: s,
|
|
19
|
+
loading: b,
|
|
20
|
+
sort: y,
|
|
21
|
+
onSortChange: u,
|
|
22
|
+
filter: o,
|
|
23
|
+
emptyState: k,
|
|
24
|
+
columnVisibility: f,
|
|
25
|
+
onColumnVisibilityChange: h,
|
|
26
|
+
className: x
|
|
27
|
+
}) {
|
|
28
|
+
const n = I(), [w, D] = M({}), c = f ?? w, g = (e) => c[e] !== !1, a = T(
|
|
29
|
+
() => t.filter((e) => c[e.key] !== !1),
|
|
30
|
+
[t, c]
|
|
31
|
+
), N = (e, l) => {
|
|
32
|
+
if (!l && a.length <= 1) return;
|
|
33
|
+
const i = { ...c, [e]: l };
|
|
34
|
+
f === void 0 && D(i), h == null || h(i);
|
|
35
|
+
}, S = () => b ? Array.from({ length: 5 }).map((e, l) => /* @__PURE__ */ r(m, { children: a.map((i) => /* @__PURE__ */ r(p, { children: /* @__PURE__ */ r(F, { variant: "text", className: "w-3/4" }) }, i.key)) }, `skel-${l}`)) : s.length === 0 ? /* @__PURE__ */ r(m, { children: /* @__PURE__ */ r(p, { colSpan: Math.max(1, a.length), className: "h-32 text-center", children: k ?? /* @__PURE__ */ r("span", { className: "text-foreground-subtle", children: n.dataGrid.empty }) }) }) : s.map((e) => /* @__PURE__ */ r(m, { children: a.map((l) => /* @__PURE__ */ r(p, { align: l.align ?? "left", children: l.cell ? l.cell(e) : J(e[l.key], n.dataGrid.emptyCell) }, l.key)) }, e.id));
|
|
36
|
+
return /* @__PURE__ */ d("div", { className: j("flex flex-col gap-3", x), children: [
|
|
37
|
+
/* @__PURE__ */ d("div", { className: "flex items-center justify-between gap-2", children: [
|
|
38
|
+
o ? /* @__PURE__ */ r(
|
|
39
|
+
K,
|
|
40
|
+
{
|
|
41
|
+
type: "search",
|
|
42
|
+
placeholder: o.placeholder ?? n.dataGrid.filterPlaceholder,
|
|
43
|
+
value: o.value,
|
|
44
|
+
onChange: (e) => o.onChange(e.target.value),
|
|
45
|
+
clearable: !0,
|
|
46
|
+
onClear: () => o.onChange(""),
|
|
47
|
+
className: "w-full max-w-sm",
|
|
48
|
+
hideLabel: !0,
|
|
49
|
+
label: n.dataGrid.filterRows
|
|
50
|
+
}
|
|
51
|
+
) : /* @__PURE__ */ r("div", {}),
|
|
52
|
+
/* @__PURE__ */ r("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ d(H, { children: [
|
|
53
|
+
/* @__PURE__ */ r(R, { asChild: !0, children: /* @__PURE__ */ r(
|
|
54
|
+
E,
|
|
55
|
+
{
|
|
56
|
+
"aria-label": n.dataGrid.columnVisibility,
|
|
57
|
+
icon: /* @__PURE__ */ r(C, {}),
|
|
58
|
+
variant: "outline"
|
|
59
|
+
}
|
|
60
|
+
) }),
|
|
61
|
+
/* @__PURE__ */ d(B, { children: [
|
|
62
|
+
/* @__PURE__ */ r(L, { children: n.dataGrid.columns }),
|
|
63
|
+
/* @__PURE__ */ r(V, {}),
|
|
64
|
+
t.map((e) => /* @__PURE__ */ r(
|
|
65
|
+
A,
|
|
66
|
+
{
|
|
67
|
+
checked: g(e.key),
|
|
68
|
+
disabled: g(e.key) && a.length <= 1,
|
|
69
|
+
onCheckedChange: (l) => N(e.key, l === !0),
|
|
70
|
+
children: e.header
|
|
71
|
+
},
|
|
72
|
+
e.key
|
|
73
|
+
))
|
|
74
|
+
] })
|
|
75
|
+
] }) })
|
|
76
|
+
] }),
|
|
77
|
+
/* @__PURE__ */ d(P, { containerClassName: "rounded-lg border border-border", children: [
|
|
78
|
+
/* @__PURE__ */ r("colgroup", { children: a.map((e) => /* @__PURE__ */ r("col", { style: e.width ? { width: e.width } : void 0 }, e.key)) }),
|
|
79
|
+
/* @__PURE__ */ r(_, { children: /* @__PURE__ */ r(m, { children: a.map(
|
|
80
|
+
(e) => e.sortable && u ? /* @__PURE__ */ r(
|
|
81
|
+
$,
|
|
82
|
+
{
|
|
83
|
+
align: e.align ?? "left",
|
|
84
|
+
sortKey: e.key,
|
|
85
|
+
currentSort: y ?? null,
|
|
86
|
+
onSortChange: (l, i) => u({ key: l, direction: i }),
|
|
87
|
+
children: e.header
|
|
88
|
+
},
|
|
89
|
+
e.key
|
|
90
|
+
) : /* @__PURE__ */ r(q, { align: e.align ?? "left", children: e.header }, e.key)
|
|
91
|
+
) }) }),
|
|
92
|
+
/* @__PURE__ */ r(z, { children: S() })
|
|
93
|
+
] })
|
|
94
|
+
] });
|
|
95
|
+
}
|
|
96
|
+
export {
|
|
97
|
+
ae as DataGrid
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=DataGrid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataGrid.js","sources":["../../../src/components/ui/DataGrid.tsx"],"sourcesContent":["'use client';\n\nimport { isValidElement, useMemo, useState, type ReactNode } from 'react';\nimport { Settings } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { formatDate } from '@/lib/format';\nimport { useStrings } from '@/hooks/use-strings';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from './DropdownMenu';\nimport { IconButton } from './IconButton';\nimport { Input } from './Input';\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n TableSortHeader,\n} from './Table';\nimport { Skeleton } from './Skeleton';\n\nexport interface DataGridColumn<TRow> {\n /**\n * Stable key used for visibility, sort, and React lists. Autocompletes\n * row fields; any string is allowed for computed columns (with `cell`).\n */\n key: (keyof TRow & string) | (string & {});\n /** Header label. */\n header: ReactNode;\n /**\n * Render the cell. Defaults to the value at `row[key]`: `Date` →\n * `formatDate` (yyyy-MM-dd HH:mm), primitives as-is, other objects via\n * `String()`.\n */\n cell?: (row: TRow) => ReactNode;\n /** Cell width — passed to `<col>` so the grid keeps shape during loading. */\n width?: string;\n /** Allow sorting on this column. */\n sortable?: boolean;\n /** Right-align numeric / monetary columns. */\n align?: 'left' | 'right';\n}\n\nexport interface DataGridProps<TRow extends { id: string | number }> {\n columns: DataGridColumn<TRow>[];\n rows: TRow[];\n loading?: boolean;\n /** Initial sort state. */\n sort?: { key: string; direction: 'asc' | 'desc' } | null;\n onSortChange?: (sort: { key: string; direction: 'asc' | 'desc' }) => void;\n /** Show a filter input row above the grid. */\n filter?: { value: string; onChange: (q: string) => void; placeholder?: string };\n /** Empty-state node when no rows are visible. */\n emptyState?: ReactNode;\n /**\n * Controlled column visibility: `{ [key]: boolean }` (missing = visible).\n * Omit for internal state. At least one column always stays visible.\n */\n columnVisibility?: Record<string, boolean>;\n onColumnVisibilityChange?: (next: Record<string, boolean>) => void;\n className?: string;\n}\n\n/** Default cell renderer for `row[key]` when no `cell` is given. */\nfunction renderValue(v: unknown, emptyLabel: string): ReactNode {\n if (v === null || v === undefined || v === '') {\n return (\n <span aria-label={emptyLabel} className=\"text-foreground-subtle\">\n —\n </span>\n );\n }\n if (v instanceof Date) return formatDate(v);\n if (typeof v === 'object') return isValidElement(v) ? v : String(v);\n return v as ReactNode;\n}\n\n/**\n * Composite grid built from `Table` + DropdownMenu + Input. Provides\n * column visibility toggle, an inline filter, sortable headers, and\n * loading / empty states.\n *\n * @example\n * <DataGrid\n * columns={[\n * { key: 'name', header: 'Name', sortable: true },\n * { key: 'status', header: 'Status', cell: r => <Badge tone={...}>{r.status}</Badge> },\n * { key: 'updatedAt', header: 'Updated', align: 'right' },\n * ]}\n * rows={rows}\n * filter={{ value: q, onChange: setQ }}\n * sort={sort}\n * onSortChange={setSort}\n * />\n *\n * @do Provide a meaningful empty state with a primary action when the grid\n * starts empty (no items at all, not just filtered out).\n * @dont Render thousands of rows synchronously — virtualise with `@tanstack/react-virtual`\n * and wrap with this component's headers as a shell.\n */\nexport function DataGrid<TRow extends { id: string | number }>({\n columns,\n rows,\n loading,\n sort,\n onSortChange,\n filter,\n emptyState,\n columnVisibility,\n onColumnVisibilityChange,\n className,\n}: DataGridProps<TRow>) {\n const strings = useStrings();\n const [internalVisibility, setInternalVisibility] = useState<Record<string, boolean>>({});\n const visibility = columnVisibility ?? internalVisibility;\n const isVisible = (key: string) => visibility[key] !== false;\n const visibleColumns = useMemo(\n () => columns.filter((c) => visibility[c.key] !== false),\n [columns, visibility],\n );\n const setColumnVisible = (key: string, visible: boolean) => {\n // Never let the user hide the last visible column — an empty grid has no\n // affordance to bring columns back.\n if (!visible && visibleColumns.length <= 1) return;\n const next = { ...visibility, [key]: visible };\n if (columnVisibility === undefined) setInternalVisibility(next);\n onColumnVisibilityChange?.(next);\n };\n\n const renderRows = () => {\n if (loading) {\n return Array.from({ length: 5 }).map((_, i) => (\n <TableRow key={`skel-${i}`}>\n {visibleColumns.map((c) => (\n <TableCell key={c.key}>\n <Skeleton variant=\"text\" className=\"w-3/4\" />\n </TableCell>\n ))}\n </TableRow>\n ));\n }\n if (rows.length === 0) {\n return (\n <TableRow>\n <TableCell colSpan={Math.max(1, visibleColumns.length)} className=\"h-32 text-center\">\n {emptyState ?? <span className=\"text-foreground-subtle\">{strings.dataGrid.empty}</span>}\n </TableCell>\n </TableRow>\n );\n }\n return rows.map((row) => (\n <TableRow key={row.id}>\n {visibleColumns.map((c) => (\n <TableCell key={c.key} align={c.align ?? 'left'}>\n {c.cell\n ? c.cell(row)\n : renderValue((row as Record<string, unknown>)[c.key], strings.dataGrid.emptyCell)}\n </TableCell>\n ))}\n </TableRow>\n ));\n };\n\n return (\n <div className={cn('flex flex-col gap-3', className)}>\n <div className=\"flex items-center justify-between gap-2\">\n {filter ? (\n <Input\n type=\"search\"\n placeholder={filter.placeholder ?? strings.dataGrid.filterPlaceholder}\n value={filter.value}\n onChange={(e) => filter.onChange(e.target.value)}\n clearable\n onClear={() => filter.onChange('')}\n className=\"w-full max-w-sm\"\n hideLabel\n label={strings.dataGrid.filterRows}\n />\n ) : (\n <div />\n )}\n <div className=\"flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <IconButton\n aria-label={strings.dataGrid.columnVisibility}\n icon={<Settings />}\n variant=\"outline\"\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuLabel>{strings.dataGrid.columns}</DropdownMenuLabel>\n <DropdownMenuSeparator />\n {columns.map((c) => (\n <DropdownMenuCheckboxItem\n key={c.key}\n checked={isVisible(c.key)}\n disabled={isVisible(c.key) && visibleColumns.length <= 1}\n onCheckedChange={(v) => setColumnVisible(c.key, v === true)}\n >\n {c.header}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </div>\n\n <Table containerClassName=\"rounded-lg border border-border\">\n <colgroup>\n {visibleColumns.map((c) => (\n <col key={c.key} style={c.width ? { width: c.width } : undefined} />\n ))}\n </colgroup>\n <TableHeader>\n <TableRow>\n {visibleColumns.map((c) =>\n c.sortable && onSortChange ? (\n <TableSortHeader\n key={c.key}\n align={c.align ?? 'left'}\n sortKey={c.key}\n currentSort={sort ?? null}\n onSortChange={(k, d) => onSortChange({ key: k, direction: d })}\n >\n {c.header}\n </TableSortHeader>\n ) : (\n <TableHead key={c.key} align={c.align ?? 'left'}>\n {c.header}\n </TableHead>\n ),\n )}\n </TableRow>\n </TableHeader>\n <TableBody>{renderRows()}</TableBody>\n </Table>\n </div>\n );\n}\n"],"names":["renderValue","v","emptyLabel","formatDate","isValidElement","DataGrid","columns","rows","loading","sort","onSortChange","filter","emptyState","columnVisibility","onColumnVisibilityChange","className","strings","useStrings","internalVisibility","setInternalVisibility","useState","visibility","isVisible","key","visibleColumns","useMemo","c","setColumnVisible","visible","next","renderRows","_","i","jsx","TableRow","TableCell","Skeleton","row","cn","jsxs","Input","DropdownMenu","DropdownMenuTrigger","IconButton","Settings","DropdownMenuContent","DropdownMenuLabel","DropdownMenuSeparator","DropdownMenuCheckboxItem","Table","TableHeader","TableSortHeader","k","d","TableHead","TableBody"],"mappings":"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"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { DateRange } from 'react-day-picker';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
onChange: (date: Date | undefined) => void;
|
|
2
|
+
import { DateRange, DayPickerProps, Matcher } from 'react-day-picker';
|
|
3
|
+
type CalendarLocale = DayPickerProps['locale'];
|
|
4
|
+
interface PickerCommonProps {
|
|
6
5
|
label?: ReactNode;
|
|
7
6
|
placeholder?: string;
|
|
8
7
|
error?: ReactNode;
|
|
@@ -10,28 +9,31 @@ export interface DatePickerProps {
|
|
|
10
9
|
/** Restrict to a date range. Days outside are not selectable. */
|
|
11
10
|
fromDate?: Date;
|
|
12
11
|
toDate?: Date;
|
|
12
|
+
/** Extra RDP matcher(s) for disabled days, merged with `fromDate`/`toDate`. */
|
|
13
|
+
disabledDays?: Matcher | Matcher[];
|
|
14
|
+
/** Custom display formatter for the trigger text. */
|
|
15
|
+
formatDate?: (d: Date) => string;
|
|
16
|
+
/** date-fns locale object passed through to react-day-picker. */
|
|
17
|
+
locale?: CalendarLocale;
|
|
13
18
|
className?: string;
|
|
14
19
|
}
|
|
20
|
+
export interface DatePickerProps extends PickerCommonProps {
|
|
21
|
+
value?: Date;
|
|
22
|
+
onChange: (date: Date | undefined) => void;
|
|
23
|
+
}
|
|
15
24
|
/**
|
|
16
25
|
* Single-date picker.
|
|
17
26
|
*
|
|
18
27
|
* @example
|
|
19
28
|
* <DatePicker label="Date of birth" value={dob} onChange={setDob} />
|
|
20
29
|
*
|
|
21
|
-
* @do Use locale-aware formatting via
|
|
30
|
+
* @do Use locale-aware formatting via `formatDate` / `locale`.
|
|
22
31
|
* @dont Roll a custom calendar — Radix Popover + react-day-picker handles a11y.
|
|
23
32
|
*/
|
|
24
33
|
export declare const DatePicker: import('react').ForwardRefExoticComponent<DatePickerProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
25
|
-
export interface DateRangePickerProps {
|
|
34
|
+
export interface DateRangePickerProps extends PickerCommonProps {
|
|
26
35
|
value?: DateRange;
|
|
27
36
|
onChange: (range: DateRange | undefined) => void;
|
|
28
|
-
label?: ReactNode;
|
|
29
|
-
placeholder?: string;
|
|
30
|
-
error?: ReactNode;
|
|
31
|
-
disabled?: boolean;
|
|
32
|
-
fromDate?: Date;
|
|
33
|
-
toDate?: Date;
|
|
34
|
-
className?: string;
|
|
35
37
|
}
|
|
36
38
|
/**
|
|
37
39
|
* Two-date range picker. `value` is `{from, to}`.
|
|
@@ -40,3 +42,4 @@ export interface DateRangePickerProps {
|
|
|
40
42
|
* <DateRangePicker label="Reporting period" value={range} onChange={setRange} />
|
|
41
43
|
*/
|
|
42
44
|
export declare const DateRangePicker: import('react').ForwardRefExoticComponent<DateRangePickerProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as n, jsxs as $ } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef as O, useId as R, useState as S, useMemo as F } from "react";
|
|
4
|
+
import * as f from "@radix-ui/react-popover";
|
|
5
|
+
import { Calendar as A } from "../../icons/index.js";
|
|
6
|
+
import { Calendar as D } from "./Calendar.js";
|
|
7
|
+
import { cn as C } from "../../lib/utils.js";
|
|
8
|
+
import { useStrings as w } from "../../hooks/use-strings.js";
|
|
9
|
+
function z(t, e) {
|
|
10
|
+
if (e != null && e.code)
|
|
11
|
+
return t.toLocaleDateString(e.code, { year: "numeric", month: "short", day: "numeric" });
|
|
12
|
+
const o = (r) => String(r).padStart(2, "0");
|
|
13
|
+
return `${t.getFullYear()}-${o(t.getMonth() + 1)}-${o(t.getDate())}`;
|
|
14
|
+
}
|
|
15
|
+
function v(t, e, o) {
|
|
16
|
+
return F(() => {
|
|
17
|
+
const r = [];
|
|
18
|
+
return t && r.push({ before: t }), e && r.push({ after: e }), o && r.push(...Array.isArray(o) ? o : [o]), r.length ? r : void 0;
|
|
19
|
+
}, [t, e, o]);
|
|
20
|
+
}
|
|
21
|
+
function B({
|
|
22
|
+
label: t,
|
|
23
|
+
placeholder: e,
|
|
24
|
+
hasValue: o,
|
|
25
|
+
children: r,
|
|
26
|
+
error: s,
|
|
27
|
+
fieldId: i,
|
|
28
|
+
disabled: g,
|
|
29
|
+
open: d
|
|
30
|
+
}) {
|
|
31
|
+
const a = `${i}-error`, p = `${i}-calendar`, c = o ? r : e;
|
|
32
|
+
return /* @__PURE__ */ $("div", { className: "flex flex-col gap-1.5", children: [
|
|
33
|
+
t && /* @__PURE__ */ n(
|
|
34
|
+
"label",
|
|
35
|
+
{
|
|
36
|
+
id: `${i}-label`,
|
|
37
|
+
htmlFor: i,
|
|
38
|
+
className: "text-foreground text-sm font-medium",
|
|
39
|
+
children: t
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
/* @__PURE__ */ n(f.Trigger, { asChild: !0, children: /* @__PURE__ */ $(
|
|
43
|
+
"button",
|
|
44
|
+
{
|
|
45
|
+
id: i,
|
|
46
|
+
type: "button",
|
|
47
|
+
role: "combobox",
|
|
48
|
+
"aria-expanded": d,
|
|
49
|
+
"aria-controls": p,
|
|
50
|
+
"aria-labelledby": t ? `${i}-label` : void 0,
|
|
51
|
+
"aria-label": t ? void 0 : e,
|
|
52
|
+
disabled: g,
|
|
53
|
+
"aria-invalid": !!s || void 0,
|
|
54
|
+
"aria-describedby": s ? a : void 0,
|
|
55
|
+
className: C(
|
|
56
|
+
"bg-card inline-flex h-9 w-full items-center justify-start gap-2 rounded-md border px-3 text-left text-lg md:text-sm",
|
|
57
|
+
"transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]",
|
|
58
|
+
"focus-visible:ring-offset-background outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
|
|
59
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
60
|
+
s ? "border-danger focus-visible:border-danger focus-visible:ring-danger" : "border-border-input focus-visible:border-accent focus-visible:ring-ring",
|
|
61
|
+
!o && "text-foreground-subtle"
|
|
62
|
+
),
|
|
63
|
+
children: [
|
|
64
|
+
/* @__PURE__ */ n(A, { className: "text-foreground-subtle size-4", "aria-hidden": !0 }),
|
|
65
|
+
/* @__PURE__ */ n("span", { className: "truncate", title: typeof c == "string" ? c : void 0, children: c })
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
) }),
|
|
69
|
+
s && /* @__PURE__ */ n("p", { id: a, className: "text-danger-text text-xs", children: s })
|
|
70
|
+
] });
|
|
71
|
+
}
|
|
72
|
+
const T = O(function({
|
|
73
|
+
value: e,
|
|
74
|
+
onChange: o,
|
|
75
|
+
label: r,
|
|
76
|
+
placeholder: s,
|
|
77
|
+
error: i,
|
|
78
|
+
disabled: g,
|
|
79
|
+
fromDate: d,
|
|
80
|
+
toDate: a,
|
|
81
|
+
disabledDays: p,
|
|
82
|
+
formatDate: c,
|
|
83
|
+
locale: h,
|
|
84
|
+
className: P
|
|
85
|
+
}, k) {
|
|
86
|
+
const N = w(), u = c ?? ((m) => z(m, h)), b = s ?? N.datePicker.pickDate, l = R(), [x, y] = S(!1), M = v(d, a, p);
|
|
87
|
+
return /* @__PURE__ */ n("div", { ref: k, className: C(P), children: /* @__PURE__ */ $(f.Root, { open: x, onOpenChange: y, children: [
|
|
88
|
+
/* @__PURE__ */ n(
|
|
89
|
+
B,
|
|
90
|
+
{
|
|
91
|
+
label: r,
|
|
92
|
+
placeholder: b,
|
|
93
|
+
hasValue: !!e,
|
|
94
|
+
error: i,
|
|
95
|
+
fieldId: l,
|
|
96
|
+
disabled: g,
|
|
97
|
+
open: x,
|
|
98
|
+
children: e ? u(e) : ""
|
|
99
|
+
}
|
|
100
|
+
),
|
|
101
|
+
/* @__PURE__ */ n(f.Portal, { children: /* @__PURE__ */ n(
|
|
102
|
+
f.Content,
|
|
103
|
+
{
|
|
104
|
+
id: `${l}-calendar`,
|
|
105
|
+
"aria-labelledby": r ? `${l}-label` : void 0,
|
|
106
|
+
"aria-label": r ? void 0 : b,
|
|
107
|
+
align: "start",
|
|
108
|
+
sideOffset: 4,
|
|
109
|
+
className: "text-popover-foreground z-[var(--z-popover)] rounded-lg shadow-md",
|
|
110
|
+
children: /* @__PURE__ */ n(
|
|
111
|
+
D,
|
|
112
|
+
{
|
|
113
|
+
mode: "single",
|
|
114
|
+
selected: e,
|
|
115
|
+
defaultMonth: e,
|
|
116
|
+
onSelect: (m) => {
|
|
117
|
+
o(m ?? void 0), m && y(!1);
|
|
118
|
+
},
|
|
119
|
+
startMonth: d,
|
|
120
|
+
endMonth: a,
|
|
121
|
+
disabled: M,
|
|
122
|
+
locale: h
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
) })
|
|
127
|
+
] }) });
|
|
128
|
+
});
|
|
129
|
+
T.displayName = "DatePicker";
|
|
130
|
+
const L = O(
|
|
131
|
+
function({
|
|
132
|
+
value: e,
|
|
133
|
+
onChange: o,
|
|
134
|
+
label: r,
|
|
135
|
+
placeholder: s,
|
|
136
|
+
error: i,
|
|
137
|
+
disabled: g,
|
|
138
|
+
fromDate: d,
|
|
139
|
+
toDate: a,
|
|
140
|
+
disabledDays: p,
|
|
141
|
+
formatDate: c,
|
|
142
|
+
locale: h,
|
|
143
|
+
className: P
|
|
144
|
+
}, k) {
|
|
145
|
+
const N = w(), u = c ?? ((j) => z(j, h)), b = s ?? N.datePicker.pickRange, l = R(), [x, y] = S(!1), M = !!(e != null && e.from), m = v(d, a, p);
|
|
146
|
+
return /* @__PURE__ */ n("div", { ref: k, className: C(P), children: /* @__PURE__ */ $(f.Root, { open: x, onOpenChange: y, children: [
|
|
147
|
+
/* @__PURE__ */ n(
|
|
148
|
+
B,
|
|
149
|
+
{
|
|
150
|
+
label: r,
|
|
151
|
+
placeholder: b,
|
|
152
|
+
hasValue: M,
|
|
153
|
+
error: i,
|
|
154
|
+
fieldId: l,
|
|
155
|
+
disabled: g,
|
|
156
|
+
open: x,
|
|
157
|
+
children: e != null && e.from && e.to ? `${u(e.from)} – ${u(e.to)}` : e != null && e.from ? u(e.from) : ""
|
|
158
|
+
}
|
|
159
|
+
),
|
|
160
|
+
/* @__PURE__ */ n(f.Portal, { children: /* @__PURE__ */ n(
|
|
161
|
+
f.Content,
|
|
162
|
+
{
|
|
163
|
+
id: `${l}-calendar`,
|
|
164
|
+
"aria-labelledby": r ? `${l}-label` : void 0,
|
|
165
|
+
"aria-label": r ? void 0 : b,
|
|
166
|
+
align: "start",
|
|
167
|
+
sideOffset: 4,
|
|
168
|
+
className: "text-popover-foreground z-[var(--z-popover)] rounded-lg shadow-md",
|
|
169
|
+
children: /* @__PURE__ */ n(
|
|
170
|
+
D,
|
|
171
|
+
{
|
|
172
|
+
mode: "range",
|
|
173
|
+
selected: e,
|
|
174
|
+
defaultMonth: e == null ? void 0 : e.from,
|
|
175
|
+
onSelect: o,
|
|
176
|
+
numberOfMonths: 2,
|
|
177
|
+
startMonth: d,
|
|
178
|
+
endMonth: a,
|
|
179
|
+
disabled: m,
|
|
180
|
+
locale: h
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
) })
|
|
185
|
+
] }) });
|
|
186
|
+
}
|
|
187
|
+
);
|
|
188
|
+
L.displayName = "DateRangePicker";
|
|
189
|
+
export {
|
|
190
|
+
T as DatePicker,
|
|
191
|
+
L as DateRangePicker
|
|
192
|
+
};
|
|
193
|
+
//# sourceMappingURL=DatePicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.js","sources":["../../../src/components/ui/DatePicker.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, useId, useMemo, useState, type ReactNode } from 'react';\nimport * as PopoverPrimitive from '@radix-ui/react-popover';\nimport type { DateRange, DayPickerProps, Matcher } from 'react-day-picker';\nimport { Calendar as CalendarIcon } from '@/icons';\nimport { Calendar } from './Calendar';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\n\n/* -----------------------------------------------------------------------------\n * Two related components share the same trigger shell:\n *\n * <DatePicker value={date} onChange={setDate} /> // single date\n * <DateRangePicker value={range} onChange={setRange} /> // {from,to}\n * --------------------------------------------------------------------------- */\n\ntype CalendarLocale = DayPickerProps['locale'];\n\n/**\n * Default trigger text. With a date-fns `locale` the date is rendered in that\n * locale; without one it is the canonical `yyyy-MM-dd` — deterministic on\n * server and client, so SSR output never depends on the host's locale.\n */\nfunction defaultFormatDate(d: Date, locale?: CalendarLocale): string {\n if (locale?.code) {\n return d.toLocaleDateString(locale.code, { year: 'numeric', month: 'short', day: 'numeric' });\n }\n const pad = (n: number) => String(n).padStart(2, '0');\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;\n}\n\n/** Merge the fromDate/toDate bounds with any consumer-supplied RDP matcher. */\nfunction useBounds(fromDate?: Date, toDate?: Date, disabled?: Matcher | Matcher[]) {\n return useMemo<Matcher[] | undefined>(() => {\n const list: Matcher[] = [];\n if (fromDate) list.push({ before: fromDate });\n if (toDate) list.push({ after: toDate });\n if (disabled) list.push(...(Array.isArray(disabled) ? disabled : [disabled]));\n return list.length ? list : undefined;\n }, [fromDate, toDate, disabled]);\n}\n\nfunction PickerTrigger({\n label,\n placeholder,\n hasValue,\n children,\n error,\n fieldId,\n disabled,\n open,\n}: {\n label?: ReactNode;\n placeholder: string;\n hasValue: boolean;\n children: ReactNode;\n error?: ReactNode;\n fieldId: string;\n disabled?: boolean;\n open: boolean;\n}) {\n const errorId = `${fieldId}-error`;\n const calendarId = `${fieldId}-calendar`;\n const text = hasValue ? children : placeholder;\n return (\n <div className=\"flex flex-col gap-1.5\">\n {label && (\n <label\n id={`${fieldId}-label`}\n htmlFor={fieldId}\n className=\"text-foreground text-sm font-medium\"\n >\n {label}\n </label>\n )}\n <PopoverPrimitive.Trigger asChild>\n <button\n id={fieldId}\n type=\"button\"\n // combobox-with-dialog pattern: lets the field carry aria-invalid like other inputs.\n role=\"combobox\"\n aria-expanded={open}\n aria-controls={calendarId}\n // role=combobox takes no name from content; expose the placeholder.\n aria-labelledby={label ? `${fieldId}-label` : undefined}\n aria-label={label ? undefined : placeholder}\n disabled={disabled}\n aria-invalid={Boolean(error) || undefined}\n aria-describedby={error ? errorId : undefined}\n className={cn(\n 'bg-card inline-flex h-9 w-full items-center justify-start gap-2 rounded-md border px-3 text-left text-lg md:text-sm',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n 'focus-visible:ring-offset-background outline-none focus-visible:ring-2 focus-visible:ring-offset-2',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n error\n ? 'border-danger focus-visible:border-danger focus-visible:ring-danger'\n : 'border-border-input focus-visible:border-accent focus-visible:ring-ring',\n !hasValue && 'text-foreground-subtle',\n )}\n >\n <CalendarIcon className=\"text-foreground-subtle size-4\" aria-hidden />\n <span className=\"truncate\" title={typeof text === 'string' ? text : undefined}>\n {text}\n </span>\n </button>\n </PopoverPrimitive.Trigger>\n {error && (\n <p id={errorId} className=\"text-danger-text text-xs\">\n {error}\n </p>\n )}\n </div>\n );\n}\n\ninterface PickerCommonProps {\n label?: ReactNode;\n placeholder?: string;\n error?: ReactNode;\n disabled?: boolean;\n /** Restrict to a date range. Days outside are not selectable. */\n fromDate?: Date;\n toDate?: Date;\n /** Extra RDP matcher(s) for disabled days, merged with `fromDate`/`toDate`. */\n disabledDays?: Matcher | Matcher[];\n /** Custom display formatter for the trigger text. */\n formatDate?: (d: Date) => string;\n /** date-fns locale object passed through to react-day-picker. */\n locale?: CalendarLocale;\n className?: string;\n}\n\nexport interface DatePickerProps extends PickerCommonProps {\n value?: Date;\n onChange: (date: Date | undefined) => void;\n}\n\n/**\n * Single-date picker.\n *\n * @example\n * <DatePicker label=\"Date of birth\" value={dob} onChange={setDob} />\n *\n * @do Use locale-aware formatting via `formatDate` / `locale`.\n * @dont Roll a custom calendar — Radix Popover + react-day-picker handles a11y.\n */\nexport const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(function DatePicker(\n {\n value,\n onChange,\n label,\n placeholder: placeholderProp,\n error,\n disabled,\n fromDate,\n toDate,\n disabledDays,\n formatDate: formatDateProp,\n locale,\n className,\n },\n ref,\n) {\n const strings = useStrings();\n const formatDate = formatDateProp ?? ((d: Date) => defaultFormatDate(d, locale));\n const placeholder = placeholderProp ?? strings.datePicker.pickDate;\n const fieldId = useId();\n const [open, setOpen] = useState(false);\n const bounds = useBounds(fromDate, toDate, disabledDays);\n\n return (\n <div ref={ref} className={cn(className)}>\n <PopoverPrimitive.Root open={open} onOpenChange={setOpen}>\n <PickerTrigger\n label={label}\n placeholder={placeholder}\n hasValue={Boolean(value)}\n error={error}\n fieldId={fieldId}\n disabled={disabled}\n open={open}\n >\n {value ? formatDate(value) : ''}\n </PickerTrigger>\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n id={`${fieldId}-calendar`}\n // Radix gives the popover role=\"dialog\"; name it after the field.\n aria-labelledby={label ? `${fieldId}-label` : undefined}\n aria-label={label ? undefined : placeholder}\n align=\"start\"\n sideOffset={4}\n className=\"text-popover-foreground z-[var(--z-popover)] rounded-lg shadow-md\"\n >\n <Calendar\n mode=\"single\"\n selected={value}\n // RDP 9 ignores `selected` for the initial month; open on the value.\n defaultMonth={value}\n onSelect={(d) => {\n onChange(d ?? undefined);\n if (d) setOpen(false);\n }}\n startMonth={fromDate}\n endMonth={toDate}\n disabled={bounds}\n locale={locale}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n </div>\n );\n});\nDatePicker.displayName = 'DatePicker';\n\nexport interface DateRangePickerProps extends PickerCommonProps {\n value?: DateRange;\n onChange: (range: DateRange | undefined) => void;\n}\n\n/**\n * Two-date range picker. `value` is `{from, to}`.\n *\n * @example\n * <DateRangePicker label=\"Reporting period\" value={range} onChange={setRange} />\n */\nexport const DateRangePicker = forwardRef<HTMLDivElement, DateRangePickerProps>(\n function DateRangePicker(\n {\n value,\n onChange,\n label,\n placeholder: placeholderProp,\n error,\n disabled,\n fromDate,\n toDate,\n disabledDays,\n formatDate: formatDateProp,\n locale,\n className,\n },\n ref,\n ) {\n const strings = useStrings();\n const formatDate = formatDateProp ?? ((d: Date) => defaultFormatDate(d, locale));\n const placeholder = placeholderProp ?? strings.datePicker.pickRange;\n const fieldId = useId();\n const [open, setOpen] = useState(false);\n const hasValue = Boolean(value?.from);\n const bounds = useBounds(fromDate, toDate, disabledDays);\n\n return (\n <div ref={ref} className={cn(className)}>\n <PopoverPrimitive.Root open={open} onOpenChange={setOpen}>\n <PickerTrigger\n label={label}\n placeholder={placeholder}\n hasValue={hasValue}\n error={error}\n fieldId={fieldId}\n disabled={disabled}\n open={open}\n >\n {value?.from && value.to\n ? `${formatDate(value.from)} – ${formatDate(value.to)}`\n : value?.from\n ? formatDate(value.from)\n : ''}\n </PickerTrigger>\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n id={`${fieldId}-calendar`}\n aria-labelledby={label ? `${fieldId}-label` : undefined}\n aria-label={label ? undefined : placeholder}\n align=\"start\"\n sideOffset={4}\n className=\"text-popover-foreground z-[var(--z-popover)] rounded-lg shadow-md\"\n >\n <Calendar\n mode=\"range\"\n selected={value}\n defaultMonth={value?.from}\n onSelect={onChange}\n numberOfMonths={2}\n startMonth={fromDate}\n endMonth={toDate}\n disabled={bounds}\n locale={locale}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n </div>\n );\n },\n);\nDateRangePicker.displayName = 'DateRangePicker';\n"],"names":["defaultFormatDate","d","locale","pad","n","useBounds","fromDate","toDate","disabled","useMemo","list","PickerTrigger","label","placeholder","hasValue","children","error","fieldId","open","errorId","calendarId","text","jsxs","jsx","PopoverPrimitive","cn","CalendarIcon","DatePicker","forwardRef","value","onChange","placeholderProp","disabledDays","formatDateProp","className","ref","strings","useStrings","formatDate","useId","setOpen","useState","bounds","Calendar","DateRangePicker"],"mappings":"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"}
|