@godxjp/ui 9.2.0 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +58 -29
  2. package/dist/app/index.d.ts +1 -1
  3. package/dist/app/index.js +4 -4
  4. package/dist/{app.prop-UTc4j4nj.d.ts → app.prop-Cy6dJnU8.d.ts} +18 -40
  5. package/dist/{checkbox-ChRsR7Nk.d.ts → checkbox-em-oFM5D.d.ts} +1 -1
  6. package/dist/{chunk-LJLGABFV.js → chunk-2HXZT2WJ.js} +17 -9
  7. package/dist/{chunk-QLMXEJSY.js → chunk-3Q4A4U2P.js} +24 -1
  8. package/dist/{chunk-26CPAKUP.js → chunk-44YRPSZ7.js} +1 -2
  9. package/dist/{chunk-HB2OHB5X.js → chunk-5NCFLCM7.js} +27 -16
  10. package/dist/{chunk-FXFJF4YA.js → chunk-6CSBMMZS.js} +262 -31
  11. package/dist/{chunk-457KVJTX.js → chunk-7Q45MBFW.js} +7 -5
  12. package/dist/{chunk-O24Z3ULJ.js → chunk-BE6GJGKJ.js} +1 -1
  13. package/dist/{chunk-FVPCVZL3.js → chunk-BG5RNXTH.js} +1 -1
  14. package/dist/{chunk-AINW5WYN.js → chunk-COD66MFF.js} +1 -2
  15. package/dist/{chunk-IOGU3ZWF.js → chunk-DNGJHWJZ.js} +3 -3
  16. package/dist/{chunk-3TS3G4U3.js → chunk-EE5DKOHX.js} +3 -1
  17. package/dist/{chunk-BHV2FUOA.js → chunk-EZHHJQWQ.js} +1 -1
  18. package/dist/{chunk-G6Q32VHO.js → chunk-FAB3LMTK.js} +33 -8
  19. package/dist/{chunk-N3JPLJ3B.js → chunk-GDDCSKCB.js} +12 -5
  20. package/dist/{chunk-RLGHEV4A.js → chunk-HTG5VHU7.js} +10 -1
  21. package/dist/{chunk-R2W2FX5Q.js → chunk-I7NQ2LIL.js} +1 -9
  22. package/dist/{chunk-XQMPK4GM.js → chunk-IHRMOJXD.js} +86 -39
  23. package/dist/{chunk-TILFZBTE.js → chunk-INIIF7F7.js} +1 -4
  24. package/dist/{chunk-UIYEAUWA.js → chunk-IY347EQA.js} +2 -2
  25. package/dist/{chunk-HCM4JAC2.js → chunk-JWGLJXQU.js} +39 -11
  26. package/dist/{chunk-TO33OY4L.js → chunk-LMKUKCTN.js} +1 -1
  27. package/dist/chunk-NXVCI6YB.js +453 -0
  28. package/dist/{chunk-O2OUNXV4.js → chunk-P5KPCT6R.js} +3 -3
  29. package/dist/{chunk-6HQMUUQW.js → chunk-PDXFQS7M.js} +14 -30
  30. package/dist/{chunk-26WDEDWL.js → chunk-PUGEOUWZ.js} +32 -23
  31. package/dist/{chunk-F7PG4OEV.js → chunk-QSGW3ZWK.js} +12 -4
  32. package/dist/{chunk-E7HBHUJY.js → chunk-QVLUCB47.js} +8 -6
  33. package/dist/{chunk-25RYBC5T.js → chunk-S2IJKT3D.js} +1 -1
  34. package/dist/{chunk-OJZ6C2HM.js → chunk-SARQRCKO.js} +54 -48
  35. package/dist/chunk-T2QO2S65.js +126 -0
  36. package/dist/{chunk-6J7GRCDA.js → chunk-UNVRNJCB.js} +71 -11
  37. package/dist/{chunk-S6TBIL7J.js → chunk-USNR424B.js} +63 -44
  38. package/dist/{chunk-6YBYAEXD.js → chunk-VSM44AYE.js} +94 -24
  39. package/dist/{chunk-QWLXN6CT.js → chunk-VSUYVT2Q.js} +3 -2
  40. package/dist/{chunk-4R7QL3MW.js → chunk-X2VY4MOW.js} +14 -29
  41. package/dist/{chunk-ETLAI3QU.js → chunk-Z46J47FY.js} +73 -77
  42. package/dist/components/admin/index.d.ts +22 -12
  43. package/dist/components/admin/index.js +29 -30
  44. package/dist/components/data-display/badge.js +3 -3
  45. package/dist/components/data-display/card.d.ts +3 -3
  46. package/dist/components/data-display/card.js +1 -1
  47. package/dist/components/data-display/carousel.js +3 -1
  48. package/dist/components/data-display/index.js +55 -33
  49. package/dist/components/data-entry/calendar.d.ts +1 -1
  50. package/dist/components/data-entry/calendar.js +1 -1
  51. package/dist/components/data-entry/cascader.d.ts +1 -1
  52. package/dist/components/data-entry/cascader.js +5 -5
  53. package/dist/components/data-entry/checkbox.d.ts +2 -2
  54. package/dist/components/data-entry/checkbox.js +2 -2
  55. package/dist/components/data-entry/color-picker.d.ts +1 -1
  56. package/dist/components/data-entry/color-picker.js +3 -3
  57. package/dist/components/data-entry/date-picker.d.ts +2 -2
  58. package/dist/components/data-entry/date-picker.js +4 -4
  59. package/dist/components/data-entry/date-range-picker.d.ts +2 -2
  60. package/dist/components/data-entry/date-range-picker.js +4 -4
  61. package/dist/components/data-entry/index.d.ts +9 -25
  62. package/dist/components/data-entry/index.js +22 -26
  63. package/dist/components/data-entry/radio.d.ts +1 -1
  64. package/dist/components/data-entry/radio.js +2 -2
  65. package/dist/components/data-entry/select.d.ts +2 -2
  66. package/dist/components/data-entry/select.js +3 -4
  67. package/dist/components/data-entry/slider.d.ts +1 -1
  68. package/dist/components/data-entry/switch.d.ts +2 -2
  69. package/dist/components/data-entry/switch.js +1 -1
  70. package/dist/components/data-entry/time-input.js +2 -2
  71. package/dist/components/data-entry/time-picker.d.ts +3 -1
  72. package/dist/components/data-entry/time-picker.js +3 -3
  73. package/dist/components/data-entry/transfer.d.ts +2 -2
  74. package/dist/components/data-entry/transfer.js +5 -5
  75. package/dist/components/data-entry/tree-select.d.ts +1 -1
  76. package/dist/components/data-entry/tree-select.js +5 -5
  77. package/dist/components/data-entry/upload.d.ts +2 -2
  78. package/dist/components/data-entry/upload.js +5 -5
  79. package/dist/components/feedback/alert.js +5 -5
  80. package/dist/components/feedback/dialog.js +3 -3
  81. package/dist/components/feedback/index.d.ts +4 -4
  82. package/dist/components/feedback/index.js +9 -9
  83. package/dist/components/feedback/sheet.js +1 -1
  84. package/dist/components/layout/index.d.ts +6 -9
  85. package/dist/components/layout/index.js +6 -4
  86. package/dist/components/navigation/dropdown-menu.js +1 -1
  87. package/dist/components/navigation/index.d.ts +14 -16
  88. package/dist/components/navigation/index.js +7 -8
  89. package/dist/components/navigation/pagination.d.ts +11 -8
  90. package/dist/components/navigation/pagination.js +4 -5
  91. package/dist/components/navigation/steps.d.ts +3 -3
  92. package/dist/components/navigation/steps.js +3 -1
  93. package/dist/components/query/index.d.ts +1 -5
  94. package/dist/components/query/index.js +6 -8
  95. package/dist/components/ui/index.d.ts +5 -7
  96. package/dist/components/ui/index.js +30 -33
  97. package/dist/{data-entry.prop-CDkOajPj.d.ts → data-entry.prop-BR4vNA1j.d.ts} +7 -35
  98. package/dist/filter-bar-BxjSJJnQ.d.ts +7 -0
  99. package/dist/{inline-CDSVAN54.d.ts → flex-D_EXRFSW.d.ts} +2 -8
  100. package/dist/form/index.js +1 -1
  101. package/dist/i18n/index.d.ts +82 -10
  102. package/dist/i18n/index.js +2 -2
  103. package/dist/index.d.ts +6 -6
  104. package/dist/index.js +41 -44
  105. package/dist/lib/datetime/index.js +1 -1
  106. package/dist/{navigation.prop-8DgElO0c.d.ts → navigation.prop-DMcXkR-J.d.ts} +9 -11
  107. package/dist/{password-strength-kQkloEeo.d.ts → password-strength-DVRvXEOK.d.ts} +2 -2
  108. package/dist/props/components/index.d.ts +3 -3
  109. package/dist/props/index.d.ts +3 -3
  110. package/dist/props/index.js +1 -1
  111. package/dist/props/registry.d.ts +84 -39
  112. package/dist/props/registry.js +1 -1
  113. package/dist/{search-input-cezAxpgb.d.ts → search-input-DpqDMXcn.d.ts} +2 -4
  114. package/dist/{skeleton-uWAjSacg.d.ts → skeleton-cj9kh5wo.d.ts} +1 -3
  115. package/dist/styles/control.css +176 -41
  116. package/dist/styles/data-display-layout.css +41 -15
  117. package/dist/styles/feedback-layout.css +44 -12
  118. package/dist/styles/index.css +45 -1
  119. package/dist/styles/layout.css +18 -17
  120. package/dist/styles/navigation-layout.css +3 -1
  121. package/dist/styles/shell-layout.css +3 -3
  122. package/dist/styles/table-layout.css +13 -0
  123. package/dist/tokens/foundation.css +12 -1
  124. package/dist/tokens/semantic/layout.css +2 -2
  125. package/package.json +6 -7
  126. package/scripts/ui-audit.mjs +35 -2
  127. package/dist/chunk-6MCI7W5G.js +0 -201
  128. package/dist/chunk-CAEL2ZD2.js +0 -222
  129. package/dist/chunk-GKXPALFT.js +0 -32
  130. package/dist/chunk-JKHWLPM5.js +0 -101
  131. package/dist/chunk-KDBGFJJI.js +0 -220
  132. package/dist/components/data-entry/autocomplete.d.ts +0 -24
  133. package/dist/components/data-entry/autocomplete.js +0 -10
  134. package/dist/components/data-entry/combobox.d.ts +0 -22
  135. package/dist/components/data-entry/combobox.js +0 -6
  136. package/dist/filter-bar-B5TPUqEO.d.ts +0 -14
  137. /package/dist/{chunk-LDSLS6HE.js → chunk-7CFO5FFE.js} +0 -0
