@godxjp/ui 13.6.0 → 13.8.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 (106) hide show
  1. package/dist/app/index.js +4 -4
  2. package/dist/{checkbox-DAIwpMHO.d.ts → checkbox-BpnDa6_M.d.ts} +1 -1
  3. package/dist/{chunk-2JW2QLUU.js → chunk-2MRAHKOD.js} +3 -3
  4. package/dist/{chunk-6MZMMMHV.js → chunk-3VFNWVR7.js} +5 -5
  5. package/dist/{chunk-IRPZJKLU.js → chunk-4FGE5XVC.js} +10 -0
  6. package/dist/{chunk-J254ZX3A.js → chunk-4SSJ54R2.js} +4 -4
  7. package/dist/{chunk-C7W5BO7R.js → chunk-5732TWQF.js} +22 -1
  8. package/dist/chunk-57VDEN64.js +881 -0
  9. package/dist/{chunk-UKTVFPRV.js → chunk-65RWSIZF.js} +4 -4
  10. package/dist/{chunk-5XFFEW2P.js → chunk-A3J2G2ZA.js} +2 -2
  11. package/dist/{chunk-QTEPKNQE.js → chunk-B6S6LTWT.js} +1 -1
  12. package/dist/{chunk-PKSHDFKP.js → chunk-BJTNKNMY.js} +36 -10
  13. package/dist/{chunk-W2RYT6NT.js → chunk-D4JX6O2W.js} +3 -3
  14. package/dist/{chunk-KNI7QI4J.js → chunk-FLY23H4G.js} +2 -2
  15. package/dist/{chunk-ZYJRZLMZ.js → chunk-HIEGUYPP.js} +1 -1
  16. package/dist/{chunk-UVGI2RPC.js → chunk-HRW7JDUJ.js} +4 -4
  17. package/dist/{chunk-UDMFKYZG.js → chunk-I5D4QYZI.js} +3 -3
  18. package/dist/{chunk-76S3TQFH.js → chunk-IAJOP2Z3.js} +31 -13
  19. package/dist/{chunk-LFO5BJ4H.js → chunk-ION2KFXK.js} +2 -2
  20. package/dist/{chunk-6AIYMYSG.js → chunk-K24AQV4R.js} +1 -1
  21. package/dist/{chunk-6VUW6EKH.js → chunk-L6NMIUKC.js} +2 -2
  22. package/dist/{chunk-RBXVCWXL.js → chunk-LVLPNKJP.js} +2 -2
  23. package/dist/{chunk-HS73G2C3.js → chunk-NU2SOVTU.js} +9 -3
  24. package/dist/{chunk-B7R7DHZF.js → chunk-NZBAFFWP.js} +1 -1
  25. package/dist/{chunk-LTKHPOE3.js → chunk-PL4NEIVO.js} +1 -1
  26. package/dist/{chunk-ZOMIELKI.js → chunk-Q3KUZG4P.js} +1 -1
  27. package/dist/{chunk-DVV6UYVS.js → chunk-QE4IYHJU.js} +3 -3
  28. package/dist/{chunk-3JQDPNTA.js → chunk-R2TXLS7S.js} +1 -1
  29. package/dist/{chunk-2FJ5TMQU.js → chunk-X6AJ5HEI.js} +1 -1
  30. package/dist/{chunk-XZH3URGD.js → chunk-XBFUROAY.js} +6 -3
  31. package/dist/{chunk-I472SSN2.js → chunk-YLRCDJMR.js} +1 -1
  32. package/dist/chunk-YXVJFYQE.js +191 -0
  33. package/dist/components/admin/index.d.ts +2 -2
  34. package/dist/components/admin/index.js +23 -23
  35. package/dist/components/data-display/badge.js +3 -3
  36. package/dist/components/data-display/card.d.ts +2 -2
  37. package/dist/components/data-display/carousel.js +3 -3
  38. package/dist/components/data-display/index.js +7 -7
  39. package/dist/components/data-entry/calendar.d.ts +1 -1
  40. package/dist/components/data-entry/calendar.js +4 -4
  41. package/dist/components/data-entry/cascader.d.ts +1 -1
  42. package/dist/components/data-entry/cascader.js +4 -4
  43. package/dist/components/data-entry/checkbox.d.ts +2 -2
  44. package/dist/components/data-entry/color-picker.d.ts +1 -1
  45. package/dist/components/data-entry/color-picker.js +4 -4
  46. package/dist/components/data-entry/date-picker.d.ts +1 -1
  47. package/dist/components/data-entry/date-picker.js +6 -6
  48. package/dist/components/data-entry/date-range-picker.d.ts +6 -4
  49. package/dist/components/data-entry/date-range-picker.js +5 -6
  50. package/dist/components/data-entry/index.d.ts +24 -6
  51. package/dist/components/data-entry/index.js +21 -21
  52. package/dist/components/data-entry/input.js +3 -3
  53. package/dist/components/data-entry/radio.d.ts +1 -1
  54. package/dist/components/data-entry/select.d.ts +1 -1
  55. package/dist/components/data-entry/select.js +5 -5
  56. package/dist/components/data-entry/slider.d.ts +1 -1
  57. package/dist/components/data-entry/switch.d.ts +1 -1
  58. package/dist/components/data-entry/textarea.js +3 -3
  59. package/dist/components/data-entry/time-input.js +2 -2
  60. package/dist/components/data-entry/time-picker.d.ts +1 -1
  61. package/dist/components/data-entry/time-picker.js +5 -5
  62. package/dist/components/data-entry/transfer.d.ts +2 -2
  63. package/dist/components/data-entry/transfer.js +6 -6
  64. package/dist/components/data-entry/tree-select.d.ts +1 -1
  65. package/dist/components/data-entry/tree-select.js +4 -4
  66. package/dist/components/data-entry/upload.d.ts +2 -2
  67. package/dist/components/data-entry/upload.js +7 -7
  68. package/dist/components/data-grid/index.js +6 -6
  69. package/dist/components/feedback/alert.js +5 -5
  70. package/dist/components/feedback/dialog.js +5 -5
  71. package/dist/components/feedback/index.js +7 -7
  72. package/dist/components/general/button.d.ts +3 -1
  73. package/dist/components/general/button.js +3 -3
  74. package/dist/components/general/index.d.ts +1 -1
  75. package/dist/components/general/index.js +3 -3
  76. package/dist/components/layout/index.js +3 -3
  77. package/dist/components/navigation/index.js +9 -9
  78. package/dist/components/navigation/pagination.js +6 -6
  79. package/dist/components/navigation/steps.js +3 -3
  80. package/dist/components/query/index.d.ts +2 -2
  81. package/dist/components/query/index.js +5 -5
  82. package/dist/components/ui/index.d.ts +3 -3
  83. package/dist/components/ui/index.js +22 -22
  84. package/dist/{data-entry.prop-vn5VGnwY.d.ts → data-entry.prop-C9QWj5Kl.d.ts} +61 -2
  85. package/dist/form/index.js +1 -1
  86. package/dist/{general.prop-CzcLDzMw.d.ts → general.prop-CzlQin6v.d.ts} +11 -1
  87. package/dist/i18n/index.d.ts +6 -0
  88. package/dist/i18n/index.js +2 -2
  89. package/dist/index.d.ts +2 -2
  90. package/dist/index.js +31 -31
  91. package/dist/lib/datetime/index.js +1 -1
  92. package/dist/props/components/index.d.ts +3 -3
  93. package/dist/props/index.d.ts +3 -3
  94. package/dist/props/index.js +1 -1
  95. package/dist/props/registry.d.ts +10 -0
  96. package/dist/props/registry.js +1 -1
  97. package/dist/{query.prop-DAILZ0x5.d.ts → query.prop-CT2gFtr4.d.ts} +1 -1
  98. package/dist/{search-input-Oxwpv_s9.d.ts → search-input-d1g8eW9z.d.ts} +1 -1
  99. package/dist/styles/form-layout.css +5 -5
  100. package/dist/styles/layout.css +2 -2
  101. package/dist/tokens/base.css +1 -0
  102. package/dist/tokens/components/form.css +11 -0
  103. package/dist/tokens/semantic/layout.css +11 -0
  104. package/package.json +4 -2
  105. package/dist/chunk-GFDKJY63.js +0 -467
  106. package/dist/chunk-OIAT773P.js +0 -183
