@kuraykaraaslan/kui-react 1.0.1

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 (47) hide show
  1. package/LICENSE +17 -0
  2. package/README.md +168 -0
  3. package/dist/AdvancedDataTable-F3DNXDKX.mjs +11 -0
  4. package/dist/DataTable-2G27T4E6.mjs +11 -0
  5. package/dist/DateRangePicker-AL32QB6L.mjs +11 -0
  6. package/dist/DropdownMenu-f5yV9dzM.d.mts +22 -0
  7. package/dist/DropdownMenu-f5yV9dzM.d.ts +22 -0
  8. package/dist/MapView-FERKPCDB.mjs +10 -0
  9. package/dist/ServerDataTable-RZV3K6KQ.mjs +11 -0
  10. package/dist/Tooltip-Bof5GvOc.d.mts +248 -0
  11. package/dist/Tooltip-Bof5GvOc.d.ts +248 -0
  12. package/dist/VideoPlayer-P3I6ESXJ.mjs +9 -0
  13. package/dist/app.d.mts +620 -0
  14. package/dist/app.d.ts +620 -0
  15. package/dist/app.js +7061 -0
  16. package/dist/app.mjs +100 -0
  17. package/dist/chunk-24BCQSLI.mjs +1 -0
  18. package/dist/chunk-45I3EDB2.mjs +90 -0
  19. package/dist/chunk-4IWCD7ID.mjs +1450 -0
  20. package/dist/chunk-5E2HXWFI.mjs +105 -0
  21. package/dist/chunk-C7AYI4XM.mjs +402 -0
  22. package/dist/chunk-J4D44TUA.mjs +1267 -0
  23. package/dist/chunk-KTEWZKNE.mjs +1020 -0
  24. package/dist/chunk-LMUQHL4Z.mjs +3829 -0
  25. package/dist/chunk-MD5OQ4J2.mjs +527 -0
  26. package/dist/chunk-MPJRPYIZ.mjs +1 -0
  27. package/dist/chunk-MPWUEQ7J.mjs +2422 -0
  28. package/dist/chunk-MTT5TKAJ.mjs +93 -0
  29. package/dist/chunk-RBDK7MWQ.mjs +46 -0
  30. package/dist/chunk-SVFQZPNZ.mjs +3648 -0
  31. package/dist/chunk-TZWBBMSG.mjs +1 -0
  32. package/dist/chunk-XA7J6PVJ.mjs +1488 -0
  33. package/dist/chunk-ZLYBRYWQ.mjs +726 -0
  34. package/dist/common.d.mts +921 -0
  35. package/dist/common.d.ts +921 -0
  36. package/dist/common.js +4991 -0
  37. package/dist/common.mjs +172 -0
  38. package/dist/index.d.mts +10 -0
  39. package/dist/index.d.ts +10 -0
  40. package/dist/index.js +17563 -0
  41. package/dist/index.mjs +349 -0
  42. package/dist/ui.d.mts +937 -0
  43. package/dist/ui.d.ts +937 -0
  44. package/dist/ui.js +10095 -0
  45. package/dist/ui.mjs +163 -0
  46. package/package.json +114 -0
  47. package/styles/index.css +129 -0
@@ -0,0 +1,1020 @@
1
+ "use client";
2
+ import {
3
+ __spreadValues,
4
+ cn
5
+ } from "./chunk-RBDK7MWQ.mjs";
6
+
7
+ // modules/ui/DatePicker/index.tsx
8
+ import { useCallback as useCallback2, useEffect as useEffect3, useId as useId2, useMemo, useRef as useRef3, useState as useState2 } from "react";
9
+
10
+ // modules/ui/DatePicker/calendar/Calendar.tsx
11
+ import { useCallback, useEffect as useEffect2, useId, useRef as useRef2, useState } from "react";
12
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
13
+ import { faChevronLeft, faChevronRight } from "@fortawesome/free-solid-svg-icons";
14
+
15
+ // modules/ui/DatePicker/locale/en.ts
16
+ var enLocale = {
17
+ code: "en",
18
+ months: [
19
+ "January",
20
+ "February",
21
+ "March",
22
+ "April",
23
+ "May",
24
+ "June",
25
+ "July",
26
+ "August",
27
+ "September",
28
+ "October",
29
+ "November",
30
+ "December"
31
+ ],
32
+ monthsShort: [
33
+ "Jan",
34
+ "Feb",
35
+ "Mar",
36
+ "Apr",
37
+ "May",
38
+ "Jun",
39
+ "Jul",
40
+ "Aug",
41
+ "Sep",
42
+ "Oct",
43
+ "Nov",
44
+ "Dec"
45
+ ],
46
+ // EN convention: Sunday-first week.
47
+ weekdaysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
48
+ weekStartsOn: 0,
49
+ displayFormat: "MM/DD/YYYY",
50
+ messages: {
51
+ placeholder: "MM/DD/YYYY",
52
+ prevMonth: "Previous month",
53
+ nextMonth: "Next month",
54
+ today: "Today",
55
+ clear: "Clear date",
56
+ dialogLabel: "Choose date",
57
+ disabledDate: "Disabled date"
58
+ }
59
+ };
60
+
61
+ // modules/ui/DatePicker/locale/tr.ts
62
+ var trLocale = {
63
+ code: "tr",
64
+ months: [
65
+ "Ocak",
66
+ "\u015Eubat",
67
+ "Mart",
68
+ "Nisan",
69
+ "May\u0131s",
70
+ "Haziran",
71
+ "Temmuz",
72
+ "A\u011Fustos",
73
+ "Eyl\xFCl",
74
+ "Ekim",
75
+ "Kas\u0131m",
76
+ "Aral\u0131k"
77
+ ],
78
+ monthsShort: [
79
+ "Oca",
80
+ "\u015Eub",
81
+ "Mar",
82
+ "Nis",
83
+ "May",
84
+ "Haz",
85
+ "Tem",
86
+ "A\u011Fu",
87
+ "Eyl",
88
+ "Eki",
89
+ "Kas",
90
+ "Ara"
91
+ ],
92
+ // TR convention: Monday-first week.
93
+ weekdaysShort: ["Pzt", "Sal", "\xC7ar", "Per", "Cum", "Cmt", "Paz"],
94
+ weekStartsOn: 1,
95
+ displayFormat: "DD.MM.YYYY",
96
+ messages: {
97
+ placeholder: "GG.AA.YYYY",
98
+ prevMonth: "\xD6nceki ay",
99
+ nextMonth: "Sonraki ay",
100
+ today: "Bug\xFCn",
101
+ clear: "Tarihi temizle",
102
+ dialogLabel: "Tarih se\xE7in",
103
+ disabledDate: "Bu tarih se\xE7ilemez"
104
+ }
105
+ };
106
+
107
+ // modules/ui/DatePicker/hooks/useDateFns.ts
108
+ var LOCALES = {
109
+ en: enLocale,
110
+ tr: trLocale
111
+ };
112
+ function resolveLocale(code) {
113
+ var _a;
114
+ if (!code) return LOCALES.tr;
115
+ return (_a = LOCALES[code]) != null ? _a : LOCALES.tr;
116
+ }
117
+ function startOfDay(d) {
118
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0);
119
+ }
120
+ function startOfMonth(d) {
121
+ return new Date(d.getFullYear(), d.getMonth(), 1, 0, 0, 0, 0);
122
+ }
123
+ function daysInMonth(year, month) {
124
+ return new Date(year, month + 1, 0).getDate();
125
+ }
126
+ function addMonths(d, n) {
127
+ const year = d.getFullYear();
128
+ const month = d.getMonth();
129
+ const day = d.getDate();
130
+ const target = new Date(year, month + n, 1);
131
+ const maxDay = daysInMonth(target.getFullYear(), target.getMonth());
132
+ target.setDate(Math.min(day, maxDay));
133
+ return target;
134
+ }
135
+ function addYears(d, n) {
136
+ return addMonths(d, n * 12);
137
+ }
138
+ function addDays(d, n) {
139
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate() + n);
140
+ }
141
+ function isSameDay(a, b) {
142
+ if (!a || !b) return false;
143
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
144
+ }
145
+ function isSameMonth(a, b) {
146
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
147
+ }
148
+ function isBefore(a, b) {
149
+ return startOfDay(a).getTime() < startOfDay(b).getTime();
150
+ }
151
+ function isAfter(a, b) {
152
+ return startOfDay(a).getTime() > startOfDay(b).getTime();
153
+ }
154
+ function clampToBounds(d, min, max) {
155
+ if (min && isBefore(d, min)) return startOfDay(min);
156
+ if (max && isAfter(d, max)) return startOfDay(max);
157
+ return d;
158
+ }
159
+ function isWithinBounds(d, min, max) {
160
+ if (min && isBefore(d, min)) return false;
161
+ if (max && isAfter(d, max)) return false;
162
+ return true;
163
+ }
164
+ function isDisabled(d, disabledDates, min, max) {
165
+ if (!isWithinBounds(d, min, max)) return true;
166
+ if (!disabledDates) return false;
167
+ if (typeof disabledDates === "function") return disabledDates(d);
168
+ return disabledDates.some((x) => isSameDay(x, d));
169
+ }
170
+ function buildMonthGrid(year, month, weekStartsOn) {
171
+ const first = new Date(year, month, 1);
172
+ const firstDow = first.getDay();
173
+ const leading = (firstDow - weekStartsOn + 7) % 7;
174
+ const gridStart = new Date(year, month, 1 - leading);
175
+ const cells = [];
176
+ for (let i = 0; i < 42; i++) {
177
+ cells.push(addDays(gridStart, i));
178
+ }
179
+ return cells;
180
+ }
181
+ var FORMAT_TOKEN = /YYYY|YY|MM|M|DD|D/g;
182
+ function pad2(n) {
183
+ return n < 10 ? "0" + n : String(n);
184
+ }
185
+ function formatDate(d, format) {
186
+ if (!d || isNaN(d.getTime())) return "";
187
+ const year = d.getFullYear();
188
+ const month = d.getMonth() + 1;
189
+ const day = d.getDate();
190
+ return format.replace(FORMAT_TOKEN, (token) => {
191
+ switch (token) {
192
+ case "YYYY":
193
+ return String(year);
194
+ case "YY":
195
+ return String(year).slice(-2);
196
+ case "MM":
197
+ return pad2(month);
198
+ case "M":
199
+ return String(month);
200
+ case "DD":
201
+ return pad2(day);
202
+ case "D":
203
+ return String(day);
204
+ default:
205
+ return token;
206
+ }
207
+ });
208
+ }
209
+ function yearRange(center, radius = 10) {
210
+ const out = [];
211
+ for (let y = center - radius; y <= center + radius; y++) out.push(y);
212
+ return out;
213
+ }
214
+
215
+ // modules/ui/DatePicker/hooks/useKeyboardNav.ts
216
+ function handleCalendarKey(e, opts) {
217
+ const { current, weekStartsOn, min, max, disabledDates } = opts;
218
+ let next = null;
219
+ let shouldSelect = false;
220
+ let shouldClose = false;
221
+ switch (e.key) {
222
+ case "ArrowLeft":
223
+ next = addDays(current, -1);
224
+ break;
225
+ case "ArrowRight":
226
+ next = addDays(current, 1);
227
+ break;
228
+ case "ArrowUp":
229
+ next = addDays(current, -7);
230
+ break;
231
+ case "ArrowDown":
232
+ next = addDays(current, 7);
233
+ break;
234
+ case "PageUp":
235
+ next = e.shiftKey ? addYears(current, -1) : addMonths(current, -1);
236
+ break;
237
+ case "PageDown":
238
+ next = e.shiftKey ? addYears(current, 1) : addMonths(current, 1);
239
+ break;
240
+ case "Home": {
241
+ const dow = current.getDay();
242
+ const offset = (dow - weekStartsOn + 7) % 7;
243
+ next = addDays(current, -offset);
244
+ break;
245
+ }
246
+ case "End": {
247
+ const dow = current.getDay();
248
+ const offset = 6 - (dow - weekStartsOn + 7) % 7;
249
+ next = addDays(current, offset);
250
+ break;
251
+ }
252
+ case "Enter":
253
+ case " ":
254
+ case "Spacebar":
255
+ next = current;
256
+ shouldSelect = !isDisabled(current, disabledDates, min, max);
257
+ break;
258
+ case "Escape":
259
+ case "Esc":
260
+ next = current;
261
+ shouldClose = true;
262
+ break;
263
+ default:
264
+ return null;
265
+ }
266
+ if (e.preventDefault) e.preventDefault();
267
+ const clamped = clampToBounds(next, min, max);
268
+ return {
269
+ focus: clamped,
270
+ monthChanged: clamped.getMonth() !== current.getMonth() || clamped.getFullYear() !== current.getFullYear(),
271
+ shouldSelect,
272
+ shouldClose
273
+ };
274
+ }
275
+
276
+ // modules/ui/DatePicker/calendar/MonthSelect.tsx
277
+ import { jsx } from "react/jsx-runtime";
278
+ function MonthSelect({ value, locale, onSelect }) {
279
+ return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-1.5 p-2", role: "listbox", "aria-label": "Month", children: locale.months.map((name, idx) => {
280
+ const active = idx === value;
281
+ return /* @__PURE__ */ jsx(
282
+ "button",
283
+ {
284
+ type: "button",
285
+ role: "option",
286
+ "aria-selected": active,
287
+ onClick: () => onSelect(idx),
288
+ className: cn(
289
+ "rounded-md px-2 py-1.5 text-sm transition-colors",
290
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
291
+ active ? "bg-primary text-primary-fg" : "text-text-primary hover:bg-surface-overlay"
292
+ ),
293
+ children: locale.monthsShort[idx]
294
+ },
295
+ name
296
+ );
297
+ }) });
298
+ }
299
+
300
+ // modules/ui/DatePicker/calendar/YearSelect.tsx
301
+ import { useEffect, useRef } from "react";
302
+ import { jsx as jsx2 } from "react/jsx-runtime";
303
+ function YearSelect({ value, min, max, onSelect }) {
304
+ const activeRef = useRef(null);
305
+ const years = yearRange(value, 10);
306
+ useEffect(() => {
307
+ var _a;
308
+ (_a = activeRef.current) == null ? void 0 : _a.scrollIntoView({ block: "center" });
309
+ }, []);
310
+ return /* @__PURE__ */ jsx2(
311
+ "div",
312
+ {
313
+ className: "max-h-56 overflow-y-auto p-2",
314
+ role: "listbox",
315
+ "aria-label": "Year",
316
+ children: /* @__PURE__ */ jsx2("div", { className: "grid grid-cols-3 gap-1.5", children: years.map((y) => {
317
+ const disabled = min && y < min.getFullYear() || max && y > max.getFullYear();
318
+ const active = y === value;
319
+ return /* @__PURE__ */ jsx2(
320
+ "button",
321
+ {
322
+ ref: active ? activeRef : void 0,
323
+ type: "button",
324
+ role: "option",
325
+ "aria-selected": active,
326
+ disabled: !!disabled,
327
+ onClick: () => onSelect(y),
328
+ className: cn(
329
+ "rounded-md px-2 py-1.5 text-sm transition-colors",
330
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
331
+ "disabled:opacity-40 disabled:cursor-not-allowed",
332
+ active ? "bg-primary text-primary-fg" : "text-text-primary hover:bg-surface-overlay"
333
+ ),
334
+ children: y
335
+ },
336
+ y
337
+ );
338
+ }) })
339
+ }
340
+ );
341
+ }
342
+
343
+ // modules/ui/DatePicker/calendar/Calendar.tsx
344
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
345
+ function Calendar({
346
+ month,
347
+ selected,
348
+ rangeStart,
349
+ rangeEnd,
350
+ onSelect,
351
+ onMonthChange,
352
+ locale,
353
+ hidePrevButton,
354
+ hideNextButton,
355
+ min,
356
+ max,
357
+ disabledDates,
358
+ ariaLabel,
359
+ compact = true,
360
+ className
361
+ }) {
362
+ const today = startOfDay(/* @__PURE__ */ new Date());
363
+ const [view, setView] = useState("days");
364
+ const [focus, setFocus] = useState(() => clampToBounds(selected != null ? selected : month, min, max));
365
+ const gridRef = useRef2(null);
366
+ const captionId = useId();
367
+ useEffect2(() => {
368
+ if (!isSameMonth(focus, month)) {
369
+ setFocus(clampToBounds(new Date(month.getFullYear(), month.getMonth(), Math.min(focus.getDate(), 28)), min, max));
370
+ }
371
+ }, [month.getFullYear(), month.getMonth()]);
372
+ const goMonth = useCallback(
373
+ (delta) => {
374
+ const next = addMonths(month, delta);
375
+ onMonthChange == null ? void 0 : onMonthChange(next);
376
+ },
377
+ [month, onMonthChange]
378
+ );
379
+ const grid = buildMonthGrid(month.getFullYear(), month.getMonth(), locale.weekStartsOn);
380
+ const weekdays = [];
381
+ for (let i = 0; i < 7; i++) {
382
+ weekdays.push(locale.weekdaysShort[(i + locale.weekStartsOn) % 7]);
383
+ }
384
+ function onKey(e) {
385
+ const r = handleCalendarKey(e, {
386
+ current: focus,
387
+ weekStartsOn: locale.weekStartsOn,
388
+ min,
389
+ max,
390
+ disabledDates
391
+ });
392
+ if (!r) return;
393
+ setFocus(r.focus);
394
+ if (r.monthChanged) onMonthChange == null ? void 0 : onMonthChange(r.focus);
395
+ if (r.shouldSelect) onSelect(r.focus);
396
+ }
397
+ function renderHeader() {
398
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-2 pt-2 pb-1", children: [
399
+ !hidePrevButton ? /* @__PURE__ */ jsx3(
400
+ "button",
401
+ {
402
+ type: "button",
403
+ onClick: () => goMonth(-1),
404
+ "aria-label": locale.messages.prevMonth,
405
+ className: cn(
406
+ "inline-flex h-7 w-7 items-center justify-center rounded-md",
407
+ "text-text-secondary hover:bg-surface-overlay hover:text-text-primary",
408
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus"
409
+ ),
410
+ children: /* @__PURE__ */ jsx3(FontAwesomeIcon, { icon: faChevronLeft, className: "h-3.5 w-3.5", "aria-hidden": "true" })
411
+ }
412
+ ) : /* @__PURE__ */ jsx3("span", { className: "h-7 w-7", "aria-hidden": "true" }),
413
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-sm font-medium text-text-primary", id: captionId, children: [
414
+ /* @__PURE__ */ jsx3(
415
+ "button",
416
+ {
417
+ type: "button",
418
+ onClick: () => setView(view === "months" ? "days" : "months"),
419
+ className: cn(
420
+ "rounded-md px-2 py-1 hover:bg-surface-overlay",
421
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
422
+ view === "months" && "bg-surface-overlay"
423
+ ),
424
+ "aria-haspopup": "listbox",
425
+ "aria-expanded": view === "months",
426
+ children: locale.months[month.getMonth()]
427
+ }
428
+ ),
429
+ /* @__PURE__ */ jsx3(
430
+ "button",
431
+ {
432
+ type: "button",
433
+ onClick: () => setView(view === "years" ? "days" : "years"),
434
+ className: cn(
435
+ "rounded-md px-2 py-1 hover:bg-surface-overlay",
436
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
437
+ view === "years" && "bg-surface-overlay"
438
+ ),
439
+ "aria-haspopup": "listbox",
440
+ "aria-expanded": view === "years",
441
+ children: month.getFullYear()
442
+ }
443
+ )
444
+ ] }),
445
+ !hideNextButton ? /* @__PURE__ */ jsx3(
446
+ "button",
447
+ {
448
+ type: "button",
449
+ onClick: () => goMonth(1),
450
+ "aria-label": locale.messages.nextMonth,
451
+ className: cn(
452
+ "inline-flex h-7 w-7 items-center justify-center rounded-md",
453
+ "text-text-secondary hover:bg-surface-overlay hover:text-text-primary",
454
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus"
455
+ ),
456
+ children: /* @__PURE__ */ jsx3(FontAwesomeIcon, { icon: faChevronRight, className: "h-3.5 w-3.5", "aria-hidden": "true" })
457
+ }
458
+ ) : /* @__PURE__ */ jsx3("span", { className: "h-7 w-7", "aria-hidden": "true" })
459
+ ] });
460
+ }
461
+ function renderGrid() {
462
+ return /* @__PURE__ */ jsxs(
463
+ "div",
464
+ {
465
+ ref: gridRef,
466
+ role: "grid",
467
+ "aria-labelledby": captionId,
468
+ "aria-label": ariaLabel != null ? ariaLabel : locale.messages.dialogLabel,
469
+ tabIndex: 0,
470
+ onKeyDown: onKey,
471
+ className: cn(
472
+ "px-2 pb-2 outline-none",
473
+ "focus-visible:ring-2 focus-visible:ring-border-focus rounded-md"
474
+ ),
475
+ children: [
476
+ /* @__PURE__ */ jsx3("div", { className: "grid grid-cols-7 gap-0.5", role: "row", children: weekdays.map((w, i) => /* @__PURE__ */ jsx3(
477
+ "div",
478
+ {
479
+ role: "columnheader",
480
+ className: "py-1 text-center text-[11px] font-medium uppercase tracking-wide text-text-secondary",
481
+ children: w
482
+ },
483
+ `wd-${i}`
484
+ )) }),
485
+ /* @__PURE__ */ jsx3("div", { className: "mt-1 grid grid-cols-7 gap-0.5", children: grid.map((d) => {
486
+ const inMonth = isSameMonth(d, month);
487
+ const disabled = isDisabled(d, disabledDates, min, max);
488
+ const isSelected = isSameDay(d, selected);
489
+ const isToday = isSameDay(d, today);
490
+ const isFocus = isSameDay(d, focus) && inMonth;
491
+ const isStart = isSameDay(d, rangeStart);
492
+ const isEnd = isSameDay(d, rangeEnd);
493
+ return /* @__PURE__ */ jsx3(
494
+ "button",
495
+ {
496
+ type: "button",
497
+ role: "gridcell",
498
+ "aria-selected": isSelected || isStart || isEnd,
499
+ "aria-disabled": disabled,
500
+ tabIndex: isFocus ? 0 : -1,
501
+ disabled,
502
+ onClick: () => {
503
+ if (disabled) return;
504
+ setFocus(d);
505
+ onSelect(d);
506
+ },
507
+ className: cn(
508
+ "relative inline-flex items-center justify-center rounded-md text-sm transition-colors",
509
+ compact ? "h-8 w-8" : "h-9 w-9",
510
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
511
+ !inMonth && "text-text-disabled",
512
+ inMonth && !disabled && !isSelected && !isStart && !isEnd && "text-text-primary hover:bg-surface-overlay",
513
+ disabled && "opacity-40 cursor-not-allowed",
514
+ (isSelected || isStart || isEnd) && "bg-primary text-primary-fg hover:bg-primary-hover",
515
+ isToday && !isSelected && !isStart && !isEnd && "ring-1 ring-inset ring-primary"
516
+ ),
517
+ children: d.getDate()
518
+ },
519
+ d.toISOString()
520
+ );
521
+ }) }),
522
+ /* @__PURE__ */ jsx3("div", { className: "mt-2 flex items-center justify-end px-1", children: /* @__PURE__ */ jsx3(
523
+ "button",
524
+ {
525
+ type: "button",
526
+ onClick: () => {
527
+ const target = clampToBounds(today, min, max);
528
+ if (!isWithinBounds(target, min, max)) return;
529
+ setFocus(target);
530
+ onMonthChange == null ? void 0 : onMonthChange(target);
531
+ if (!isDisabled(target, disabledDates, min, max)) onSelect(target);
532
+ },
533
+ className: cn(
534
+ "rounded-md px-2 py-1 text-xs font-medium text-primary",
535
+ "hover:bg-primary-subtle focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus"
536
+ ),
537
+ children: locale.messages.today
538
+ }
539
+ ) })
540
+ ]
541
+ }
542
+ );
543
+ }
544
+ return /* @__PURE__ */ jsxs(
545
+ "div",
546
+ {
547
+ className: cn(
548
+ "select-none",
549
+ compact ? "w-[15.5rem]" : "w-[18rem]",
550
+ className
551
+ ),
552
+ children: [
553
+ renderHeader(),
554
+ view === "days" && renderGrid(),
555
+ view === "months" && /* @__PURE__ */ jsx3(
556
+ MonthSelect,
557
+ {
558
+ value: month.getMonth(),
559
+ locale,
560
+ onSelect: (m) => {
561
+ const next = new Date(month.getFullYear(), m, 1);
562
+ onMonthChange == null ? void 0 : onMonthChange(next);
563
+ setView("days");
564
+ }
565
+ }
566
+ ),
567
+ view === "years" && /* @__PURE__ */ jsx3(
568
+ YearSelect,
569
+ {
570
+ value: month.getFullYear(),
571
+ min,
572
+ max,
573
+ onSelect: (y) => {
574
+ const next = new Date(y, month.getMonth(), 1);
575
+ onMonthChange == null ? void 0 : onMonthChange(next);
576
+ setView("days");
577
+ }
578
+ }
579
+ )
580
+ ]
581
+ }
582
+ );
583
+ }
584
+
585
+ // modules/ui/DatePicker/parts/PresetList.tsx
586
+ import { jsx as jsx4 } from "react/jsx-runtime";
587
+ function PresetList({ className }) {
588
+ return /* @__PURE__ */ jsx4(
589
+ "div",
590
+ {
591
+ className: cn("hidden", className),
592
+ "aria-hidden": "true",
593
+ "data-preset-list-placeholder": true
594
+ }
595
+ );
596
+ }
597
+
598
+ // modules/ui/DatePicker/parts/Trigger.tsx
599
+ import { forwardRef } from "react";
600
+ import { FontAwesomeIcon as FontAwesomeIcon2 } from "@fortawesome/react-fontawesome";
601
+ import { faCalendar, faXmark } from "@fortawesome/free-solid-svg-icons";
602
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
603
+ var Trigger = forwardRef(function Trigger2({
604
+ display,
605
+ placeholder,
606
+ open,
607
+ disabled,
608
+ invalid,
609
+ showClear,
610
+ clearLabel,
611
+ onToggle,
612
+ onClear,
613
+ controlsId,
614
+ ariaLabel,
615
+ ariaDescribedBy,
616
+ required,
617
+ testId,
618
+ className
619
+ }, ref) {
620
+ return /* @__PURE__ */ jsxs2(
621
+ "div",
622
+ {
623
+ className: cn(
624
+ "group relative flex w-full items-center rounded-md border transition-colors",
625
+ "bg-surface-base text-text-primary",
626
+ "focus-within:ring-2 focus-within:ring-border-focus focus-within:border-border-focus",
627
+ disabled && "opacity-50 cursor-not-allowed bg-surface-sunken",
628
+ invalid ? "border-error ring-1 ring-error bg-error-subtle" : "border-border",
629
+ className
630
+ ),
631
+ children: [
632
+ /* @__PURE__ */ jsx5(
633
+ "button",
634
+ {
635
+ ref,
636
+ type: "button",
637
+ onClick: onToggle,
638
+ disabled,
639
+ "aria-haspopup": "dialog",
640
+ "aria-expanded": open,
641
+ "aria-controls": controlsId,
642
+ "aria-label": ariaLabel,
643
+ "aria-describedby": ariaDescribedBy,
644
+ "aria-invalid": invalid || void 0,
645
+ "aria-required": required || void 0,
646
+ "data-testid": testId,
647
+ className: cn(
648
+ "flex-1 text-left px-3 py-2 text-sm bg-transparent rounded-l-md",
649
+ "focus-visible:outline-none",
650
+ "disabled:cursor-not-allowed"
651
+ ),
652
+ children: display ? /* @__PURE__ */ jsx5("span", { children: display }) : /* @__PURE__ */ jsx5("span", { className: "text-text-disabled", children: placeholder })
653
+ }
654
+ ),
655
+ showClear && !disabled ? /* @__PURE__ */ jsx5(
656
+ "button",
657
+ {
658
+ type: "button",
659
+ onClick: onClear,
660
+ "aria-label": clearLabel,
661
+ className: cn(
662
+ "inline-flex h-7 w-7 items-center justify-center rounded-md mr-1",
663
+ "text-text-secondary hover:bg-surface-overlay hover:text-text-primary",
664
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus"
665
+ ),
666
+ children: /* @__PURE__ */ jsx5(FontAwesomeIcon2, { icon: faXmark, className: "h-3 w-3", "aria-hidden": "true" })
667
+ }
668
+ ) : null,
669
+ /* @__PURE__ */ jsx5(
670
+ "span",
671
+ {
672
+ className: cn(
673
+ "pointer-events-none mr-3 text-text-secondary",
674
+ disabled && "opacity-50"
675
+ ),
676
+ "aria-hidden": "true",
677
+ children: /* @__PURE__ */ jsx5(FontAwesomeIcon2, { icon: faCalendar, className: "h-3.5 w-3.5" })
678
+ }
679
+ )
680
+ ]
681
+ }
682
+ );
683
+ });
684
+
685
+ // modules/ui/DatePicker/index.tsx
686
+ import { Fragment, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
687
+ function mergeMessages(base, override) {
688
+ return override ? __spreadValues(__spreadValues({}, base), override) : base;
689
+ }
690
+ function useDismissOnOutside(ref, open, onClose) {
691
+ useEffect3(() => {
692
+ if (!open) return;
693
+ function onDocClick(e) {
694
+ const node = ref.current;
695
+ if (!node) return;
696
+ if (e.target instanceof Node && node.contains(e.target)) return;
697
+ onClose();
698
+ }
699
+ function onKey(e) {
700
+ if (e.key === "Escape") onClose();
701
+ }
702
+ document.addEventListener("mousedown", onDocClick);
703
+ document.addEventListener("keydown", onKey);
704
+ return () => {
705
+ document.removeEventListener("mousedown", onDocClick);
706
+ document.removeEventListener("keydown", onKey);
707
+ };
708
+ }, [open, onClose, ref]);
709
+ }
710
+ function DatePicker({
711
+ id,
712
+ label,
713
+ hint,
714
+ error,
715
+ value,
716
+ onChange,
717
+ disabled,
718
+ required,
719
+ min,
720
+ max,
721
+ disabledDates,
722
+ locale: localeCode,
723
+ format,
724
+ messages,
725
+ variant = "popover",
726
+ className,
727
+ name
728
+ }) {
729
+ const reactId = useId2();
730
+ const baseId = id != null ? id : `dp-${reactId}`;
731
+ const hintId = hint ? `${baseId}-hint` : void 0;
732
+ const errorId = error ? `${baseId}-error` : void 0;
733
+ const describedBy = [hintId, errorId].filter(Boolean).join(" ") || void 0;
734
+ const popoverId = `${baseId}-popover`;
735
+ const locale = resolveLocale(localeCode);
736
+ const msgs = mergeMessages(locale.messages, messages);
737
+ const fmt = format != null ? format : locale.displayFormat;
738
+ const [open, setOpen] = useState2(false);
739
+ const [visibleMonth, setVisibleMonth] = useState2(
740
+ () => startOfMonth(value != null ? value : clampToBounds(/* @__PURE__ */ new Date(), min, max))
741
+ );
742
+ const wrapperRef = useRef3(null);
743
+ useDismissOnOutside(wrapperRef, open, () => setOpen(false));
744
+ useEffect3(() => {
745
+ if (value && !isSameMonth(value, visibleMonth)) {
746
+ setVisibleMonth(startOfMonth(value));
747
+ }
748
+ }, [value == null ? void 0 : value.getTime()]);
749
+ const display = formatDate(value, fmt);
750
+ const handleSelect = useCallback2(
751
+ (d) => {
752
+ if (isDisabled(d, disabledDates, min, max)) return;
753
+ onChange(startOfDay(d));
754
+ setOpen(false);
755
+ },
756
+ [disabledDates, min, max, onChange]
757
+ );
758
+ return /* @__PURE__ */ jsxs3("div", { ref: wrapperRef, className: cn("relative space-y-1", className), "data-testid": `datepicker-${baseId}`, children: [
759
+ label ? /* @__PURE__ */ jsxs3("label", { htmlFor: baseId, className: "block text-sm font-medium text-text-primary", children: [
760
+ label,
761
+ required ? /* @__PURE__ */ jsxs3(Fragment, { children: [
762
+ /* @__PURE__ */ jsx6("span", { className: "text-error ml-1", "aria-hidden": "true", children: "*" }),
763
+ /* @__PURE__ */ jsx6("span", { className: "sr-only", children: "(required)" })
764
+ ] }) : null
765
+ ] }) : null,
766
+ /* @__PURE__ */ jsx6(
767
+ Trigger,
768
+ {
769
+ display,
770
+ placeholder: msgs.placeholder,
771
+ open,
772
+ disabled,
773
+ invalid: !!error,
774
+ showClear: !!value,
775
+ clearLabel: msgs.clear,
776
+ onToggle: () => setOpen((o) => !o),
777
+ onClear: () => onChange(null),
778
+ controlsId: popoverId,
779
+ ariaLabel: label,
780
+ ariaDescribedBy: describedBy,
781
+ required,
782
+ testId: `datepicker-${baseId}-trigger`
783
+ }
784
+ ),
785
+ name ? /* @__PURE__ */ jsx6("input", { type: "hidden", name, value: display }) : null,
786
+ open && variant === "popover" ? /* @__PURE__ */ jsxs3(
787
+ "div",
788
+ {
789
+ id: popoverId,
790
+ role: "dialog",
791
+ "aria-modal": "false",
792
+ "aria-label": msgs.dialogLabel,
793
+ className: cn(
794
+ "absolute z-30 mt-1 rounded-lg border border-border bg-surface-raised shadow-lg",
795
+ "p-1"
796
+ ),
797
+ children: [
798
+ /* @__PURE__ */ jsx6(PresetList, {}),
799
+ /* @__PURE__ */ jsx6(
800
+ Calendar,
801
+ {
802
+ month: visibleMonth,
803
+ selected: value != null ? value : null,
804
+ onSelect: handleSelect,
805
+ onMonthChange: (m) => setVisibleMonth(startOfMonth(m)),
806
+ locale,
807
+ min,
808
+ max,
809
+ disabledDates,
810
+ ariaLabel: msgs.dialogLabel
811
+ }
812
+ )
813
+ ]
814
+ }
815
+ ) : null,
816
+ hint && !error ? /* @__PURE__ */ jsx6("p", { id: hintId, className: "text-xs text-text-secondary", children: hint }) : null,
817
+ error ? /* @__PURE__ */ jsx6("p", { id: errorId, className: "text-xs text-error", role: "alert", children: error }) : null
818
+ ] });
819
+ }
820
+ function normaliseRange(r) {
821
+ var _a, _b;
822
+ return { start: (_a = r == null ? void 0 : r.start) != null ? _a : null, end: (_b = r == null ? void 0 : r.end) != null ? _b : null };
823
+ }
824
+ function DateRangePicker({
825
+ id,
826
+ label,
827
+ hint,
828
+ error,
829
+ value,
830
+ onChange,
831
+ disabled,
832
+ required,
833
+ min,
834
+ max,
835
+ disabledDates,
836
+ locale: localeCode,
837
+ format,
838
+ messages,
839
+ variant = "popover",
840
+ className
841
+ }) {
842
+ var _a, _b, _c, _d, _e, _f;
843
+ const reactId = useId2();
844
+ const baseId = id != null ? id : `dr-${reactId}`;
845
+ const hintId = hint ? `${baseId}-hint` : void 0;
846
+ const errorId = error ? `${baseId}-error` : void 0;
847
+ const describedBy = [hintId, errorId].filter(Boolean).join(" ") || void 0;
848
+ const popoverId = `${baseId}-popover`;
849
+ const locale = resolveLocale(localeCode);
850
+ const msgs = mergeMessages(locale.messages, messages);
851
+ const fmt = format != null ? format : locale.displayFormat;
852
+ const range = normaliseRange(value);
853
+ const [open, setOpen] = useState2(false);
854
+ const [leftMonth, setLeftMonth] = useState2(
855
+ () => {
856
+ var _a2;
857
+ return startOfMonth((_a2 = range.start) != null ? _a2 : clampToBounds(/* @__PURE__ */ new Date(), min, max));
858
+ }
859
+ );
860
+ const wrapperRef = useRef3(null);
861
+ useDismissOnOutside(wrapperRef, open, () => setOpen(false));
862
+ const rightMonth = useMemo(() => addMonths(leftMonth, 1), [leftMonth]);
863
+ const startStr = formatDate(range.start, fmt);
864
+ const endStr = formatDate(range.end, fmt);
865
+ const display = range.start || range.end ? `${startStr || msgs.placeholder} \u2192 ${endStr || msgs.placeholder}` : "";
866
+ const handleSelect = useCallback2(
867
+ (d) => {
868
+ if (isDisabled(d, disabledDates, min, max)) return;
869
+ const day = startOfDay(d);
870
+ if (!range.start || range.start && range.end) {
871
+ onChange({ start: day, end: null });
872
+ return;
873
+ }
874
+ if (isBefore(day, range.start)) {
875
+ onChange({ start: day, end: null });
876
+ return;
877
+ }
878
+ onChange({ start: range.start, end: day });
879
+ setOpen(false);
880
+ },
881
+ [range.start, range.end, disabledDates, min, max, onChange]
882
+ );
883
+ return /* @__PURE__ */ jsxs3("div", { ref: wrapperRef, className: cn("relative space-y-1", className), "data-testid": `daterangepicker-${baseId}`, children: [
884
+ label ? /* @__PURE__ */ jsxs3("span", { className: "block text-sm font-medium text-text-primary", children: [
885
+ label,
886
+ required ? /* @__PURE__ */ jsxs3(Fragment, { children: [
887
+ /* @__PURE__ */ jsx6("span", { className: "text-error ml-1", "aria-hidden": "true", children: "*" }),
888
+ /* @__PURE__ */ jsx6("span", { className: "sr-only", children: "(required)" })
889
+ ] }) : null
890
+ ] }) : null,
891
+ /* @__PURE__ */ jsx6(
892
+ Trigger,
893
+ {
894
+ display,
895
+ placeholder: `${msgs.placeholder} \u2192 ${msgs.placeholder}`,
896
+ open,
897
+ disabled,
898
+ invalid: !!error,
899
+ showClear: !!(range.start || range.end),
900
+ clearLabel: msgs.clear,
901
+ onToggle: () => setOpen((o) => !o),
902
+ onClear: () => onChange({ start: null, end: null }),
903
+ controlsId: popoverId,
904
+ ariaLabel: label,
905
+ ariaDescribedBy: describedBy,
906
+ required,
907
+ testId: `daterangepicker-${baseId}-trigger`
908
+ }
909
+ ),
910
+ open && variant === "popover" ? /* @__PURE__ */ jsxs3(
911
+ "div",
912
+ {
913
+ id: popoverId,
914
+ role: "dialog",
915
+ "aria-modal": "false",
916
+ "aria-label": msgs.dialogLabel,
917
+ className: cn(
918
+ "absolute z-30 mt-1 rounded-lg border border-border bg-surface-raised shadow-lg p-1",
919
+ "flex"
920
+ ),
921
+ children: [
922
+ /* @__PURE__ */ jsx6(PresetList, {}),
923
+ /* @__PURE__ */ jsx6(
924
+ Calendar,
925
+ {
926
+ month: leftMonth,
927
+ selected: (_a = range.start) != null ? _a : null,
928
+ rangeStart: (_b = range.start) != null ? _b : null,
929
+ rangeEnd: (_c = range.end) != null ? _c : null,
930
+ onSelect: handleSelect,
931
+ onMonthChange: (m) => setLeftMonth(startOfMonth(m)),
932
+ locale,
933
+ min,
934
+ max,
935
+ disabledDates,
936
+ hideNextButton: true,
937
+ ariaLabel: msgs.dialogLabel
938
+ }
939
+ ),
940
+ /* @__PURE__ */ jsx6(
941
+ Calendar,
942
+ {
943
+ month: rightMonth,
944
+ selected: (_d = range.end) != null ? _d : null,
945
+ rangeStart: (_e = range.start) != null ? _e : null,
946
+ rangeEnd: (_f = range.end) != null ? _f : null,
947
+ onSelect: handleSelect,
948
+ onMonthChange: (m) => setLeftMonth(startOfMonth(addMonths(m, -1))),
949
+ locale,
950
+ min,
951
+ max,
952
+ disabledDates,
953
+ hidePrevButton: true,
954
+ ariaLabel: msgs.dialogLabel
955
+ }
956
+ )
957
+ ]
958
+ }
959
+ ) : null,
960
+ hint && !error ? /* @__PURE__ */ jsx6("p", { id: hintId, className: "text-xs text-text-secondary", children: hint }) : null,
961
+ error ? /* @__PURE__ */ jsx6("p", { id: errorId, className: "text-xs text-error", role: "alert", children: error }) : null
962
+ ] });
963
+ }
964
+
965
+ // modules/ui/DateRangePicker.tsx
966
+ import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
967
+ function TimePicker({
968
+ id,
969
+ label,
970
+ hint,
971
+ error,
972
+ value,
973
+ onChange,
974
+ disabled,
975
+ required,
976
+ step = 60,
977
+ className
978
+ }) {
979
+ const hintId = hint ? `${id}-hint` : void 0;
980
+ const errorId = error ? `${id}-error` : void 0;
981
+ const describedBy = [hintId, errorId].filter(Boolean).join(" ") || void 0;
982
+ return /* @__PURE__ */ jsxs4("div", { className: cn("space-y-1", className), children: [
983
+ /* @__PURE__ */ jsxs4("label", { htmlFor: id, className: "block text-sm font-medium text-text-primary", children: [
984
+ label,
985
+ required && /* @__PURE__ */ jsxs4(Fragment2, { children: [
986
+ /* @__PURE__ */ jsx7("span", { className: "text-error ml-1", "aria-hidden": "true", children: "*" }),
987
+ /* @__PURE__ */ jsx7("span", { className: "sr-only", children: "(required)" })
988
+ ] })
989
+ ] }),
990
+ /* @__PURE__ */ jsx7(
991
+ "input",
992
+ {
993
+ id,
994
+ type: "time",
995
+ value: value != null ? value : "",
996
+ step,
997
+ onChange: (e) => onChange(e.target.value),
998
+ disabled,
999
+ required,
1000
+ "aria-describedby": describedBy,
1001
+ "aria-invalid": !!error,
1002
+ className: cn(
1003
+ "block w-full rounded-md border px-3 py-2 text-sm transition-colors",
1004
+ "text-text-primary bg-surface-base",
1005
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
1006
+ "disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-surface-sunken",
1007
+ error ? "border-error ring-1 ring-error bg-error-subtle" : "border-border"
1008
+ )
1009
+ }
1010
+ ),
1011
+ hint && !error && /* @__PURE__ */ jsx7("p", { id: hintId, className: "text-xs text-text-secondary", children: hint }),
1012
+ error && /* @__PURE__ */ jsx7("p", { id: errorId, className: "text-xs text-error", role: "alert", children: error })
1013
+ ] });
1014
+ }
1015
+
1016
+ export {
1017
+ DatePicker,
1018
+ DateRangePicker,
1019
+ TimePicker
1020
+ };