@kopexa/date-picker 1.3.0 → 1.4.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.
@@ -27,6 +27,11 @@ var datePickerMessages = defineMessages({
27
27
  id: "date-picker.select_date_and_time",
28
28
  defaultMessage: "Select date and time",
29
29
  description: "Placeholder for date+time input"
30
+ },
31
+ save: {
32
+ id: "date-picker.save",
33
+ defaultMessage: "Save",
34
+ description: "Button to commit the staged date selection (only shown when an onSave callback is provided)"
30
35
  }
31
36
  });
32
37
 
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  datePickerMessages
4
- } from "./chunk-HPM5Y2V6.mjs";
4
+ } from "./chunk-6IFLG64O.mjs";
5
5
 
6
6
  // src/date-picker-field.tsx
7
7
  import {
@@ -36,7 +36,12 @@ import {
36
36
  getLocalTimeZone
37
37
  } from "@internationalized/date";
38
38
  import { useSafeIntl } from "@kopexa/i18n";
39
- import { useCallback, useMemo, useState } from "react";
39
+ import {
40
+ useCallback,
41
+ useEffect,
42
+ useMemo,
43
+ useState
44
+ } from "react";
40
45
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
41
46
  function CalendarIcon({ className }) {
42
47
  return /* @__PURE__ */ jsxs(
@@ -186,6 +191,7 @@ var styles = {
186
191
  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",
187
192
  footer: "flex items-center gap-1 pt-2 mt-2 border-t",
188
193
  footerButton: "text-sm px-2 py-1 rounded-md hover:bg-muted transition-colors",
194
+ footerSaveButton: "ml-auto text-sm px-3 py-1 rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
189
195
  timeInput: "h-9 rounded-md border bg-transparent px-3 text-sm outline-none focus:ring-2 focus:ring-ring",
190
196
  label: "text-sm font-medium",
191
197
  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",
@@ -307,7 +313,9 @@ function CalendarPanel() {
307
313
  function CalendarFooter({
308
314
  todayLabel,
309
315
  clearLabel,
310
- clearable = true
316
+ saveLabel,
317
+ clearable = true,
318
+ onSave
311
319
  }) {
312
320
  return /* @__PURE__ */ jsx(DatePickerContext, { children: (api) => /* @__PURE__ */ jsxs("div", { className: styles.footer, children: [
313
321
  /* @__PURE__ */ jsx(
@@ -327,17 +335,35 @@ function CalendarFooter({
327
335
  className: `${styles.footerButton} text-destructive`,
328
336
  children: clearLabel
329
337
  }
338
+ ),
339
+ onSave && /* @__PURE__ */ jsx(
340
+ "button",
341
+ {
342
+ type: "button",
343
+ onClick: () => {
344
+ onSave({
345
+ value: api.value,
346
+ valueAsString: api.valueAsString,
347
+ view: api.view
348
+ });
349
+ api.setOpen(false);
350
+ },
351
+ className: styles.footerSaveButton,
352
+ children: saveLabel
353
+ }
330
354
  )
331
355
  ] }) });
332
356
  }
333
357
  function DateTimeFooter({
334
358
  todayLabel,
335
359
  clearLabel,
360
+ saveLabel,
336
361
  clearable = true,
337
362
  onSelectNow,
338
- onClear
363
+ onClear,
364
+ onSave
339
365
  }) {
340
- return /* @__PURE__ */ jsxs("div", { className: styles.footer, children: [
366
+ return /* @__PURE__ */ jsx(DatePickerContext, { children: (api) => /* @__PURE__ */ jsxs("div", { className: styles.footer, children: [
341
367
  /* @__PURE__ */ jsx(
342
368
  "button",
343
369
  {
@@ -355,8 +381,20 @@ function DateTimeFooter({
355
381
  className: `${styles.footerButton} text-destructive`,
356
382
  children: clearLabel
357
383
  }
384
+ ),
385
+ onSave && /* @__PURE__ */ jsx(
386
+ "button",
387
+ {
388
+ type: "button",
389
+ onClick: () => {
390
+ onSave();
391
+ api.setOpen(false);
392
+ },
393
+ className: styles.footerSaveButton,
394
+ children: saveLabel
395
+ }
358
396
  )
359
- ] });
397
+ ] }) });
360
398
  }
361
399
  function DatePickerField({
362
400
  label,
@@ -377,13 +415,16 @@ function DatePickerField({
377
415
  rootProps,
378
416
  variant = "input",
379
417
  trigger,
380
- formatValue
418
+ formatValue,
419
+ onSave,
420
+ saveLabel: saveLabelProp
381
421
  }) {
382
422
  var _a;
383
423
  const intl = useSafeIntl();
384
424
  const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
385
425
  const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
386
426
  const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
427
+ const saveLabel = saveLabelProp != null ? saveLabelProp : intl.formatMessage(datePickerMessages.save);
387
428
  const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(
388
429
  showTime ? datePickerMessages.select_date_and_time : datePickerMessages.select_date
389
430
  );
@@ -405,10 +446,12 @@ function DatePickerField({
405
446
  placeholder,
406
447
  todayLabel,
407
448
  clearLabel,
449
+ saveLabel,
408
450
  className,
409
451
  rootProps,
410
452
  trigger,
411
- formatValue
453
+ formatValue,
454
+ onSave
412
455
  }
413
456
  );
414
457
  }
@@ -429,8 +472,10 @@ function DatePickerField({
429
472
  placeholder,
430
473
  todayLabel,
431
474
  clearLabel,
475
+ saveLabel,
432
476
  className,
433
- rootProps
477
+ rootProps,
478
+ onSave
434
479
  }
435
480
  );
436
481
  }
@@ -476,7 +521,9 @@ function DatePickerField({
476
521
  {
477
522
  todayLabel,
478
523
  clearLabel,
479
- clearable
524
+ saveLabel,
525
+ clearable,
526
+ onSave
480
527
  }
481
528
  )
482
529
  ] }) }) })
@@ -498,14 +545,17 @@ function DateTimePickerField({
498
545
  placeholder: placeholderProp,
499
546
  todayLabel: todayLabelProp,
500
547
  clearLabel: clearLabelProp,
548
+ saveLabel: saveLabelProp,
501
549
  className,
502
- rootProps
550
+ rootProps,
551
+ onSave
503
552
  }) {
504
553
  var _a;
505
554
  const intl = useSafeIntl();
506
555
  const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
507
556
  const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
508
557
  const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
558
+ const saveLabel = saveLabelProp != null ? saveLabelProp : intl.formatMessage(datePickerMessages.save);
509
559
  const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(datePickerMessages.select_date_and_time);
510
560
  const [internalValue, setInternalValue] = useState(() => {
511
561
  const initial = valueProp != null ? valueProp : defaultValue;
@@ -662,9 +712,15 @@ function DateTimePickerField({
662
712
  {
663
713
  todayLabel,
664
714
  clearLabel,
715
+ saveLabel,
665
716
  clearable,
666
717
  onSelectNow: handleSelectNow,
667
- onClear: handleClear
718
+ onClear: handleClear,
719
+ onSave: onSave ? () => onSave({
720
+ value: currentValue,
721
+ valueAsString: currentValue.map((v) => v.toString()),
722
+ view: "day"
723
+ }) : void 0
668
724
  }
669
725
  )
670
726
  ] }) }) })