@@ -0,0 +1,453 @@
1
+ import { Command, CommandList, CommandItem, CommandGroup } from './chunk-HTEL5DQI.js';
2
+ import { Input } from './chunk-VOHTRR5X.js';
3
+ import { Button } from './chunk-M4PZNAMV.js';
4
+ import { Popover, PopoverTrigger, PopoverContent } from './chunk-DY5C44UP.js';
5
+ import { controlTriggerClass } from './chunk-IBK5D2Q6.js';
6
+ import { useTranslation } from './chunk-HTG5VHU7.js';
7
+ import { cn } from './chunk-U7N2A7A3.js';
8
+ import * as React from 'react';
9
+ import * as SelectPrimitive from '@radix-ui/react-select';
10
+ import { ChevronDown, ChevronUp, ChevronsUpDown, Check, Loader2 } from 'lucide-react';
11
+ import { jsxs, jsx } from 'react/jsx-runtime';
12
+
13
+ var DEBOUNCE_MS = 250;
14
+ function SearchSelect({
15
+ value = "",
16
+ onValueChange,
17
+ options: staticOptions,
18
+ loadOptions,
19
+ renderOption,
20
+ selectedLabel,
21
+ placeholder,
22
+ searchPlaceholder,
23
+ emptyMessage,
24
+ loadingMessage,
25
+ clearLabel,
26
+ clearable = true,
27
+ disabled = false,
28
+ name,
29
+ id,
30
+ className,
31
+ "data-testid": dataTestId
32
+ }) {
33
+ const { t } = useTranslation();
34
+ const reactId = React.useId();
35
+ const listId = `${reactId}-listbox`;
36
+ const optionDomId = (optionValue) => `${reactId}-opt-${optionValue}`;
37
+ const [open, setOpen] = React.useState(false);
38
+ const [query, setQuery] = React.useState("");
39
+ const [debouncedQuery, setDebouncedQuery] = React.useState("");
40
+ const [loaded, setLoaded] = React.useState([]);
41
+ const [page, setPage] = React.useState(1);
42
+ const [hasMore, setHasMore] = React.useState(false);
43
+ const [loading, setLoading] = React.useState(false);
44
+ const [activeIndex, setActiveIndex] = React.useState(0);
45
+ const [picked, setPicked] = React.useState(null);
46
+ const reqId = React.useRef(0);
47
+ const resolvedLoad = React.useMemo(
48
+ () => loadOptions ?? (async ({ query: search }) => {
49
+ const needle = search.trim().toLowerCase();
50
+ const list = staticOptions ?? [];
51
+ return {
52
+ options: needle ? list.filter(
53
+ (option) => option.label.toLowerCase().includes(needle) || option.value.toLowerCase().includes(needle)
54
+ ) : list,
55
+ hasMore: false
56
+ };
57
+ }),
58
+ [loadOptions, staticOptions]
59
+ );
60
+ React.useEffect(() => {
61
+ const handle = window.setTimeout(() => setDebouncedQuery(query.trim()), DEBOUNCE_MS);
62
+ return () => window.clearTimeout(handle);
63
+ }, [query]);
64
+ const fetchPage = React.useCallback(
65
+ async (nextPage, search, append) => {
66
+ const ticket = ++reqId.current;
67
+ setLoading(true);
68
+ try {
69
+ const result = await resolvedLoad({ query: search, page: nextPage });
70
+ if (ticket !== reqId.current) return;
71
+ setLoaded((prev) => append ? [...prev, ...result.options] : result.options);
72
+ setHasMore(Boolean(result.hasMore));
73
+ setPage(nextPage);
74
+ } finally {
75
+ if (ticket === reqId.current) setLoading(false);
76
+ }
77
+ },
78
+ [resolvedLoad]
79
+ );
80
+ React.useEffect(() => {
81
+ if (!open) return;
82
+ setActiveIndex(0);
83
+ void fetchPage(1, debouncedQuery, false);
84
+ }, [open, debouncedQuery, fetchPage]);
85
+ const grouped = React.useMemo(() => {
86
+ const order = [];
87
+ const buckets = /* @__PURE__ */ new Map();
88
+ for (const option of loaded) {
89
+ const key = option.group ?? "";
90
+ if (!buckets.has(key)) {
91
+ buckets.set(key, []);
92
+ order.push(key);
93
+ }
94
+ buckets.get(key).push(option);
95
+ }
96
+ let flatIndex = 0;
97
+ return order.map((key) => ({
98
+ heading: key || void 0,
99
+ items: (buckets.get(key) ?? []).map((option) => ({ option, index: flatIndex++ }))
100
+ }));
101
+ }, [loaded]);
102
+ const flatOrdered = React.useMemo(
103
+ () => grouped.flatMap((group) => group.items.map((entry) => entry.option)),
104
+ [grouped]
105
+ );
106
+ const resolvedPlaceholder = placeholder ?? t("dataEntry.searchSelect.placeholder");
107
+ const currentLabel = value ? picked?.label ?? selectedLabel ?? resolvedPlaceholder : resolvedPlaceholder;
108
+ const select = (option) => {
109
+ if (option.disabled) return;
110
+ setPicked(option);
111
+ onValueChange?.(option.value, option);
112
+ setOpen(false);
113
+ };
114
+ const clear = () => {
115
+ setPicked(null);
116
+ onValueChange?.("", void 0);
117
+ setOpen(false);
118
+ };
119
+ const onScroll = (event) => {
120
+ const el = event.currentTarget;
121
+ if (el.scrollHeight - el.scrollTop - el.clientHeight < 48 && hasMore && !loading) {
122
+ void fetchPage(page + 1, debouncedQuery, true);
123
+ }
124
+ };
125
+ const onKeyDown = (event) => {
126
+ if (event.key === "ArrowDown") {
127
+ event.preventDefault();
128
+ setActiveIndex((i) => Math.min(i + 1, Math.max(flatOrdered.length - 1, 0)));
129
+ } else if (event.key === "ArrowUp") {
130
+ event.preventDefault();
131
+ setActiveIndex((i) => Math.max(i - 1, 0));
132
+ } else if (event.key === "Enter" && flatOrdered[activeIndex]) {
133
+ event.preventDefault();
134
+ select(flatOrdered[activeIndex]);
135
+ } else if (event.key === "Escape") {
136
+ event.preventDefault();
137
+ setOpen(false);
138
+ }
139
+ };
140
+ const optionTestId = (optionValue) => dataTestId ? `${dataTestId}-option-${optionValue}` : void 0;
141
+ const activeOption = flatOrdered[activeIndex];
142
+ const activeOptionId = activeOption ? optionDomId(activeOption.value) : void 0;
143
+ return /* @__PURE__ */ jsxs(
144
+ Popover,
145
+ {
146
+ open,
147
+ onOpenChange: (next) => {
148
+ setOpen(next);
149
+ if (!next) setQuery("");
150
+ },
151
+ children: [
152
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
153
+ Button,
154
+ {
155
+ id,
156
+ type: "button",
157
+ variant: "outline",
158
+ role: "combobox",
159
+ "aria-expanded": open,
160
+ disabled,
161
+ "data-testid": dataTestId,
162
+ className: cn("w-full justify-between font-normal", className),
163
+ children: [
164
+ /* @__PURE__ */ jsx("span", { className: cn("truncate text-start", !value && "text-muted-foreground"), children: currentLabel }),
165
+ /* @__PURE__ */ jsx(ChevronsUpDown, { className: "ms-2 size-4 shrink-0 opacity-50", "aria-hidden": "true" })
166
+ ]
167
+ }
168
+ ) }),
169
+ name ? /* @__PURE__ */ jsx("input", { type: "hidden", name, value }) : null,
170
+ /* @__PURE__ */ jsx(
171
+ PopoverContent,
172
+ {
173
+ align: "start",
174
+ sideOffset: 4,
175
+ collisionPadding: 12,
176
+ className: "flex max-h-[min(24rem,var(--radix-popover-content-available-height))] w-max max-w-[min(32rem,calc(100vw-1.5rem))] min-w-[var(--radix-popover-trigger-width)] flex-col p-0",
177
+ children: /* @__PURE__ */ jsxs(Command, { shouldFilter: false, className: "flex min-h-0 flex-col", children: [
178
+ /* @__PURE__ */ jsx("div", { className: "border-border shrink-0 border-b p-2", children: /* @__PURE__ */ jsx(
179
+ Input,
180
+ {
181
+ autoFocus: true,
182
+ "aria-controls": listId,
183
+ "aria-autocomplete": "list",
184
+ "aria-activedescendant": activeOptionId,
185
+ value: query,
186
+ onChange: (event) => setQuery(event.target.value),
187
+ onKeyDown,
188
+ placeholder: searchPlaceholder ?? t("dataEntry.searchSelect.search")
189
+ }
190
+ ) }),
191
+ /* @__PURE__ */ jsxs(
192
+ CommandList,
193
+ {
194
+ id: listId,
195
+ role: "listbox",
196
+ className: "min-h-0 flex-1 overflow-y-auto p-1",
197
+ onScroll,
198
+ children: [
199
+ clearable && value ? /* @__PURE__ */ jsx(CommandItem, { value: "", "data-testid": optionTestId("none"), onSelect: clear, children: /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: clearLabel ?? t("dataEntry.searchSelect.clear") }) }) : null,
200
+ grouped.map((group) => {
201
+ const rows = group.items.map(({ option, index }) => /* @__PURE__ */ jsxs(
202
+ CommandItem,
203
+ {
204
+ id: optionDomId(option.value),
205
+ role: "option",
206
+ value: option.value,
207
+ "data-testid": optionTestId(option.value),
208
+ "aria-selected": activeIndex === index,
209
+ disabled: option.disabled,
210
+ className: activeIndex === index ? "bg-accent text-accent-foreground" : void 0,
211
+ onMouseEnter: () => setActiveIndex(index),
212
+ onSelect: () => select(option),
213
+ children: [
214
+ renderOption ? /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: renderOption(option) }) : /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
215
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sm", children: option.label }),
216
+ option.sublabel ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground truncate text-xs", children: option.sublabel }) : null
217
+ ] }),
218
+ value === option.value ? /* @__PURE__ */ jsx(Check, { className: "text-primary size-4 shrink-0", "aria-hidden": "true" }) : null
219
+ ]
220
+ },
221
+ option.value
222
+ ));
223
+ return group.heading ? /* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: rows }, group.heading) : /* @__PURE__ */ jsx(React.Fragment, { children: rows }, "__ungrouped");
224
+ }),
225
+ loading ? /* @__PURE__ */ jsxs("div", { className: "text-muted-foreground flex items-center gap-2 px-2 py-3 text-sm", children: [
226
+ /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin", "aria-hidden": "true" }),
227
+ loadingMessage ?? t("dataEntry.searchSelect.loading")
228
+ ] }) : null,
229
+ !loading && loaded.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-muted-foreground px-2 py-6 text-center text-sm", children: emptyMessage ?? t("dataEntry.searchSelect.empty") }) : null
230
+ ]
231
+ }
232
+ )
233
+ ] })
234
+ }
235
+ )
236
+ ]
237
+ }
238
+ );
239
+ }
240
+ function isDataSelect(props) {
241
+ return "options" in props || "loadOptions" in props;
242
+ }
243
+ function Select(props) {
244
+ if (isDataSelect(props)) {
245
+ return /* @__PURE__ */ jsx(DataSelect, { ...props });
246
+ }
247
+ return /* @__PURE__ */ jsx(SelectPrimitive.Root, { "data-slot": "select", ...props });
248
+ }
249
+ function SelectGroup(props) {
250
+ return /* @__PURE__ */ jsx(SelectPrimitive.Group, { "data-slot": "select-group", ...props });
251
+ }
252
+ function SelectValue(props) {
253
+ return /* @__PURE__ */ jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
254
+ }
255
+ var SelectTrigger = React.forwardRef(({ className, children, size = "md", ...props }, ref) => /* @__PURE__ */ jsxs(
256
+ SelectPrimitive.Trigger,
257
+ {
258
+ ref,
259
+ "data-slot": "select-trigger",
260
+ "data-size": size,
261
+ className: cn(
262
+ controlTriggerClass,
263
+ "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground w-fit gap-2 whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2",
264
+ className
265
+ ),
266
+ ...props,
267
+ children: [
268
+ children,
269
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4 shrink-0 opacity-50", "aria-hidden": "true" }) })
270
+ ]
271
+ }
272
+ ));
273
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
274
+ var SelectScrollUpButton = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
275
+ SelectPrimitive.ScrollUpButton,
276
+ {
277
+ ref,
278
+ "data-slot": "select-scroll-up-button",
279
+ className: cn("flex cursor-default items-center justify-center py-1", className),
280
+ ...props,
281
+ children: /* @__PURE__ */ jsx(ChevronUp, { className: "size-4", "aria-hidden": "true" })
282
+ }
283
+ ));
284
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
285
+ var SelectScrollDownButton = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
286
+ SelectPrimitive.ScrollDownButton,
287
+ {
288
+ ref,
289
+ "data-slot": "select-scroll-down-button",
290
+ className: cn("flex cursor-default items-center justify-center py-1", className),
291
+ ...props,
292
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4", "aria-hidden": "true" })
293
+ }
294
+ ));
295
+ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
296
+ var SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
297
+ SelectPrimitive.Content,
298
+ {
299
+ ref,
300
+ "data-slot": "select-content",
301
+ className: cn(
302
+ "bg-popover text-popover-foreground data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-32 overflow-hidden rounded-md border shadow-md",
303
+ position === "popper" && "translate-y-1",
304
+ className
305
+ ),
306
+ position,
307
+ ...props,
308
+ children: [
309
+ /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
310
+ /* @__PURE__ */ jsx(
311
+ SelectPrimitive.Viewport,
312
+ {
313
+ "data-slot": "select-viewport",
314
+ className: cn(
315
+ "p-1",
316
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
317
+ ),
318
+ children
319
+ }
320
+ ),
321
+ /* @__PURE__ */ jsx(SelectScrollDownButton, {})
322
+ ]
323
+ }
324
+ ) }));
325
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
326
+ var SelectLabel = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
327
+ SelectPrimitive.Label,
328
+ {
329
+ ref,
330
+ "data-slot": "select-label",
331
+ className: cn("px-2 py-1.5 text-sm font-medium", className),
332
+ ...props
333
+ }
334
+ ));
335
+ SelectLabel.displayName = SelectPrimitive.Label.displayName;
336
+ var SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
337
+ SelectPrimitive.Item,
338
+ {
339
+ ref,
340
+ "data-slot": "select-item",
341
+ className: cn(
342
+ "focus:bg-accent focus:text-accent-foreground data-[state=checked]:bg-accent data-[state=checked]:text-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm px-2.5 py-1.5 text-sm outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[state=checked]:font-medium [&_svg]:pointer-events-none [&_svg]:shrink-0",
343
+ className
344
+ ),
345
+ ...props,
346
+ children: /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
347
+ }
348
+ ));
349
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
350
+ var SelectSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
351
+ SelectPrimitive.Separator,
352
+ {
353
+ ref,
354
+ "data-slot": "select-separator",
355
+ className: cn("bg-border -mx-1 my-1 h-px", className),
356
+ ...props
357
+ }
358
+ ));
359
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
360
+ function groupDataOptions(options) {
361
+ const order = [];
362
+ const buckets = /* @__PURE__ */ new Map();
363
+ for (const option of options) {
364
+ const key = option.group ?? "";
365
+ if (!buckets.has(key)) {
366
+ buckets.set(key, []);
367
+ order.push(key);
368
+ }
369
+ buckets.get(key).push(option);
370
+ }
371
+ return order.map((key) => ({ heading: key || void 0, items: buckets.get(key) ?? [] }));
372
+ }
373
+ function DataSelect({
374
+ options = [],
375
+ loadOptions,
376
+ showSearch,
377
+ value = "",
378
+ onValueChange,
379
+ renderOption,
380
+ selectedLabel,
381
+ placeholder,
382
+ searchPlaceholder,
383
+ emptyMessage,
384
+ loadingMessage,
385
+ clearLabel,
386
+ clearable,
387
+ disabled,
388
+ name,
389
+ id,
390
+ className,
391
+ "data-testid": dataTestId
392
+ }) {
393
+ const searchable = showSearch ?? Boolean(loadOptions);
394
+ if (searchable) {
395
+ return /* @__PURE__ */ jsx(
396
+ SearchSelect,
397
+ {
398
+ value,
399
+ onValueChange,
400
+ options,
401
+ loadOptions,
402
+ renderOption,
403
+ selectedLabel,
404
+ placeholder,
405
+ searchPlaceholder,
406
+ emptyMessage,
407
+ loadingMessage,
408
+ clearLabel,
409
+ clearable,
410
+ disabled,
411
+ name,
412
+ id,
413
+ className,
414
+ "data-testid": dataTestId
415
+ }
416
+ );
417
+ }
418
+ const optionTestId = (optionValue) => dataTestId ? `${dataTestId}-option-${optionValue}` : void 0;
419
+ const renderItem = (option) => /* @__PURE__ */ jsx(
420
+ SelectItem,
421
+ {
422
+ value: option.value,
423
+ disabled: option.disabled,
424
+ "data-testid": optionTestId(option.value),
425
+ children: renderOption ? renderOption(option) : option.label
426
+ },
427
+ option.value
428
+ );
429
+ return /* @__PURE__ */ jsxs(
430
+ SelectPrimitive.Root,
431
+ {
432
+ "data-slot": "select",
433
+ value: value || void 0,
434
+ onValueChange: (next) => onValueChange?.(
435
+ next,
436
+ options.find((option) => option.value === next)
437
+ ),
438
+ disabled,
439
+ name,
440
+ children: [
441
+ /* @__PURE__ */ jsx(SelectTrigger, { id, "data-testid": dataTestId, className, children: /* @__PURE__ */ jsx(SelectValue, { placeholder }) }),
442
+ /* @__PURE__ */ jsx(SelectContent, { children: groupDataOptions(options).map(
443
+ (group) => group.heading ? /* @__PURE__ */ jsxs(SelectGroup, { children: [
444
+ /* @__PURE__ */ jsx(SelectLabel, { children: group.heading }),
445
+ group.items.map(renderItem)
446
+ ] }, group.heading) : /* @__PURE__ */ jsx(React.Fragment, { children: group.items.map(renderItem) }, "__ungrouped")
447
+ ) })
448
+ ]
449
+ }
450
+ );
451
+ }
452
+
453
+ export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue };
@@ -6,14 +6,14 @@ import { jsx, jsxs } from 'react/jsx-runtime';
6
6
  var cardVariants = cva("group/card border", {
7
7
  variants: {
8
8
  size: {
9
- default: "",
9
+ md: "",
10
10
  compact: ""
11
11
  }
12
12
  },
13
- defaultVariants: { size: "default" }
13
+ defaultVariants: { size: "md" }
14
14
  });