@@ -1,467 +0,0 @@
1
- import { Input } from './chunk-6AIYMYSG.js';
2
- import { Button } from './chunk-XZH3URGD.js';
3
- import { useTranslation } from './chunk-QTEPKNQE.js';
4
- import { cn } from './chunk-U7N2A7A3.js';
5
- import * as React from 'react';
6
- import { ChevronUp, ChevronDown, EyeOff, Eye, Minus, Star, X } from 'lucide-react';
7
- import { jsxs, jsx } from 'react/jsx-runtime';
8
- import { OTPInput, OTPInputContext } from 'input-otp';
9
-
10
- function decimalsOf(n) {
11
- if (!Number.isFinite(n)) return 0;
12
- const s = String(n);
13
- const dot = s.indexOf(".");
14
- return dot === -1 ? 0 : s.length - dot - 1;
15
- }
16
- function clamp(n, min, max) {
17
- let out = n;
18
- if (min != null && out < min) out = min;
19
- if (max != null && out > max) out = max;
20
- return out;
21
- }
22
- function roundTo(n, precision) {
23
- if (!Number.isFinite(n)) return n;
24
- const factor = 10 ** precision;
25
- return Math.round((n + Number.EPSILON) * factor) / factor;
26
- }
27
- var NumberInput = React.forwardRef(
28
- ({
29
- value: controlledValue,
30
- defaultValue = null,
31
- onValueChange,
32
- min,
33
- max,
34
- step = 1,
35
- precision,
36
- disabled,
37
- readOnly,
38
- size = "md",
39
- placeholder,
40
- prefix,
41
- suffix,
42
- name,
43
- id,
44
- className,
45
- "aria-label": ariaLabel,
46
- "aria-labelledby": ariaLabelledby,
47
- "aria-describedby": ariaDescribedby,
48
- "data-testid": dataTestId
49
- }, ref) => {
50
- const { t, locale } = useTranslation();
51
- const isControlled = controlledValue !== void 0;
52
- const [internal, setInternal] = React.useState(defaultValue);
53
- const numericValue = isControlled ? controlledValue ?? null : internal;
54
- const effectivePrecision = precision ?? decimalsOf(step);
55
- const formatter = React.useMemo(
56
- () => new Intl.NumberFormat(locale, {
57
- minimumFractionDigits: 0,
58
- maximumFractionDigits: Math.max(effectivePrecision, 0),
59
- useGrouping: false
60
- }),
61
- [locale, effectivePrecision]
62
- );
63
- const formatAtRest = React.useCallback(
64
- (n) => n == null ? "" : formatter.format(n),
65
- [formatter]
66
- );
67
- const [draft, setDraft] = React.useState(() => formatAtRest(numericValue));
68
- const [focused, setFocused] = React.useState(false);
69
- React.useEffect(() => {
70
- if (focused) return;
71
- setDraft(formatAtRest(numericValue));
72
- }, [numericValue, focused, formatAtRest]);
73
- const commit = React.useCallback(
74
- (next) => {
75
- const normalized = next == null || Number.isNaN(next) ? null : roundTo(clamp(next, min, max), effectivePrecision);
76
- if (!isControlled) setInternal(normalized);
77
- onValueChange?.(normalized);
78
- if (!focused) setDraft(formatAtRest(normalized));
79
- return normalized;
80
- },
81
- [effectivePrecision, focused, formatAtRest, isControlled, max, min, onValueChange]
82
- );
83
- const stepBy = React.useCallback(
84
- (direction, multiplier = 1) => {
85
- const base = numericValue ?? min ?? 0;
86
- const next = base + direction * step * multiplier;
87
- const committed = commit(next);
88
- setDraft(formatAtRest(committed));
89
- },
90
- [commit, formatAtRest, min, numericValue, step]
91
- );
92
- const atMin = min != null && numericValue != null && numericValue <= min;
93
- const atMax = max != null && numericValue != null && numericValue >= max;
94
- const interactive = !disabled && !readOnly;
95
- const handleChange = (event) => {
96
- const raw = event.target.value;
97
- setDraft(raw);
98
- if (readOnly) return;
99
- const trimmed = raw.trim();
100
- if (trimmed === "" || trimmed === "-") {
101
- if (trimmed === "") commit(null);
102
- return;
103
- }
104
- const parsed = Number(trimmed);
105
- if (Number.isNaN(parsed)) return;
106
- if (!isControlled) setInternal(parsed);
107
- onValueChange?.(parsed);
108
- };
109
- const handleBlur = () => {
110
- setFocused(false);
111
- const trimmed = draft.trim();
112
- if (trimmed === "" || trimmed === "-") {
113
- commit(null);
114
- setDraft(formatAtRest(null));
115
- return;
116
- }
117
- const parsed = Number(trimmed);
118
- const committed = commit(Number.isNaN(parsed) ? null : parsed);
119
- setDraft(formatAtRest(committed));
120
- };
121
- const handleKeyDown = (event) => {
122
- if (!interactive) return;
123
- if (event.key === "ArrowUp") {
124
- event.preventDefault();
125
- stepBy(1, event.shiftKey ? 10 : 1);
126
- } else if (event.key === "ArrowDown") {
127
- event.preventDefault();
128
- stepBy(-1, event.shiftKey ? 10 : 1);
129
- } else if (event.key === "Enter") {
130
- const trimmed = draft.trim();
131
- const parsed = Number(trimmed);
132
- const committed = commit(trimmed === "" || Number.isNaN(parsed) ? null : parsed);
133
- setDraft(formatAtRest(committed));
134
- }
135
- };
136
- return /* @__PURE__ */ jsxs("div", { "data-slot": "number-input", "data-size": size, className: cn("ui-number-input", className), children: [
137
- prefix != null ? /* @__PURE__ */ jsx(
138
- "span",
139
- {
140
- "data-slot": "number-input-prefix",
141
- className: "ui-number-input-affix",
142
- "aria-hidden": "true",
143
- children: prefix
144
- }
145
- ) : null,
146
- /* @__PURE__ */ jsx(
147
- Input,
148
- {
149
- ref,
150
- id,
151
- name,
152
- type: "text",
153
- inputMode: "decimal",
154
- autoComplete: "off",
155
- role: "spinbutton",
156
- "data-slot": "number-input-field",
157
- "data-testid": dataTestId,
158
- className: "ui-number-input-field",
159
- value: draft,
160
- placeholder,
161
- disabled,
162
- readOnly,
163
- "aria-label": ariaLabel,
164
- "aria-labelledby": ariaLabelledby,
165
- "aria-describedby": ariaDescribedby,
166
- "aria-valuenow": numericValue ?? void 0,
167
- "aria-valuemin": min,
168
- "aria-valuemax": max,
169
- "aria-valuetext": numericValue != null ? formatAtRest(numericValue) : void 0,
170
- onChange: handleChange,
171
- onFocus: () => setFocused(true),
172
- onBlur: handleBlur,
173
- onKeyDown: handleKeyDown
174
- }
175
- ),
176
- suffix != null ? /* @__PURE__ */ jsx(
177
- "span",
178
- {
179
- "data-slot": "number-input-suffix",
180
- className: "ui-number-input-affix",
181
- "aria-hidden": "true",
182
- children: suffix
183
- }
184
- ) : null,
185
- /* @__PURE__ */ jsxs("span", { "data-slot": "number-input-steppers", className: "ui-number-input-steppers", children: [
186
- /* @__PURE__ */ jsx(
187
- Button,
188
- {
189
- type: "button",
190
- variant: "outline",
191
- size: "icon-xs",
192
- className: "ui-number-input-step ui-number-input-step-up",
193
- tabIndex: -1,
194
- disabled: !interactive || atMax,
195
- "aria-label": t("ui.numberInput.increment"),
196
- onClick: () => stepBy(1),
197
- children: /* @__PURE__ */ jsx(ChevronUp, { "aria-hidden": "true" })
198
- }
199
- ),
200
- /* @__PURE__ */ jsx(
201
- Button,
202
- {
203
- type: "button",
204
- variant: "outline",
205
- size: "icon-xs",
206
- className: "ui-number-input-step ui-number-input-step-down",
207
- tabIndex: -1,
208
- disabled: !interactive || atMin,
209
- "aria-label": t("ui.numberInput.decrement"),
210
- onClick: () => stepBy(-1),
211
- children: /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" })
212
- }
213
- )
214
- ] })
215
- ] });
216
- }
217
- );
218
- NumberInput.displayName = "NumberInput";
219
- var PasswordInput = React.forwardRef(
220
- ({ className, ...props }, ref) => {
221
- const { t } = useTranslation();
222
- const [visible, setVisible] = React.useState(false);
223
- return /* @__PURE__ */ jsxs("div", { className: "ui-password-input", "data-slot": "password-input", children: [
224
- /* @__PURE__ */ jsx(
225
- Input,
226
- {
227
- ref,
228
- type: visible ? "text" : "password",
229
- className: cn("ui-password-input-field", className),
230
- ...props
231
- }
232
- ),
233
- /* @__PURE__ */ jsx(
234
- "button",
235
- {
236
- type: "button",
237
- className: "ui-password-input-toggle",
238
- onClick: () => setVisible((v) => !v),
239
- "aria-label": visible ? t("ui.passwordInput.hide") : t("ui.passwordInput.show"),
240
- "aria-pressed": visible,
241
- children: visible ? /* @__PURE__ */ jsx(EyeOff, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Eye, { "aria-hidden": "true" })
242
- }
243
- )
244
- ] });
245
- }
246
- );
247
- PasswordInput.displayName = "PasswordInput";
248
- var InputOTP = React.forwardRef(({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ jsx(
249
- OTPInput,
250
- {
251
- ref,
252
- "data-slot": "input-otp",
253
- containerClassName: cn("ui-otp-container", containerClassName),
254
- className: cn("ui-otp-input", className),
255
- ...props
256
- }
257
- ));
258
- InputOTP.displayName = "InputOTP";
259
- var InputOTPGroup = React.forwardRef(
260
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
261
- "div",
262
- {
263
- ref,
264
- "data-slot": "input-otp-group",
265
- className: cn("ui-otp-group", className),
266
- ...props
267
- }
268
- )
269
- );
270
- InputOTPGroup.displayName = "InputOTPGroup";
271
- var InputOTPSlot = React.forwardRef(({ index, className, ...props }, ref) => {
272
- const context = React.useContext(OTPInputContext);
273
- const slot = context.slots[index] ?? { char: null, hasFakeCaret: false, isActive: false };
274
- return /* @__PURE__ */ jsxs(
275
- "div",
276
- {
277
- ref,
278
- "data-slot": "input-otp-slot",
279
- "data-active": slot.isActive || void 0,
280
- className: cn("ui-otp-slot", className),
281
- ...props,
282
- children: [
283
- slot.char,
284
- slot.hasFakeCaret ? /* @__PURE__ */ jsx("div", { className: "ui-otp-caret-wrapper", "aria-hidden": "true", children: /* @__PURE__ */ jsx("div", { className: "ui-otp-caret" }) }) : null
285
- ]
286
- }
287
- );
288
- });
289
- InputOTPSlot.displayName = "InputOTPSlot";
290
- var InputOTPSeparator = React.forwardRef(({ ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, "data-slot": "input-otp-separator", role: "separator", ...props, children: /* @__PURE__ */ jsx(Minus, { className: "ui-otp-separator-icon", "aria-hidden": "true" }) }));
291
- InputOTPSeparator.displayName = "InputOTPSeparator";
292
- var Rating = React.forwardRef(
293
- ({
294
- value,
295
- defaultValue = 0,
296
- onValueChange,
297
- max = 5,
298
- readOnly,
299
- disabled,
300
- name,
301
- className,
302
- ...rest
303
- }, ref) => {
304
- const { t } = useTranslation();
305
- const [internal, setInternal] = React.useState(defaultValue);
306
- const current = value ?? internal;
307
- const [hover, setHover] = React.useState(null);
308
- const display = hover ?? current;
309
- const interactive = !readOnly && !disabled;
310
- const select = (next) => {
311
- if (!interactive) return;
312
- if (value === void 0) setInternal(next);
313
- onValueChange?.(next);
314
- };
315
- const focusableStar = current > 0 ? current : 1;
316
- const onKeyDown = (e, star) => {
317
- if (!interactive) return;
318
- let next = null;
319
- switch (e.key) {
320
- case "ArrowRight":
321
- case "ArrowUp":
322
- next = Math.min(max, star + 1);
323
- break;
324
- case "ArrowLeft":
325
- case "ArrowDown":
326
- next = Math.max(1, star - 1);
327
- break;
328
- case "Home":
329
- next = 1;
330
- break;
331
- case "End":
332
- next = max;
333
- break;
334
- default:
335
- return;
336
- }
337
- e.preventDefault();
338
- select(next);
339
- };
340
- return /* @__PURE__ */ jsxs(
341
- "div",
342
- {
343
- ref,
344
- role: "radiogroup",
345
- "data-slot": "rating",
346
- className: cn("ui-rating", className),
347
- "aria-label": rest["aria-label"] ?? t("ui.rating.ariaLabel"),
348
- children: [
349
- Array.from({ length: max }, (_, i) => i + 1).map((star) => /* @__PURE__ */ jsx(
350
- "button",
351
- {
352
- type: "button",
353
- role: "radio",
354
- "aria-checked": current === star,
355
- "aria-label": t("ui.rating.starLabel", { star, max }),
356
- disabled: disabled || readOnly,
357
- tabIndex: interactive && star === focusableStar ? 0 : -1,
358
- className: cn("ui-rating-star", star <= display && "ui-rating-star-filled"),
359
- onMouseEnter: () => interactive && setHover(star),
360
- onMouseLeave: () => setHover(null),
361
- onClick: () => select(star),
362
- onKeyDown: (e) => onKeyDown(e, star),
363
- children: /* @__PURE__ */ jsx(Star, { "aria-hidden": "true" })
364
- },
365
- star
366
- )),
367
- name ? /* @__PURE__ */ jsx("input", { type: "hidden", name, value: current }) : null
368
- ]
369
- }
370
- );
371
- }
372
- );
373
- Rating.displayName = "Rating";
374
- var TagInput = React.forwardRef(
375
- ({
376
- value,
377
- defaultValue = [],
378
- onValueChange,
379
- placeholder,
380
- disabled,
381
- name,
382
- className,
383
- id,
384
- "aria-label": ariaLabel
385
- }, ref) => {
386
- const { t } = useTranslation();
387
- const [internal, setInternal] = React.useState(defaultValue);
388
- const tags = value ?? internal;
389
- const [draft, setDraft] = React.useState("");
390
- const commit = (next) => {
391
- if (value === void 0) setInternal(next);
392
- onValueChange?.(next);
393
- };
394
- const add = (raw) => {
395
- const tag = raw.trim();
396
- if (!tag || tags.includes(tag)) return;
397
- commit([...tags, tag]);
398
- };
399
- const removeAt = (i) => commit(tags.filter((_, idx) => idx !== i));
400
- const onKeyDown = (e) => {
401
- if (e.key === "Enter" || e.key === ",") {
402
- e.preventDefault();
403
- add(draft);
404
- setDraft("");
405
- } else if (e.key === "Backspace" && draft === "" && tags.length > 0) {
406
- removeAt(tags.length - 1);
407
- }
408
- };
409
- return /* @__PURE__ */ jsxs(
410
- "div",
411
- {
412
- "data-slot": "tag-input",
413
- className: cn("ui-tag-input", disabled && "ui-tag-input-disabled", className),
414
- children: [
415
- tags.length > 0 ? /* @__PURE__ */ jsx("ul", { role: "list", className: "ui-tag-input-list", "data-slot": "tag-input-list", children: tags.map((tag, i) => /* @__PURE__ */ jsxs(
416
- "li",
417
- {
418
- role: "listitem",
419
- className: "ui-tag-input-chip",
420
- "data-slot": "tag-input-chip",
421
- children: [
422
- tag,
423
- !disabled ? /* @__PURE__ */ jsx(
424
- "button",
425
- {
426
- type: "button",
427
- className: "ui-tag-input-remove",
428
- "aria-label": t("ui.tagInput.removeTag", { tag }),
429
- onClick: () => removeAt(i),
430
- children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true" })
431
- }
432
- ) : null
433
- ]
434
- },
435
- tag
436
- )) }) : null,
437
- /* @__PURE__ */ jsx(
438
- "input",
439
- {
440
- ref,
441
- id,
442
- type: "text",
443
- className: "ui-tag-input-field",
444
- value: draft,
445
- placeholder: tags.length === 0 ? placeholder : void 0,
446
- disabled,
447
- "aria-label": ariaLabel ?? t("ui.tagInput.inputLabel"),
448
- onChange: (e) => setDraft(e.target.value),
449
- onKeyDown,
450
- onBlur: () => {
451
- if (draft.trim()) {
452
- add(draft);
453
- setDraft("");
454
- }
455
- }
456
- }
457
- ),
458
- /* @__PURE__ */ jsx("span", { "aria-live": "polite", className: "sr-only", "data-slot": "tag-input-status", children: t("ui.tagInput.tagCount", { count: tags.length }) }),
459
- name ? /* @__PURE__ */ jsx("input", { type: "hidden", name, value: tags.join(",") }) : null
460
- ]
461
- }
462
- );
463
- }
464
- );
465
- TagInput.displayName = "TagInput";
466
-
467
- export { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, NumberInput, PasswordInput, Rating, TagInput };
@@ -1,183 +0,0 @@
1
- import { Calendar } from './chunk-HS73G2C3.js';
2
- import { Input } from './chunk-6AIYMYSG.js';
3
- import { Button } from './chunk-XZH3URGD.js';
4
- import { Popover, PopoverAnchor, PopoverTrigger, PopoverContent } from './chunk-DY5C44UP.js';
5
- import { useTranslation, usePickerLocales } from './chunk-QTEPKNQE.js';
6
- import { toIsoDate, parseDateInput } from './chunk-C7W5BO7R.js';
7
- import { cn } from './chunk-U7N2A7A3.js';
8
- import * as React from 'react';
9
- import { X, CalendarIcon } from 'lucide-react';
10
- import { jsx, jsxs } from 'react/jsx-runtime';
11
-
12
- var ISO_HINT = "yyyy-mm-dd";
13
- function DateRangePicker({
14
- value: valueProp,
15
- defaultValue,
16
- onValueChange,
17
- placeholder,
18
- disabled,
19
- className,
20
- id,
21
- name,
22
- locale: localeProp,
23
- fromDate,
24
- toDate,
25
- allowClear = true
26
- }) {
27
- const { t } = useTranslation();
28
- const { dayPickerLocale } = usePickerLocales(localeProp);
29
- const [open, setOpen] = React.useState(false);
30
- const isControlled = React.useRef(valueProp !== void 0).current;
31
- const [internalValue, setInternalValue] = React.useState(defaultValue);
32
- const value = isControlled ? valueProp : internalValue;
33
- const [fromText, setFromText] = React.useState(() => toIsoDate(value?.from));
34
- const [toText, setToText] = React.useState(() => toIsoDate(value?.to));
35
- React.useEffect(() => {
36
- setFromText(toIsoDate(value?.from));
37
- setToText(toIsoDate(value?.to));
38
- }, [value?.from, value?.to]);
39
- const resolvedPlaceholder = placeholder ?? t("dataEntry.dateRangePicker.placeholder") ?? ISO_HINT;
40
- const emit = (next) => {
41
- if (!isControlled) setInternalValue(next);
42
- onValueChange?.(next);
43
- };
44
- const showClear = allowClear && Boolean(value?.from || value?.to) && !disabled;
45
- const clear = () => {
46
- emit(void 0);
47
- setFromText("");
48
- setToText("");
49
- };
50
- const commitEdge = (edge, raw) => {
51
- const trimmed = raw.trim();
52
- if (trimmed !== "" && !/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) return;
53
- const parsed = trimmed === "" ? void 0 : parseDateInput(trimmed) ?? void 0;
54
- const next = { from: value?.from, to: value?.to, [edge]: parsed };
55
- emit(next.from || next.to ? next : void 0);
56
- };
57
- return /* @__PURE__ */ jsx(Popover, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-1", className), children: [
58
- /* @__PURE__ */ jsx(
59
- Input,
60
- {
61
- id,
62
- name: name ? `${name}_from` : void 0,
63
- value: fromText,
64
- disabled,
65
- placeholder: resolvedPlaceholder,
66
- inputMode: "numeric",
67
- autoComplete: "off",
68
- "aria-label": t("dataEntry.dateRangePicker.from") ?? "From",
69
- className: "tabular-nums",
70
- onClick: () => {
71
- if (!disabled) setOpen(true);
72
- },
73
- onKeyDown: (event) => {
74
- if (event.key === "ArrowDown") {
75
- event.preventDefault();
76
- setOpen(true);
77
- } else if (event.key === "Escape" && open) {
78
- setOpen(false);
79
- }
80
- },
81
- onChange: (event) => {
82
- setFromText(event.target.value);
83
- commitEdge("from", event.target.value);
84
- },
85
- onBlur: (event) => {
86
- const parsed = parseDateInput(event.target.value.trim());
87
- setFromText(parsed ? toIsoDate(parsed) : toIsoDate(value?.from));
88
- }
89
- }
90
- ),
91
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground shrink-0", "aria-hidden": "true", children: "\u2013" }),
92
- /* @__PURE__ */ jsx(
93
- Input,
94
- {
95
- name: name ? `${name}_to` : void 0,
96
- value: toText,
97
- disabled,
98
- placeholder: resolvedPlaceholder,
99
- inputMode: "numeric",
100
- autoComplete: "off",
101
- "aria-label": t("dataEntry.dateRangePicker.to") ?? "To",
102
- className: "tabular-nums",
103
- onClick: () => {
104
- if (!disabled) setOpen(true);
105
- },
106
- onKeyDown: (event) => {
107
- if (event.key === "ArrowDown") {
108
- event.preventDefault();
109
- setOpen(true);
110
- } else if (event.key === "Escape" && open) {
111
- setOpen(false);
112
- }
113
- },
114
- onChange: (event) => {
115
- setToText(event.target.value);
116
- commitEdge("to", event.target.value);
117
- },
118
- onBlur: (event) => {
119
- const parsed = parseDateInput(event.target.value.trim());
120
- setToText(parsed ? toIsoDate(parsed) : toIsoDate(value?.to));
121
- }
122
- }
123
- ),
124
- showClear ? /* @__PURE__ */ jsx(
125
- Button,
126
- {
127
- type: "button",
128
- variant: "ghost",
129
- size: "icon",
130
- disabled,
131
- tabIndex: -1,
132
- "aria-label": t("common.clear") ?? "Clear",
133
- className: "text-muted-foreground shrink-0 hover:bg-transparent",
134
- onClick: clear,
135
- children: /* @__PURE__ */ jsx(X, { className: "size-4 shrink-0", "aria-hidden": "true" })
136
- }
137
- ) : null,
138
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
139
- Button,
140
- {
141
- type: "button",
142
- variant: "ghost",
143
- size: "icon",
144
- disabled,
145
- tabIndex: -1,
146
- "aria-label": t("dataEntry.dateRangePicker.openCalendar") ?? "Open calendar",
147
- className: "text-muted-foreground shrink-0 hover:bg-transparent",
148
- children: /* @__PURE__ */ jsx(CalendarIcon, { className: "size-4 shrink-0", "aria-hidden": "true" })
149
- }
150
- ) }),
151
- /* @__PURE__ */ jsx(
152
- PopoverContent,
153
- {
154
- className: "w-auto p-0",
155
- align: "start",
156
- onOpenAutoFocus: (event) => event.preventDefault(),
157
- children: /* @__PURE__ */ jsx(
158
- Calendar,
159
- {
160
- mode: "range",
161
- selected: value,
162
- defaultMonth: value?.from,
163
- numberOfMonths: 2,
164
- onSelect: (range) => {
165
- emit(range);
166
- setFromText(toIsoDate(range?.from));
167
- setToText(toIsoDate(range?.to));
168
- },
169
- locale: dayPickerLocale,
170
- disabled: [
171
- ...fromDate ? [{ before: fromDate }] : [],
172
- ...toDate ? [{ after: toDate }] : []
173
- ],
174
- startMonth: fromDate,
175
- endMonth: toDate
176
- }
177
- )
178
- }
179
- )
180
- ] }) }) });
181
- }
182
-
183
- export { DateRangePicker };