@@ -687,34 +743,46 @@ function DateTriggerPickerField({
687
743
  placeholder: placeholderProp,
688
744
  todayLabel: todayLabelProp,
689
745
  clearLabel: clearLabelProp,
746
+ saveLabel: saveLabelProp,
690
747
  className,
691
748
  rootProps,
692
749
  trigger,
693
- formatValue
750
+ formatValue,
751
+ onSave
694
752
  }) {
695
753
  var _a;
696
754
  const intl = useSafeIntl();
697
755
  const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
698
756
  const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
699
757
  const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
758
+ const saveLabel = saveLabelProp != null ? saveLabelProp : intl.formatMessage(datePickerMessages.save);
700
759
  const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(
701
760
  showTime ? datePickerMessages.select_date_and_time : datePickerMessages.select_date
702
761
  );
703
- const [internalValue, setInternalValue] = useState(
762
+ const [draft, setDraft] = useState(
704
763
  () => {
705
764
  var _a2;
706
765
  return (_a2 = valueProp != null ? valueProp : defaultValue) != null ? _a2 : [];
707
766
  }
708
767
  );
709
- const currentValue = useMemo(() => {
710
- if (valueProp === void 0) return internalValue;
711
- return valueProp;
712
- }, [valueProp, internalValue]);
768
+ const [committed, setCommitted] = useState(
769
+ () => {
770
+ var _a2;
771
+ return (_a2 = valueProp != null ? valueProp : defaultValue) != null ? _a2 : [];
772
+ }
773
+ );
774
+ useEffect(() => {
775
+ if (valueProp !== void 0) {
776
+ setCommitted(valueProp);
777
+ if (!onSave) setDraft(valueProp);
778
+ }
779
+ }, [valueProp, onSave]);
780
+ const currentValue = onSave ? draft : valueProp != null ? valueProp : draft;
713
781
  const handleDateChange = useCallback(
714
782
  (details) => {
715
783
  const next = details.value[0];
716
784
  if (!showTime || !next) {
717
- setInternalValue(details.value);
785
+ setDraft(details.value);
718
786
  onValueChange == null ? void 0 : onValueChange(details);
719
787
  return;
720
788
  }
@@ -728,7 +796,7 @@ function DateTriggerPickerField({
728
796
  prevHour,
729
797
  prevMinute
730
798
  );
731
- setInternalValue([merged]);
799
+ setDraft([merged]);
732
800
  onValueChange == null ? void 0 : onValueChange({ ...details, value: [merged] });
733
801
  },
734
802
  [currentValue, onValueChange, showTime]
@@ -748,7 +816,7 @@ function DateTriggerPickerField({
748
816
  );
749
817
  })();
750
818
  const updated = base.set({ hour: hours, minute: minutes });
751
- setInternalValue([updated]);
819
+ setDraft([updated]);
752
820
  onValueChange == null ? void 0 : onValueChange({
753
821
  value: [updated],
754
822
  valueAsString: [updated.toString()],
@@ -757,6 +825,23 @@ function DateTriggerPickerField({
757
825
  },
758
826
  [currentValue, onValueChange]
759
827
  );
828
+ const userOnOpenChange = rootProps == null ? void 0 : rootProps.onOpenChange;
829
+ const handleOpenChange = useCallback(
830
+ (details) => {
831
+ if (onSave && details.open) {
832
+ setDraft(committed);
833
+ }
834
+ userOnOpenChange == null ? void 0 : userOnOpenChange(details);
835
+ },
836
+ [committed, onSave, userOnOpenChange]
837
+ );
838
+ const handleSaveCommit = useCallback(
839
+ (details) => {
840
+ setCommitted(details.value);
841
+ onSave == null ? void 0 : onSave(details);
842
+ },
843
+ [onSave]
844
+ );
760
845
  const formatter = useMemo(() => {
761
846
  if (formatValue) return formatValue;
762
847
  const fmt = new Intl.DateTimeFormat(
@@ -766,7 +851,10 @@ function DateTriggerPickerField({
766
851
  return (v) => fmt.format(v.toDate(getLocalTimeZone()));
767
852
  }, [formatValue, locale, showTime]);
768
853
  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: [
854
+ const triggerElement = trigger != null ? trigger : onSave ? /* @__PURE__ */ jsxs("button", { type: "button", className: styles.defaultGhostTrigger, children: [
855
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "size-4 shrink-0 opacity-70" }),
856
+ /* @__PURE__ */ jsx("span", { children: committed[0] ? formatter(committed[0]) : placeholder })
857
+ ] }) : /* @__PURE__ */ jsxs("button", { type: "button", className: styles.defaultGhostTrigger, children: [
770
858
  /* @__PURE__ */ jsx(CalendarIcon, { className: "size-4 shrink-0 opacity-70" }),
771
859
  /* @__PURE__ */ jsx(DatePickerValueText, { placeholder, children: ({ value }) => formatter(value) })
772
860
  ] });
@@ -783,9 +871,10 @@ function DateTriggerPickerField({
783
871
  readOnly,
784
872
  selectionMode: "single",
785
873
  outsideDaySelectable: true,
786
- closeOnSelect: !showTime,
874
+ closeOnSelect: !showTime && !onSave,
787
875
  className,
788
876
  ...rootProps,
877
+ onOpenChange: handleOpenChange,
789
878
  children: [
790
879
  label && /* @__PURE__ */ jsx(DatePickerLabel, { className: styles.label, children: label }),
791
880
  /* @__PURE__ */ jsx(DatePickerControl, { children: /* @__PURE__ */ jsx(DatePickerTrigger, { asChild: true, children: triggerElement }) }),
@@ -807,7 +896,9 @@ function DateTriggerPickerField({
807
896
  {
808
897
  todayLabel,
809
898
  clearLabel,
810
- clearable
899
+ saveLabel,
900
+ clearable,
901
+ onSave: onSave ? handleSaveCommit : void 0
811
902
  }
812
903
  )
813
904
  ] }) }) })
@@ -59,7 +59,20 @@ type DatePickerFieldProps = {
59
59
  * picker's locale, including time when `showTime` is true.
60
60
  */
61
61
  formatValue?: (value: DateValue) => string;
62
+ /**
63
+ * When provided, a "Save" button is rendered in the popover footer.
64
+ * `onValueChange` still fires per interaction so the picker stays
65
+ * controllable, but `onSave` is the explicit commit signal — callers
66
+ * that need draft-then-commit semantics (e.g. avoiding a save on every
67
+ * minute increment of the time picker) should listen here instead of
68
+ * `onValueChange`. Clicking Save also closes the popover.
69
+ */
70
+ onSave?: (details: DatePickerValueChangeDetails) => void;
71
+ /**
72
+ * Override the Save button label. Defaults to the i18n message.
73
+ */
74
+ saveLabel?: string;
62
75
  };
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;
76
+ 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, onSave, saveLabel: saveLabelProp, }: DatePickerFieldProps): react_jsx_runtime.JSX.Element;
64
77
 
65
78
  export { DatePickerField, type DatePickerFieldProps };
@@ -59,7 +59,20 @@ type DatePickerFieldProps = {
59
59
  * picker's locale, including time when `showTime` is true.
60
60
  */
61
61
  formatValue?: (value: DateValue) => string;
62
+ /**
63
+ * When provided, a "Save" button is rendered in the popover footer.
64
+ * `onValueChange` still fires per interaction so the picker stays
65
+ * controllable, but `onSave` is the explicit commit signal — callers
66
+ * that need draft-then-commit semantics (e.g. avoiding a save on every
67
+ * minute increment of the time picker) should listen here instead of
68
+ * `onValueChange`. Clicking Save also closes the popover.
69
+ */
70
+ onSave?: (details: DatePickerValueChangeDetails) => void;
71
+ /**
72
+ * Override the Save button label. Defaults to the i18n message.
73
+ */
74
+ saveLabel?: string;
62
75
  };
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;
76
+ 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, onSave, saveLabel: saveLabelProp, }: DatePickerFieldProps): react_jsx_runtime.JSX.Element;
64
77
 