15
15
  var Card = React.forwardRef(
16
- ({ className, size = "default", accent, variant, density, ...props }, ref) => /* @__PURE__ */ jsx(
16
+ ({ className, size = "md", accent, variant, density, ...props }, ref) => /* @__PURE__ */ jsx(
17
17
  "div",
18
18
  {
19
19
  ref,
@@ -1,6 +1,6 @@
1
- import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-CAEL2ZD2.js';
1
+ import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-NXVCI6YB.js';
2
2
  import { Button } from './chunk-M4PZNAMV.js';
3
- import { useTranslation } from './chunk-RLGHEV4A.js';
3
+ import { useTranslation } from './chunk-HTG5VHU7.js';
4
4
  import { cn } from './chunk-U7N2A7A3.js';
5
5
  import * as React from 'react';
6
6
  import { MoreHorizontal, ChevronLeft, ChevronRight } from 'lucide-react';
@@ -38,13 +38,14 @@ var PaginationItem = React.forwardRef(
38
38
  );
39
39
  PaginationItem.displayName = "PaginationItem";
40
40
  var PaginationLink = React.forwardRef(
41
- ({ className, isActive, disabled, children, onClick, ...props }, ref) => /* @__PURE__ */ jsx(
42
- "a",
41
+ ({ className, isActive, disabled, children, onClick, href: _href, ...props }, ref) => /* @__PURE__ */ jsx(
42
+ "button",
43
43
  {
44
44
  ref,
45
+ type: "button",
45
46
  "data-active": isActive || void 0,
46
47
  "aria-current": isActive ? "page" : void 0,
47
- "aria-disabled": disabled || void 0,
48
+ disabled: disabled || void 0,
48
49
  "data-state": disabled ? "disabled" : void 0,
49
50
  className: cn(
50
51
  "ui-pagination-link ui-button--compact-icon ui-pagination-page",
@@ -52,14 +53,7 @@ var PaginationLink = React.forwardRef(
52
53
  disabled ? "ui-pagination-link-disabled" : void 0,
53
54
  className
54
55
  ),
55
- role: "button",
56
- onClick: (event) => {
57
- if (disabled) {
58
- event.preventDefault();
59
- return;
60
- }
61
- onClick?.(event);
62
- },
56
+ onClick,
63
57
  ...props,
64
58
  children
65
59
  }
@@ -104,7 +98,7 @@ var PaginationNext = React.forwardRef(
104
98
  );
105
99
  PaginationNext.displayName = "PaginationNext";
106
100
  function Pagination({
107
- current = 1,
101
+ value = 1,
108
102
  total = 0,
109
103
  pageSize = 10,
110
104
  pageSizeOptions = [10, 20, 50, 100],
@@ -113,16 +107,16 @@ function Pagination({
113
107
  simple,
114
108
  disabled,
115
109
  className,
116
- onChange
110
+ onValueChange
117
111
  }) {
118
112
  const { t } = useTranslation();
119
113
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
120
- const safeCurrent = Math.min(Math.max(1, current), totalPages);
114
+ const safeCurrent = Math.min(Math.max(1, value), totalPages);
121
115
  const pages = buildPageRange(safeCurrent, totalPages);
122
116
  const go = (page, size = pageSize) => {
123
117
  if (disabled) return;
124
118
  const nextPage = Math.min(Math.max(1, page), Math.max(1, Math.ceil(total / size)));
125
- onChange?.(nextPage, size);
119
+ onValueChange?.(nextPage, size);
126
120
  };
127
121
  const totalLabel = typeof showTotal === "function" ? showTotal(total, [
128
122
  (safeCurrent - 1) * pageSize + 1,
@@ -200,12 +194,8 @@ function Pagination({
200
194
  /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
201
195
  PaginationPrevious,
202
196
  {
203
- href: "#",
204
197
  "aria-label": t("navigation.pagination.prev"),
205
- onClick: (event) => {
206
- event.preventDefault();
207
- go(safeCurrent - 1);
208
- },
198
+ onClick: () => go(safeCurrent - 1),
209
199
  className: "ui-button--compact-icon",
210
200
  disabled: Boolean(disabled) || safeCurrent <= 1,
211
201
  children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true" })
@@ -217,11 +207,9 @@ function Pagination({
217
207
  {
218
208
  isActive: page === safeCurrent,
219
209
  "aria-label": t("navigation.pagination.page", { page }),
220
- onClick: (event) => {
221
- event.preventDefault();
210
+ onClick: () => {
222
211
  if (!disabled) go(page);
223
212
  },
224
- href: "#",
225
213
  disabled,
226
214
  children: page
227
215
  }
@@ -230,12 +218,8 @@ function Pagination({
230
218
  /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
231
219
  PaginationNext,
232
220
  {
233
- href: "#",
234
221
  "aria-label": t("navigation.pagination.next"),
235
- onClick: (event) => {
236
- event.preventDefault();
237
- go(safeCurrent + 1);
238
- },
222
+ onClick: () => go(safeCurrent + 1),
239
223
  className: "ui-button--compact-icon",
240
224
  disabled: Boolean(disabled) || safeCurrent >= totalPages,
241
225
  children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })