@kopexa/date-picker 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-VYQ6BFFN.mjs → chunk-RWJEVZ4B.mjs} +336 -18
- package/dist/date-picker-field.d.mts +25 -1
- package/dist/date-picker-field.d.ts +25 -1
- package/dist/date-picker-field.js +330 -17
- package/dist/date-picker-field.mjs +1 -1
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +330 -17
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
|
@@ -24,12 +24,17 @@ import {
|
|
|
24
24
|
DatePickerTableHeader,
|
|
25
25
|
DatePickerTableRow,
|
|
26
26
|
DatePickerTrigger,
|
|
27
|
+
DatePickerValueText,
|
|
27
28
|
DatePickerView,
|
|
28
29
|
DatePickerViewControl,
|
|
29
30
|
DatePickerViewTrigger
|
|
30
31
|
} from "@ark-ui/react/date-picker";
|
|
31
32
|
import { Portal } from "@ark-ui/react/portal";
|
|
32
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
CalendarDate,
|
|
35
|
+
CalendarDateTime,
|
|
36
|
+
getLocalTimeZone
|
|
37
|
+
} from "@internationalized/date";
|
|
33
38
|
import { useSafeIntl } from "@kopexa/i18n";
|
|
34
39
|
import { useCallback, useMemo, useState } from "react";
|
|
35
40
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -109,6 +114,55 @@ function XIcon({ className }) {
|
|
|
109
114
|
}
|
|
110
115
|
);
|
|
111
116
|
}
|
|
117
|
+
function getDatePartOrder(locale) {
|
|
118
|
+
try {
|
|
119
|
+
const fmt = new Intl.DateTimeFormat(locale, {
|
|
120
|
+
day: "2-digit",
|
|
121
|
+
month: "2-digit",
|
|
122
|
+
year: "numeric"
|
|
123
|
+
});
|
|
124
|
+
return fmt.formatToParts(new Date(2024, 0, 1)).filter(
|
|
125
|
+
(p) => p.type === "day" || p.type === "month" || p.type === "year"
|
|
126
|
+
).map((p) => p.type);
|
|
127
|
+
} catch {
|
|
128
|
+
return ["day", "month", "year"];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function finalizeDateParts(parts) {
|
|
132
|
+
var _a, _b, _c;
|
|
133
|
+
const day = (_a = parts.day) != null ? _a : 1;
|
|
134
|
+
const month = (_b = parts.month) != null ? _b : 1;
|
|
135
|
+
let year = (_c = parts.year) != null ? _c : (/* @__PURE__ */ new Date()).getFullYear();
|
|
136
|
+
if (year < 100) year = year < 50 ? 2e3 + year : 1900 + year;
|
|
137
|
+
if (month < 1 || month > 12) return void 0;
|
|
138
|
+
if (day < 1 || day > 31) return void 0;
|
|
139
|
+
return { year, month, day };
|
|
140
|
+
}
|
|
141
|
+
function parseLocalizedDate(value, locale) {
|
|
142
|
+
const trimmed = value.trim();
|
|
143
|
+
if (!trimmed) return void 0;
|
|
144
|
+
const order = getDatePartOrder(locale);
|
|
145
|
+
const segments = trimmed.split(/[./\-\s]+/).filter(Boolean);
|
|
146
|
+
if (segments.length === 3 && segments.every((s) => /^\d+$/.test(s))) {
|
|
147
|
+
const map2 = {};
|
|
148
|
+
order.forEach((field, i) => {
|
|
149
|
+
map2[field] = Number.parseInt(segments[i], 10);
|
|
150
|
+
});
|
|
151
|
+
return finalizeDateParts(map2);
|
|
152
|
+
}
|
|
153
|
+
const digits = trimmed.replace(/\D/g, "");
|
|
154
|
+
const widths = digits.length === 8 ? { day: 2, month: 2, year: 4 } : digits.length === 6 ? { day: 2, month: 2, year: 2 } : digits.length === 4 ? { day: 2, month: 2, year: 0 } : null;
|
|
155
|
+
if (!widths) return void 0;
|
|
156
|
+
let pos = 0;
|
|
157
|
+
const map = {};
|
|
158
|
+
for (const field of order) {
|
|
159
|
+
const w = widths[field];
|
|
160
|
+
if (w === 0) continue;
|
|
161
|
+
map[field] = Number.parseInt(digits.slice(pos, pos + w), 10);
|
|
162
|
+
pos += w;
|
|
163
|
+
}
|
|
164
|
+
return finalizeDateParts(map);
|
|
165
|
+
}
|
|
112
166
|
var styles = {
|
|
113
167
|
control: "relative flex items-center",
|
|
114
168
|
input: "w-full h-9 rounded-md border bg-transparent pl-3 pr-9 text-sm outline-none focus:ring-2 focus:ring-ring",
|
|
@@ -134,7 +188,11 @@ var styles = {
|
|
|
134
188
|
footerButton: "text-sm px-2 py-1 rounded-md hover:bg-muted transition-colors",
|
|
135
189
|
timeInput: "h-9 rounded-md border bg-transparent px-3 text-sm outline-none focus:ring-2 focus:ring-ring",
|
|
136
190
|
label: "text-sm font-medium",
|
|
137
|
-
timeTrigger: "flex-1 h-9 rounded-md border bg-transparent px-3 text-sm text-left hover:bg-muted transition-colors flex items-center justify-between"
|
|
191
|
+
timeTrigger: "flex-1 h-9 rounded-md border bg-transparent px-3 text-sm text-left hover:bg-muted transition-colors flex items-center justify-between",
|
|
192
|
+
defaultGhostTrigger: "inline-flex items-center gap-2 h-9 rounded-md px-2.5 text-sm font-normal text-foreground transition-colors hover:bg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[placeholder]:text-muted-foreground",
|
|
193
|
+
defaultGhostPlaceholder: "text-muted-foreground",
|
|
194
|
+
timeRow: "mt-2 pt-2 border-t flex items-center gap-2",
|
|
195
|
+
timeRowLabel: "text-xs text-muted-foreground"
|
|
138
196
|
};
|
|
139
197
|
function DayView() {
|
|
140
198
|
return /* @__PURE__ */ jsx(DatePickerView, { view: "day", children: /* @__PURE__ */ jsx(DatePickerContext, { children: (api) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -239,9 +297,17 @@ function YearView() {
|
|
|
239
297
|
)) }) })
|
|
240
298
|
] }) }) });
|
|
241
299
|
}
|
|
300
|
+
function CalendarPanel() {
|
|
301
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
302
|
+
/* @__PURE__ */ jsx(DayView, {}),
|
|
303
|
+
/* @__PURE__ */ jsx(MonthView, {}),
|
|
304
|
+
/* @__PURE__ */ jsx(YearView, {})
|
|
305
|
+
] });
|
|
306
|
+
}
|
|
242
307
|
function CalendarFooter({
|
|
243
308
|
todayLabel,
|
|
244
|
-
clearLabel
|
|
309
|
+
clearLabel,
|
|
310
|
+
clearable = true
|
|
245
311
|
}) {
|
|
246
312
|
return /* @__PURE__ */ jsx(DatePickerContext, { children: (api) => /* @__PURE__ */ jsxs("div", { className: styles.footer, children: [
|
|
247
313
|
/* @__PURE__ */ jsx(
|
|
@@ -253,7 +319,7 @@ function CalendarFooter({
|
|
|
253
319
|
children: todayLabel
|
|
254
320
|
}
|
|
255
321
|
),
|
|
256
|
-
/* @__PURE__ */ jsx(
|
|
322
|
+
clearable && /* @__PURE__ */ jsx(
|
|
257
323
|
"button",
|
|
258
324
|
{
|
|
259
325
|
type: "button",
|
|
@@ -264,6 +330,34 @@ function CalendarFooter({
|
|
|
264
330
|
)
|
|
265
331
|
] }) });
|
|
266
332
|
}
|
|
333
|
+
function DateTimeFooter({
|
|
334
|
+
todayLabel,
|
|
335
|
+
clearLabel,
|
|
336
|
+
clearable = true,
|
|
337
|
+
onSelectNow,
|
|
338
|
+
onClear
|
|
339
|
+
}) {
|
|
340
|
+
return /* @__PURE__ */ jsxs("div", { className: styles.footer, children: [
|
|
341
|
+
/* @__PURE__ */ jsx(
|
|
342
|
+
"button",
|
|
343
|
+
{
|
|
344
|
+
type: "button",
|
|
345
|
+
onClick: onSelectNow,
|
|
346
|
+
className: `${styles.footerButton} text-foreground`,
|
|
347
|
+
children: todayLabel
|
|
348
|
+
}
|
|
349
|
+
),
|
|
350
|
+
clearable && /* @__PURE__ */ jsx(
|
|
351
|
+
"button",
|
|
352
|
+
{
|
|
353
|
+
type: "button",
|
|
354
|
+
onClick: onClear,
|
|
355
|
+
className: `${styles.footerButton} text-destructive`,
|
|
356
|
+
children: clearLabel
|
|
357
|
+
}
|
|
358
|
+
)
|
|
359
|
+
] });
|
|
360
|
+
}
|
|
267
361
|
function DatePickerField({
|
|
268
362
|
label,
|
|
269
363
|
value,
|
|
@@ -280,7 +374,10 @@ function DatePickerField({
|
|
|
280
374
|
todayLabel: todayLabelProp,
|
|
281
375
|
clearLabel: clearLabelProp,
|
|
282
376
|
className,
|
|
283
|
-
rootProps
|
|
377
|
+
rootProps,
|
|
378
|
+
variant = "input",
|
|
379
|
+
trigger,
|
|
380
|
+
formatValue
|
|
284
381
|
}) {
|
|
285
382
|
var _a;
|
|
286
383
|
const intl = useSafeIntl();
|
|
@@ -290,6 +387,31 @@ function DatePickerField({
|
|
|
290
387
|
const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(
|
|
291
388
|
showTime ? datePickerMessages.select_date_and_time : datePickerMessages.select_date
|
|
292
389
|
);
|
|
390
|
+
if (variant === "trigger") {
|
|
391
|
+
return /* @__PURE__ */ jsx(
|
|
392
|
+
DateTriggerPickerField,
|
|
393
|
+
{
|
|
394
|
+
label,
|
|
395
|
+
value,
|
|
396
|
+
defaultValue,
|
|
397
|
+
onValueChange,
|
|
398
|
+
showTime,
|
|
399
|
+
clearable,
|
|
400
|
+
locale,
|
|
401
|
+
min,
|
|
402
|
+
max,
|
|
403
|
+
disabled,
|
|
404
|
+
readOnly,
|
|
405
|
+
placeholder,
|
|
406
|
+
todayLabel,
|
|
407
|
+
clearLabel,
|
|
408
|
+
className,
|
|
409
|
+
rootProps,
|
|
410
|
+
trigger,
|
|
411
|
+
formatValue
|
|
412
|
+
}
|
|
413
|
+
);
|
|
414
|
+
}
|
|
293
415
|
if (showTime) {
|
|
294
416
|
return /* @__PURE__ */ jsx(
|
|
295
417
|
DateTimePickerField,
|
|
@@ -326,6 +448,10 @@ function DatePickerField({
|
|
|
326
448
|
selectionMode: "single",
|
|
327
449
|
outsideDaySelectable: true,
|
|
328
450
|
closeOnSelect: true,
|
|
451
|
+
parse: (input, details) => {
|
|
452
|
+
const parts = parseLocalizedDate(input, details.locale);
|
|
453
|
+
return parts ? new CalendarDate(parts.year, parts.month, parts.day) : void 0;
|
|
454
|
+
},
|
|
329
455
|
className,
|
|
330
456
|
...rootProps,
|
|
331
457
|
children: [
|
|
@@ -344,10 +470,15 @@ function DatePickerField({
|
|
|
344
470
|
] }) : /* @__PURE__ */ jsx(DatePickerTrigger, { className: styles.trigger, children: /* @__PURE__ */ jsx(CalendarIcon, { className: "size-4" }) })
|
|
345
471
|
] }),
|
|
346
472
|
/* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(DatePickerPositioner, { children: /* @__PURE__ */ jsxs(DatePickerContent, { className: styles.content, children: [
|
|
347
|
-
/* @__PURE__ */ jsx(
|
|
348
|
-
/* @__PURE__ */ jsx(
|
|
349
|
-
|
|
350
|
-
|
|
473
|
+
/* @__PURE__ */ jsx(CalendarPanel, {}),
|
|
474
|
+
/* @__PURE__ */ jsx(
|
|
475
|
+
CalendarFooter,
|
|
476
|
+
{
|
|
477
|
+
todayLabel,
|
|
478
|
+
clearLabel,
|
|
479
|
+
clearable
|
|
480
|
+
}
|
|
481
|
+
)
|
|
351
482
|
] }) }) })
|
|
352
483
|
]
|
|
353
484
|
}
|
|
@@ -445,6 +576,22 @@ function DateTimePickerField({
|
|
|
445
576
|
view: "day"
|
|
446
577
|
});
|
|
447
578
|
}, [onValueChange]);
|
|
579
|
+
const handleSelectNow = useCallback(() => {
|
|
580
|
+
const now = /* @__PURE__ */ new Date();
|
|
581
|
+
const nowValue = new CalendarDateTime(
|
|
582
|
+
now.getFullYear(),
|
|
583
|
+
now.getMonth() + 1,
|
|
584
|
+
now.getDate(),
|
|
585
|
+
now.getHours(),
|
|
586
|
+
now.getMinutes()
|
|
587
|
+
);
|
|
588
|
+
setInternalValue([nowValue]);
|
|
589
|
+
onValueChange == null ? void 0 : onValueChange({
|
|
590
|
+
value: [nowValue],
|
|
591
|
+
valueAsString: [nowValue.toString()],
|
|
592
|
+
view: "day"
|
|
593
|
+
});
|
|
594
|
+
}, [onValueChange]);
|
|
448
595
|
return /* @__PURE__ */ jsxs(
|
|
449
596
|
DatePickerRoot,
|
|
450
597
|
{
|
|
@@ -458,13 +605,33 @@ function DateTimePickerField({
|
|
|
458
605
|
selectionMode: "single",
|
|
459
606
|
outsideDaySelectable: true,
|
|
460
607
|
closeOnSelect: false,
|
|
608
|
+
parse: (input, details) => {
|
|
609
|
+
const parts = parseLocalizedDate(input, details.locale);
|
|
610
|
+
if (!parts) return void 0;
|
|
611
|
+
const prev = currentValue[0];
|
|
612
|
+
const hour = prev && "hour" in prev ? prev.hour : 0;
|
|
613
|
+
const minute = prev && "minute" in prev ? prev.minute : 0;
|
|
614
|
+
return new CalendarDateTime(
|
|
615
|
+
parts.year,
|
|
616
|
+
parts.month,
|
|
617
|
+
parts.day,
|
|
618
|
+
hour,
|
|
619
|
+
minute
|
|
620
|
+
);
|
|
621
|
+
},
|
|
461
622
|
className,
|
|
462
623
|
...rootProps,
|
|
463
624
|
children: [
|
|
464
625
|
label && /* @__PURE__ */ jsx(DatePickerLabel, { className: styles.label, children: label }),
|
|
465
|
-
/* @__PURE__ */ jsxs(DatePickerControl, { className: "flex items-center
|
|
626
|
+
/* @__PURE__ */ jsxs(DatePickerControl, { className: "flex items-center", children: [
|
|
466
627
|
/* @__PURE__ */ jsxs("div", { className: "relative flex-1 flex items-center", children: [
|
|
467
|
-
/* @__PURE__ */ jsx(
|
|
628
|
+
/* @__PURE__ */ jsx(
|
|
629
|
+
DatePickerInput,
|
|
630
|
+
{
|
|
631
|
+
className: "w-full h-9 rounded-l-md border border-r-0 bg-transparent pl-3 pr-9 text-sm outline-none focus:ring-2 focus:ring-ring",
|
|
632
|
+
placeholder
|
|
633
|
+
}
|
|
634
|
+
),
|
|
468
635
|
/* @__PURE__ */ jsx(DatePickerTrigger, { className: styles.trigger, children: /* @__PURE__ */ jsx(CalendarIcon, { className: "size-4" }) })
|
|
469
636
|
] }),
|
|
470
637
|
/* @__PURE__ */ jsx(
|
|
@@ -475,23 +642,174 @@ function DateTimePickerField({
|
|
|
475
642
|
onChange: handleTimeChange,
|
|
476
643
|
disabled,
|
|
477
644
|
readOnly,
|
|
478
|
-
className:
|
|
645
|
+
className: `h-9 border bg-transparent px-3 text-sm outline-none focus:ring-2 focus:ring-ring ${clearable && !disabled && !readOnly ? "border-r-0" : "rounded-r-md"}`
|
|
479
646
|
}
|
|
480
647
|
),
|
|
481
648
|
clearable && !disabled && !readOnly && /* @__PURE__ */ jsx(
|
|
482
|
-
|
|
649
|
+
"button",
|
|
483
650
|
{
|
|
484
|
-
|
|
651
|
+
type: "button",
|
|
652
|
+
className: "inline-flex items-center justify-center size-9 rounded-r-md border text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
|
|
485
653
|
onClick: handleClear,
|
|
486
654
|
children: /* @__PURE__ */ jsx(XIcon, { className: "size-4" })
|
|
487
655
|
}
|
|
488
656
|
)
|
|
489
657
|
] }),
|
|
490
658
|
/* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(DatePickerPositioner, { children: /* @__PURE__ */ jsxs(DatePickerContent, { className: styles.content, children: [
|
|
491
|
-
/* @__PURE__ */ jsx(
|
|
492
|
-
/* @__PURE__ */ jsx(
|
|
493
|
-
|
|
494
|
-
|
|
659
|
+
/* @__PURE__ */ jsx(CalendarPanel, {}),
|
|
660
|
+
/* @__PURE__ */ jsx(
|
|
661
|
+
DateTimeFooter,
|
|
662
|
+
{
|
|
663
|
+
todayLabel,
|
|
664
|
+
clearLabel,
|
|
665
|
+
clearable,
|
|
666
|
+
onSelectNow: handleSelectNow,
|
|
667
|
+
onClear: handleClear
|
|
668
|
+
}
|
|
669
|
+
)
|
|
670
|
+
] }) }) })
|
|
671
|
+
]
|
|
672
|
+
}
|
|
673
|
+
);
|
|
674
|
+
}
|
|
675
|
+
function DateTriggerPickerField({
|
|
676
|
+
label,
|
|
677
|
+
value: valueProp,
|
|
678
|
+
defaultValue,
|
|
679
|
+
onValueChange,
|
|
680
|
+
showTime = false,
|
|
681
|
+
clearable = true,
|
|
682
|
+
locale: localeProp,
|
|
683
|
+
min,
|
|
684
|
+
max,
|
|
685
|
+
disabled,
|
|
686
|
+
readOnly,
|
|
687
|
+
placeholder: placeholderProp,
|
|
688
|
+
todayLabel: todayLabelProp,
|
|
689
|
+
clearLabel: clearLabelProp,
|
|
690
|
+
className,
|
|
691
|
+
rootProps,
|
|
692
|
+
trigger,
|
|
693
|
+
formatValue
|
|
694
|
+
}) {
|
|
695
|
+
var _a;
|
|
696
|
+
const intl = useSafeIntl();
|
|
697
|
+
const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
|
|
698
|
+
const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
|
|
699
|
+
const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
|
|
700
|
+
const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(
|
|
701
|
+
showTime ? datePickerMessages.select_date_and_time : datePickerMessages.select_date
|
|
702
|
+
);
|
|
703
|
+
const [internalValue, setInternalValue] = useState(
|
|
704
|
+
() => {
|
|
705
|
+
var _a2;
|
|
706
|
+
return (_a2 = valueProp != null ? valueProp : defaultValue) != null ? _a2 : [];
|
|
707
|
+
}
|
|
708
|
+
);
|
|
709
|
+
const currentValue = useMemo(() => {
|
|
710
|
+
if (valueProp === void 0) return internalValue;
|
|
711
|
+
return valueProp;
|
|
712
|
+
}, [valueProp, internalValue]);
|
|
713
|
+
const handleDateChange = useCallback(
|
|
714
|
+
(details) => {
|
|
715
|
+
const next = details.value[0];
|
|
716
|
+
if (!showTime || !next) {
|
|
717
|
+
setInternalValue(details.value);
|
|
718
|
+
onValueChange == null ? void 0 : onValueChange(details);
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
const prev = currentValue[0];
|
|
722
|
+
const prevHour = prev && "hour" in prev ? prev.hour : 0;
|
|
723
|
+
const prevMinute = prev && "minute" in prev ? prev.minute : 0;
|
|
724
|
+
const merged = new CalendarDateTime(
|
|
725
|
+
next.year,
|
|
726
|
+
next.month,
|
|
727
|
+
next.day,
|
|
728
|
+
prevHour,
|
|
729
|
+
prevMinute
|
|
730
|
+
);
|
|
731
|
+
setInternalValue([merged]);
|
|
732
|
+
onValueChange == null ? void 0 : onValueChange({ ...details, value: [merged] });
|
|
733
|
+
},
|
|
734
|
+
[currentValue, onValueChange, showTime]
|
|
735
|
+
);
|
|
736
|
+
const handleTimeChange = useCallback(
|
|
737
|
+
(e) => {
|
|
738
|
+
const [hours, minutes] = e.currentTarget.value.split(":").map(Number);
|
|
739
|
+
const prev = currentValue[0];
|
|
740
|
+
const base = prev && "hour" in prev ? prev : prev ? new CalendarDateTime(prev.year, prev.month, prev.day, 0, 0) : (() => {
|
|
741
|
+
const now = /* @__PURE__ */ new Date();
|
|
742
|
+
return new CalendarDateTime(
|
|
743
|
+
now.getFullYear(),
|
|
744
|
+
now.getMonth() + 1,
|
|
745
|
+
now.getDate(),
|
|
746
|
+
0,
|
|
747
|
+
0
|
|
748
|
+
);
|
|
749
|
+
})();
|
|
750
|
+
const updated = base.set({ hour: hours, minute: minutes });
|
|
751
|
+
setInternalValue([updated]);
|
|
752
|
+
onValueChange == null ? void 0 : onValueChange({
|
|
753
|
+
value: [updated],
|
|
754
|
+
valueAsString: [updated.toString()],
|
|
755
|
+
view: "day"
|
|
756
|
+
});
|
|
757
|
+
},
|
|
758
|
+
[currentValue, onValueChange]
|
|
759
|
+
);
|
|
760
|
+
const formatter = useMemo(() => {
|
|
761
|
+
if (formatValue) return formatValue;
|
|
762
|
+
const fmt = new Intl.DateTimeFormat(
|
|
763
|
+
locale,
|
|
764
|
+
showTime ? { dateStyle: "medium", timeStyle: "short" } : { dateStyle: "medium" }
|
|
765
|
+
);
|
|
766
|
+
return (v) => fmt.format(v.toDate(getLocalTimeZone()));
|
|
767
|
+
}, [formatValue, locale, showTime]);
|
|
768
|
+
const timeValue = currentValue[0] && "hour" in currentValue[0] ? `${String(currentValue[0].hour).padStart(2, "0")}:${String(currentValue[0].minute).padStart(2, "0")}` : "";
|
|
769
|
+
const triggerElement = trigger != null ? trigger : /* @__PURE__ */ jsxs("button", { type: "button", className: styles.defaultGhostTrigger, children: [
|
|
770
|
+
/* @__PURE__ */ jsx(CalendarIcon, { className: "size-4 shrink-0 opacity-70" }),
|
|
771
|
+
/* @__PURE__ */ jsx(DatePickerValueText, { placeholder, children: ({ value }) => formatter(value) })
|
|
772
|
+
] });
|
|
773
|
+
return /* @__PURE__ */ jsxs(
|
|
774
|
+
DatePickerRoot,
|
|
775
|
+
{
|
|
776
|
+
value: currentValue,
|
|
777
|
+
defaultValue,
|
|
778
|
+
onValueChange: handleDateChange,
|
|
779
|
+
locale,
|
|
780
|
+
min,
|
|
781
|
+
max,
|
|
782
|
+
disabled,
|
|
783
|
+
readOnly,
|
|
784
|
+
selectionMode: "single",
|
|
785
|
+
outsideDaySelectable: true,
|
|
786
|
+
closeOnSelect: !showTime,
|
|
787
|
+
className,
|
|
788
|
+
...rootProps,
|
|
789
|
+
children: [
|
|
790
|
+
label && /* @__PURE__ */ jsx(DatePickerLabel, { className: styles.label, children: label }),
|
|
791
|
+
/* @__PURE__ */ jsx(DatePickerControl, { children: /* @__PURE__ */ jsx(DatePickerTrigger, { asChild: true, children: triggerElement }) }),
|
|
792
|
+
/* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(DatePickerPositioner, { children: /* @__PURE__ */ jsxs(DatePickerContent, { className: styles.content, children: [
|
|
793
|
+
/* @__PURE__ */ jsx(CalendarPanel, {}),
|
|
794
|
+
showTime && /* @__PURE__ */ jsx("div", { className: styles.timeRow, children: /* @__PURE__ */ jsx(
|
|
795
|
+
"input",
|
|
796
|
+
{
|
|
797
|
+
type: "time",
|
|
798
|
+
value: timeValue,
|
|
799
|
+
onChange: handleTimeChange,
|
|
800
|
+
disabled,
|
|
801
|
+
readOnly,
|
|
802
|
+
className: styles.timeInput
|
|
803
|
+
}
|
|
804
|
+
) }),
|
|
805
|
+
/* @__PURE__ */ jsx(
|
|
806
|
+
CalendarFooter,
|
|
807
|
+
{
|
|
808
|
+
todayLabel,
|
|
809
|
+
clearLabel,
|
|
810
|
+
clearable
|
|
811
|
+
}
|
|
812
|
+
)
|
|
495
813
|
] }) }) })
|
|
496
814
|
]
|
|
497
815
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { DatePickerValueChangeDetails, DatePickerRootProps } from '@ark-ui/react/date-picker';
|
|
3
3
|
import { DateValue } from '@internationalized/date';
|
|
4
|
+
import { ReactElement } from 'react';
|
|
4
5
|
|
|
5
6
|
type DatePickerFieldProps = {
|
|
6
7
|
/** Label text */
|
|
@@ -35,7 +36,30 @@ type DatePickerFieldProps = {
|
|
|
35
36
|
className?: string;
|
|
36
37
|
/** Additional Ark UI Root props */
|
|
37
38
|
rootProps?: Partial<DatePickerRootProps>;
|
|
39
|
+
/**
|
|
40
|
+
* Visual variant.
|
|
41
|
+
* - `"input"` (default): bordered input + calendar button + optional inline time/clear
|
|
42
|
+
* - `"trigger"`: a single ghost-style button that opens the popover
|
|
43
|
+
* with the calendar (and time picker, if `showTime`). Use `trigger`
|
|
44
|
+
* to provide a custom trigger element.
|
|
45
|
+
*/
|
|
46
|
+
variant?: "input" | "trigger";
|
|
47
|
+
/**
|
|
48
|
+
* Custom trigger element rendered in `variant="trigger"` mode. Wrapped
|
|
49
|
+
* with `DatePickerTrigger asChild`, so any clickable element works
|
|
50
|
+
* (sight Button, Chip, etc.). The element should display the value —
|
|
51
|
+
* pass `<DatePickerValueText placeholder={…} />` as its children, or
|
|
52
|
+
* use the `formatValue` prop for default formatting.
|
|
53
|
+
*/
|
|
54
|
+
trigger?: ReactElement;
|
|
55
|
+
/**
|
|
56
|
+
* Custom formatter for the trigger label (only used by the default
|
|
57
|
+
* `variant="trigger"` button). Receives the selected `DateValue` and
|
|
58
|
+
* returns a display string. Defaults to `Intl.DateTimeFormat` with the
|
|
59
|
+
* picker's locale, including time when `showTime` is true.
|
|
60
|
+
*/
|
|
61
|
+
formatValue?: (value: DateValue) => string;
|
|
38
62
|
};
|
|
39
|
-
declare function DatePickerField({ label, value, defaultValue, onValueChange, showTime, clearable, locale: localeProp, min, max, disabled, readOnly, placeholder: placeholderProp, todayLabel: todayLabelProp, clearLabel: clearLabelProp, className, rootProps, }: DatePickerFieldProps): react_jsx_runtime.JSX.Element;
|
|
63
|
+
declare function DatePickerField({ label, value, defaultValue, onValueChange, showTime, clearable, locale: localeProp, min, max, disabled, readOnly, placeholder: placeholderProp, todayLabel: todayLabelProp, clearLabel: clearLabelProp, className, rootProps, variant, trigger, formatValue, }: DatePickerFieldProps): react_jsx_runtime.JSX.Element;
|
|
40
64
|
|
|
41
65
|
export { DatePickerField, type DatePickerFieldProps };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { DatePickerValueChangeDetails, DatePickerRootProps } from '@ark-ui/react/date-picker';
|
|
3
3
|
import { DateValue } from '@internationalized/date';
|
|
4
|
+
import { ReactElement } from 'react';
|
|
4
5
|
|
|
5
6
|
type DatePickerFieldProps = {
|
|
6
7
|
/** Label text */
|
|
@@ -35,7 +36,30 @@ type DatePickerFieldProps = {
|
|
|
35
36
|
className?: string;
|
|
36
37
|
/** Additional Ark UI Root props */
|
|
37
38
|
rootProps?: Partial<DatePickerRootProps>;
|
|
39
|
+
/**
|
|
40
|
+
* Visual variant.
|
|
41
|
+
* - `"input"` (default): bordered input + calendar button + optional inline time/clear
|
|
42
|
+
* - `"trigger"`: a single ghost-style button that opens the popover
|
|
43
|
+
* with the calendar (and time picker, if `showTime`). Use `trigger`
|
|
44
|
+
* to provide a custom trigger element.
|
|
45
|
+
*/
|
|
46
|
+
variant?: "input" | "trigger";
|
|
47
|
+
/**
|
|
48
|
+
* Custom trigger element rendered in `variant="trigger"` mode. Wrapped
|
|
49
|
+
* with `DatePickerTrigger asChild`, so any clickable element works
|
|
50
|
+
* (sight Button, Chip, etc.). The element should display the value —
|
|
51
|
+
* pass `<DatePickerValueText placeholder={…} />` as its children, or
|
|
52
|
+
* use the `formatValue` prop for default formatting.
|
|
53
|
+
*/
|
|
54
|
+
trigger?: ReactElement;
|
|
55
|
+
/**
|
|
56
|
+
* Custom formatter for the trigger label (only used by the default
|
|
57
|
+
* `variant="trigger"` button). Receives the selected `DateValue` and
|
|
58
|
+
* returns a display string. Defaults to `Intl.DateTimeFormat` with the
|
|
59
|
+
* picker's locale, including time when `showTime` is true.
|
|
60
|
+
*/
|
|
61
|
+
formatValue?: (value: DateValue) => string;
|
|
38
62
|
};
|
|
39
|
-
declare function DatePickerField({ label, value, defaultValue, onValueChange, showTime, clearable, locale: localeProp, min, max, disabled, readOnly, placeholder: placeholderProp, todayLabel: todayLabelProp, clearLabel: clearLabelProp, className, rootProps, }: DatePickerFieldProps): react_jsx_runtime.JSX.Element;
|
|
63
|
+
declare function DatePickerField({ label, value, defaultValue, onValueChange, showTime, clearable, locale: localeProp, min, max, disabled, readOnly, placeholder: placeholderProp, todayLabel: todayLabelProp, clearLabel: clearLabelProp, className, rootProps, variant, trigger, formatValue, }: DatePickerFieldProps): react_jsx_runtime.JSX.Element;
|
|
40
64
|
|
|
41
65
|
export { DatePickerField, type DatePickerFieldProps };
|