65
78
  export { DatePickerField, type DatePickerFieldProps };
@@ -58,6 +58,11 @@ var datePickerMessages = (0, import_i18n.defineMessages)({
58
58
  id: "date-picker.select_date_and_time",
59
59
  defaultMessage: "Select date and time",
60
60
  description: "Placeholder for date+time input"
61
+ },
62
+ save: {
63
+ id: "date-picker.save",
64
+ defaultMessage: "Save",
65
+ description: "Button to commit the staged date selection (only shown when an onSave callback is provided)"
61
66
  }
62
67
  });
63
68
 
@@ -211,6 +216,7 @@ var styles = {
211
216
  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",
212
217
  footer: "flex items-center gap-1 pt-2 mt-2 border-t",
213
218
  footerButton: "text-sm px-2 py-1 rounded-md hover:bg-muted transition-colors",
219
+ footerSaveButton: "ml-auto text-sm px-3 py-1 rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
214
220
  timeInput: "h-9 rounded-md border bg-transparent px-3 text-sm outline-none focus:ring-2 focus:ring-ring",
215
221
  label: "text-sm font-medium",
216
222
  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",
@@ -332,7 +338,9 @@ function CalendarPanel() {
332
338
  function CalendarFooter({
333
339
  todayLabel,
334
340
  clearLabel,
335
- clearable = true
341
+ saveLabel,
342
+ clearable = true,
343
+ onSave
336
344
  }) {
337
345
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker.DatePickerContext, { children: (api) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.footer, children: [
338
346
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -352,17 +360,35 @@ function CalendarFooter({
352
360
  className: `${styles.footerButton} text-destructive`,
353
361
  children: clearLabel
354
362
  }
363
+ ),
364
+ onSave && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
365
+ "button",
366
+ {
367
+ type: "button",
368
+ onClick: () => {
369
+ onSave({
370
+ value: api.value,
371
+ valueAsString: api.valueAsString,
372
+ view: api.view
373
+ });
374
+ api.setOpen(false);
375
+ },
376
+ className: styles.footerSaveButton,
377
+ children: saveLabel
378
+ }
355
379
  )
356
380
  ] }) });
