@kopexa/date-picker 1.2.1 → 1.4.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-HPM5Y2V6.mjs → chunk-6IFLG64O.mjs} +5 -0
- package/dist/{chunk-VYQ6BFFN.mjs → chunk-BA6CJAOH.mjs} +431 -22
- package/dist/date-picker-field.d.mts +38 -1
- package/dist/date-picker-field.d.ts +38 -1
- package/dist/date-picker-field.js +423 -19
- package/dist/date-picker-field.mjs +2 -2
- package/dist/date-picker-messages.d.mts +5 -0
- package/dist/date-picker-messages.d.ts +5 -0
- package/dist/date-picker-messages.js +5 -0
- package/dist/date-picker-messages.mjs +1 -1
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +423 -19
- package/dist/index.mjs +2 -2
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -4,3 +4,4 @@ export { DatePickerField, DatePickerFieldProps } from './date-picker-field.mjs';
|
|
|
4
4
|
export { datePickerMessages } from './date-picker-messages.mjs';
|
|
5
5
|
export { DatePickerValueChangeDetails, DateValue, parseDate } from '@ark-ui/react/date-picker';
|
|
6
6
|
import 'react/jsx-runtime';
|
|
7
|
+
import 'react';
|
package/dist/index.d.ts
CHANGED
|
@@ -4,3 +4,4 @@ export { DatePickerField, DatePickerFieldProps } from './date-picker-field.js';
|
|
|
4
4
|
export { datePickerMessages } from './date-picker-messages.js';
|
|
5
5
|
export { DatePickerValueChangeDetails, DateValue, parseDate } from '@ark-ui/react/date-picker';
|
|
6
6
|
import 'react/jsx-runtime';
|
|
7
|
+
import 'react';
|
package/dist/index.js
CHANGED
|
@@ -100,6 +100,11 @@ var datePickerMessages = (0, import_i18n.defineMessages)({
|
|
|
100
100
|
id: "date-picker.select_date_and_time",
|
|
101
101
|
defaultMessage: "Select date and time",
|
|
102
102
|
description: "Placeholder for date+time input"
|
|
103
|
+
},
|
|
104
|
+
save: {
|
|
105
|
+
id: "date-picker.save",
|
|
106
|
+
defaultMessage: "Save",
|
|
107
|
+
description: "Button to commit the staged date selection (only shown when an onSave callback is provided)"
|
|
103
108
|
}
|
|
104
109
|
});
|
|
105
110
|
|
|
@@ -181,6 +186,55 @@ function XIcon({ className }) {
|
|
|
181
186
|
}
|
|
182
187
|
);
|
|
183
188
|
}
|
|
189
|
+
function getDatePartOrder(locale) {
|
|
190
|
+
try {
|
|
191
|
+
const fmt = new Intl.DateTimeFormat(locale, {
|
|
192
|
+
day: "2-digit",
|
|
193
|
+
month: "2-digit",
|
|
194
|
+
year: "numeric"
|
|
195
|
+
});
|
|
196
|
+
return fmt.formatToParts(new Date(2024, 0, 1)).filter(
|
|
197
|
+
(p) => p.type === "day" || p.type === "month" || p.type === "year"
|
|
198
|
+
).map((p) => p.type);
|
|
199
|
+
} catch {
|
|
200
|
+
return ["day", "month", "year"];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function finalizeDateParts(parts) {
|
|
204
|
+
var _a, _b, _c;
|
|
205
|
+
const day = (_a = parts.day) != null ? _a : 1;
|
|
206
|
+
const month = (_b = parts.month) != null ? _b : 1;
|
|
207
|
+
let year = (_c = parts.year) != null ? _c : (/* @__PURE__ */ new Date()).getFullYear();
|
|
208
|
+
if (year < 100) year = year < 50 ? 2e3 + year : 1900 + year;
|
|
209
|
+
if (month < 1 || month > 12) return void 0;
|
|
210
|
+
if (day < 1 || day > 31) return void 0;
|
|
211
|
+
return { year, month, day };
|
|
212
|
+
}
|
|
213
|
+
function parseLocalizedDate(value, locale) {
|
|
214
|
+
const trimmed = value.trim();
|
|
215
|
+
if (!trimmed) return void 0;
|
|
216
|
+
const order = getDatePartOrder(locale);
|
|
217
|
+
const segments = trimmed.split(/[./\-\s]+/).filter(Boolean);
|
|
218
|
+
if (segments.length === 3 && segments.every((s) => /^\d+$/.test(s))) {
|
|
219
|
+
const map2 = {};
|
|
220
|
+
order.forEach((field, i) => {
|
|
221
|
+
map2[field] = Number.parseInt(segments[i], 10);
|
|
222
|
+
});
|
|
223
|
+
return finalizeDateParts(map2);
|
|
224
|
+
}
|
|
225
|
+
const digits = trimmed.replace(/\D/g, "");
|
|
226
|
+
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;
|
|
227
|
+
if (!widths) return void 0;
|
|
228
|
+
let pos = 0;
|
|
229
|
+
const map = {};
|
|
230
|
+
for (const field of order) {
|
|
231
|
+
const w = widths[field];
|
|
232
|
+
if (w === 0) continue;
|
|
233
|
+
map[field] = Number.parseInt(digits.slice(pos, pos + w), 10);
|
|
234
|
+
pos += w;
|
|
235
|
+
}
|
|
236
|
+
return finalizeDateParts(map);
|
|
237
|
+
}
|
|
184
238
|
var styles = {
|
|
185
239
|
control: "relative flex items-center",
|
|
186
240
|
input: "w-full h-9 rounded-md border bg-transparent pl-3 pr-9 text-sm outline-none focus:ring-2 focus:ring-ring",
|
|
@@ -204,9 +258,14 @@ var styles = {
|
|
|
204
258
|
yearCellTrigger: "inline-flex items-center justify-center w-full py-2 text-sm rounded-md transition-colors hover:bg-muted data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[disabled]:text-muted-foreground/30 data-[disabled]:pointer-events-none",
|
|
205
259
|
footer: "flex items-center gap-1 pt-2 mt-2 border-t",
|
|
206
260
|
footerButton: "text-sm px-2 py-1 rounded-md hover:bg-muted transition-colors",
|
|
261
|
+
footerSaveButton: "ml-auto text-sm px-3 py-1 rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
|
|
207
262
|
timeInput: "h-9 rounded-md border bg-transparent px-3 text-sm outline-none focus:ring-2 focus:ring-ring",
|
|
208
263
|
label: "text-sm font-medium",
|
|
209
|
-
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"
|
|
264
|
+
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",
|
|
265
|
+
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",
|
|
266
|
+
defaultGhostPlaceholder: "text-muted-foreground",
|
|
267
|
+
timeRow: "mt-2 pt-2 border-t flex items-center gap-2",
|
|
268
|
+
timeRowLabel: "text-xs text-muted-foreground"
|
|
210
269
|
};
|
|
211
270
|
function DayView() {
|
|
212
271
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerView, { view: "day", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerContext, { children: (api) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
@@ -311,9 +370,19 @@ function YearView() {
|
|
|
311
370
|
)) }) })
|
|
312
371
|
] }) }) });
|
|
313
372
|
}
|
|
373
|
+
function CalendarPanel() {
|
|
374
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
375
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DayView, {}),
|
|
376
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MonthView, {}),
|
|
377
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(YearView, {})
|
|
378
|
+
] });
|
|
379
|
+
}
|
|
314
380
|
function CalendarFooter({
|
|
315
381
|
todayLabel,
|
|
316
|
-
clearLabel
|
|
382
|
+
clearLabel,
|
|
383
|
+
saveLabel,
|
|
384
|
+
clearable = true,
|
|
385
|
+
onSave
|
|
317
386
|
}) {
|
|
318
387
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerContext, { children: (api) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.footer, children: [
|
|
319
388
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -325,7 +394,7 @@ function CalendarFooter({
|
|
|
325
394
|
children: todayLabel
|
|
326
395
|
}
|
|
327
396
|
),
|
|
328
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
397
|
+
clearable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
329
398
|
"button",
|
|
330
399
|
{
|
|
331
400
|
type: "button",
|
|
@@ -333,6 +402,64 @@ function CalendarFooter({
|
|
|
333
402
|
className: `${styles.footerButton} text-destructive`,
|
|
334
403
|
children: clearLabel
|
|
335
404
|
}
|
|
405
|
+
),
|
|
406
|
+
onSave && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
407
|
+
"button",
|
|
408
|
+
{
|
|
409
|
+
type: "button",
|
|
410
|
+
onClick: () => {
|
|
411
|
+
onSave({
|
|
412
|
+
value: api.value,
|
|
413
|
+
valueAsString: api.valueAsString,
|
|
414
|
+
view: api.view
|
|
415
|
+
});
|
|
416
|
+
api.setOpen(false);
|
|
417
|
+
},
|
|
418
|
+
className: styles.footerSaveButton,
|
|
419
|
+
children: saveLabel
|
|
420
|
+
}
|
|
421
|
+
)
|
|
422
|
+
] }) });
|
|
423
|
+
}
|
|
424
|
+
function DateTimeFooter({
|
|
425
|
+
todayLabel,
|
|
426
|
+
clearLabel,
|
|
427
|
+
saveLabel,
|
|
428
|
+
clearable = true,
|
|
429
|
+
onSelectNow,
|
|
430
|
+
onClear,
|
|
431
|
+
onSave
|
|
432
|
+
}) {
|
|
433
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerContext, { children: (api) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.footer, children: [
|
|
434
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
435
|
+
"button",
|
|
436
|
+
{
|
|
437
|
+
type: "button",
|
|
438
|
+
onClick: onSelectNow,
|
|
439
|
+
className: `${styles.footerButton} text-foreground`,
|
|
440
|
+
children: todayLabel
|
|
441
|
+
}
|
|
442
|
+
),
|
|
443
|
+
clearable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
444
|
+
"button",
|
|
445
|
+
{
|
|
446
|
+
type: "button",
|
|
447
|
+
onClick: onClear,
|
|
448
|
+
className: `${styles.footerButton} text-destructive`,
|
|
449
|
+
children: clearLabel
|
|
450
|
+
}
|
|
451
|
+
),
|
|
452
|
+
onSave && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
453
|
+
"button",
|
|
454
|
+
{
|
|
455
|
+
type: "button",
|
|
456
|
+
onClick: () => {
|
|
457
|
+
onSave();
|
|
458
|
+
api.setOpen(false);
|
|
459
|
+
},
|
|
460
|
+
className: styles.footerSaveButton,
|
|
461
|
+
children: saveLabel
|
|
462
|
+
}
|
|
336
463
|
)
|
|
337
464
|
] }) });
|
|
338
465
|
}
|
|
@@ -352,16 +479,49 @@ function DatePickerField({
|
|
|
352
479
|
todayLabel: todayLabelProp,
|
|
353
480
|
clearLabel: clearLabelProp,
|
|
354
481
|
className,
|
|
355
|
-
rootProps
|
|
482
|
+
rootProps,
|
|
483
|
+
variant = "input",
|
|
484
|
+
trigger,
|
|
485
|
+
formatValue,
|
|
486
|
+
onSave,
|
|
487
|
+
saveLabel: saveLabelProp
|
|
356
488
|
}) {
|
|
357
489
|
var _a;
|
|
358
490
|
const intl = (0, import_i18n2.useSafeIntl)();
|
|
359
491
|
const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
|
|
360
492
|
const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
|
|
361
493
|
const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
|
|
494
|
+
const saveLabel = saveLabelProp != null ? saveLabelProp : intl.formatMessage(datePickerMessages.save);
|
|
362
495
|
const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(
|
|
363
496
|
showTime ? datePickerMessages.select_date_and_time : datePickerMessages.select_date
|
|
364
497
|
);
|
|
498
|
+
if (variant === "trigger") {
|
|
499
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
500
|
+
DateTriggerPickerField,
|
|
501
|
+
{
|
|
502
|
+
label,
|
|
503
|
+
value,
|
|
504
|
+
defaultValue,
|
|
505
|
+
onValueChange,
|
|
506
|
+
showTime,
|
|
507
|
+
clearable,
|
|
508
|
+
locale,
|
|
509
|
+
min,
|
|
510
|
+
max,
|
|
511
|
+
disabled,
|
|
512
|
+
readOnly,
|
|
513
|
+
placeholder,
|
|
514
|
+
todayLabel,
|
|
515
|
+
clearLabel,
|
|
516
|
+
saveLabel,
|
|
517
|
+
className,
|
|
518
|
+
rootProps,
|
|
519
|
+
trigger,
|
|
520
|
+
formatValue,
|
|
521
|
+
onSave
|
|
522
|
+
}
|
|
523
|
+
);
|
|
524
|
+
}
|
|
365
525
|
if (showTime) {
|
|
366
526
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
367
527
|
DateTimePickerField,
|
|
@@ -379,8 +539,10 @@ function DatePickerField({
|
|
|
379
539
|
placeholder,
|
|
380
540
|
todayLabel,
|
|
381
541
|
clearLabel,
|
|
542
|
+
saveLabel,
|
|
382
543
|
className,
|
|
383
|
-
rootProps
|
|
544
|
+
rootProps,
|
|
545
|
+
onSave
|
|
384
546
|
}
|
|
385
547
|
);
|
|
386
548
|
}
|
|
@@ -398,6 +560,10 @@ function DatePickerField({
|
|
|
398
560
|
selectionMode: "single",
|
|
399
561
|
outsideDaySelectable: true,
|
|
400
562
|
closeOnSelect: true,
|
|
563
|
+
parse: (input, details) => {
|
|
564
|
+
const parts = parseLocalizedDate(input, details.locale);
|
|
565
|
+
return parts ? new import_date.CalendarDate(parts.year, parts.month, parts.day) : void 0;
|
|
566
|
+
},
|
|
401
567
|
className,
|
|
402
568
|
...rootProps,
|
|
403
569
|
children: [
|
|
@@ -416,10 +582,17 @@ function DatePickerField({
|
|
|
416
582
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerTrigger, { className: styles.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CalendarIcon, { className: "size-4" }) })
|
|
417
583
|
] }),
|
|
418
584
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_portal.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerPositioner, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_date_picker2.DatePickerContent, { className: styles.content, children: [
|
|
419
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
420
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
421
|
-
|
|
422
|
-
|
|
585
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CalendarPanel, {}),
|
|
586
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
587
|
+
CalendarFooter,
|
|
588
|
+
{
|
|
589
|
+
todayLabel,
|
|
590
|
+
clearLabel,
|
|
591
|
+
saveLabel,
|
|
592
|
+
clearable,
|
|
593
|
+
onSave
|
|
594
|
+
}
|
|
595
|
+
)
|
|
423
596
|
] }) }) })
|
|
424
597
|
]
|
|
425
598
|
}
|
|
@@ -439,14 +612,17 @@ function DateTimePickerField({
|
|
|
439
612
|
placeholder: placeholderProp,
|
|
440
613
|
todayLabel: todayLabelProp,
|
|
441
614
|
clearLabel: clearLabelProp,
|
|
615
|
+
saveLabel: saveLabelProp,
|
|
442
616
|
className,
|
|
443
|
-
rootProps
|
|
617
|
+
rootProps,
|
|
618
|
+
onSave
|
|
444
619
|
}) {
|
|
445
620
|
var _a;
|
|
446
621
|
const intl = (0, import_i18n2.useSafeIntl)();
|
|
447
622
|
const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
|
|
448
623
|
const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
|
|
449
624
|
const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
|
|
625
|
+
const saveLabel = saveLabelProp != null ? saveLabelProp : intl.formatMessage(datePickerMessages.save);
|
|
450
626
|
const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(datePickerMessages.select_date_and_time);
|
|
451
627
|
const [internalValue, setInternalValue] = (0, import_react.useState)(() => {
|
|
452
628
|
const initial = valueProp != null ? valueProp : defaultValue;
|
|
@@ -517,6 +693,22 @@ function DateTimePickerField({
|
|
|
517
693
|
view: "day"
|
|
518
694
|
});
|
|
519
695
|
}, [onValueChange]);
|
|
696
|
+
const handleSelectNow = (0, import_react.useCallback)(() => {
|
|
697
|
+
const now = /* @__PURE__ */ new Date();
|
|
698
|
+
const nowValue = new import_date.CalendarDateTime(
|
|
699
|
+
now.getFullYear(),
|
|
700
|
+
now.getMonth() + 1,
|
|
701
|
+
now.getDate(),
|
|
702
|
+
now.getHours(),
|
|
703
|
+
now.getMinutes()
|
|
704
|
+
);
|
|
705
|
+
setInternalValue([nowValue]);
|
|
706
|
+
onValueChange == null ? void 0 : onValueChange({
|
|
707
|
+
value: [nowValue],
|
|
708
|
+
valueAsString: [nowValue.toString()],
|
|
709
|
+
view: "day"
|
|
710
|
+
});
|
|
711
|
+
}, [onValueChange]);
|
|
520
712
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
521
713
|
import_date_picker2.DatePickerRoot,
|
|
522
714
|
{
|
|
@@ -530,13 +722,33 @@ function DateTimePickerField({
|
|
|
530
722
|
selectionMode: "single",
|
|
531
723
|
outsideDaySelectable: true,
|
|
532
724
|
closeOnSelect: false,
|
|
725
|
+
parse: (input, details) => {
|
|
726
|
+
const parts = parseLocalizedDate(input, details.locale);
|
|
727
|
+
if (!parts) return void 0;
|
|
728
|
+
const prev = currentValue[0];
|
|
729
|
+
const hour = prev && "hour" in prev ? prev.hour : 0;
|
|
730
|
+
const minute = prev && "minute" in prev ? prev.minute : 0;
|
|
731
|
+
return new import_date.CalendarDateTime(
|
|
732
|
+
parts.year,
|
|
733
|
+
parts.month,
|
|
734
|
+
parts.day,
|
|
735
|
+
hour,
|
|
736
|
+
minute
|
|
737
|
+
);
|
|
738
|
+
},
|
|
533
739
|
className,
|
|
534
740
|
...rootProps,
|
|
535
741
|
children: [
|
|
536
742
|
label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerLabel, { className: styles.label, children: label }),
|
|
537
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_date_picker2.DatePickerControl, { className: "flex items-center
|
|
743
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_date_picker2.DatePickerControl, { className: "flex items-center", children: [
|
|
538
744
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative flex-1 flex items-center", children: [
|
|
539
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
745
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
746
|
+
import_date_picker2.DatePickerInput,
|
|
747
|
+
{
|
|
748
|
+
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",
|
|
749
|
+
placeholder
|
|
750
|
+
}
|
|
751
|
+
),
|
|
540
752
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerTrigger, { className: styles.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CalendarIcon, { className: "size-4" }) })
|
|
541
753
|
] }),
|
|
542
754
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -547,23 +759,215 @@ function DateTimePickerField({
|
|
|
547
759
|
onChange: handleTimeChange,
|
|
548
760
|
disabled,
|
|
549
761
|
readOnly,
|
|
550
|
-
className:
|
|
762
|
+
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"}`
|
|
551
763
|
}
|
|
552
764
|
),
|
|
553
765
|
clearable && !disabled && !readOnly && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
554
|
-
|
|
766
|
+
"button",
|
|
555
767
|
{
|
|
556
|
-
|
|
768
|
+
type: "button",
|
|
769
|
+
className: "inline-flex items-center justify-center size-9 rounded-r-md border text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
|
|
557
770
|
onClick: handleClear,
|
|
558
771
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(XIcon, { className: "size-4" })
|
|
559
772
|
}
|
|
560
773
|
)
|
|
561
774
|
] }),
|
|
562
775
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_portal.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerPositioner, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_date_picker2.DatePickerContent, { className: styles.content, children: [
|
|
563
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
564
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
565
|
-
|
|
566
|
-
|
|
776
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CalendarPanel, {}),
|
|
777
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
778
|
+
DateTimeFooter,
|
|
779
|
+
{
|
|
780
|
+
todayLabel,
|
|
781
|
+
clearLabel,
|
|
782
|
+
saveLabel,
|
|
783
|
+
clearable,
|
|
784
|
+
onSelectNow: handleSelectNow,
|
|
785
|
+
onClear: handleClear,
|
|
786
|
+
onSave: onSave ? () => onSave({
|
|
787
|
+
value: currentValue,
|
|
788
|
+
valueAsString: currentValue.map((v) => v.toString()),
|
|
789
|
+
view: "day"
|
|
790
|
+
}) : void 0
|
|
791
|
+
}
|
|
792
|
+
)
|
|
793
|
+
] }) }) })
|
|
794
|
+
]
|
|
795
|
+
}
|
|
796
|
+
);
|
|
797
|
+
}
|
|
798
|
+
function DateTriggerPickerField({
|
|
799
|
+
label,
|
|
800
|
+
value: valueProp,
|
|
801
|
+
defaultValue,
|
|
802
|
+
onValueChange,
|
|
803
|
+
showTime = false,
|
|
804
|
+
clearable = true,
|
|
805
|
+
locale: localeProp,
|
|
806
|
+
min,
|
|
807
|
+
max,
|
|
808
|
+
disabled,
|
|
809
|
+
readOnly,
|
|
810
|
+
placeholder: placeholderProp,
|
|
811
|
+
todayLabel: todayLabelProp,
|
|
812
|
+
clearLabel: clearLabelProp,
|
|
813
|
+
saveLabel: saveLabelProp,
|
|
814
|
+
className,
|
|
815
|
+
rootProps,
|
|
816
|
+
trigger,
|
|
817
|
+
formatValue,
|
|
818
|
+
onSave
|
|
819
|
+
}) {
|
|
820
|
+
var _a;
|
|
821
|
+
const intl = (0, import_i18n2.useSafeIntl)();
|
|
822
|
+
const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
|
|
823
|
+
const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
|
|
824
|
+
const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
|
|
825
|
+
const saveLabel = saveLabelProp != null ? saveLabelProp : intl.formatMessage(datePickerMessages.save);
|
|
826
|
+
const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(
|
|
827
|
+
showTime ? datePickerMessages.select_date_and_time : datePickerMessages.select_date
|
|
828
|
+
);
|
|
829
|
+
const [draft, setDraft] = (0, import_react.useState)(
|
|
830
|
+
() => {
|
|
831
|
+
var _a2;
|
|
832
|
+
return (_a2 = valueProp != null ? valueProp : defaultValue) != null ? _a2 : [];
|
|
833
|
+
}
|
|
834
|
+
);
|
|
835
|
+
const [committed, setCommitted] = (0, import_react.useState)(
|
|
836
|
+
() => {
|
|
837
|
+
var _a2;
|
|
838
|
+
return (_a2 = valueProp != null ? valueProp : defaultValue) != null ? _a2 : [];
|
|
839
|
+
}
|
|
840
|
+
);
|
|
841
|
+
(0, import_react.useEffect)(() => {
|
|
842
|
+
if (valueProp !== void 0) {
|
|
843
|
+
setCommitted(valueProp);
|
|
844
|
+
if (!onSave) setDraft(valueProp);
|
|
845
|
+
}
|
|
846
|
+
}, [valueProp, onSave]);
|
|
847
|
+
const currentValue = onSave ? draft : valueProp != null ? valueProp : draft;
|
|
848
|
+
const handleDateChange = (0, import_react.useCallback)(
|
|
849
|
+
(details) => {
|
|
850
|
+
const next = details.value[0];
|
|
851
|
+
if (!showTime || !next) {
|
|
852
|
+
setDraft(details.value);
|
|
853
|
+
onValueChange == null ? void 0 : onValueChange(details);
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
const prev = currentValue[0];
|
|
857
|
+
const prevHour = prev && "hour" in prev ? prev.hour : 0;
|
|
858
|
+
const prevMinute = prev && "minute" in prev ? prev.minute : 0;
|
|
859
|
+
const merged = new import_date.CalendarDateTime(
|
|
860
|
+
next.year,
|
|
861
|
+
next.month,
|
|
862
|
+
next.day,
|
|
863
|
+
prevHour,
|
|
864
|
+
prevMinute
|
|
865
|
+
);
|
|
866
|
+
setDraft([merged]);
|
|
867
|
+
onValueChange == null ? void 0 : onValueChange({ ...details, value: [merged] });
|
|
868
|
+
},
|
|
869
|
+
[currentValue, onValueChange, showTime]
|
|
870
|
+
);
|
|
871
|
+
const handleTimeChange = (0, import_react.useCallback)(
|
|
872
|
+
(e) => {
|
|
873
|
+
const [hours, minutes] = e.currentTarget.value.split(":").map(Number);
|
|
874
|
+
const prev = currentValue[0];
|
|
875
|
+
const base = prev && "hour" in prev ? prev : prev ? new import_date.CalendarDateTime(prev.year, prev.month, prev.day, 0, 0) : (() => {
|
|
876
|
+
const now = /* @__PURE__ */ new Date();
|
|
877
|
+
return new import_date.CalendarDateTime(
|
|
878
|
+
now.getFullYear(),
|
|
879
|
+
now.getMonth() + 1,
|
|
880
|
+
now.getDate(),
|
|
881
|
+
0,
|
|
882
|
+
0
|
|
883
|
+
);
|
|
884
|
+
})();
|
|
885
|
+
const updated = base.set({ hour: hours, minute: minutes });
|
|
886
|
+
setDraft([updated]);
|
|
887
|
+
onValueChange == null ? void 0 : onValueChange({
|
|
888
|
+
value: [updated],
|
|
889
|
+
valueAsString: [updated.toString()],
|
|
890
|
+
view: "day"
|
|
891
|
+
});
|
|
892
|
+
},
|
|
893
|
+
[currentValue, onValueChange]
|
|
894
|
+
);
|
|
895
|
+
const userOnOpenChange = rootProps == null ? void 0 : rootProps.onOpenChange;
|
|
896
|
+
const handleOpenChange = (0, import_react.useCallback)(
|
|
897
|
+
(details) => {
|
|
898
|
+
if (onSave && details.open) {
|
|
899
|
+
setDraft(committed);
|
|
900
|
+
}
|
|
901
|
+
userOnOpenChange == null ? void 0 : userOnOpenChange(details);
|
|
902
|
+
},
|
|
903
|
+
[committed, onSave, userOnOpenChange]
|
|
904
|
+
);
|
|
905
|
+
const handleSaveCommit = (0, import_react.useCallback)(
|
|
906
|
+
(details) => {
|
|
907
|
+
setCommitted(details.value);
|
|
908
|
+
onSave == null ? void 0 : onSave(details);
|
|
909
|
+
},
|
|
910
|
+
[onSave]
|
|
911
|
+
);
|
|
912
|
+
const formatter = (0, import_react.useMemo)(() => {
|
|
913
|
+
if (formatValue) return formatValue;
|
|
914
|
+
const fmt = new Intl.DateTimeFormat(
|
|
915
|
+
locale,
|
|
916
|
+
showTime ? { dateStyle: "medium", timeStyle: "short" } : { dateStyle: "medium" }
|
|
917
|
+
);
|
|
918
|
+
return (v) => fmt.format(v.toDate((0, import_date.getLocalTimeZone)()));
|
|
919
|
+
}, [formatValue, locale, showTime]);
|
|
920
|
+
const timeValue = currentValue[0] && "hour" in currentValue[0] ? `${String(currentValue[0].hour).padStart(2, "0")}:${String(currentValue[0].minute).padStart(2, "0")}` : "";
|
|
921
|
+
const triggerElement = trigger != null ? trigger : onSave ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", className: styles.defaultGhostTrigger, children: [
|
|
922
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CalendarIcon, { className: "size-4 shrink-0 opacity-70" }),
|
|
923
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: committed[0] ? formatter(committed[0]) : placeholder })
|
|
924
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", className: styles.defaultGhostTrigger, children: [
|
|
925
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CalendarIcon, { className: "size-4 shrink-0 opacity-70" }),
|
|
926
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerValueText, { placeholder, children: ({ value }) => formatter(value) })
|
|
927
|
+
] });
|
|
928
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
929
|
+
import_date_picker2.DatePickerRoot,
|
|
930
|
+
{
|
|
931
|
+
value: currentValue,
|
|
932
|
+
defaultValue,
|
|
933
|
+
onValueChange: handleDateChange,
|
|
934
|
+
locale,
|
|
935
|
+
min,
|
|
936
|
+
max,
|
|
937
|
+
disabled,
|
|
938
|
+
readOnly,
|
|
939
|
+
selectionMode: "single",
|
|
940
|
+
outsideDaySelectable: true,
|
|
941
|
+
closeOnSelect: !showTime && !onSave,
|
|
942
|
+
className,
|
|
943
|
+
...rootProps,
|
|
944
|
+
onOpenChange: handleOpenChange,
|
|
945
|
+
children: [
|
|
946
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerLabel, { className: styles.label, children: label }),
|
|
947
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerControl, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerTrigger, { asChild: true, children: triggerElement }) }),
|
|
948
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_portal.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerPositioner, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_date_picker2.DatePickerContent, { className: styles.content, children: [
|
|
949
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CalendarPanel, {}),
|
|
950
|
+
showTime && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.timeRow, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
951
|
+
"input",
|
|
952
|
+
{
|
|
953
|
+
type: "time",
|
|
954
|
+
value: timeValue,
|
|
955
|
+
onChange: handleTimeChange,
|
|
956
|
+
disabled,
|
|
957
|
+
readOnly,
|
|
958
|
+
className: styles.timeInput
|
|
959
|
+
}
|
|
960
|
+
) }),
|
|
961
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
962
|
+
CalendarFooter,
|
|
963
|
+
{
|
|
964
|
+
todayLabel,
|
|
965
|
+
clearLabel,
|
|
966
|
+
saveLabel,
|
|
967
|
+
clearable,
|
|
968
|
+
onSave: onSave ? handleSaveCommit : void 0
|
|
969
|
+
}
|
|
970
|
+
)
|
|
567
971
|
] }) }) })
|
|
568
972
|
]
|
|
569
973
|
}
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kopexa/date-picker",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "DatePicker component for selecting dates and times",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"date-picker",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@ark-ui/react": "^5.35.0",
|
|
32
32
|
"@internationalized/date": "^3.12.1",
|
|
33
|
-
"@kopexa/i18n": "17.14.
|
|
33
|
+
"@kopexa/i18n": "17.14.4"
|
|
34
34
|
},
|
|
35
35
|
"clean-package": "../../../clean-package.config.json",
|
|
36
36
|
"module": "dist/index.mjs",
|