357
381
  }
358
382
  function DateTimeFooter({
359
383
  todayLabel,
360
384
  clearLabel,
385
+ saveLabel,
361
386
  clearable = true,
362
387
  onSelectNow,
363
- onClear
388
+ onClear,
389
+ onSave
364
390
  }) {
365
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.footer, children: [
391
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker.DatePickerContext, { children: (api) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.footer, children: [
366
392
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
367
393
  "button",
368
394
  {
@@ -380,8 +406,20 @@ function DateTimeFooter({
380
406
  className: `${styles.footerButton} text-destructive`,
381
407
  children: clearLabel
382
408
  }
409
+ ),
410
+ onSave && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
411
+ "button",
412
+ {
413
+ type: "button",
414
+ onClick: () => {
415
+ onSave();
416
+ api.setOpen(false);
417
+ },
418
+ className: styles.footerSaveButton,
419
+ children: saveLabel
420
+ }
383
421
  )
384
- ] });
422
+ ] }) });
385
423
  }
386
424
  function DatePickerField({
387
425
  label,
@@ -402,13 +440,16 @@ function DatePickerField({
402
440
  rootProps,
403
441
  variant = "input",
404
442
  trigger,
405
- formatValue
443
+ formatValue,
444
+ onSave,
445
+ saveLabel: saveLabelProp
406
446
  }) {
407
447
  var _a;
408
448
  const intl = (0, import_i18n2.useSafeIntl)();
409
449
  const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
410
450
  const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
411
451
  const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
452
+ const saveLabel = saveLabelProp != null ? saveLabelProp : intl.formatMessage(datePickerMessages.save);
412
453
  const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(
413
454
  showTime ? datePickerMessages.select_date_and_time : datePickerMessages.select_date
414
455
  );
@@ -430,10 +471,12 @@ function DatePickerField({
430
471
  placeholder,
431
472
  todayLabel,
432
473
  clearLabel,
474
+ saveLabel,
433
475
  className,
434
476
  rootProps,
435
477
  trigger,
436
- formatValue
478
+ formatValue,
479
+ onSave
437
480
  }
438
481
  );
439
482
  }
@@ -454,8 +497,10 @@ function DatePickerField({
454
497
  placeholder,
455
498
  todayLabel,
456
499
  clearLabel,
500
+ saveLabel,
457
501
  className,
458
- rootProps
502
+ rootProps,
503
+ onSave
459
504
  }
460
505
  );
461
506
  }
@@ -501,7 +546,9 @@ function DatePickerField({
501
546
  {
502
547
  todayLabel,
503
548
  clearLabel,
504
- clearable
549
+ saveLabel,
550
+ clearable,
551
+ onSave
505
552
  }
506
553
  )
507
554
  ] }) }) })
@@ -523,14 +570,17 @@ function DateTimePickerField({
523
570
  placeholder: placeholderProp,
524
571
  todayLabel: todayLabelProp,
525
572
  clearLabel: clearLabelProp,
573
+ saveLabel: saveLabelProp,
526
574
  className,
527
- rootProps
575
+ rootProps,
576
+ onSave
528
577
  }) {
529
578
  var _a;
530
579
  const intl = (0, import_i18n2.useSafeIntl)();
531
580
  const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
532
581
  const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
533
582
  const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
583
+ const saveLabel = saveLabelProp != null ? saveLabelProp : intl.formatMessage(datePickerMessages.save);
534
584
  const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(datePickerMessages.select_date_and_time);
535
585
  const [internalValue, setInternalValue] = (0, import_react.useState)(() => {
536
586
  const initial = valueProp != null ? valueProp : defaultValue;
@@ -687,9 +737,15 @@ function DateTimePickerField({
687
737
  {
688
738
  todayLabel,
689
739
  clearLabel,
740
+ saveLabel,
690
741
  clearable,
691
742
  onSelectNow: handleSelectNow,
692
- onClear: handleClear
743
+ onClear: handleClear,
744
+ onSave: onSave ? () => onSave({
745
+ value: currentValue,
746
+ valueAsString: currentValue.map((v) => v.toString()),
747
+ view: "day"
748
+ }) : void 0
693
749
  }
694
750
  )
695
751
  ] }) }) })
@@ -712,34 +768,46 @@ function DateTriggerPickerField({
712
768
  placeholder: placeholderProp,
713
769
  todayLabel: todayLabelProp,
714
770
  clearLabel: clearLabelProp,
771
+ saveLabel: saveLabelProp,
715
772
  className,
716
773
  rootProps,
717
774
  trigger,
718
- formatValue
775
+ formatValue,
776
+ onSave
719
777
  }) {
720
778
  var _a;
721
779
  const intl = (0, import_i18n2.useSafeIntl)();
722
780
  const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
723
781
  const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
724
782
  const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
783
+ const saveLabel = saveLabelProp != null ? saveLabelProp : intl.formatMessage(datePickerMessages.save);
725
784
  const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(
726
785
  showTime ? datePickerMessages.select_date_and_time : datePickerMessages.select_date
727
786
  );
728
- const [internalValue, setInternalValue] = (0, import_react.useState)(
787
+ const [draft, setDraft] = (0, import_react.useState)(
729
788
  () => {
730
789
  var _a2;
731
790
  return (_a2 = valueProp != null ? valueProp : defaultValue) != null ? _a2 : [];
732
791
  }
733
792
  );
734
- const currentValue = (0, import_react.useMemo)(() => {
735
- if (valueProp === void 0) return internalValue;
736
- return valueProp;
737
- }, [valueProp, internalValue]);
793
+ const [committed, setCommitted] = (0, import_react.useState)(
794
+ () => {
795
+ var _a2;
796
+ return (_a2 = valueProp != null ? valueProp : defaultValue) != null ? _a2 : [];
797
+ }
798
+ );
799
+ (0, import_react.useEffect)(() => {
800
+ if (valueProp !== void 0) {
801
+ setCommitted(valueProp);
802
+ if (!onSave) setDraft(valueProp);
803
+ }
804
+ }, [valueProp, onSave]);
805
+ const currentValue = onSave ? draft : valueProp != null ? valueProp : draft;
738
806
  const handleDateChange = (0, import_react.useCallback)(
739
807
  (details) => {
740
808
  const next = details.value[0];
741
809
  if (!showTime || !next) {
742
- setInternalValue(details.value);
810
+ setDraft(details.value);
743
811
  onValueChange == null ? void 0 : onValueChange(details);
744
812
  return;
745
813
  }
@@ -753,7 +821,7 @@ function DateTriggerPickerField({
753
821
  prevHour,
754
822
  prevMinute
755
823
  );
756
- setInternalValue([merged]);
824
+ setDraft([merged]);
757
825
  onValueChange == null ? void 0 : onValueChange({ ...details, value: [merged] });
758
826
  },
759
827
  [currentValue, onValueChange, showTime]
@@ -773,7 +841,7 @@ function DateTriggerPickerField({
773
841
  );
774
842
  })();
775
843
  const updated = base.set({ hour: hours, minute: minutes });
776
- setInternalValue([updated]);
844
+ setDraft([updated]);
777
845
  onValueChange == null ? void 0 : onValueChange({
778
846
  value: [updated],
779
847
  valueAsString: [updated.toString()],
@@ -782,6 +850,23 @@ function DateTriggerPickerField({
782
850
  },
783
851
  [currentValue, onValueChange]
784
852
  );
853
+ const userOnOpenChange = rootProps == null ? void 0 : rootProps.onOpenChange;
854
+ const handleOpenChange = (0, import_react.useCallback)(
855
+ (details) => {
856
+ if (onSave && details.open) {
857
+ setDraft(committed);
858
+ }
859
+ userOnOpenChange == null ? void 0 : userOnOpenChange(details);
860
+ },
861
+ [committed, onSave, userOnOpenChange]
862
+ );
863
+ const handleSaveCommit = (0, import_react.useCallback)(
864
+ (details) => {
865
+ setCommitted(details.value);
866
+ onSave == null ? void 0 : onSave(details);
867
+ },
868
+ [onSave]
869
+ );
785
870
  const formatter = (0, import_react.useMemo)(() => {
786
871
  if (formatValue) return formatValue;
787
872
  const fmt = new Intl.DateTimeFormat(
@@ -791,7 +876,10 @@ function DateTriggerPickerField({
791
876
  return (v) => fmt.format(v.toDate((0, import_date.getLocalTimeZone)()));
792
877
  }, [formatValue, locale, showTime]);
793
878
  const timeValue = currentValue[0] && "hour" in currentValue[0] ? `${String(currentValue[0].hour).padStart(2, "0")}:${String(currentValue[0].minute).padStart(2, "0")}` : "";
794
- const triggerElement = trigger != null ? trigger : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", className: styles.defaultGhostTrigger, children: [
879
+ const triggerElement = trigger != null ? trigger : onSave ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", className: styles.defaultGhostTrigger, children: [
880
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CalendarIcon, { className: "size-4 shrink-0 opacity-70" }),
881
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: committed[0] ? formatter(committed[0]) : placeholder })
882
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", className: styles.defaultGhostTrigger, children: [
795
883
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CalendarIcon, { className: "size-4 shrink-0 opacity-70" }),
796
884
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker.DatePickerValueText, { placeholder, children: ({ value }) => formatter(value) })
797
885
  ] });
@@ -808,9 +896,10 @@ function DateTriggerPickerField({
808
896
  readOnly,
809
897
  selectionMode: "single",
810
898
  outsideDaySelectable: true,
811
- closeOnSelect: !showTime,
899
+ closeOnSelect: !showTime && !onSave,
812
900
  className,
813
901
  ...rootProps,
902
+ onOpenChange: handleOpenChange,
814
903
  children: [
815
904
  label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker.DatePickerLabel, { className: styles.label, children: label }),
816
905
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker.DatePickerControl, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker.DatePickerTrigger, { asChild: true, children: triggerElement }) }),
@@ -832,7 +921,9 @@ function DateTriggerPickerField({
832
921
  {
833
922
  todayLabel,
834
923
  clearLabel,
835
- clearable
924
+ saveLabel,
925
+ clearable,
926
+ onSave: onSave ? handleSaveCommit : void 0
836
927
  }
837
928
  )
838
929
  ] }) }) })
@@ -2,8 +2,8 @@
2
2
  "use client";
3
3
  import {
4
4
  DatePickerField
5
- } from "./chunk-RWJEVZ4B.mjs";
6
- import "./chunk-HPM5Y2V6.mjs";
5
+ } from "./chunk-BA6CJAOH.mjs";
6
+ import "./chunk-6IFLG64O.mjs";
7
7
  import "./chunk-C7GZJJIK.mjs";
8
8
  export {
9
9
  DatePickerField
@@ -24,6 +24,11 @@ declare const datePickerMessages: {
24
24
  defaultMessage: string;
25
25
  description: string;
26
26
  };
27
+ save: {
28
+ id: string;
29
+ defaultMessage: string;
30
+ description: string;
31
+ };
27
32
  };
28
33
 
29
34
  export { datePickerMessages };
@@ -24,6 +24,11 @@ declare const datePickerMessages: {
24
24
  defaultMessage: string;
25
25
  description: string;
26
26
  };
27
+ save: {
28
+ id: string;
29
+ defaultMessage: string;
30
+ description: string;
31
+ };
27
32
  };
28
33
 
29
34
  export { datePickerMessages };
@@ -50,6 +50,11 @@ var datePickerMessages = (0, import_i18n.defineMessages)({
50
50
  id: "date-picker.select_date_and_time",
51
51
  defaultMessage: "Select date and time",
52
52
  description: "Placeholder for date+time input"
53
+ },
54
+ save: {
55
+ id: "date-picker.save",
56
+ defaultMessage: "Save",
57
+ description: "Button to commit the staged date selection (only shown when an onSave callback is provided)"
53
58
  }
54
59
  });
55
60
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  datePickerMessages
4
- } from "./chunk-HPM5Y2V6.mjs";
4
+ } from "./chunk-6IFLG64O.mjs";
5
5
  import "./chunk-C7GZJJIK.mjs";
6
6
  export {
7
7
  datePickerMessages
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
 
@@ -253,6 +258,7 @@ var styles = {
253
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",
254
259
  footer: "flex items-center gap-1 pt-2 mt-2 border-t",
255
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",
256
262
  timeInput: "h-9 rounded-md border bg-transparent px-3 text-sm outline-none focus:ring-2 focus:ring-ring",
257
263
  label: "text-sm font-medium",
258
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",
@@ -374,7 +380,9 @@ function CalendarPanel() {
374
380
  function CalendarFooter({
375
381
  todayLabel,
376
382
  clearLabel,
377
- clearable = true
383
+ saveLabel,
384
+ clearable = true,
385
+ onSave
378
386
  }) {
379
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: [
380
388
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -394,17 +402,35 @@ function CalendarFooter({
394
402
  className: `${styles.footerButton} text-destructive`,
395
403
  children: clearLabel
396
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
+ }
397
421
  )
398
422
  ] }) });
399
423
  }
400
424
  function DateTimeFooter({
401
425
  todayLabel,
402
426
  clearLabel,
427
+ saveLabel,
403
428
  clearable = true,
404
429
  onSelectNow,
405
- onClear
430
+ onClear,
431
+ onSave
406
432
  }) {
407
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.footer, children: [
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: [
408
434
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
409
435
  "button",
410
436
  {
@@ -422,8 +448,20 @@ function DateTimeFooter({
422
448
  className: `${styles.footerButton} text-destructive`,
423
449
  children: clearLabel
424
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
+ }
425
463
  )
426
- ] });
464
+ ] }) });
427
465
  }
428
466
  function DatePickerField({
429
467
  label,
@@ -444,13 +482,16 @@ function DatePickerField({
444
482
  rootProps,
445
483
  variant = "input",
446
484
  trigger,
447
- formatValue
485
+ formatValue,
486
+ onSave,
487
+ saveLabel: saveLabelProp
448
488
  }) {
449
489
  var _a;
450
490
  const intl = (0, import_i18n2.useSafeIntl)();
451
491
  const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
452
492
  const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
453
493
  const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
494
+ const saveLabel = saveLabelProp != null ? saveLabelProp : intl.formatMessage(datePickerMessages.save);
454
495
  const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(
455
496
  showTime ? datePickerMessages.select_date_and_time : datePickerMessages.select_date
456
497
  );
@@ -472,10 +513,12 @@ function DatePickerField({
472
513
  placeholder,
473
514
  todayLabel,
474
515
  clearLabel,
516
+ saveLabel,
475
517
  className,
476
518
  rootProps,
477
519
  trigger,
478
- formatValue
520
+ formatValue,
521
+ onSave
479
522
  }
480
523
  );
481
524
  }
@@ -496,8 +539,10 @@ function DatePickerField({
496
539
  placeholder,
497
540
  todayLabel,
498
541
  clearLabel,
542
+ saveLabel,
499
543
  className,
500
- rootProps
544
+ rootProps,
545
+ onSave
501
546
  }
502
547
  );
503
548
  }
@@ -543,7 +588,9 @@ function DatePickerField({
543
588
  {
544
589
  todayLabel,
545
590
  clearLabel,
546
- clearable
591
+ saveLabel,
592
+ clearable,
593
+ onSave
547
594
  }
548
595
  )
549
596
  ] }) }) })
@@ -565,14 +612,17 @@ function DateTimePickerField({
565
612
  placeholder: placeholderProp,
566
613
  todayLabel: todayLabelProp,
567
614
  clearLabel: clearLabelProp,
615
+ saveLabel: saveLabelProp,
568
616
  className,
569
- rootProps
617
+ rootProps,
618
+ onSave
570
619
  }) {
571
620
  var _a;
572
621
  const intl = (0, import_i18n2.useSafeIntl)();
573
622
  const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
574
623
  const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
575
624
  const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
625
+ const saveLabel = saveLabelProp != null ? saveLabelProp : intl.formatMessage(datePickerMessages.save);
576
626
  const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(datePickerMessages.select_date_and_time);
577
627
  const [internalValue, setInternalValue] = (0, import_react.useState)(() => {
578
628
  const initial = valueProp != null ? valueProp : defaultValue;
@@ -729,9 +779,15 @@ function DateTimePickerField({
729
779
  {
730
780
  todayLabel,
731
781
  clearLabel,
782
+ saveLabel,
732
783
  clearable,
733
784
  onSelectNow: handleSelectNow,
734
- onClear: handleClear
785
+ onClear: handleClear,
786
+ onSave: onSave ? () => onSave({
787
+ value: currentValue,
788
+ valueAsString: currentValue.map((v) => v.toString()),
789
+ view: "day"
790
+ }) : void 0
735
791
  }
736
792
  )
737
793
  ] }) }) })
@@ -754,34 +810,46 @@ function DateTriggerPickerField({
754
810
  placeholder: placeholderProp,
755
811
  todayLabel: todayLabelProp,
756
812
  clearLabel: clearLabelProp,
813
+ saveLabel: saveLabelProp,
757
814
  className,
758
815
  rootProps,
759
816
  trigger,
760
- formatValue
817
+ formatValue,
818
+ onSave
761
819
  }) {
762
820
  var _a;
763
821
  const intl = (0, import_i18n2.useSafeIntl)();
764
822
  const locale = (_a = localeProp != null ? localeProp : intl.locale) != null ? _a : "en-US";
765
823
  const todayLabel = todayLabelProp != null ? todayLabelProp : intl.formatMessage(datePickerMessages.today);
766
824
  const clearLabel = clearLabelProp != null ? clearLabelProp : intl.formatMessage(datePickerMessages.clear);
825
+ const saveLabel = saveLabelProp != null ? saveLabelProp : intl.formatMessage(datePickerMessages.save);
767
826
  const placeholder = placeholderProp != null ? placeholderProp : intl.formatMessage(
768
827
  showTime ? datePickerMessages.select_date_and_time : datePickerMessages.select_date
769
828
  );
770
- const [internalValue, setInternalValue] = (0, import_react.useState)(
829
+ const [draft, setDraft] = (0, import_react.useState)(
771
830
  () => {
772
831
  var _a2;
773
832
  return (_a2 = valueProp != null ? valueProp : defaultValue) != null ? _a2 : [];
774
833
  }
775
834
  );
776
- const currentValue = (0, import_react.useMemo)(() => {
777
- if (valueProp === void 0) return internalValue;
778
- return valueProp;
779
- }, [valueProp, internalValue]);
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;
780
848
  const handleDateChange = (0, import_react.useCallback)(
781
849
  (details) => {
782
850
  const next = details.value[0];
783
851
  if (!showTime || !next) {
784
- setInternalValue(details.value);
852
+ setDraft(details.value);
785
853
  onValueChange == null ? void 0 : onValueChange(details);
786
854
  return;
787
855
  }
@@ -795,7 +863,7 @@ function DateTriggerPickerField({
795
863
  prevHour,
796
864
  prevMinute
797
865
  );
798
- setInternalValue([merged]);
866
+ setDraft([merged]);
799
867
  onValueChange == null ? void 0 : onValueChange({ ...details, value: [merged] });
800
868
  },
801
869
  [currentValue, onValueChange, showTime]
@@ -815,7 +883,7 @@ function DateTriggerPickerField({
815
883
  );
816
884
  })();
817
885
  const updated = base.set({ hour: hours, minute: minutes });
818
- setInternalValue([updated]);
886
+ setDraft([updated]);
819
887
  onValueChange == null ? void 0 : onValueChange({
820
888
  value: [updated],
821
889
  valueAsString: [updated.toString()],
@@ -824,6 +892,23 @@ function DateTriggerPickerField({
824
892
  },
825
893
  [currentValue, onValueChange]
826
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
+ );
827
912
  const formatter = (0, import_react.useMemo)(() => {
828
913
  if (formatValue) return formatValue;
829
914
  const fmt = new Intl.DateTimeFormat(
@@ -833,7 +918,10 @@ function DateTriggerPickerField({
833
918
  return (v) => fmt.format(v.toDate((0, import_date.getLocalTimeZone)()));
834
919
  }, [formatValue, locale, showTime]);
835
920
  const timeValue = currentValue[0] && "hour" in currentValue[0] ? `${String(currentValue[0].hour).padStart(2, "0")}:${String(currentValue[0].minute).padStart(2, "0")}` : "";
836
- const triggerElement = trigger != null ? trigger : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", className: styles.defaultGhostTrigger, children: [
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: [
837
925
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CalendarIcon, { className: "size-4 shrink-0 opacity-70" }),
838
926
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerValueText, { placeholder, children: ({ value }) => formatter(value) })
839
927
  ] });
@@ -850,9 +938,10 @@ function DateTriggerPickerField({
850
938
  readOnly,
851
939
  selectionMode: "single",
852
940
  outsideDaySelectable: true,
853
- closeOnSelect: !showTime,
941
+ closeOnSelect: !showTime && !onSave,
854
942
  className,
855
943
  ...rootProps,
944
+ onOpenChange: handleOpenChange,
856
945
  children: [
857
946
  label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_date_picker2.DatePickerLabel, { className: styles.label, children: label }),
858
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 }) }),
@@ -874,7 +963,9 @@ function DateTriggerPickerField({
874
963
  {
875
964
  todayLabel,
876
965
  clearLabel,
877
- clearable
966
+ saveLabel,
967
+ clearable,
968
+ onSave: onSave ? handleSaveCommit : void 0
878
969
  }
879
970
  )
880
971
  ] }) }) })
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  DatePickerField
4
- } from "./chunk-RWJEVZ4B.mjs";
4
+ } from "./chunk-BA6CJAOH.mjs";
5
5
  import {
6
6
  datePickerMessages
7
- } from "./chunk-HPM5Y2V6.mjs";
7
+ } from "./chunk-6IFLG64O.mjs";
8
8
  import {
9
9
  date_picker_exports,
10
10
  parseDate
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kopexa/date-picker",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
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.3"
33
+ "@kopexa/i18n": "17.15.0"
34
34
  },
35
35
  "clean-package": "../../../clean-package.config.json",
36
36
  "module": "dist/index.mjs",