@kazee-ds/react 0.6.0 → 0.7.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/index.js CHANGED
@@ -27,8 +27,11 @@ import { Tooltip as Tooltip$1, TooltipTrigger } from "react-aria-components/Tool
27
27
  import { Menu, MenuItem, MenuSection, MenuTrigger, SubmenuTrigger } from "react-aria-components/Menu";
28
28
  import { Separator as Separator$1 } from "react-aria-components/Separator";
29
29
  import { Button as Button$5, ComboBox, ComboBoxStateContext, Input as Input$3, Label as Label$6, ListBox as ListBox$3, ListBoxItem as ListBoxItem$2, Popover as Popover$3 } from "react-aria-components/ComboBox";
30
- import { CalendarCell, CalendarGrid, CalendarGridBody, CalendarGridHeader, CalendarHeaderCell, CalendarHeading, RangeCalendar, RangeCalendarStateContext } from "react-aria-components/RangeCalendar";
31
- import { GregorianCalendar, endOfMonth, getLocalTimeZone, parseDate, startOfMonth, startOfWeek, today } from "@internationalized/date";
30
+ import { CalendarCell, CalendarGrid, CalendarGridBody, CalendarGridHeader, CalendarHeaderCell, RangeCalendar as RangeCalendar$1, RangeCalendarStateContext } from "react-aria-components/RangeCalendar";
31
+ import { CalendarDate, GregorianCalendar, endOfMonth, getLocalTimeZone, now, parseAbsolute, parseDate, parseDateTime, parseTime, parseZonedDateTime, startOfMonth, startOfWeek, toCalendarDateTime, toZoned, today } from "@internationalized/date";
32
+ import { Calendar as Calendar$1, CalendarCell as CalendarCell$1, CalendarGrid as CalendarGrid$1, CalendarGridBody as CalendarGridBody$1, CalendarGridHeader as CalendarGridHeader$1, CalendarHeaderCell as CalendarHeaderCell$1, CalendarStateContext } from "react-aria-components/Calendar";
33
+ import { DateField as DateField$1, DateInput, DateSegment } from "react-aria-components/DateField";
34
+ import { TimeField as TimeField$1 } from "react-aria-components/TimeField";
32
35
  //#region src/Button.tsx
33
36
  function PendingLabelAnchor() {
34
37
  const context = useContext(ProgressBarContext);
@@ -80,7 +83,7 @@ function ButtonGroupSeparator({ className, style, classNames } = {}) {
80
83
  "aria-hidden": "true"
81
84
  });
82
85
  }
83
- function Root$1({ children, label, variant, size, isDisabled, fullWidth, orientation = "horizontal", dir, className, style, classNames }) {
86
+ function Root$2({ children, label, variant, size, isDisabled, fullWidth, orientation = "horizontal", dir, className, style, classNames }) {
84
87
  function defaults(nodes) {
85
88
  return Children.map(nodes, (child) => {
86
89
  if (!isValidElement(child)) return child;
@@ -104,12 +107,14 @@ function Root$1({ children, label, variant, size, isDisabled, fullWidth, orienta
104
107
  children: defaults(children)
105
108
  });
106
109
  }
107
- var ButtonGroup = /* @__PURE__ */ Object.assign(Root$1, { Separator: ButtonGroupSeparator });
110
+ var ButtonGroup = /* @__PURE__ */ Object.assign(Root$2, { Separator: ButtonGroupSeparator });
108
111
  //#endregion
109
112
  //#region src/ToggleButton.tsx
110
113
  var ToggleButtonSizeContext = createContext("md");
111
- function ToggleButton({ children, variant = "default", size, isIconOnly, className: consumerClassName, classNames, style, ...props }) {
114
+ var ToggleButtonVariantContext = createContext("default");
115
+ function ToggleButton({ children, variant, size, isIconOnly, className: consumerClassName, classNames, style, ...props }) {
112
116
  const inheritedSize = useContext(ToggleButtonSizeContext);
117
+ const inheritedVariant = useContext(ToggleButtonVariantContext);
113
118
  const resolvedSize = size ?? inheritedSize;
114
119
  return /* @__PURE__ */ jsx(ToggleButton$1, {
115
120
  ...props,
@@ -119,7 +124,7 @@ function ToggleButton({ children, variant = "default", size, isIconOnly, classNa
119
124
  classNames?.root,
120
125
  consumerClassName,
121
126
  "toggle-button",
122
- `toggle-button--${variant}`,
127
+ `toggle-button--${variant ?? inheritedVariant}`,
123
128
  resolvedSize !== "md" && `button--${resolvedSize}`,
124
129
  isIconOnly && "button--icon-only"
125
130
  ].filter(Boolean).join(" "),
@@ -144,41 +149,44 @@ function OverlayDirection({ dir, children }) {
144
149
  //#endregion
145
150
  //#region src/ToggleButtonGroup.tsx
146
151
  var keys = (value) => Array.isArray(value) ? value : value ? [value] : [];
147
- function Root(props) {
152
+ function Root$1(props) {
148
153
  return /* @__PURE__ */ jsx(OverlayDirection, {
149
154
  dir: props.dir,
150
155
  children: /* @__PURE__ */ jsx(ToggleButtonSizeContext.Provider, {
151
156
  value: props.size ?? "md",
152
- children: /* @__PURE__ */ jsx(ToggleButtonGroup$1, {
153
- "aria-label": props.label,
154
- dir: props.dir,
155
- className: [
156
- "button-group",
157
- props.classNames?.root,
158
- props.className,
159
- "toggle-button-group",
160
- props.isDetached && "button-group--detached",
161
- props.fullWidth && "button-group--full-width"
162
- ].filter(Boolean).join(" "),
163
- style: props.style,
164
- orientation: props.orientation ?? "horizontal",
165
- selectionMode: props.selectionMode ?? "single",
166
- selectedKeys: props.value === void 0 ? void 0 : keys(props.value),
167
- defaultSelectedKeys: keys(props.defaultValue),
168
- onSelectionChange: (selected) => {
169
- if (props.isDisabled) return;
170
- const next = Array.from(selected, String);
171
- if (props.selectionMode === "multiple") props.onChange?.(next);
172
- else props.onChange?.(next[0] ?? null);
173
- },
174
- isDisabled: props.isDisabled,
175
- disallowEmptySelection: props.disallowEmptySelection,
176
- children: props.children
157
+ children: /* @__PURE__ */ jsx(ToggleButtonVariantContext.Provider, {
158
+ value: props.variant ?? "default",
159
+ children: /* @__PURE__ */ jsx(ToggleButtonGroup$1, {
160
+ "aria-label": props.label,
161
+ dir: props.dir,
162
+ className: [
163
+ "button-group",
164
+ props.classNames?.root,
165
+ props.className,
166
+ "toggle-button-group",
167
+ (props.isDetached ?? props.variant === "chip") && "button-group--detached",
168
+ props.fullWidth && "button-group--full-width"
169
+ ].filter(Boolean).join(" "),
170
+ style: props.style,
171
+ orientation: props.orientation ?? "horizontal",
172
+ selectionMode: props.selectionMode ?? "single",
173
+ selectedKeys: props.value === void 0 ? void 0 : keys(props.value),
174
+ defaultSelectedKeys: keys(props.defaultValue),
175
+ onSelectionChange: (selected) => {
176
+ if (props.isDisabled) return;
177
+ const next = Array.from(selected, String);
178
+ if (props.selectionMode === "multiple") props.onChange?.(next);
179
+ else props.onChange?.(next[0] ?? null);
180
+ },
181
+ isDisabled: props.isDisabled,
182
+ disallowEmptySelection: props.disallowEmptySelection,
183
+ children: props.children
184
+ })
177
185
  })
178
186
  })
179
187
  });
180
188
  }
181
- var ToggleButtonGroup = /* @__PURE__ */ Object.assign(Root, { Separator: ButtonGroupSeparator });
189
+ var ToggleButtonGroup = /* @__PURE__ */ Object.assign(Root$1, { Separator: ButtonGroupSeparator });
182
190
  //#endregion
183
191
  //#region src/label-context.ts
184
192
  /** Item labels use Text slots rather than introducing native label elements. */
@@ -227,6 +235,64 @@ function CloseIcon({ className }) {
227
235
  });
228
236
  }
229
237
  //#endregion
238
+ //#region src/input-clear.tsx
239
+ var InputClearContext = createContext(null);
240
+ function useClearableInput({ value, defaultValue = "", onChange, isDisabled, isReadOnly }, element) {
241
+ const [local, setLocal] = useState(defaultValue);
242
+ const current = value === void 0 ? local : value;
243
+ const update = (next) => {
244
+ if (!isDisabled && !isReadOnly) {
245
+ if (value === void 0) setLocal(next);
246
+ onChange?.(next);
247
+ }
248
+ };
249
+ useEffect(() => {
250
+ const form = (element.current instanceof HTMLInputElement || element.current instanceof HTMLTextAreaElement ? element.current : element.current?.querySelector("input,textarea"))?.form;
251
+ const reset = (event) => {
252
+ queueMicrotask(() => {
253
+ if (!event.defaultPrevented && value === void 0) setLocal(defaultValue);
254
+ });
255
+ };
256
+ form?.addEventListener("reset", reset);
257
+ return () => form?.removeEventListener("reset", reset);
258
+ }, [
259
+ element,
260
+ value,
261
+ defaultValue
262
+ ]);
263
+ return {
264
+ value: current,
265
+ update,
266
+ context: {
267
+ value: current,
268
+ disabled: isDisabled,
269
+ readOnly: isReadOnly,
270
+ clear: () => {
271
+ if (isDisabled || isReadOnly) return;
272
+ update("");
273
+ (element.current instanceof HTMLInputElement || element.current instanceof HTMLTextAreaElement ? element.current : element.current?.querySelector("input,textarea"))?.focus();
274
+ }
275
+ }
276
+ };
277
+ }
278
+ function InputClearButton({ className, children, onClick, ...props }) {
279
+ const context = useContext(InputClearContext);
280
+ if (!context) throw new Error("Input.ClearButton requires Input.Root.");
281
+ if (!context.value || context.readOnly) return null;
282
+ return /* @__PURE__ */ jsx("button", {
283
+ "aria-label": "Hapus input / Clear input",
284
+ ...props,
285
+ type: "button",
286
+ className: partClass("input__clear", className),
287
+ disabled: context.disabled || props.disabled,
288
+ onClick: (event) => {
289
+ onClick?.(event);
290
+ if (!event.defaultPrevented) context.clear();
291
+ },
292
+ children: children ?? /* @__PURE__ */ jsx(CloseIcon, {})
293
+ });
294
+ }
295
+ //#endregion
230
296
  //#region src/control-composition.tsx
231
297
  var SelectPartsContext = createContext({
232
298
  clearButtons: 0,
@@ -418,10 +484,24 @@ function FieldError({ className, ...props }) {
418
484
  className: partClass(partClass("input__error", fieldClasses.error), className)
419
485
  });
420
486
  }
421
- function InputRoot({ className, ...props }) {
422
- return /* @__PURE__ */ jsx(TextField, {
423
- ...props,
424
- className: partClass("input", className)
487
+ function InputRoot({ className, size = "md", variant = "primary", hideLabel = false, value, defaultValue, onChange, ...props }) {
488
+ const root = useRef(null);
489
+ const clearable = useClearableInput({
490
+ value,
491
+ defaultValue,
492
+ onChange,
493
+ isDisabled: props.isDisabled,
494
+ isReadOnly: props.isReadOnly
495
+ }, root);
496
+ return /* @__PURE__ */ jsx(InputClearContext.Provider, {
497
+ value: clearable.context,
498
+ children: /* @__PURE__ */ jsx(TextField, {
499
+ ...props,
500
+ ref: root,
501
+ value: clearable.value,
502
+ onChange: clearable.update,
503
+ className: partClass(`input input--${size} input--${variant}${hideLabel ? " input--label-hidden" : ""}`, className)
504
+ })
425
505
  });
426
506
  }
427
507
  var InputControlRefContext = createContext(void 0);
@@ -717,10 +797,17 @@ function SelectGroup({ label, children, size, variant, fullWidth = true, isDisab
717
797
  }
718
798
  //#endregion
719
799
  //#region src/Input.tsx
720
- var CompactInput = /* @__PURE__ */ forwardRef(function Input({ label, value, defaultValue, onChange, description, errorMessage, isInvalid = false, isDisabled = false, isReadOnly = false, isRequired = false, placeholder, type = "text", size = "md", variant = "primary", fullWidth = true, prefix, suffix, name, id, autoComplete, maxLength, minLength, pattern, inputMode, enterKeyHint, autoFocus, spellCheck, form, onFocus, onBlur, onKeyDown, onKeyUp, dir, className, style, classNames }, ref) {
800
+ var CompactInput = /* @__PURE__ */ forwardRef(function Input({ label, value, defaultValue, onChange, description, errorMessage, isInvalid = false, isDisabled = false, isReadOnly = false, isRequired = false, placeholder, type = "text", size = "md", variant = "primary", fullWidth = true, hideLabel = false, isClearable = false, clearLabel, prefix, suffix, name, id, autoComplete, maxLength, minLength, pattern, inputMode, enterKeyHint, autoFocus, spellCheck, form, onFocus, onBlur, onKeyDown, onKeyUp, dir, className, style, classNames }, ref) {
721
801
  const control = useRef(null);
802
+ const clearable = useClearableInput({
803
+ value,
804
+ defaultValue,
805
+ onChange,
806
+ isDisabled,
807
+ isReadOnly
808
+ }, control);
722
809
  useImperativeHandle(ref, () => control.current);
723
- const hasAdornment = prefix != null || suffix != null;
810
+ const hasAdornment = prefix != null || suffix != null || isClearable;
724
811
  const input = /* @__PURE__ */ jsx(Input$1, {
725
812
  ref: control,
726
813
  className: partClass(partClass("input__control", classNames?.input), classNames?.control),
@@ -738,65 +825,71 @@ var CompactInput = /* @__PURE__ */ forwardRef(function Input({ label, value, def
738
825
  onKeyDown,
739
826
  onKeyUp
740
827
  });
741
- return /* @__PURE__ */ jsxs(TextField, {
742
- className: partClass(partClass(`input input--${size} input--${variant}${fullWidth ? "" : " input--fit"}`, classNames?.root), className),
743
- style,
744
- value,
745
- defaultValue,
746
- onChange,
747
- isInvalid,
748
- isDisabled,
749
- isReadOnly,
750
- isRequired,
751
- validationBehavior: "aria",
752
- type,
753
- name,
754
- id,
755
- autoComplete,
756
- maxLength,
757
- dir,
758
- children: [
759
- /* @__PURE__ */ jsx(Label$2, {
760
- className: partClass("input__label", classNames?.label),
761
- children: label
762
- }),
763
- /* @__PURE__ */ jsx("fieldset", {
764
- className: partClass("input__boundary", classNames?.boundary),
765
- role: "presentation",
766
- disabled: isDisabled,
767
- children: /* @__PURE__ */ jsxs("div", {
768
- className: partClass(hasAdornment ? "input__group" : "input__plain", classNames?.group),
769
- "data-invalid": isInvalid || void 0,
770
- "data-readonly": isReadOnly || void 0,
771
- onPointerDown: (event) => {
772
- if (!isDisabled && !event.target.closest("input,button,a,select,textarea,[tabindex],[contenteditable]")) {
773
- event.preventDefault();
774
- control.current?.focus();
775
- }
776
- },
777
- children: [
778
- prefix != null && /* @__PURE__ */ jsx("span", {
779
- className: partClass("input__prefix", classNames?.prefix),
780
- children: prefix
781
- }),
782
- input,
783
- suffix != null && /* @__PURE__ */ jsx("span", {
784
- className: partClass("input__suffix", classNames?.suffix),
785
- children: suffix
786
- })
787
- ]
828
+ return /* @__PURE__ */ jsx(InputClearContext.Provider, {
829
+ value: clearable.context,
830
+ children: /* @__PURE__ */ jsxs(TextField, {
831
+ className: partClass(partClass(`input input--${size} input--${variant}${fullWidth ? "" : " input--fit"}${hideLabel ? " input--label-hidden" : ""}`, classNames?.root), className),
832
+ style,
833
+ value: clearable.value,
834
+ onChange: clearable.update,
835
+ isInvalid,
836
+ isDisabled,
837
+ isReadOnly,
838
+ isRequired,
839
+ validationBehavior: "aria",
840
+ type,
841
+ name,
842
+ id,
843
+ autoComplete,
844
+ maxLength,
845
+ dir,
846
+ children: [
847
+ /* @__PURE__ */ jsx(Label$2, {
848
+ className: partClass("input__label", classNames?.label),
849
+ children: label
850
+ }),
851
+ /* @__PURE__ */ jsx("fieldset", {
852
+ className: partClass("input__boundary", classNames?.boundary),
853
+ role: "presentation",
854
+ disabled: isDisabled,
855
+ children: /* @__PURE__ */ jsxs("div", {
856
+ className: partClass(hasAdornment ? "input__group" : "input__plain", classNames?.group),
857
+ "data-invalid": isInvalid || void 0,
858
+ "data-readonly": isReadOnly || void 0,
859
+ onPointerDown: (event) => {
860
+ if (!isDisabled && !event.target.closest("input,button,a,select,textarea,[tabindex],[contenteditable]")) {
861
+ event.preventDefault();
862
+ control.current?.focus();
863
+ }
864
+ },
865
+ children: [
866
+ prefix != null && /* @__PURE__ */ jsx("span", {
867
+ className: partClass("input__prefix", classNames?.prefix),
868
+ children: prefix
869
+ }),
870
+ input,
871
+ isClearable && /* @__PURE__ */ jsx(InputClearButton, {
872
+ "aria-label": clearLabel ?? "Hapus input / Clear input",
873
+ className: classNames?.clearButton
874
+ }),
875
+ suffix != null && /* @__PURE__ */ jsx("span", {
876
+ className: partClass("input__suffix", classNames?.suffix),
877
+ children: suffix
878
+ })
879
+ ]
880
+ })
881
+ }),
882
+ description && /* @__PURE__ */ jsx(Text$1, {
883
+ slot: "description",
884
+ className: partClass("input__description", classNames?.description),
885
+ children: description
886
+ }),
887
+ isInvalid && errorMessage && /* @__PURE__ */ jsx(FieldError$2, {
888
+ className: partClass("input__error", classNames?.error),
889
+ children: errorMessage
788
890
  })
789
- }),
790
- description && /* @__PURE__ */ jsx(Text$1, {
791
- slot: "description",
792
- className: partClass("input__description", classNames?.description),
793
- children: description
794
- }),
795
- isInvalid && errorMessage && /* @__PURE__ */ jsx(FieldError$2, {
796
- className: partClass("input__error", classNames?.error),
797
- children: errorMessage
798
- })
799
- ]
891
+ ]
892
+ })
800
893
  });
801
894
  });
802
895
  var Input = /* @__PURE__ */ Object.assign(/* @__PURE__ */ forwardRef(function InputWithComposition(props, ref) {
@@ -813,7 +906,8 @@ var Input = /* @__PURE__ */ Object.assign(/* @__PURE__ */ forwardRef(function In
813
906
  Control: InputControl,
814
907
  Group: InputGroup,
815
908
  Prefix: InputPrefix,
816
- Suffix: InputSuffix
909
+ Suffix: InputSuffix,
910
+ ClearButton: InputClearButton
817
911
  });
818
912
  //#endregion
819
913
  //#region src/Textarea.tsx
@@ -894,6 +988,36 @@ function Label({ children, htmlFor, id, className, style, classNames }) {
894
988
  });
895
989
  }
896
990
  //#endregion
991
+ //#region src/switch-visual.tsx
992
+ var SwitchVisualContext = createContext({});
993
+ function SwitchGroup({ size, tone, variant, isDisabled, orientation = "vertical", className, ...props }) {
994
+ const { label, ...native } = props;
995
+ return /* @__PURE__ */ jsx(SwitchVisualContext.Provider, {
996
+ value: {
997
+ size,
998
+ tone,
999
+ variant,
1000
+ isDisabled
1001
+ },
1002
+ children: /* @__PURE__ */ jsx("div", {
1003
+ ...native,
1004
+ role: "group",
1005
+ "aria-label": label ?? props["aria-label"],
1006
+ className: partClass("switch-group", className),
1007
+ "data-orientation": orientation
1008
+ })
1009
+ });
1010
+ }
1011
+ function useSwitchVisual(props) {
1012
+ const inherited = useContext(SwitchVisualContext);
1013
+ return {
1014
+ size: props.size ?? inherited.size ?? "md",
1015
+ tone: props.tone ?? inherited.tone ?? "primary",
1016
+ variant: props.variant ?? inherited.variant ?? "default",
1017
+ disabled: inherited.isDisabled
1018
+ };
1019
+ }
1020
+ //#endregion
897
1021
  //#region src/choice-composition.tsx
898
1022
  var ChoiceStateContext = createContext({
899
1023
  isSelected: false,
@@ -939,24 +1063,43 @@ function ChoiceContent({ className, ...props }) {
939
1063
  className: partClass("choice__label", className)
940
1064
  });
941
1065
  }
942
- function SwitchComposition({ className, children, ...props }) {
943
- return /* @__PURE__ */ jsx(SwitchField, {
944
- ...props,
945
- className: partClass("input", className),
946
- children: (fieldState) => /* @__PURE__ */ jsx(SwitchButton, {
947
- className: "choice",
948
- children: (state) => /* @__PURE__ */ jsx(ChoiceStateContext.Provider, {
949
- value: state,
950
- children: typeof children === "function" ? children(fieldState) : children
1066
+ function SwitchComposition({ className, children, size, tone, variant, ...props }) {
1067
+ const visual = useSwitchVisual({
1068
+ size,
1069
+ tone,
1070
+ variant
1071
+ });
1072
+ return /* @__PURE__ */ jsx(SwitchVisualContext.Provider, {
1073
+ value: visual,
1074
+ children: /* @__PURE__ */ jsx(SwitchField, {
1075
+ ...props,
1076
+ isDisabled: props.isDisabled ?? visual.disabled,
1077
+ className: partClass("input", className),
1078
+ children: (fieldState) => /* @__PURE__ */ jsx(SwitchButton, {
1079
+ className: "choice",
1080
+ children: (state) => /* @__PURE__ */ jsx(ChoiceStateContext.Provider, {
1081
+ value: state,
1082
+ children: /* @__PURE__ */ jsx(ItemLabelContext.Provider, {
1083
+ value: true,
1084
+ children: typeof children === "function" ? children({
1085
+ ...fieldState,
1086
+ ...state
1087
+ }) : children
1088
+ })
1089
+ })
951
1090
  })
952
1091
  })
953
1092
  });
954
1093
  }
955
1094
  function SwitchControl({ className, ...props }) {
956
1095
  const state = useContext(ChoiceStateContext);
1096
+ const visual = useSwitchVisual({});
957
1097
  return /* @__PURE__ */ jsx("span", {
958
1098
  ...props,
959
1099
  className: partClass("switch__control", className),
1100
+ "data-size": visual.size,
1101
+ "data-tone": visual.tone,
1102
+ "data-variant": visual.variant,
960
1103
  "aria-hidden": "true",
961
1104
  "data-state": state.isSelected ? "checked" : "unchecked",
962
1105
  "data-disabled": state.isDisabled || void 0,
@@ -971,6 +1114,13 @@ function SwitchThumb({ className, ...props }) {
971
1114
  "aria-hidden": "true"
972
1115
  });
973
1116
  }
1117
+ function SwitchIcon({ className, ...props }) {
1118
+ return /* @__PURE__ */ jsx("span", {
1119
+ ...props,
1120
+ className: partClass("switch__icon", className),
1121
+ "aria-hidden": "true"
1122
+ });
1123
+ }
974
1124
  function RadioGroupComposition({ className, ...props }) {
975
1125
  return /* @__PURE__ */ jsx(RadioGroup$1, {
976
1126
  ...props,
@@ -1129,7 +1279,12 @@ var RadioGroup = /* @__PURE__ */ Object.assign(RadioGroupRoot, {
1129
1279
  });
1130
1280
  //#endregion
1131
1281
  //#region src/Switch.tsx
1132
- function CompactSwitch({ label, description, errorMessage, isInvalid = false, isSelected, defaultSelected, onChange, isDisabled = false, name, value = "on", id, dir, className, style, classNames }) {
1282
+ function CompactSwitch({ label, description, errorMessage, isInvalid = false, isSelected, defaultSelected, onChange, isDisabled, isReadOnly = false, isRequired = false, validate, validationBehavior = "aria", size, tone, variant, name, value = "on", id, dir, className, style, classNames }) {
1283
+ const visual = useSwitchVisual({
1284
+ size,
1285
+ tone,
1286
+ variant
1287
+ });
1133
1288
  return /* @__PURE__ */ jsxs(SwitchField, {
1134
1289
  className: partClass(partClass("input", classNames?.root), className),
1135
1290
  style,
@@ -1137,9 +1292,12 @@ function CompactSwitch({ label, description, errorMessage, isInvalid = false, is
1137
1292
  isSelected,
1138
1293
  defaultSelected,
1139
1294
  onChange,
1140
- isDisabled,
1295
+ isDisabled: isDisabled ?? visual.disabled,
1296
+ isReadOnly,
1297
+ isRequired,
1298
+ validate,
1141
1299
  isInvalid,
1142
- validationBehavior: "aria",
1300
+ validationBehavior,
1143
1301
  name,
1144
1302
  value,
1145
1303
  id,
@@ -1149,6 +1307,9 @@ function CompactSwitch({ label, description, errorMessage, isInvalid = false, is
1149
1307
  children: ({ isSelected: selected, isDisabled: disabled, isFocusVisible }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
1150
1308
  "aria-hidden": "true",
1151
1309
  className: partClass("switch__control", classNames?.control),
1310
+ "data-size": visual.size,
1311
+ "data-tone": visual.tone,
1312
+ "data-variant": visual.variant,
1152
1313
  "data-state": selected ? "checked" : "unchecked",
1153
1314
  "data-disabled": disabled || void 0,
1154
1315
  "data-invalid": isInvalid || void 0,
@@ -1179,6 +1340,7 @@ var Switch = /* @__PURE__ */ Object.assign(SwitchRoot, {
1179
1340
  Root: SwitchComposition,
1180
1341
  Control: SwitchControl,
1181
1342
  Thumb: SwitchThumb,
1343
+ Icon: SwitchIcon,
1182
1344
  Content: ChoiceContent
1183
1345
  });
1184
1346
  //#endregion
@@ -1561,14 +1723,65 @@ var NumberField = /* @__PURE__ */ Object.assign(NumberFieldRoot, {
1561
1723
  });
1562
1724
  //#endregion
1563
1725
  //#region src/Card.tsx
1564
- /** A content container; place links and buttons inside rather than making it clickable. */
1565
- function CompactCard({ title, description, headingLevel = 3, actions, header, titleExtras, footer, children, className, classNames, ...props }) {
1726
+ /** Native primary action is a sibling of content, so nested controls remain valid HTML. */
1727
+ var CardTitleIdContext = createContext(void 0);
1728
+ function CardAction({ href, target, rel, onPress, isDisabled, actionLabel, actionLabelledBy, actionClassName, renderLink }) {
1729
+ if (!href && !onPress) return null;
1730
+ if (href) {
1731
+ const props = {
1732
+ className: partClass("card__action", actionClassName),
1733
+ href: isDisabled ? void 0 : href,
1734
+ target,
1735
+ rel: rel ?? (target === "_blank" ? "noopener noreferrer" : void 0),
1736
+ "aria-label": actionLabel,
1737
+ "aria-disabled": isDisabled || void 0,
1738
+ "aria-labelledby": actionLabelledBy,
1739
+ role: isDisabled ? "link" : void 0,
1740
+ tabIndex: isDisabled ? -1 : void 0,
1741
+ onClick: (event) => {
1742
+ if (isDisabled) event.preventDefault();
1743
+ else onPress?.();
1744
+ }
1745
+ };
1746
+ return renderLink ? renderLink(props) : /* @__PURE__ */ jsx("a", {
1747
+ ...props,
1748
+ "aria-label": actionLabel,
1749
+ "aria-labelledby": actionLabelledBy
1750
+ });
1751
+ }
1752
+ const props = {
1753
+ type: "button",
1754
+ className: partClass("card__action", actionClassName),
1755
+ "aria-label": actionLabel,
1756
+ "aria-labelledby": actionLabelledBy,
1757
+ disabled: isDisabled,
1758
+ onClick: () => onPress?.()
1759
+ };
1760
+ return /* @__PURE__ */ jsx("button", { ...props });
1761
+ }
1762
+ function CompactCard({ title, description, headingLevel = 3, actions, header, titleExtras, footer, children, className, classNames, density, href, target, rel, onPress, isDisabled, actionLabel, actionLabelledBy, actionClassName, renderLink, headerAlign, dividedHeader, flushFooter, ...props }) {
1566
1763
  const Heading = `h${headingLevel}`;
1567
1764
  return /* @__PURE__ */ jsxs("div", {
1568
1765
  ...props,
1766
+ "data-density": density,
1767
+ "data-interactive": !!(href || onPress) || void 0,
1768
+ "data-disabled": isDisabled || void 0,
1569
1769
  className: partClass(partClass("card", classNames?.root), className),
1570
1770
  children: [
1771
+ /* @__PURE__ */ jsx(CardAction, {
1772
+ href,
1773
+ target,
1774
+ rel,
1775
+ onPress,
1776
+ isDisabled,
1777
+ renderLink,
1778
+ actionClassName: partClass(classNames?.action ?? "", actionClassName),
1779
+ actionLabelledBy: actionLabelledBy ?? props["aria-labelledby"],
1780
+ actionLabel: actionLabel ?? title ?? props["aria-label"]
1781
+ }),
1571
1782
  (title || description || actions || header || titleExtras) && /* @__PURE__ */ jsxs("div", {
1783
+ "data-align": headerAlign,
1784
+ "data-divided": dividedHeader || void 0,
1572
1785
  className: partClass("card__header", classNames?.header),
1573
1786
  children: [(title || description || header || titleExtras) && /* @__PURE__ */ jsx("div", {
1574
1787
  className: partClass("card__heading", classNames?.heading),
@@ -1595,21 +1808,43 @@ function CompactCard({ title, description, headingLevel = 3, actions, header, ti
1595
1808
  children
1596
1809
  }),
1597
1810
  footer && /* @__PURE__ */ jsx("div", {
1811
+ "data-flush": flushFooter || void 0,
1598
1812
  className: partClass("card__footer", classNames?.footer),
1599
1813
  children: footer
1600
1814
  })
1601
1815
  ]
1602
1816
  });
1603
1817
  }
1604
- function CardRoot({ className, ...props }) {
1605
- return /* @__PURE__ */ jsx("div", {
1606
- ...props,
1607
- className: partClass("card", className)
1818
+ function CardRoot({ className, classNames, children, density, href, target, rel, onPress, isDisabled, actionLabel, actionLabelledBy, actionClassName, renderLink, ...props }) {
1819
+ const titleId = useId();
1820
+ const label = actionLabel ?? props["aria-label"];
1821
+ return /* @__PURE__ */ jsx(CardTitleIdContext.Provider, {
1822
+ value: titleId,
1823
+ children: /* @__PURE__ */ jsxs("div", {
1824
+ ...props,
1825
+ "data-density": density,
1826
+ "data-interactive": !!(href || onPress) || void 0,
1827
+ "data-disabled": isDisabled || void 0,
1828
+ className: partClass(partClass("card", classNames?.root), className),
1829
+ children: [/* @__PURE__ */ jsx(CardAction, {
1830
+ href,
1831
+ target,
1832
+ rel,
1833
+ onPress,
1834
+ isDisabled,
1835
+ renderLink,
1836
+ actionClassName: partClass(classNames?.action ?? "", actionClassName),
1837
+ actionLabel: label,
1838
+ actionLabelledBy: actionLabelledBy ?? props["aria-labelledby"] ?? (label ? void 0 : titleId)
1839
+ }), children]
1840
+ })
1608
1841
  });
1609
1842
  }
1610
- function CardHeader({ className, ...props }) {
1843
+ function CardHeader({ className, align, divided, ...props }) {
1611
1844
  return /* @__PURE__ */ jsx("div", {
1612
1845
  ...props,
1846
+ "data-align": align,
1847
+ "data-divided": divided || void 0,
1613
1848
  className: partClass("card__header", className)
1614
1849
  });
1615
1850
  }
@@ -1626,8 +1861,10 @@ function CardTitleRow({ className, ...props }) {
1626
1861
  });
1627
1862
  }
1628
1863
  function CardTitle({ className, headingLevel = 3, ...props }) {
1864
+ const titleId = useContext(CardTitleIdContext);
1629
1865
  const Heading = `h${headingLevel}`;
1630
1866
  return /* @__PURE__ */ jsx(Heading, {
1867
+ id: titleId,
1631
1868
  ...props,
1632
1869
  className: partClass("card__title", className)
1633
1870
  });
@@ -1650,9 +1887,10 @@ function CardContent({ className, ...props }) {
1650
1887
  className: partClass("card__content", className)
1651
1888
  });
1652
1889
  }
1653
- function CardFooter({ className, ...props }) {
1890
+ function CardFooter({ className, flush, ...props }) {
1654
1891
  return /* @__PURE__ */ jsx("div", {
1655
1892
  ...props,
1893
+ "data-flush": flush || void 0,
1656
1894
  className: partClass("card__footer", className)
1657
1895
  });
1658
1896
  }
@@ -1668,15 +1906,261 @@ var Card = /* @__PURE__ */ Object.assign(CompactCard, {
1668
1906
  Footer: CardFooter
1669
1907
  });
1670
1908
  //#endregion
1909
+ //#region src/visual-slot.tsx
1910
+ /** Decorate one child while preserving its handlers and ref. */
1911
+ function visualSlot(children, props) {
1912
+ const child = Children.only(children);
1913
+ const merged = {
1914
+ ...child.props,
1915
+ ...props
1916
+ };
1917
+ merged.className = [props.className, child.props.className].filter(Boolean).join(" ");
1918
+ merged.style = {
1919
+ ...props.style,
1920
+ ...child.props.style
1921
+ };
1922
+ for (const key of Object.keys(props)) if (/^on[A-Z]/.test(key) && typeof child.props[key] === "function" && typeof props[key] === "function") merged[key] = (...args) => {
1923
+ child.props[key](...args);
1924
+ props[key](...args);
1925
+ };
1926
+ if (child.props.ref && props.ref) merged.ref = (node) => {
1927
+ const cleanups = [];
1928
+ for (const ref of [child.props.ref, props.ref]) if (typeof ref === "function") {
1929
+ const cleanup = ref(node);
1930
+ cleanups.push(typeof cleanup === "function" ? cleanup : () => {
1931
+ ref(null);
1932
+ });
1933
+ } else if (ref) {
1934
+ ref.current = node;
1935
+ cleanups.push(() => {
1936
+ ref.current = null;
1937
+ });
1938
+ }
1939
+ return () => {
1940
+ for (const cleanup of cleanups) cleanup();
1941
+ };
1942
+ };
1943
+ return cloneElement(child, merged);
1944
+ }
1945
+ //#endregion
1671
1946
  //#region src/Badge.tsx
1672
- /** Static status text. Dynamic announcements belong in an application-owned live region. */
1673
- function Badge({ tone = "neutral", className, classNames, ...props }) {
1674
- return /* @__PURE__ */ jsx("span", {
1947
+ var AnchorContext = createContext(false);
1948
+ /** Static status text; wrap in Badge.Anchor to position it relative to another element. */
1949
+ function BadgeRoot({ tone = "neutral", size = "md", variant = "default", placement = "top-right", asChild, children, className, classNames, ...props }) {
1950
+ const anchored = useContext(AnchorContext);
1951
+ const attributes = {
1675
1952
  ...props,
1676
1953
  className: partClass(partClass("badge", classNames?.root), className),
1954
+ "data-tone": tone,
1955
+ "data-size": size,
1956
+ "data-variant": variant,
1957
+ "data-placement": anchored ? placement : void 0,
1958
+ "data-anchored": anchored || void 0,
1959
+ "data-dot": anchored && children == null || void 0
1960
+ };
1961
+ return asChild ? visualSlot(children, attributes) : /* @__PURE__ */ jsx("span", {
1962
+ ...attributes,
1963
+ children: classNames?.label ? /* @__PURE__ */ jsx("span", {
1964
+ className: partClass("badge__label", classNames.label),
1965
+ children
1966
+ }) : children
1967
+ });
1968
+ }
1969
+ function BadgeAnchor({ className, ...props }) {
1970
+ return /* @__PURE__ */ jsx(AnchorContext.Provider, {
1971
+ value: true,
1972
+ children: /* @__PURE__ */ jsx("span", {
1973
+ ...props,
1974
+ className: partClass("badge-anchor badge__anchor", className)
1975
+ })
1976
+ });
1977
+ }
1978
+ function BadgeLabel({ className, ...props }) {
1979
+ return /* @__PURE__ */ jsx("span", {
1980
+ ...props,
1981
+ className: partClass("badge__label", className)
1982
+ });
1983
+ }
1984
+ var Badge = /* @__PURE__ */ Object.assign(BadgeRoot, {
1985
+ Root: BadgeRoot,
1986
+ Anchor: BadgeAnchor,
1987
+ Label: BadgeLabel
1988
+ });
1989
+ //#endregion
1990
+ //#region src/Avatar.tsx
1991
+ var AvatarGroupContext = createContext({});
1992
+ var AvatarContext = createContext(null);
1993
+ function AvatarRoot({ size, tone, variant, radius = "full", asChild, children, className, classNames, ...props }) {
1994
+ const group = useContext(AvatarGroupContext);
1995
+ const [status, setStatus] = useState("idle");
1996
+ const actualSize = size ?? group.size ?? "md";
1997
+ const attributes = {
1998
+ ...props,
1999
+ className: partClass(partClass("avatar", classNames?.root), className),
2000
+ "data-size": actualSize,
2001
+ "data-tone": tone ?? group.tone ?? "neutral",
2002
+ "data-variant": variant ?? group.variant ?? "default",
2003
+ "data-radius": radius,
2004
+ "data-image-status": status
2005
+ };
2006
+ return /* @__PURE__ */ jsx(AvatarContext.Provider, {
2007
+ value: {
2008
+ status,
2009
+ setStatus,
2010
+ size: actualSize,
2011
+ classNames
2012
+ },
2013
+ children: asChild ? visualSlot(children, attributes) : /* @__PURE__ */ jsx("span", {
2014
+ ...attributes,
2015
+ children
2016
+ })
2017
+ });
2018
+ }
2019
+ function AvatarImage(props) {
2020
+ return /* @__PURE__ */ jsx(AvatarImageLoader, { ...props }, `${props.src ?? ""}|${props.srcSet ?? ""}|${props.sizes ?? ""}`);
2021
+ }
2022
+ function AvatarImageLoader({ src, srcSet, sizes, alt, asChild, children, className, onLoad, onError, onLoadingStatusChange, ref, ...props }) {
2023
+ const context = useContext(AvatarContext);
2024
+ const setStatus = context?.setStatus;
2025
+ const imageRef = useRef(null);
2026
+ const [result, setResult] = useState({
2027
+ source: "",
2028
+ status: "idle"
2029
+ });
2030
+ const source = `${src ?? ""}|${srcSet ?? ""}|${sizes ?? ""}`;
2031
+ const status = result.source === source ? result.status : src || srcSet ? "loading" : "error";
2032
+ const statusCallback = useRef(onLoadingStatusChange);
2033
+ useEffect(() => {
2034
+ statusCallback.current = onLoadingStatusChange;
2035
+ });
2036
+ useEffect(() => {
2037
+ setStatus?.(status);
2038
+ statusCallback.current?.(status);
2039
+ }, [status, setStatus]);
2040
+ useEffect(() => () => setStatus?.("idle"), [setStatus]);
2041
+ useEffect(() => {
2042
+ if (imageRef.current?.complete && imageRef.current.naturalWidth > 0) setResult({
2043
+ source,
2044
+ status: "loaded"
2045
+ });
2046
+ }, [source]);
2047
+ const attributes = {
2048
+ ...props,
2049
+ src,
2050
+ srcSet,
2051
+ sizes,
2052
+ className: partClass(partClass("avatar__image", context?.classNames?.image), className),
2053
+ "data-status": status,
2054
+ "aria-hidden": status !== "loaded" || void 0,
2055
+ ref: (node) => {
2056
+ imageRef.current = node;
2057
+ if (typeof ref === "function") return ref(node);
2058
+ else if (ref) ref.current = node;
2059
+ },
2060
+ onLoad: (event) => {
2061
+ if (event.currentTarget !== imageRef.current) return;
2062
+ setResult({
2063
+ source,
2064
+ status: "loaded"
2065
+ });
2066
+ onLoad?.(event);
2067
+ },
2068
+ onError: (event) => {
2069
+ if (event.currentTarget !== imageRef.current) return;
2070
+ setResult({
2071
+ source,
2072
+ status: "error"
2073
+ });
2074
+ onError?.(event);
2075
+ }
2076
+ };
2077
+ return asChild ? visualSlot(children, {
2078
+ ...attributes,
2079
+ ...alt !== void 0 ? { alt } : {}
2080
+ }) : /* @__PURE__ */ jsx("img", {
2081
+ ...attributes,
2082
+ alt: alt ?? ""
2083
+ }, source);
2084
+ }
2085
+ function AvatarFallback({ delayMs = 0, tone, className, ...props }) {
2086
+ const context = useContext(AvatarContext);
2087
+ const [ready, setReady] = useState(delayMs <= 0);
2088
+ useEffect(() => {
2089
+ setReady(delayMs <= 0);
2090
+ if (delayMs <= 0) return;
2091
+ const timer = setTimeout(() => setReady(true), delayMs);
2092
+ return () => clearTimeout(timer);
2093
+ }, [delayMs, context?.status]);
2094
+ if (context?.status === "loaded" || !ready) return null;
2095
+ return /* @__PURE__ */ jsx("span", {
2096
+ ...props,
2097
+ className: partClass(partClass("avatar__fallback", context?.classNames?.fallback), className),
1677
2098
  "data-tone": tone
1678
2099
  });
1679
2100
  }
2101
+ function AvatarBadge({ size, tone = "primary", placement = "bottom-right", className, children, ...props }) {
2102
+ const context = useContext(AvatarContext);
2103
+ return /* @__PURE__ */ jsx("span", {
2104
+ ...props,
2105
+ className: partClass(partClass("avatar__badge", context?.classNames?.badge), className),
2106
+ "data-size": size ?? context?.size ?? "md",
2107
+ "data-tone": tone,
2108
+ "data-placement": placement,
2109
+ "data-dot": children == null || void 0,
2110
+ children
2111
+ });
2112
+ }
2113
+ var Avatar = /* @__PURE__ */ Object.assign(AvatarRoot, {
2114
+ Root: AvatarRoot,
2115
+ Image: AvatarImage,
2116
+ Fallback: AvatarFallback,
2117
+ Badge: AvatarBadge
2118
+ });
2119
+ //#endregion
2120
+ //#region src/AvatarGroup.tsx
2121
+ function flatten(children, prefix = "") {
2122
+ return Children.toArray(children).flatMap((child, index) => {
2123
+ const key = `${prefix}/${isValidElement(child) ? child.key ?? index : index}`;
2124
+ return isValidElement(child) && child.type === Fragment ? flatten(child.props.children, key) : isValidElement(child) ? [cloneElement(child, { key })] : [];
2125
+ });
2126
+ }
2127
+ function AvatarGroupCount({ className, ...props }) {
2128
+ return /* @__PURE__ */ jsx(Avatar, {
2129
+ ...props,
2130
+ className: partClass("avatar-group__count", className),
2131
+ children: /* @__PURE__ */ jsx(Avatar.Fallback, { children: props.children })
2132
+ });
2133
+ }
2134
+ function AvatarGroupRoot({ size = "md", tone = "neutral", variant = "default", max, isGrid = false, overlap = "clip", className, classNames, children, ...props }) {
2135
+ const items = flatten(children);
2136
+ const counts = items.filter((item) => isValidElement(item) && item.type === AvatarGroupCount);
2137
+ const avatars = items.filter((item) => !counts.includes(item));
2138
+ const limit = max === void 0 || !Number.isFinite(max) ? avatars.length : Math.max(0, Math.floor(max));
2139
+ const hidden = Math.max(0, avatars.length - limit);
2140
+ return /* @__PURE__ */ jsx(AvatarGroupContext.Provider, {
2141
+ value: {
2142
+ size,
2143
+ tone,
2144
+ variant
2145
+ },
2146
+ children: /* @__PURE__ */ jsxs("div", {
2147
+ ...props,
2148
+ className: partClass(partClass("avatar-group", classNames?.root), className),
2149
+ "data-size": size,
2150
+ "data-grid": isGrid || void 0,
2151
+ "data-overlap": overlap,
2152
+ children: [avatars.slice(0, limit), counts.length ? counts : hidden > 0 ? /* @__PURE__ */ jsxs(AvatarGroupCount, {
2153
+ className: classNames?.count,
2154
+ "aria-label": `${hidden} more`,
2155
+ children: ["+", hidden]
2156
+ }) : null]
2157
+ })
2158
+ });
2159
+ }
2160
+ var AvatarGroup = /* @__PURE__ */ Object.assign(AvatarGroupRoot, {
2161
+ Root: AvatarGroupRoot,
2162
+ Count: AvatarGroupCount
2163
+ });
1680
2164
  //#endregion
1681
2165
  //#region src/Skeleton.tsx
1682
2166
  /** Decorative placeholder. Set aria-busy and loading text on the surrounding content. */
@@ -1800,7 +2284,7 @@ function mountTabsIndicator(container) {
1800
2284
  }
1801
2285
  //#endregion
1802
2286
  //#region src/Tabs.tsx
1803
- function CompactTabs({ className, style, classNames, label, variant = "primary", size = "md", orientation = "horizontal", align = "center", fullWidth = false, inset = "default", showSeparators = false, renderIcon, previousLabel = "Tab sebelumnya / Previous tabs", nextLabel = "Tab berikutnya / Next tabs", extras, actions, items, value, defaultValue, onChange, renderPanel, activationMode = "manual", dir, id }) {
2287
+ function CompactTabs({ className, style, classNames, label, variant = "primary", size = "md", indicatorShadow = true, orientation = "horizontal", align = "center", fullWidth = false, inset = "default", showSeparators = false, renderIcon, previousLabel = "Tab sebelumnya / Previous tabs", nextLabel = "Tab berikutnya / Next tabs", extras, actions, items, value, defaultValue, onChange, renderPanel, activationMode = "manual", dir, id }) {
1804
2288
  const container = useRef(null);
1805
2289
  const hasToolbar = !!(extras || actions);
1806
2290
  useEffect(() => container.current ? mountTabsIndicator(container.current) : void 0, [items.length, hasToolbar]);
@@ -1861,6 +2345,7 @@ function CompactTabs({ className, style, classNames, label, variant = "primary",
1861
2345
  ]
1862
2346
  }) : null;
1863
2347
  const content = /* @__PURE__ */ jsxs(Tabs$1, {
2348
+ "data-indicator-shadow": indicatorShadow,
1864
2349
  className: [
1865
2350
  "tabs",
1866
2351
  classNames?.root,
@@ -1908,9 +2393,10 @@ function CompactTabs({ className, style, classNames, label, variant = "primary",
1908
2393
  children: content
1909
2394
  }) : content;
1910
2395
  }
1911
- function TabsRoot({ className, classNames, value, defaultValue, onChange, variant = "primary", size = "md", align = "center", fullWidth, ...props }) {
2396
+ function TabsRoot({ className, classNames, value, defaultValue, onChange, variant = "primary", size = "md", align = "center", fullWidth, indicatorShadow = true, ...props }) {
1912
2397
  return /* @__PURE__ */ jsx(Tabs$1, {
1913
2398
  ...props,
2399
+ "data-indicator-shadow": indicatorShadow,
1914
2400
  selectedKey: value,
1915
2401
  defaultSelectedKey: defaultValue,
1916
2402
  onSelectionChange: onChange ? (key) => onChange(String(key)) : void 0,
@@ -3259,7 +3745,7 @@ function CompactDropdownMenu(props) {
3259
3745
  onOpenChange: change,
3260
3746
  children: [/* @__PURE__ */ jsx(Button$1, {
3261
3747
  style,
3262
- className: partClass(partClass(partClass(`button button--${props.triggerVariant ?? "secondary"}${props.triggerIconOnly ? " button--icon-only" : ""}`, classNames?.trigger), classNames?.root), className),
3748
+ className: partClass(partClass(partClass(`button button--${props.triggerVariant ?? "secondary"} button--${props.triggerSize ?? "md"}${props.triggerIconOnly ? " button--icon-only" : ""}`, classNames?.trigger), classNames?.root), className),
3263
3749
  "aria-label": triggerLabel,
3264
3750
  isDisabled: isDisabled || !items.length,
3265
3751
  children: props.triggerContent ?? triggerLabel
@@ -3861,38 +4347,355 @@ function DateRangeCancelButton({ className, onClick, children, ...props }) {
3861
4347
  });
3862
4348
  }
3863
4349
  //#endregion
3864
- //#region src/date-range-model.ts
3865
- function dateRangeLabels(locale = "id-ID") {
3866
- return locale.startsWith("id") ? {
3867
- title: "Pilih rentang tanggal",
3868
- start: "Tanggal mulai",
3869
- end: "Tanggal akhir",
3870
- apply: "Terapkan",
3871
- cancel: "Batal",
3872
- clear: "Kosongkan",
3873
- previousMonth: "Bulan sebelumnya",
3874
- nextMonth: "Bulan berikutnya",
3875
- presets: "Pilihan cepat",
3876
- placeholder: "Pilih tanggal",
3877
- incomplete: "Lengkapi tanggal mulai dan akhir.",
3878
- order: "Tanggal akhir harus setelah atau sama dengan tanggal mulai.",
3879
- bounds: "Tanggal berada di luar batas yang diizinkan.",
3880
- unavailable: "Rentang memuat tanggal yang tidak tersedia.",
3881
- length: "Durasi rentang tidak sesuai batas yang diizinkan.",
3882
- required: "Rentang tanggal wajib diisi."
3883
- } : {
3884
- title: "Select date range",
3885
- start: "Start date",
3886
- end: "End date",
3887
- apply: "Apply",
3888
- cancel: "Cancel",
3889
- clear: "Clear",
3890
- previousMonth: "Previous month",
3891
- nextMonth: "Next month",
3892
- presets: "Quick selections",
3893
- placeholder: "Choose dates",
3894
- incomplete: "Enter both start and end dates.",
3895
- order: "End date must be on or after start date.",
4350
+ //#region src/Calendar.tsx
4351
+ function date(value) {
4352
+ try {
4353
+ return value ? parseDate(value) : void 0;
4354
+ } catch {
4355
+ return;
4356
+ }
4357
+ }
4358
+ function monthName(year, month, locale) {
4359
+ return new Intl.DateTimeFormat(locale, {
4360
+ month: "long",
4361
+ timeZone: "UTC",
4362
+ calendar: "gregory"
4363
+ }).format(new CalendarDate(year, month, 1).toDate("UTC"));
4364
+ }
4365
+ function MonthPicker({ value, year = today("UTC").year, onChange, locale = "id-ID", minDate, maxDate, isDisabled, className, ...props }) {
4366
+ return /* @__PURE__ */ jsx("div", {
4367
+ ...props,
4368
+ className: partClass("calendar__choices", className),
4369
+ role: "group",
4370
+ "aria-label": locale.startsWith("id") ? "Pilih bulan" : "Choose month",
4371
+ children: Array.from({ length: 12 }, (_, i) => i + 1).map((month) => {
4372
+ const start = new CalendarDate(year, month, 1);
4373
+ const end = start.add({ months: 1 }).subtract({ days: 1 });
4374
+ return /* @__PURE__ */ jsx("button", {
4375
+ type: "button",
4376
+ disabled: isDisabled || !!(date(minDate) && end.compare(date(minDate)) < 0) || !!(date(maxDate) && start.compare(date(maxDate)) > 0),
4377
+ "aria-pressed": value === month,
4378
+ onClick: () => onChange?.(month),
4379
+ children: monthName(year, month, locale)
4380
+ }, month);
4381
+ })
4382
+ });
4383
+ }
4384
+ function YearPicker({ value = today("UTC").year, onChange, locale = "id-ID", minDate, maxDate, isDisabled, className, ...props }) {
4385
+ const min = date(minDate)?.year ?? 1, max = date(maxDate)?.year ?? 9999;
4386
+ const [page, setPage] = useState(Math.max(min, Math.min(max, Math.floor((value - 1) / 12) * 12 + 1)));
4387
+ return /* @__PURE__ */ jsxs("div", {
4388
+ ...props,
4389
+ className: partClass("calendar__years", className),
4390
+ children: [/* @__PURE__ */ jsxs("div", {
4391
+ className: "calendar__year-navigation",
4392
+ children: [
4393
+ /* @__PURE__ */ jsx("button", {
4394
+ type: "button",
4395
+ "aria-label": locale.startsWith("id") ? "Tahun sebelumnya" : "Previous years",
4396
+ disabled: isDisabled || page <= min,
4397
+ onClick: () => setPage(Math.max(min, page - 12)),
4398
+ children: "‹"
4399
+ }),
4400
+ /* @__PURE__ */ jsxs("span", { children: [
4401
+ page,
4402
+ "–",
4403
+ Math.min(page + 11, max)
4404
+ ] }),
4405
+ /* @__PURE__ */ jsx("button", {
4406
+ type: "button",
4407
+ "aria-label": locale.startsWith("id") ? "Tahun berikutnya" : "Next years",
4408
+ disabled: isDisabled || page + 11 >= max,
4409
+ onClick: () => setPage(Math.max(min, Math.min(max - 11, page + 12))),
4410
+ children: "›"
4411
+ })
4412
+ ]
4413
+ }), /* @__PURE__ */ jsx("div", {
4414
+ className: "calendar__choices",
4415
+ role: "group",
4416
+ "aria-label": locale.startsWith("id") ? "Pilih tahun" : "Choose year",
4417
+ children: Array.from({ length: 12 }, (_, i) => page + i).filter((year) => year <= 9999).map((year) => /* @__PURE__ */ jsx("button", {
4418
+ type: "button",
4419
+ disabled: isDisabled || year < min || year > max,
4420
+ "aria-pressed": value === year,
4421
+ onClick: () => onChange?.(year),
4422
+ children: year
4423
+ }, year))
4424
+ })]
4425
+ });
4426
+ }
4427
+ function MonthYearNavigation({ value, onChange, locale = "id-ID", minDate, maxDate, isDisabled, className, ...props }) {
4428
+ const current = date(value) ?? today("UTC");
4429
+ const [view, setView] = useState(null);
4430
+ const header = useRef(null), lastToggle = useRef("month"), previousView = useRef(null);
4431
+ useEffect(() => {
4432
+ if (view) (header.current?.querySelector(".calendar__view [aria-pressed=\"true\"]:not(:disabled)") ?? header.current?.querySelector(".calendar__view button:not(:disabled)"))?.focus();
4433
+ else if (previousView.current) header.current?.querySelectorAll(".date-range__heading > button")[lastToggle.current === "month" ? 0 : 1]?.focus();
4434
+ previousView.current = view;
4435
+ }, [view]);
4436
+ useEffect(() => {
4437
+ if (!view) return;
4438
+ const grid = header.current?.closest(".date-range__month")?.querySelector(".date-range__grid");
4439
+ if (!grid) return;
4440
+ const inert = grid.hasAttribute("inert"), hidden = grid.getAttribute("aria-hidden");
4441
+ grid.inert = true;
4442
+ grid.setAttribute("inert", "");
4443
+ grid.setAttribute("aria-hidden", "true");
4444
+ return () => {
4445
+ grid.inert = inert;
4446
+ if (!inert) grid.removeAttribute("inert");
4447
+ if (hidden === null) grid.removeAttribute("aria-hidden");
4448
+ else grid.setAttribute("aria-hidden", hidden);
4449
+ };
4450
+ }, [view]);
4451
+ const navigate = (year, month) => {
4452
+ let next = new CalendarDate(year, month, 1);
4453
+ const min = date(minDate), max = date(maxDate);
4454
+ if (min && next.compare(min) < 0) next = min;
4455
+ if (max && next.compare(max) > 0) next = max;
4456
+ onChange(next.toString());
4457
+ };
4458
+ return /* @__PURE__ */ jsxs("div", {
4459
+ ...props,
4460
+ ref: header,
4461
+ className: partClass("calendar__header", className),
4462
+ children: [/* @__PURE__ */ jsxs("div", {
4463
+ className: "date-range__heading",
4464
+ children: [/* @__PURE__ */ jsx("button", {
4465
+ type: "button",
4466
+ disabled: isDisabled,
4467
+ "aria-expanded": view === "month",
4468
+ onClick: () => {
4469
+ lastToggle.current = "month";
4470
+ setView(view === "month" ? null : "month");
4471
+ },
4472
+ children: monthName(current.year, current.month, locale)
4473
+ }), /* @__PURE__ */ jsx("button", {
4474
+ type: "button",
4475
+ disabled: isDisabled,
4476
+ "aria-expanded": view === "year",
4477
+ onClick: () => {
4478
+ lastToggle.current = "year";
4479
+ setView(view === "year" ? null : "year");
4480
+ },
4481
+ children: current.year
4482
+ })]
4483
+ }), view && /* @__PURE__ */ jsxs("div", {
4484
+ className: "calendar__view",
4485
+ role: "group",
4486
+ "aria-label": view === "year" ? locale.startsWith("id") ? "Pilih tahun" : "Choose year" : locale.startsWith("id") ? "Pilih bulan" : "Choose month",
4487
+ onKeyDownCapture: (e) => {
4488
+ if (e.key === "Escape") {
4489
+ e.stopPropagation();
4490
+ setView(null);
4491
+ }
4492
+ },
4493
+ children: [view === "month" ? /* @__PURE__ */ jsx(MonthPicker, {
4494
+ value: current.month,
4495
+ year: current.year,
4496
+ locale,
4497
+ minDate,
4498
+ maxDate,
4499
+ isDisabled,
4500
+ onChange: (month) => {
4501
+ navigate(current.year, month);
4502
+ setView(null);
4503
+ }
4504
+ }) : /* @__PURE__ */ jsx(YearPicker, {
4505
+ value: current.year,
4506
+ locale,
4507
+ minDate,
4508
+ maxDate,
4509
+ isDisabled,
4510
+ onChange: (year) => {
4511
+ navigate(year, current.month);
4512
+ setView("month");
4513
+ }
4514
+ }), /* @__PURE__ */ jsx("button", {
4515
+ type: "button",
4516
+ className: "calendar__back",
4517
+ onClick: () => setView(null),
4518
+ children: locale.startsWith("id") ? "Kembali" : "Back"
4519
+ })]
4520
+ })]
4521
+ });
4522
+ }
4523
+ /** Reads actual visibleRange rather than assuming the focused day is the first panel. */
4524
+ function CalendarViewHeader({ offset = 0, onNavigate, ...props }) {
4525
+ const single = useContext(CalendarStateContext);
4526
+ const visible = (useContext(RangeCalendarStateContext) ?? single)?.visibleRange.start ?? today("UTC");
4527
+ return /* @__PURE__ */ jsx(MonthYearNavigation, {
4528
+ ...props,
4529
+ value: visible.add({ months: offset }).toString(),
4530
+ onChange: (value) => onNavigate(parseDate(value).subtract({ months: offset }))
4531
+ });
4532
+ }
4533
+ function CalendarBody({ props, onNavigate }) {
4534
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
4535
+ className: "date-range__navigation",
4536
+ children: [/* @__PURE__ */ jsx(Button$1, {
4537
+ slot: "previous",
4538
+ className: "date-range__nav",
4539
+ "aria-label": props.locale?.startsWith("id") ? "Bulan sebelumnya" : "Previous month",
4540
+ children: "‹"
4541
+ }), /* @__PURE__ */ jsx(Button$1, {
4542
+ slot: "next",
4543
+ className: "date-range__nav",
4544
+ "aria-label": props.locale?.startsWith("id") ? "Bulan berikutnya" : "Next month",
4545
+ children: "›"
4546
+ })]
4547
+ }), /* @__PURE__ */ jsx("div", {
4548
+ className: "date-range__months",
4549
+ children: Array.from({ length: props.visibleMonths ?? 1 }, (_, i) => /* @__PURE__ */ jsxs("div", {
4550
+ className: partClass("date-range__month", props.classNames?.month),
4551
+ children: [/* @__PURE__ */ jsx(CalendarViewHeader, {
4552
+ offset: i,
4553
+ onNavigate,
4554
+ locale: props.locale,
4555
+ minDate: props.minDate,
4556
+ maxDate: props.maxDate,
4557
+ isDisabled: props.isDisabled,
4558
+ className: props.classNames?.header
4559
+ }), /* @__PURE__ */ jsxs(CalendarGrid$1, {
4560
+ offset: { months: i },
4561
+ className: partClass("date-range__grid", props.classNames?.grid),
4562
+ weekdayStyle: "short",
4563
+ children: [/* @__PURE__ */ jsx(CalendarGridHeader$1, { children: (day) => /* @__PURE__ */ jsx(CalendarHeaderCell$1, {
4564
+ className: "date-range__weekday",
4565
+ children: day
4566
+ }) }), /* @__PURE__ */ jsx(CalendarGridBody$1, { children: (day) => /* @__PURE__ */ jsx(CalendarCell$1, {
4567
+ date: day,
4568
+ className: partClass("date-range__day", props.classNames?.day)
4569
+ }) })]
4570
+ })]
4571
+ }, i))
4572
+ })] });
4573
+ }
4574
+ function Calendar(props) {
4575
+ const [local, setLocal] = useState(props.defaultValue ?? null);
4576
+ const value = props.value === void 0 ? local : props.value;
4577
+ useEffect(() => {
4578
+ const next = date(value);
4579
+ if (next) setFocused(next);
4580
+ }, [value]);
4581
+ const [focused, setFocused] = useState(() => date(value) ?? date(props.referenceDate) ?? date(props.minDate) ?? today("UTC"));
4582
+ return /* @__PURE__ */ jsx(I18nProvider, {
4583
+ locale: props.locale ?? "id-ID",
4584
+ children: /* @__PURE__ */ jsx(Calendar$1, {
4585
+ className: partClass(partClass("date-range__calendar calendar", props.classNames?.root), props.className),
4586
+ style: props.style,
4587
+ "aria-label": props.label ?? "Calendar",
4588
+ dir: props.dir,
4589
+ value: date(value) ?? null,
4590
+ focusedValue: focused,
4591
+ onFocusChange: setFocused,
4592
+ createCalendar: () => new GregorianCalendar(),
4593
+ visibleDuration: { months: props.visibleMonths ?? 1 },
4594
+ pageBehavior: "single",
4595
+ firstDayOfWeek: props.weekStartsOn === 0 ? "sun" : "mon",
4596
+ minValue: date(props.minDate),
4597
+ maxValue: date(props.maxDate),
4598
+ isDisabled: props.isDisabled,
4599
+ isReadOnly: props.isReadOnly,
4600
+ isDateUnavailable: (v) => props.isDateUnavailable?.(v.toString()) ?? false,
4601
+ onChange: (v) => {
4602
+ const next = v?.toString() ?? null;
4603
+ setLocal(next);
4604
+ props.onChange?.(next);
4605
+ },
4606
+ children: /* @__PURE__ */ jsx(CalendarBody, {
4607
+ props,
4608
+ onNavigate: setFocused
4609
+ })
4610
+ })
4611
+ });
4612
+ }
4613
+ function RangeCalendar(props) {
4614
+ const [local, setLocal] = useState(props.defaultValue ?? null);
4615
+ const value = props.value === void 0 ? local : props.value;
4616
+ const selectedStart = value?.start;
4617
+ useEffect(() => {
4618
+ const next = date(selectedStart);
4619
+ if (next) setFocused(next);
4620
+ }, [selectedStart]);
4621
+ const [focused, setFocused] = useState(() => date(value?.start) ?? date(props.referenceDate) ?? date(props.minDate) ?? today("UTC"));
4622
+ const selected = date(value?.start) && date(value?.end) ? {
4623
+ start: date(value?.start),
4624
+ end: date(value?.end)
4625
+ } : null;
4626
+ return /* @__PURE__ */ jsx(I18nProvider, {
4627
+ locale: props.locale ?? "id-ID",
4628
+ children: /* @__PURE__ */ jsx(RangeCalendar$1, {
4629
+ className: partClass(partClass("date-range__calendar calendar", props.classNames?.root), props.className),
4630
+ style: props.style,
4631
+ "aria-label": props.label ?? "Calendar",
4632
+ dir: props.dir,
4633
+ value: selected,
4634
+ focusedValue: focused,
4635
+ onFocusChange: setFocused,
4636
+ createCalendar: () => new GregorianCalendar(),
4637
+ visibleDuration: { months: props.visibleMonths ?? 2 },
4638
+ pageBehavior: "single",
4639
+ firstDayOfWeek: props.weekStartsOn === 0 ? "sun" : "mon",
4640
+ minValue: date(props.minDate),
4641
+ maxValue: date(props.maxDate),
4642
+ isDisabled: props.isDisabled,
4643
+ isReadOnly: props.isReadOnly,
4644
+ isDateUnavailable: (v) => props.isDateUnavailable?.(v.toString()) ?? false,
4645
+ onChange: (v) => {
4646
+ const next = v ? {
4647
+ start: v.start.toString(),
4648
+ end: v.end.toString()
4649
+ } : null;
4650
+ setLocal(next);
4651
+ props.onChange?.(next);
4652
+ },
4653
+ children: /* @__PURE__ */ jsx(CalendarBody, {
4654
+ props: {
4655
+ ...props,
4656
+ visibleMonths: props.visibleMonths ?? 2,
4657
+ value: null,
4658
+ defaultValue: null,
4659
+ onChange: void 0
4660
+ },
4661
+ onNavigate: setFocused
4662
+ })
4663
+ })
4664
+ });
4665
+ }
4666
+ //#endregion
4667
+ //#region src/date-range-model.ts
4668
+ function dateRangeLabels(locale = "id-ID") {
4669
+ return locale.startsWith("id") ? {
4670
+ title: "Pilih rentang tanggal",
4671
+ start: "Tanggal mulai",
4672
+ end: "Tanggal akhir",
4673
+ apply: "Terapkan",
4674
+ cancel: "Batal",
4675
+ clear: "Kosongkan",
4676
+ previousMonth: "Bulan sebelumnya",
4677
+ nextMonth: "Bulan berikutnya",
4678
+ presets: "Pilihan cepat",
4679
+ placeholder: "Pilih tanggal",
4680
+ incomplete: "Lengkapi tanggal mulai dan akhir.",
4681
+ order: "Tanggal akhir harus setelah atau sama dengan tanggal mulai.",
4682
+ bounds: "Tanggal berada di luar batas yang diizinkan.",
4683
+ unavailable: "Rentang memuat tanggal yang tidak tersedia.",
4684
+ length: "Durasi rentang tidak sesuai batas yang diizinkan.",
4685
+ required: "Rentang tanggal wajib diisi."
4686
+ } : {
4687
+ title: "Select date range",
4688
+ start: "Start date",
4689
+ end: "End date",
4690
+ apply: "Apply",
4691
+ cancel: "Cancel",
4692
+ clear: "Clear",
4693
+ previousMonth: "Previous month",
4694
+ nextMonth: "Next month",
4695
+ presets: "Quick selections",
4696
+ placeholder: "Choose dates",
4697
+ incomplete: "Enter both start and end dates.",
4698
+ order: "End date must be on or after start date.",
3896
4699
  bounds: "Dates are outside the allowed limits.",
3897
4700
  unavailable: "The range includes an unavailable date.",
3898
4701
  length: "The range duration is outside the allowed limits.",
@@ -4011,7 +4814,7 @@ function CalendarContent({ onPending, dir, children }) {
4011
4814
  });
4012
4815
  }
4013
4816
  function DateRangePickerRoot(props) {
4014
- const { label, locale = "id-ID", dir, size = "md", variant = "primary", fullWidth = true, hideLabel = false, visibleMonths = 2, weekStartsOn = 1, display = "popover", showInputs = true, presets = [], isDisabled = false, isReadOnly = false, isRequired = false } = props;
4817
+ const { label, locale = "id-ID", dir, size = "md", variant = "primary", fullWidth = true, hideLabel = false, visibleMonths = 2, weekStartsOn = 1, display = "auto", showInputs = true, presets = [], isDisabled = false, isReadOnly = false, isRequired = false } = props;
4015
4818
  const labels = {
4016
4819
  ...dateRangeLabels(locale),
4017
4820
  ...props.labels
@@ -4032,6 +4835,15 @@ function DateRangePickerRoot(props) {
4032
4835
  const [formError, setFormError] = useState(false);
4033
4836
  const [pending, setPending] = useState(false), [calendarKey, setCalendarKey] = useState(0);
4034
4837
  const trigger = useRef(null);
4838
+ const [mobile, setMobile] = useState(false);
4839
+ useEffect(() => {
4840
+ const query = window.matchMedia("(max-width: 640px)");
4841
+ const change = () => setMobile(query.matches);
4842
+ change();
4843
+ query.addEventListener("change", change);
4844
+ return () => query.removeEventListener("change", change);
4845
+ }, []);
4846
+ const isDialog = display === "dialog" || display === "auto" && mobile;
4035
4847
  const id = useId();
4036
4848
  const disclosure = useDisclosure(props.open, props.defaultOpen, props.onOpenChange);
4037
4849
  const visible = disclosure.visible && !isDisabled;
@@ -4044,6 +4856,23 @@ function DateRangePickerRoot(props) {
4044
4856
  setPending(false);
4045
4857
  setCalendarKey((k) => k + 1);
4046
4858
  }
4859
+ function updateDraft(next) {
4860
+ if (isDisabled || isReadOnly) return;
4861
+ setDraft(next);
4862
+ const value = next.start || next.end ? next : null;
4863
+ if (props.commitMode === "immediate" && !rangeError(value, props)) {
4864
+ setLocal(value);
4865
+ setFormError(false);
4866
+ props.onChange?.(value);
4867
+ }
4868
+ }
4869
+ function clearDraft() {
4870
+ replaceDraft(empty());
4871
+ if (props.commitMode === "immediate" && !isDisabled && !isReadOnly) {
4872
+ setLocal(null);
4873
+ props.onChange?.(null);
4874
+ }
4875
+ }
4047
4876
  function resetDraft() {
4048
4877
  replaceDraft({
4049
4878
  start,
@@ -4079,13 +4908,17 @@ function DateRangePickerRoot(props) {
4079
4908
  ...draft,
4080
4909
  [part]: value
4081
4910
  });
4911
+ updateDraft({
4912
+ ...draft,
4913
+ [part]: value
4914
+ });
4082
4915
  if (asDate(value)) setFocused(asDate(value));
4083
4916
  }
4084
4917
  const calendarValue = asDate(draft.start) && asDate(draft.end) && draft.start <= draft.end ? {
4085
4918
  start: asDate(draft.start),
4086
4919
  end: asDate(draft.end)
4087
4920
  } : null;
4088
- const calendar = /* @__PURE__ */ jsx(RangeCalendar, {
4921
+ const calendar = /* @__PURE__ */ jsx(RangeCalendar$1, {
4089
4922
  dir,
4090
4923
  className: partClass("date-range__calendar", props.classNames?.calendar),
4091
4924
  "aria-label": labels.title,
@@ -4094,7 +4927,7 @@ function DateRangePickerRoot(props) {
4094
4927
  onFocusChange: setFocused,
4095
4928
  createCalendar: () => new GregorianCalendar(),
4096
4929
  onChange: (v) => {
4097
- if (v) setDraft({
4930
+ if (v) updateDraft({
4098
4931
  start: v.start.toString(),
4099
4932
  end: v.end.toString()
4100
4933
  });
@@ -4127,9 +4960,14 @@ function DateRangePickerRoot(props) {
4127
4960
  className: partClass("date-range__months", props.classNames?.months),
4128
4961
  children: Array.from({ length: visibleMonths }, (_, i) => /* @__PURE__ */ jsxs("div", {
4129
4962
  className: partClass("date-range__month", props.classNames?.month),
4130
- children: [/* @__PURE__ */ jsx(CalendarHeading, {
4131
- offset: { months: i },
4132
- className: partClass("date-range__heading", props.classNames?.heading)
4963
+ children: [/* @__PURE__ */ jsx(CalendarViewHeader, {
4964
+ offset: i,
4965
+ onNavigate: setFocused,
4966
+ locale,
4967
+ minDate: props.minDate,
4968
+ maxDate: props.maxDate,
4969
+ isDisabled,
4970
+ className: props.classNames?.heading
4133
4971
  }), /* @__PURE__ */ jsxs(CalendarGrid, {
4134
4972
  offset: { months: i },
4135
4973
  className: partClass("date-range__grid", props.classNames?.grid),
@@ -4175,6 +5013,7 @@ function DateRangePickerRoot(props) {
4175
5013
  "aria-pressed": !pending && draft.start === p.value.start && draft.end === p.value.end,
4176
5014
  onClick: () => {
4177
5015
  replaceDraft({ ...p.value });
5016
+ updateDraft({ ...p.value });
4178
5017
  setFocused(asDate(p.value.start));
4179
5018
  },
4180
5019
  children: p.label
@@ -4253,26 +5092,46 @@ function DateRangePickerRoot(props) {
4253
5092
  ]
4254
5093
  })]
4255
5094
  }),
4256
- /* @__PURE__ */ jsxs("footer", {
5095
+ props.showActions !== false && /* @__PURE__ */ jsxs("footer", {
4257
5096
  className: partClass("date-range__footer", props.classNames?.footer),
4258
5097
  children: [/* @__PURE__ */ jsx("button", {
4259
5098
  type: "button",
4260
5099
  className: partClass("button button--ghost button--sm", props.classNames?.clearButton),
4261
5100
  disabled: isDisabled || isReadOnly,
4262
- onClick: () => replaceDraft(empty()),
5101
+ onClick: clearDraft,
4263
5102
  children: labels.clear
4264
- }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("button", {
4265
- type: "button",
4266
- className: partClass("button button--secondary button--sm", props.classNames?.cancelButton),
4267
- onClick: () => changeOpen(false),
4268
- children: labels.cancel
4269
- }), /* @__PURE__ */ jsx("button", {
4270
- type: "button",
4271
- className: partClass("button button--primary button--sm", props.classNames?.applyButton),
4272
- disabled: isDisabled || isReadOnly || !!errorCode,
4273
- onClick: apply,
4274
- children: labels.apply
4275
- })] })]
5103
+ }), /* @__PURE__ */ jsxs("div", { children: [
5104
+ /* @__PURE__ */ jsx("button", {
5105
+ type: "button",
5106
+ className: "button button--ghost button--sm",
5107
+ disabled: isDisabled || isReadOnly || !!rangeError({
5108
+ start: currentDate(),
5109
+ end: currentDate()
5110
+ }, props),
5111
+ onClick: () => {
5112
+ const next = {
5113
+ start: currentDate(),
5114
+ end: currentDate()
5115
+ };
5116
+ replaceDraft(next);
5117
+ updateDraft(next);
5118
+ },
5119
+ children: locale.startsWith("id") ? "Hari ini" : "Today"
5120
+ }),
5121
+ /* @__PURE__ */ jsx("button", {
5122
+ type: "button",
5123
+ className: partClass("button button--secondary button--sm", props.classNames?.cancelButton),
5124
+ onClick: () => changeOpen(false),
5125
+ children: labels.cancel
5126
+ }),
5127
+ props.commitMode !== "immediate" && /* @__PURE__ */ jsx("button", {
5128
+ type: "button",
5129
+ className: partClass("button button--primary button--sm", props.classNames?.applyButton),
5130
+ disabled: isDisabled || isReadOnly || !!errorCode,
5131
+ onClick: apply,
5132
+ children: labels.apply
5133
+ })
5134
+ ] })]
4276
5135
  })
4277
5136
  ]
4278
5137
  });
@@ -4299,7 +5158,7 @@ function DateRangePickerRoot(props) {
4299
5158
  panel,
4300
5159
  edit,
4301
5160
  apply,
4302
- clear: () => replaceDraft(empty()),
5161
+ clear: clearDraft,
4303
5162
  cancel: () => changeOpen(false)
4304
5163
  },
4305
5164
  children: /* @__PURE__ */ jsxs("div", {
@@ -4369,7 +5228,17 @@ function DateRangePickerRoot(props) {
4369
5228
  }),
4370
5229
  /* @__PURE__ */ jsx(ChevronIcon, { className: partClass("date-range__chevron", props.classNames?.chevron) })
4371
5230
  ]
4372
- }), /* @__PURE__ */ jsx(Popover$2, {
5231
+ }), isDialog ? /* @__PURE__ */ jsx(ModalOverlay, {
5232
+ className: "temporal-picker__overlay",
5233
+ children: /* @__PURE__ */ jsx(Modal, {
5234
+ className: "date-range__panel temporal-picker__modal",
5235
+ children: /* @__PURE__ */ jsx(Dialog$1, {
5236
+ "aria-labelledby": `${id}-title`,
5237
+ className: "date-range__dialog",
5238
+ children: panel
5239
+ })
5240
+ })
5241
+ }) : /* @__PURE__ */ jsx(Popover$2, {
4373
5242
  className: partClass("date-range__panel", props.classNames?.panel),
4374
5243
  placement: "bottom start",
4375
5244
  offset: 8,
@@ -5272,6 +6141,1030 @@ function ToastRenderer({ composed = false, style, classNames, entry, indicator,
5272
6141
  });
5273
6142
  }
5274
6143
  //#endregion
5275
- export { Alert, AlertActions, AlertContent, AlertDescription, AlertIndicator, AlertTitle, Badge, Breadcrumb, BreadcrumbCurrent, BreadcrumbItemPart, BreadcrumbLink, BreadcrumbList, BreadcrumbRoot, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, Card, CardActions, CardContent, CardDescription, CardFooter, CardHeader, CardHeading, CardRoot, CardTitle, CardTitleRow, Chart, ChartDescription, ChartPlot, ChartRoot, ChartTitle, Checkbox, Combobox, DataTable, DataTableColumn as DataTableColumnPart, DataTableEmpty, DataTableError, DataTableRoot, DataTableSortButton, DataTableStatus, DateRangePicker, Description, Dialog, DialogBackdrop as DialogBackdropPart, DialogCloseButton, DialogContent, DialogPanel, DialogRoot, DialogTriggerPart, DropdownHeading, DropdownItem, DropdownItemIndicator, DropdownList, DropdownMenu, DropdownPopover, DropdownRoot, DropdownSection, DropdownSeparator, DropdownSubmenuIndicator, DropdownSubmenuTrigger, DropdownTrigger, Empty, EmptyActions, EmptyDescription, EmptyRoot, EmptyTitle, Field, FieldError, Form, Header, Input, Label, ListBox, Listbox, NumberField, OverlayBody, OverlayDescription, OverlayFooter, OverlayHeader, OverlayHeading, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPageButton, PaginationPrevious, PaginationRoot, PaginationSummary, Popover, PopoverCloseButton, PopoverContent, PopoverDialog, PopoverTrigger, RadioGroup, Select, SelectGroup, Separator, Sidebar, SidebarHeader, SidebarItem, SidebarLink, SidebarList, SidebarNavigation, SidebarRoot, SidebarTitle, SidebarToggle, Skeleton, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableColumn, TableFooter, TableHeader, TableRoot, TableRow, TableScrollContainer, Tabs, TabsIndicator, TabsList, TabsListContainer, TabsPanel, TabsRoot, TabsSeparator, TabsTab, Textarea, Toast, ToastActionButton, ToastActions, ToastBody, ToastCloseButton, ToastDescription, ToastIndicator, ToastProgress, ToastProvider, ToastRoot, ToastTitle, ToggleButton, ToggleButtonGroup, ToggleGroup, Tooltip, TooltipContent, TooltipRoot, TooltipTriggerPart, createDateRangePresets, createToastManager, rangeText as formatDateRange, useToast };
6144
+ //#region src/temporal-model.ts
6145
+ /** Wall time is resolved explicitly; DST gaps/overlaps reject by default. */
6146
+ function toZonedValue(value, timeZone = "UTC", disambiguation = "reject") {
6147
+ return toZoned(parseDateTime(value), timeZone, disambiguation).toString();
6148
+ }
6149
+ function toLocalValue(value, timeZone = "UTC", seconds = false) {
6150
+ if (!value) return "";
6151
+ const zoned = value.includes("[") ? parseZonedDateTime(value) : parseAbsolute(value, timeZone);
6152
+ const display = parseAbsolute(zoned.toAbsoluteString(), timeZone);
6153
+ return toCalendarDateTime(display).toString().slice(0, seconds ? 19 : 16);
6154
+ }
6155
+ function orderedValue(value, kind) {
6156
+ if (kind === "datetime") return (value.includes("[") ? parseZonedDateTime(value) : parseAbsolute(value, "UTC")).toDate().getTime();
6157
+ if (kind === "time") {
6158
+ const t = parseTime(value);
6159
+ return t.hour * 3600 + t.minute * 60 + t.second;
6160
+ }
6161
+ return parseDate(value).toDate("UTC").getTime();
6162
+ }
6163
+ function step(value) {
6164
+ if (value !== void 0 && (!Number.isInteger(value) || value <= 0)) throw new RangeError("Time steps must be positive integers.");
6165
+ return value ?? 1;
6166
+ }
6167
+ function temporalError(value, options) {
6168
+ if (!value) return options.isRequired ? "required" : null;
6169
+ let date = "", time = "";
6170
+ try {
6171
+ if (options.kind === "date") {
6172
+ if (!/^(?!0000)\d{4}-\d{2}-\d{2}$/.test(value) || parseDate(value).toString() !== value) return "invalid";
6173
+ date = value;
6174
+ } else if (options.kind === "time") {
6175
+ if (!/^\d{2}:\d{2}(:\d{2})?$/.test(value)) return "invalid";
6176
+ parseTime(value);
6177
+ time = value;
6178
+ } else {
6179
+ orderedValue(value, "datetime");
6180
+ const local = toLocalValue(value, options.timeZone, true);
6181
+ date = local.slice(0, 10);
6182
+ time = local.slice(11);
6183
+ }
6184
+ if (date && (options.minDate && date < options.minDate || options.maxDate && date > options.maxDate)) return "bounds";
6185
+ if (time && (options.minTime && orderedValue(time, "time") < orderedValue(options.minTime, "time") || options.maxTime && orderedValue(time, "time") > orderedValue(options.maxTime, "time"))) return "bounds";
6186
+ if (options.kind === "datetime" && (options.minDateTime && orderedValue(value, "datetime") < orderedValue(options.minDateTime, "datetime") || options.maxDateTime && orderedValue(value, "datetime") > orderedValue(options.maxDateTime, "datetime"))) return "bounds";
6187
+ if (date && options.isDateUnavailable?.(date)) return "unavailable";
6188
+ if (time && options.isTimeUnavailable?.(time)) return "unavailable";
6189
+ if (time) {
6190
+ const t = parseTime(time);
6191
+ if (t.hour % step(options.hourStep) || t.minute % step(options.minuteStep) || t.second % step(options.secondStep)) return "step";
6192
+ }
6193
+ return null;
6194
+ } catch {
6195
+ return "invalid";
6196
+ }
6197
+ }
6198
+ function temporalRangeError(value, options) {
6199
+ if (!value || !value.start && !value.end) return options.isRequired ? "required" : null;
6200
+ if (!value.start || !value.end) return "incomplete";
6201
+ const error = temporalError(value.start, options) ?? temporalError(value.end, options);
6202
+ if (error) return error;
6203
+ if (orderedValue(value.start, options.kind) > orderedValue(value.end, options.kind)) return "order";
6204
+ if (options.kind !== "time" && options.isDateUnavailable) {
6205
+ const first = parseDate(options.kind === "date" ? value.start : toLocalValue(value.start, options.timeZone).slice(0, 10));
6206
+ const last = parseDate(options.kind === "date" ? value.end : toLocalValue(value.end, options.timeZone).slice(0, 10));
6207
+ for (let day = first.add({ days: 1 }); day.compare(last) < 0; day = day.add({ days: 1 })) if (options.isDateUnavailable(day.toString())) return "unavailable";
6208
+ }
6209
+ return null;
6210
+ }
6211
+ /** Project instant boundaries into the selected display zone for disabled calendar/time options. */
6212
+ function temporalDisplayBounds(options, selectedDate) {
6213
+ let minDate = options.minDate, maxDate = options.maxDate, minTime = options.minTime, maxTime = options.maxTime;
6214
+ if (options.kind === "datetime") try {
6215
+ const min = options.minDateTime ? toLocalValue(options.minDateTime, options.timeZone, true) : "", max = options.maxDateTime ? toLocalValue(options.maxDateTime, options.timeZone, true) : "";
6216
+ if (min) {
6217
+ const day = min.slice(0, 10);
6218
+ if (!minDate || day > minDate) minDate = day;
6219
+ if (selectedDate === day && (!minTime || orderedValue(min.slice(11), "time") > orderedValue(minTime, "time"))) minTime = min.slice(11);
6220
+ }
6221
+ if (max) {
6222
+ const day = max.slice(0, 10);
6223
+ if (!maxDate || day < maxDate) maxDate = day;
6224
+ if (selectedDate === day && (!maxTime || orderedValue(max.slice(11), "time") < orderedValue(maxTime, "time"))) maxTime = max.slice(11);
6225
+ }
6226
+ } catch {}
6227
+ return {
6228
+ minDate,
6229
+ maxDate,
6230
+ minTime,
6231
+ maxTime
6232
+ };
6233
+ }
6234
+ /** Minute-granularity list; seconds are edited with TimeField/TimeClock to avoid 86k DOM options. */
6235
+ function timeChoices(options) {
6236
+ const hours = step(options.hourStep), minutes = options.granularity === "hour" ? 60 : step(options.minuteStep ?? 30);
6237
+ const values = [];
6238
+ for (let hour = 0; hour < 24; hour += hours) for (let minute = 0; minute < 60; minute += minutes) {
6239
+ const value = `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
6240
+ if (!temporalError(value, options)) values.push(value);
6241
+ }
6242
+ return values;
6243
+ }
6244
+ /** User edits zero units hidden by the configured field granularity. */
6245
+ function normalizeTime(value, granularity = "minute") {
6246
+ const time = parseTime(value);
6247
+ return time.set({
6248
+ minute: granularity === "hour" ? 0 : time.minute,
6249
+ second: granularity === "second" ? time.second : 0,
6250
+ millisecond: 0
6251
+ }).toString().slice(0, granularity === "second" ? 8 : 5);
6252
+ }
6253
+ function normalizeWallDateTime(value, granularity = "minute") {
6254
+ const date = parseDateTime(value);
6255
+ return date.toString().slice(0, 10) + "T" + normalizeTime(date.toString().slice(11), granularity);
6256
+ }
6257
+ /** Keep the selected unit and choose the nearest complete valid time for the other units. */
6258
+ function resolveTimeUnit(value, part, selected, options) {
6259
+ let initial;
6260
+ try {
6261
+ initial = parseTime(value || options.minTime || "00:00");
6262
+ } catch {
6263
+ initial = parseTime("00:00");
6264
+ }
6265
+ const desired = initial.set({ [part]: selected });
6266
+ let best = null, distance = Infinity;
6267
+ const hours = step(options.hourStep), minutes = step(options.minuteStep), seconds = step(options.secondStep);
6268
+ for (let hour = 0; hour < 24; hour += hours) {
6269
+ if (part === "hour" && hour !== selected) continue;
6270
+ for (let minute = 0; minute < 60; minute += options.granularity === "hour" ? 60 : minutes) {
6271
+ if (part === "minute" && minute !== selected) continue;
6272
+ for (let second = 0; second < 60; second += options.granularity === "second" ? seconds : 60) {
6273
+ if (part === "second" && second !== selected) continue;
6274
+ const next = normalizeTime(`${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}:${String(second).padStart(2, "0")}`, options.granularity);
6275
+ if (temporalError(next, {
6276
+ ...options,
6277
+ kind: "time"
6278
+ })) continue;
6279
+ const delta = Math.abs(orderedValue(next, "time") - (desired.hour * 3600 + desired.minute * 60 + desired.second));
6280
+ if (delta < distance) {
6281
+ best = next;
6282
+ distance = delta;
6283
+ }
6284
+ }
6285
+ }
6286
+ }
6287
+ return best;
6288
+ }
6289
+ function temporalMessages(locale = "id-ID") {
6290
+ return locale.startsWith("id") ? {
6291
+ invalid: "Nilai tanggal atau waktu tidak valid.",
6292
+ required: "Nilai wajib diisi.",
6293
+ incomplete: "Lengkapi nilai mulai dan akhir.",
6294
+ order: "Nilai akhir harus setelah atau sama dengan nilai mulai.",
6295
+ bounds: "Nilai berada di luar batas yang diizinkan.",
6296
+ unavailable: "Nilai tidak tersedia.",
6297
+ step: "Nilai tidak sesuai interval yang diizinkan."
6298
+ } : {
6299
+ invalid: "Invalid date or time.",
6300
+ required: "A value is required.",
6301
+ incomplete: "Enter both start and end values.",
6302
+ order: "End must be on or after start.",
6303
+ bounds: "Value is outside the allowed limits.",
6304
+ unavailable: "Value is unavailable.",
6305
+ step: "Value does not match the allowed interval."
6306
+ };
6307
+ }
6308
+ //#endregion
6309
+ //#region src/TemporalField.tsx
6310
+ function parsed(value, kind, zone) {
6311
+ try {
6312
+ return value ? kind === "time" ? parseTime(value) : kind === "date" ? parseDate(value) : parseDateTime(toLocalValue(value, zone, true)) : null;
6313
+ } catch {
6314
+ return null;
6315
+ }
6316
+ }
6317
+ function TemporalField({ kind, ...props }) {
6318
+ const [local, setLocal] = useState(props.defaultValue ?? null), [editError, setEditError] = useState(null);
6319
+ const value = props.value === void 0 ? local : props.value;
6320
+ const id = useId();
6321
+ const error = editError ?? temporalError(value, {
6322
+ ...props,
6323
+ kind
6324
+ });
6325
+ useEffect(() => {
6326
+ setEditError(null);
6327
+ }, [value]);
6328
+ function change(v) {
6329
+ if (props.isDisabled || props.isReadOnly) return;
6330
+ let next;
6331
+ try {
6332
+ next = v ? kind === "datetime" ? toZonedValue(normalizeWallDateTime(v.toString(), props.granularity), props.timeZone, props.disambiguation) : kind === "time" ? normalizeTime(v.toString(), props.granularity) : v.toString().slice(0, 10) : null;
6333
+ } catch {
6334
+ const message = temporalMessages(props.locale).invalid;
6335
+ setEditError(message);
6336
+ props.onError?.(message);
6337
+ return;
6338
+ }
6339
+ setEditError(null);
6340
+ setLocal(next);
6341
+ props.onChange?.(next);
6342
+ props.onError?.(temporalError(next, {
6343
+ ...props,
6344
+ kind
6345
+ }));
6346
+ }
6347
+ const fieldContent = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Label$3, {
6348
+ className: partClass(props.hideLabel ? "temporal__sr-only" : "input__label", props.classNames?.label),
6349
+ children: props.label
6350
+ }), /* @__PURE__ */ jsx(DateInput, {
6351
+ className: partClass("temporal-field__input input__control", props.classNames?.input),
6352
+ children: (segment) => /* @__PURE__ */ jsx(DateSegment, {
6353
+ segment,
6354
+ className: partClass("temporal-field__segment", props.classNames?.segment)
6355
+ })
6356
+ })] });
6357
+ const shared = {
6358
+ id: props.id ?? id,
6359
+ isDisabled: props.isDisabled,
6360
+ isReadOnly: props.isReadOnly,
6361
+ isRequired: props.isRequired,
6362
+ isInvalid: props.isInvalid || !!error,
6363
+ validationBehavior: "aria",
6364
+ "aria-describedby": [props.description ? `${id}-description` : void 0, props.isInvalid || error ? `${id}-error` : void 0].filter(Boolean).join(" ") || void 0
6365
+ };
6366
+ return /* @__PURE__ */ jsx(I18nProvider, {
6367
+ locale: props.locale ?? "id-ID",
6368
+ children: /* @__PURE__ */ jsxs("div", {
6369
+ className: partClass(partClass("input temporal-field", props.classNames?.root), props.className),
6370
+ style: props.style,
6371
+ dir: props.dir,
6372
+ children: [
6373
+ kind === "time" ? /* @__PURE__ */ jsx(TimeField$1, {
6374
+ ...shared,
6375
+ value: parsed(value, kind, props.timeZone),
6376
+ onChange: change,
6377
+ granularity: props.granularity ?? "minute",
6378
+ hourCycle: props.hourCycle,
6379
+ children: fieldContent
6380
+ }) : /* @__PURE__ */ jsx(DateField$1, {
6381
+ ...shared,
6382
+ value: parsed(value, kind, props.timeZone),
6383
+ onChange: change,
6384
+ granularity: kind === "date" ? "day" : props.granularity ?? "minute",
6385
+ hourCycle: props.hourCycle,
6386
+ children: fieldContent
6387
+ }),
6388
+ props.description && /* @__PURE__ */ jsx("span", {
6389
+ id: `${id}-description`,
6390
+ className: partClass("input__description", props.classNames?.description),
6391
+ children: props.description
6392
+ }),
6393
+ (props.isInvalid || error) && /* @__PURE__ */ jsx("span", {
6394
+ id: `${id}-error`,
6395
+ className: partClass("input__error", props.classNames?.error),
6396
+ role: "alert",
6397
+ children: props.errorMessage ?? (error && error in temporalMessages(props.locale) ? temporalMessages(props.locale)[error] : error ?? temporalMessages(props.locale).invalid)
6398
+ }),
6399
+ props.name && /* @__PURE__ */ jsx("input", {
6400
+ type: "hidden",
6401
+ name: props.name,
6402
+ value: value ?? "",
6403
+ disabled: props.isDisabled
6404
+ }),
6405
+ /* @__PURE__ */ jsx(SelectionValidation, {
6406
+ hasValue: !!value && !error,
6407
+ required: props.isRequired || !!error,
6408
+ disabled: props.isDisabled || props.formValidation === false,
6409
+ onInvalid: () => props.onError?.(error ?? "required"),
6410
+ onResetStart: () => {},
6411
+ onReset: (cancelled) => {
6412
+ if (!cancelled && props.value === void 0) {
6413
+ setLocal(props.defaultValue ?? null);
6414
+ setEditError(null);
6415
+ }
6416
+ }
6417
+ })
6418
+ ]
6419
+ })
6420
+ });
6421
+ }
6422
+ function DateField(props) {
6423
+ return /* @__PURE__ */ jsx(TemporalField, {
6424
+ ...props,
6425
+ kind: "date"
6426
+ });
6427
+ }
6428
+ function TimeField(props) {
6429
+ return /* @__PURE__ */ jsx(TemporalField, {
6430
+ ...props,
6431
+ kind: "time"
6432
+ });
6433
+ }
6434
+ function DateTimeField(props) {
6435
+ return /* @__PURE__ */ jsx(TemporalField, {
6436
+ ...props,
6437
+ kind: "datetime"
6438
+ });
6439
+ }
6440
+ function TemporalRangeField({ kind, ...props }) {
6441
+ const groupId = useId();
6442
+ const [local, setLocal] = useState(props.defaultValue ?? null);
6443
+ const value = props.value === void 0 ? local : props.value;
6444
+ const error = temporalRangeError(value, {
6445
+ ...props,
6446
+ kind
6447
+ });
6448
+ const fields = /* @__PURE__ */ jsx("div", {
6449
+ className: "temporal-picker__fields",
6450
+ children: ["start", "end"].map((part) => /* @__PURE__ */ createElement(TemporalField, {
6451
+ ...props,
6452
+ id: props.id ? `${props.id}-${part}` : void 0,
6453
+ className: void 0,
6454
+ style: void 0,
6455
+ classNames: {
6456
+ ...props.classNames,
6457
+ root: void 0
6458
+ },
6459
+ kind,
6460
+ key: part,
6461
+ value: value?.[part] ?? null,
6462
+ defaultValue: void 0,
6463
+ formValidation: false,
6464
+ name: props.name ? `${props.name}.${part}` : void 0,
6465
+ label: `${props.label} ${part === "start" ? props.locale?.startsWith("id") ? "Mulai" : "Start" : props.locale?.startsWith("id") ? "Akhir" : "End"}`,
6466
+ onChange: (next) => {
6467
+ const result = {
6468
+ ...value ?? {
6469
+ start: "",
6470
+ end: ""
6471
+ },
6472
+ [part]: next ?? ""
6473
+ };
6474
+ setLocal(result);
6475
+ props.onChange?.(result);
6476
+ }
6477
+ }))
6478
+ });
6479
+ return /* @__PURE__ */ jsxs("div", {
6480
+ id: props.id ?? groupId,
6481
+ role: "group",
6482
+ "aria-label": props.label,
6483
+ "aria-describedby": error ? `${groupId}-error` : void 0,
6484
+ className: partClass(partClass("temporal-range-field", props.classNames?.root), props.className),
6485
+ style: props.style,
6486
+ children: [
6487
+ fields,
6488
+ error && /* @__PURE__ */ jsx("span", {
6489
+ id: `${groupId}-error`,
6490
+ role: "alert",
6491
+ className: "input__error",
6492
+ children: props.errorMessage ?? temporalMessages(props.locale)[error]
6493
+ }),
6494
+ /* @__PURE__ */ jsx(SelectionValidation, {
6495
+ hasValue: !!value && !error,
6496
+ required: props.isRequired || !!error,
6497
+ disabled: props.isDisabled || props.formValidation === false,
6498
+ onInvalid: () => props.onError?.(error ?? "required"),
6499
+ onResetStart: () => {},
6500
+ onReset: (cancelled) => {
6501
+ if (!cancelled && props.value === void 0) setLocal(props.defaultValue ?? null);
6502
+ }
6503
+ })
6504
+ ]
6505
+ });
6506
+ }
6507
+ function DateRangeField(props) {
6508
+ return /* @__PURE__ */ jsx(TemporalRangeField, {
6509
+ ...props,
6510
+ kind: "date"
6511
+ });
6512
+ }
6513
+ function TimeRangeField(props) {
6514
+ return /* @__PURE__ */ jsx(TemporalRangeField, {
6515
+ ...props,
6516
+ kind: "time"
6517
+ });
6518
+ }
6519
+ function DateTimeRangeField(props) {
6520
+ return /* @__PURE__ */ jsx(TemporalRangeField, {
6521
+ ...props,
6522
+ kind: "datetime"
6523
+ });
6524
+ }
6525
+ //#endregion
6526
+ //#region src/TimeControls.tsx
6527
+ function format(value, locale, hourCycle) {
6528
+ const time = parseTime(value);
6529
+ const date = new Date(Date.UTC(2e3, 0, 1, time.hour, time.minute, time.second));
6530
+ return new Intl.DateTimeFormat(locale, {
6531
+ hour: "2-digit",
6532
+ minute: "2-digit",
6533
+ hourCycle: hourCycle === 12 ? "h12" : "h23",
6534
+ timeZone: "UTC"
6535
+ }).format(date);
6536
+ }
6537
+ function TimeList({ value, defaultValue, onChange, label = "Time", locale = "id-ID", hourCycle, isDisabled, isReadOnly, className, minTime, maxTime, hourStep, minuteStep, secondStep, granularity, isTimeUnavailable, ...props }) {
6538
+ const [local, setLocal] = useState(defaultValue ?? "");
6539
+ const actual = value === void 0 ? local : value ?? "";
6540
+ const options = {
6541
+ kind: "time",
6542
+ minTime,
6543
+ maxTime,
6544
+ hourStep,
6545
+ minuteStep,
6546
+ secondStep,
6547
+ granularity,
6548
+ isTimeUnavailable
6549
+ };
6550
+ return /* @__PURE__ */ jsx("div", {
6551
+ ...props,
6552
+ className: partClass("time-list", className),
6553
+ children: /* @__PURE__ */ jsxs("select", {
6554
+ "aria-label": label,
6555
+ size: 6,
6556
+ value: actual,
6557
+ disabled: isDisabled,
6558
+ "aria-readonly": isReadOnly || void 0,
6559
+ onChange: (event) => {
6560
+ if (isReadOnly) {
6561
+ event.currentTarget.value = actual;
6562
+ return;
6563
+ }
6564
+ setLocal(event.target.value);
6565
+ onChange?.(event.target.value);
6566
+ },
6567
+ children: [/* @__PURE__ */ jsx("option", {
6568
+ value: "",
6569
+ disabled: true,
6570
+ children: locale.startsWith("id") ? "Pilih waktu" : "Choose time"
6571
+ }), timeChoices(options).map((time) => /* @__PURE__ */ jsx("option", {
6572
+ value: time,
6573
+ children: format(time, locale, hourCycle)
6574
+ }, time))]
6575
+ })
6576
+ });
6577
+ }
6578
+ function TimeClock({ value, defaultValue, onChange, label = "Time", locale = "id-ID", hourCycle = 24, isDisabled, isReadOnly, className, minTime, maxTime, hourStep = 1, minuteStep = 1, secondStep = 1, granularity = "minute", isTimeUnavailable, ...props }) {
6579
+ const [local, setLocal] = useState(defaultValue ?? minTime ?? "00:00");
6580
+ const actual = value === void 0 ? local : value || minTime || "00:00";
6581
+ let time;
6582
+ try {
6583
+ time = parseTime(actual);
6584
+ } catch {
6585
+ time = parseTime("00:00");
6586
+ }
6587
+ const id = locale.startsWith("id");
6588
+ const parts = granularity === "hour" ? ["hour"] : granularity === "second" ? [
6589
+ "hour",
6590
+ "minute",
6591
+ "second"
6592
+ ] : ["hour", "minute"];
6593
+ return /* @__PURE__ */ jsx("div", {
6594
+ ...props,
6595
+ role: "group",
6596
+ "aria-label": label,
6597
+ className: partClass("time-clock", className),
6598
+ children: parts.map((part) => {
6599
+ const step = part === "hour" ? hourStep : part === "minute" ? minuteStep : secondStep;
6600
+ const count = part === "hour" ? 24 : 60;
6601
+ const values = Array.from({ length: Math.ceil(count / Math.max(1, step)) }, (_, i) => i * Math.max(1, step)).filter((n) => n < count);
6602
+ return /* @__PURE__ */ jsxs("label", { children: [/* @__PURE__ */ jsx("span", { children: part === "hour" ? id ? "Jam" : "Hours" : part === "minute" ? id ? "Menit" : "Minutes" : id ? "Detik" : "Seconds" }), /* @__PURE__ */ jsx("select", {
6603
+ value: time[part],
6604
+ disabled: isDisabled,
6605
+ "aria-readonly": isReadOnly || void 0,
6606
+ onChange: (event) => {
6607
+ if (isReadOnly) {
6608
+ event.currentTarget.value = String(time[part]);
6609
+ return;
6610
+ }
6611
+ const next = resolveTimeUnit(time.toString(), part, Number(event.target.value), {
6612
+ kind: "time",
6613
+ minTime,
6614
+ maxTime,
6615
+ hourStep,
6616
+ minuteStep,
6617
+ secondStep,
6618
+ granularity,
6619
+ isTimeUnavailable
6620
+ });
6621
+ if (!next) return;
6622
+ setLocal(next);
6623
+ onChange?.(next);
6624
+ },
6625
+ children: values.map((n) => /* @__PURE__ */ jsx("option", {
6626
+ value: n,
6627
+ children: part === "hour" && hourCycle === 12 ? `${n % 12 || 12} ${n < 12 ? "AM" : "PM"}` : String(n).padStart(2, "0")
6628
+ }, n))
6629
+ })] }, part);
6630
+ })
6631
+ });
6632
+ }
6633
+ //#endregion
6634
+ //#region src/TemporalPicker.tsx
6635
+ var PickerContext = createContext(null);
6636
+ function usePicker() {
6637
+ const context = useContext(PickerContext);
6638
+ if (!context) throw new Error("Picker parts must be inside their picker Root.");
6639
+ return context;
6640
+ }
6641
+ function labels(locale = "id-ID") {
6642
+ return locale.startsWith("id") ? {
6643
+ apply: "Terapkan",
6644
+ cancel: "Batal",
6645
+ clear: "Kosongkan",
6646
+ today: "Hari ini",
6647
+ now: "Sekarang",
6648
+ start: "Mulai",
6649
+ end: "Akhir",
6650
+ choose: "Pilih tanggal atau waktu"
6651
+ } : {
6652
+ apply: "Apply",
6653
+ cancel: "Cancel",
6654
+ clear: "Clear",
6655
+ today: "Today",
6656
+ now: "Now",
6657
+ start: "Start",
6658
+ end: "End",
6659
+ choose: "Choose date or time"
6660
+ };
6661
+ }
6662
+ function localValue(value, kind, options) {
6663
+ try {
6664
+ return kind === "datetime" ? toLocalValue(value, options.timeZone, options.granularity === "second") : value;
6665
+ } catch {
6666
+ return "";
6667
+ }
6668
+ }
6669
+ function datePart(value, kind, options) {
6670
+ return localValue(value, kind, options).slice(0, 10);
6671
+ }
6672
+ function combineDate(date, time, options) {
6673
+ try {
6674
+ return toZonedValue(`${date}T${time || "00:00"}`, options.timeZone, options.disambiguation);
6675
+ } catch {
6676
+ return "";
6677
+ }
6678
+ }
6679
+ function displayText(value, kind, options) {
6680
+ if (!value) return labels(options.locale).choose;
6681
+ if (options.formatValue) return options.formatValue(value, options.locale ?? "id-ID");
6682
+ const one = (v) => {
6683
+ if (!v) return "—";
6684
+ try {
6685
+ if (kind === "time") return new Intl.DateTimeFormat(options.locale ?? "id-ID", {
6686
+ hour: "2-digit",
6687
+ minute: "2-digit",
6688
+ second: options.granularity === "second" ? "2-digit" : void 0,
6689
+ hourCycle: options.hourCycle === 12 ? "h12" : "h23",
6690
+ timeZone: "UTC"
6691
+ }).format(/* @__PURE__ */ new Date(`2000-01-01T${v}Z`));
6692
+ if (kind === "date") return new Intl.DateTimeFormat(options.locale ?? "id-ID", {
6693
+ day: "numeric",
6694
+ month: "short",
6695
+ year: "numeric",
6696
+ timeZone: "UTC"
6697
+ }).format(/* @__PURE__ */ new Date(`${v}T12:00:00Z`));
6698
+ return `${localValue(v, kind, options).replace("T", " ")} ${options.timeZone ?? "UTC"}`;
6699
+ } catch {
6700
+ return v;
6701
+ }
6702
+ };
6703
+ return typeof value === "string" ? one(value) : `${one(value.start)} – ${one(value.end)}`;
6704
+ }
6705
+ function TemporalPickerField({ part = "start", ...props }) {
6706
+ const context = usePicker(), o = context.options, l = labels(o.locale);
6707
+ const Field = context.kind === "date" ? DateField : context.kind === "time" ? TimeField : DateTimeField;
6708
+ const value = typeof context.draft === "string" ? context.draft : context.draft?.[part] ?? null;
6709
+ return /* @__PURE__ */ jsx(Field, {
6710
+ ...o,
6711
+ ...props,
6712
+ className: partClass(o.classNames?.field ?? "", props.className),
6713
+ style: props.style,
6714
+ classNames: void 0,
6715
+ label: props.label ?? (context.range ? `${o.label} ${l[part]}` : o.label),
6716
+ value,
6717
+ name: void 0,
6718
+ formValidation: false,
6719
+ isRequired: false,
6720
+ onError: (error) => context.inputError(part, error),
6721
+ onChange: (next) => context.edit(context.range ? {
6722
+ ...typeof context.draft === "object" && context.draft ? context.draft : {
6723
+ start: "",
6724
+ end: ""
6725
+ },
6726
+ [part]: next ?? ""
6727
+ } : next, part)
6728
+ });
6729
+ }
6730
+ function TemporalPickerCalendar(props) {
6731
+ const c = usePicker(), o = c.options;
6732
+ const selected = typeof c.draft === "string" ? c.draft : "";
6733
+ const onSingle = (value) => {
6734
+ if (c.kind === "date") c.edit(value);
6735
+ else {
6736
+ const next = value ? combineDate(value, localValue(selected, c.kind, o).slice(11), o) : null;
6737
+ if (value && !next) {
6738
+ c.inputError("date", "invalid");
6739
+ return;
6740
+ }
6741
+ c.edit(next);
6742
+ }
6743
+ };
6744
+ const bounds = temporalDisplayBounds({
6745
+ ...o,
6746
+ kind: c.kind
6747
+ });
6748
+ const range = typeof c.draft === "object" && c.draft ? c.draft : {
6749
+ start: "",
6750
+ end: ""
6751
+ };
6752
+ return /* @__PURE__ */ jsx("div", {
6753
+ ...props,
6754
+ className: partClass("temporal-picker__calendar", props.className),
6755
+ children: c.kind !== "time" && (c.range ? /* @__PURE__ */ jsx(RangeCalendar, {
6756
+ ...o,
6757
+ minDate: bounds.minDate,
6758
+ maxDate: bounds.maxDate,
6759
+ style: void 0,
6760
+ className: void 0,
6761
+ classNames: void 0,
6762
+ value: {
6763
+ start: datePart(range.start, c.kind, o),
6764
+ end: datePart(range.end, c.kind, o)
6765
+ },
6766
+ onChange: (v) => {
6767
+ if (!v || c.kind === "date") {
6768
+ c.edit(v);
6769
+ return;
6770
+ }
6771
+ const start = v.start ? combineDate(v.start, localValue(range.start, c.kind, o).slice(11), o) : "", end = v.end ? combineDate(v.end, localValue(range.end, c.kind, o).slice(11), o) : "";
6772
+ if (v.start && !start || v.end && !end) {
6773
+ c.inputError("date", "invalid");
6774
+ return;
6775
+ }
6776
+ c.edit({
6777
+ start,
6778
+ end
6779
+ });
6780
+ }
6781
+ }) : /* @__PURE__ */ jsx(Calendar, {
6782
+ ...o,
6783
+ minDate: bounds.minDate,
6784
+ maxDate: bounds.maxDate,
6785
+ style: void 0,
6786
+ className: void 0,
6787
+ classNames: void 0,
6788
+ value: datePart(selected, c.kind, o),
6789
+ onChange: onSingle
6790
+ }))
6791
+ });
6792
+ }
6793
+ function TemporalPickerTime({ part = "start", ...props }) {
6794
+ const c = usePicker(), o = c.options, l = labels(o.locale);
6795
+ const wall = localValue(typeof c.draft === "string" ? c.draft : c.draft?.[part] ?? "", c.kind, o);
6796
+ const time = c.kind === "time" ? wall : wall.slice(11);
6797
+ const bounds = temporalDisplayBounds({
6798
+ ...o,
6799
+ kind: c.kind
6800
+ }, wall.slice(0, 10));
6801
+ const Control = o.timePresentation === "clock" ? TimeClock : TimeList;
6802
+ return /* @__PURE__ */ jsx("div", {
6803
+ ...props,
6804
+ className: partClass("temporal-picker__time", props.className),
6805
+ children: /* @__PURE__ */ jsx(Control, {
6806
+ locale: o.locale,
6807
+ hourCycle: o.hourCycle,
6808
+ minTime: bounds.minTime,
6809
+ maxTime: bounds.maxTime,
6810
+ hourStep: o.hourStep,
6811
+ minuteStep: o.minuteStep,
6812
+ secondStep: o.secondStep,
6813
+ granularity: o.granularity,
6814
+ isTimeUnavailable: o.isTimeUnavailable,
6815
+ isDisabled: o.isDisabled,
6816
+ isReadOnly: o.isReadOnly,
6817
+ label: c.range ? `${o.label} ${l[part]}` : o.label,
6818
+ value: time,
6819
+ onChange: (next) => {
6820
+ const result = c.kind === "time" ? next : combineDate(wall.slice(0, 10) || o.referenceDate || today(o.timeZone ?? "UTC").toString(), next, o);
6821
+ if (!result) {
6822
+ c.inputError(part, "invalid");
6823
+ return;
6824
+ }
6825
+ c.edit(c.range ? {
6826
+ ...typeof c.draft === "object" && c.draft ? c.draft : {
6827
+ start: "",
6828
+ end: ""
6829
+ },
6830
+ [part]: result
6831
+ } : result, part);
6832
+ }
6833
+ })
6834
+ });
6835
+ }
6836
+ function TemporalPickerValue({ children, className, ...props }) {
6837
+ const c = usePicker();
6838
+ return /* @__PURE__ */ jsx("span", {
6839
+ ...props,
6840
+ id: `${c.id}-value`,
6841
+ className: partClass("date-range__value", className),
6842
+ children: children ?? c.text
6843
+ });
6844
+ }
6845
+ function TemporalPickerTrigger({ children, className, ...props }) {
6846
+ const c = usePicker();
6847
+ return /* @__PURE__ */ jsx(Button$1, {
6848
+ ...props,
6849
+ isDisabled: c.options.isDisabled,
6850
+ className: partClass("date-range__trigger", className),
6851
+ "aria-labelledby": `${c.id}-label ${c.id}-value`,
6852
+ "aria-invalid": c.invalid || void 0,
6853
+ "aria-describedby": c.describedBy,
6854
+ children: children ?? /* @__PURE__ */ jsx(TemporalPickerValue, {})
6855
+ });
6856
+ }
6857
+ function TemporalPickerContent({ children, className, ...props }) {
6858
+ const c = usePicker();
6859
+ return /* @__PURE__ */ jsx("div", {
6860
+ ...props,
6861
+ className,
6862
+ children: children ?? c.panel
6863
+ });
6864
+ }
6865
+ function TemporalPickerPopover({ children, className, ...props }) {
6866
+ const c = usePicker();
6867
+ return /* @__PURE__ */ jsx(Popover$2, {
6868
+ className: partClass("date-range__panel temporal-picker__panel", className),
6869
+ placement: "bottom start",
6870
+ offset: 8,
6871
+ children: /* @__PURE__ */ jsx(Dialog$1, {
6872
+ "aria-labelledby": `${c.id}-label`,
6873
+ className: "date-range__dialog",
6874
+ children: /* @__PURE__ */ jsx("div", {
6875
+ ...props,
6876
+ children: children ?? c.panel
6877
+ })
6878
+ })
6879
+ });
6880
+ }
6881
+ function action(type) {
6882
+ return function PickerAction({ children, className, onClick, ...props }) {
6883
+ const c = usePicker();
6884
+ return /* @__PURE__ */ jsx("button", {
6885
+ type: "button",
6886
+ ...props,
6887
+ className: partClass(`button button--${type === "apply" ? "primary" : "ghost"} button--sm`, className),
6888
+ disabled: props.disabled || type !== "cancel" && (c.options.isDisabled || c.options.isReadOnly) || type === "apply" && !!c.error,
6889
+ onClick: (e) => {
6890
+ onClick?.(e);
6891
+ if (!e.defaultPrevented) c[type]();
6892
+ },
6893
+ children: children ?? labels(c.options.locale)[type]
6894
+ });
6895
+ };
6896
+ }
6897
+ var TemporalPickerApplyButton = /* @__PURE__ */ action("apply");
6898
+ var TemporalPickerCancelButton = /* @__PURE__ */ action("cancel");
6899
+ var TemporalPickerClearButton = /* @__PURE__ */ action("clear");
6900
+ function Root({ kind, range, ...props }) {
6901
+ const [local, setLocal] = useState(props.defaultValue ?? null);
6902
+ const committed = props.value === void 0 ? local : props.value;
6903
+ const [draft, setDraft] = useState(committed), [inputErrors, setInputErrors] = useState({}), [formError, setFormError] = useState(false), [mobile, setMobile] = useState(false);
6904
+ const id = useId(), trigger = useRef(null);
6905
+ const disclosure = useDisclosure(props.open, props.defaultOpen, props.onOpenChange);
6906
+ const l = labels(props.locale);
6907
+ const committedKey = JSON.stringify(committed), lastCommitted = useRef(committedKey);
6908
+ useEffect(() => {
6909
+ if (lastCommitted.current === committedKey) return;
6910
+ lastCommitted.current = committedKey;
6911
+ setDraft(committed);
6912
+ setInputErrors({});
6913
+ }, [committed, committedKey]);
6914
+ useEffect(() => {
6915
+ const media = window.matchMedia("(max-width: 640px)");
6916
+ const update = () => setMobile(media.matches);
6917
+ update();
6918
+ media.addEventListener("change", update);
6919
+ return () => media.removeEventListener("change", update);
6920
+ }, []);
6921
+ const constraints = {
6922
+ ...props,
6923
+ kind
6924
+ };
6925
+ const validate = (value) => range ? temporalRangeError(typeof value === "object" ? value : null, constraints) : temporalError(typeof value === "string" ? value : null, constraints);
6926
+ const code = Object.values(inputErrors).find(Boolean) ?? validate(draft);
6927
+ const error = code ? code in temporalMessages(props.locale) ? temporalMessages(props.locale)[code] : code : null;
6928
+ const committedError = validate(committed);
6929
+ const errorCallback = useRef(props.onError);
6930
+ useEffect(() => {
6931
+ errorCallback.current = props.onError;
6932
+ }, [props.onError]);
6933
+ useEffect(() => {
6934
+ errorCallback.current?.(error);
6935
+ }, [error]);
6936
+ function changeOpen(next) {
6937
+ if (props.isDisabled && next) return;
6938
+ setDraft(committed);
6939
+ setInputErrors({});
6940
+ disclosure.change(next);
6941
+ }
6942
+ function commit(value, close) {
6943
+ if (props.isDisabled || props.isReadOnly || validate(value)) return;
6944
+ setLocal(value);
6945
+ setFormError(false);
6946
+ props.onChange?.(value);
6947
+ if (close) {
6948
+ props.onApply?.(value);
6949
+ disclosure.change(false);
6950
+ }
6951
+ }
6952
+ function edit(value, part) {
6953
+ if (props.isDisabled || props.isReadOnly) return;
6954
+ setDraft(value);
6955
+ const remaining = part ? {
6956
+ ...inputErrors,
6957
+ [part]: null
6958
+ } : {};
6959
+ setInputErrors(remaining);
6960
+ if (props.commitMode === "immediate" && !Object.values(remaining).some(Boolean)) commit(value, false);
6961
+ }
6962
+ function clear() {
6963
+ if (props.isDisabled || props.isReadOnly) return;
6964
+ setDraft(null);
6965
+ setInputErrors({});
6966
+ if (props.commitMode === "immediate") {
6967
+ setLocal(null);
6968
+ props.onChange?.(null);
6969
+ }
6970
+ }
6971
+ const context = {
6972
+ options: props,
6973
+ kind,
6974
+ range,
6975
+ draft,
6976
+ error,
6977
+ id,
6978
+ invalid: props.isInvalid || !!committedError || formError,
6979
+ describedBy: [props.description ? `${id}-description` : void 0, props.isInvalid || committedError || formError ? `${id}-error` : void 0].filter(Boolean).join(" ") || void 0,
6980
+ text: displayText(committed, kind, props),
6981
+ edit,
6982
+ inputError: (part, error) => setInputErrors((current) => current[part] === error ? current : {
6983
+ ...current,
6984
+ [part]: error
6985
+ }),
6986
+ apply: () => {
6987
+ if (!error) commit(draft, true);
6988
+ },
6989
+ cancel: () => changeOpen(false),
6990
+ clear,
6991
+ panel: null
6992
+ };
6993
+ const current = kind === "date" ? today(props.timeZone ?? "UTC").toString() : kind === "time" ? now(props.timeZone ?? "UTC").toString().slice(11, props.granularity === "second" ? 19 : 16) : now(props.timeZone ?? "UTC").toString();
6994
+ const panel = /* @__PURE__ */ jsxs("div", {
6995
+ className: partClass("temporal-picker__content", props.classNames?.content),
6996
+ children: [
6997
+ /* @__PURE__ */ jsx("h2", {
6998
+ className: "temporal-picker__title",
6999
+ children: props.label
7000
+ }),
7001
+ !!props.presets?.length && /* @__PURE__ */ jsx("div", {
7002
+ className: "temporal-picker__presets",
7003
+ children: props.presets.map((p) => /* @__PURE__ */ jsx("button", {
7004
+ type: "button",
7005
+ className: partClass("date-range__preset", props.classNames?.preset),
7006
+ disabled: props.isDisabled || props.isReadOnly || !!validate(p.value),
7007
+ onClick: () => edit(p.value),
7008
+ children: p.label
7009
+ }, p.id))
7010
+ }),
7011
+ props.showInputs !== false && /* @__PURE__ */ jsxs("div", {
7012
+ className: "temporal-picker__fields",
7013
+ children: [/* @__PURE__ */ jsx(TemporalPickerField, {}), range && /* @__PURE__ */ jsx(TemporalPickerField, { part: "end" })]
7014
+ }),
7015
+ /* @__PURE__ */ jsxs("div", {
7016
+ className: "temporal-picker__views",
7017
+ children: [
7018
+ kind !== "time" && /* @__PURE__ */ jsx(TemporalPickerCalendar, { className: props.classNames?.calendar }),
7019
+ " ",
7020
+ kind !== "date" && /* @__PURE__ */ jsxs("div", {
7021
+ className: "temporal-picker__times",
7022
+ children: [/* @__PURE__ */ jsx(TemporalPickerTime, { className: props.classNames?.time }), range && /* @__PURE__ */ jsx(TemporalPickerTime, {
7023
+ part: "end",
7024
+ className: props.classNames?.time
7025
+ })]
7026
+ })
7027
+ ]
7028
+ }),
7029
+ error && /* @__PURE__ */ jsx("span", {
7030
+ className: "input__error",
7031
+ role: "alert",
7032
+ children: error
7033
+ }),
7034
+ /* @__PURE__ */ jsx("button", {
7035
+ type: "button",
7036
+ className: "button button--ghost button--sm",
7037
+ disabled: props.isDisabled || props.isReadOnly || !!temporalError(current, constraints),
7038
+ onClick: () => edit(range ? {
7039
+ start: current,
7040
+ end: current
7041
+ } : current),
7042
+ children: kind === "date" ? l.today : l.now
7043
+ }),
7044
+ props.showActions !== false && /* @__PURE__ */ jsxs("footer", {
7045
+ className: partClass("date-range__footer", props.classNames?.footer),
7046
+ children: [/* @__PURE__ */ jsx(TemporalPickerClearButton, { className: props.classNames?.clearButton }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(TemporalPickerCancelButton, { className: props.classNames?.cancelButton }), props.commitMode !== "immediate" && /* @__PURE__ */ jsx(TemporalPickerApplyButton, { className: props.classNames?.applyButton })] })]
7047
+ })
7048
+ ]
7049
+ });
7050
+ context.panel = panel;
7051
+ const dialog = props.display === "dialog" || props.display !== "inline" && props.display !== "popover" && mobile;
7052
+ return /* @__PURE__ */ jsx(PickerContext.Provider, {
7053
+ value: context,
7054
+ children: /* @__PURE__ */ jsxs("div", {
7055
+ className: partClass(partClass(`date-range temporal-picker date-range--${props.size ?? "md"}`, props.classNames?.root), props.className),
7056
+ style: props.style,
7057
+ dir: props.dir,
7058
+ children: [
7059
+ /* @__PURE__ */ jsx("span", {
7060
+ id: `${id}-label`,
7061
+ className: partClass(props.hideLabel ? "temporal__sr-only" : "date-range__label", props.classNames?.label),
7062
+ children: props.label
7063
+ }),
7064
+ props.display === "inline" ? /* @__PURE__ */ jsx("section", {
7065
+ className: partClass("date-range__panel date-range__inline", props.classNames?.panel),
7066
+ "aria-labelledby": `${id}-label`,
7067
+ children: props.children ?? panel
7068
+ }) : /* @__PURE__ */ jsx(DialogTrigger, {
7069
+ isOpen: disclosure.visible && !props.isDisabled,
7070
+ onOpenChange: changeOpen,
7071
+ children: props.children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button$1, {
7072
+ ref: trigger,
7073
+ className: partClass("date-range__trigger", props.classNames?.trigger),
7074
+ isDisabled: props.isDisabled,
7075
+ "aria-labelledby": `${id}-label ${id}-value`,
7076
+ "aria-invalid": context.invalid || void 0,
7077
+ "aria-describedby": context.describedBy,
7078
+ children: /* @__PURE__ */ jsx(TemporalPickerValue, { className: props.classNames?.value })
7079
+ }), dialog ? /* @__PURE__ */ jsx(ModalOverlay, {
7080
+ className: "temporal-picker__overlay",
7081
+ children: /* @__PURE__ */ jsx(Modal, {
7082
+ className: "date-range__panel temporal-picker__modal",
7083
+ children: /* @__PURE__ */ jsx(Dialog$1, {
7084
+ "aria-labelledby": `${id}-label`,
7085
+ children: panel
7086
+ })
7087
+ })
7088
+ }) : /* @__PURE__ */ jsx(TemporalPickerPopover, { className: props.classNames?.panel })] })
7089
+ }),
7090
+ props.description && /* @__PURE__ */ jsx("span", {
7091
+ id: `${id}-description`,
7092
+ className: partClass("input__description", props.classNames?.description),
7093
+ children: props.description
7094
+ }),
7095
+ (props.isInvalid || committedError || formError) && /* @__PURE__ */ jsx("span", {
7096
+ id: `${id}-error`,
7097
+ role: "alert",
7098
+ className: partClass("input__error", props.classNames?.error),
7099
+ children: props.errorMessage ?? temporalMessages(props.locale)[committedError ?? (props.isInvalid ? "invalid" : "required")]
7100
+ }),
7101
+ props.name && (range ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("input", {
7102
+ type: "hidden",
7103
+ name: `${props.name}.start`,
7104
+ value: typeof committed === "object" && committed ? committed.start : "",
7105
+ disabled: props.isDisabled
7106
+ }), /* @__PURE__ */ jsx("input", {
7107
+ type: "hidden",
7108
+ name: `${props.name}.end`,
7109
+ value: typeof committed === "object" && committed ? committed.end : "",
7110
+ disabled: props.isDisabled
7111
+ })] }) : /* @__PURE__ */ jsx("input", {
7112
+ type: "hidden",
7113
+ name: props.name,
7114
+ value: typeof committed === "string" ? committed : "",
7115
+ disabled: props.isDisabled
7116
+ })),
7117
+ /* @__PURE__ */ jsx(SelectionValidation, {
7118
+ hasValue: !!committed && !committedError,
7119
+ required: props.isRequired || !!committedError,
7120
+ disabled: props.isDisabled,
7121
+ onInvalid: () => {
7122
+ setFormError(true);
7123
+ trigger.current?.focus();
7124
+ },
7125
+ onResetStart: () => {},
7126
+ onReset: (cancelled) => {
7127
+ if (!cancelled) {
7128
+ if (props.value === void 0) setLocal(props.defaultValue ?? null);
7129
+ setDraft(props.value === void 0 ? props.defaultValue ?? null : committed);
7130
+ setInputErrors({});
7131
+ setFormError(false);
7132
+ disclosure.change(false);
7133
+ }
7134
+ }
7135
+ })
7136
+ ]
7137
+ })
7138
+ });
7139
+ }
7140
+ function picker(kind, range) {
7141
+ const Component = (props) => /* @__PURE__ */ jsx(Root, {
7142
+ ...props,
7143
+ kind,
7144
+ range
7145
+ });
7146
+ return Object.assign(Component, {
7147
+ Root: Component,
7148
+ Trigger: TemporalPickerTrigger,
7149
+ Value: TemporalPickerValue,
7150
+ Popover: TemporalPickerPopover,
7151
+ Content: TemporalPickerContent,
7152
+ Field: TemporalPickerField,
7153
+ Calendar: TemporalPickerCalendar,
7154
+ Time: TemporalPickerTime,
7155
+ MonthPicker,
7156
+ YearPicker,
7157
+ ApplyButton: TemporalPickerApplyButton,
7158
+ CancelButton: TemporalPickerCancelButton,
7159
+ ClearButton: TemporalPickerClearButton
7160
+ });
7161
+ }
7162
+ var DatePicker = /* @__PURE__ */ picker("date", false);
7163
+ var TimePicker = /* @__PURE__ */ picker("time", false);
7164
+ var TimeRangePicker = /* @__PURE__ */ picker("time", true);
7165
+ var DateTimePicker = /* @__PURE__ */ picker("datetime", false);
7166
+ var DateTimeRangePicker = /* @__PURE__ */ picker("datetime", true);
7167
+ //#endregion
7168
+ export { Alert, AlertActions, AlertContent, AlertDescription, AlertIndicator, AlertTitle, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarGroupRoot, AvatarImage, AvatarRoot, Badge, Breadcrumb, BreadcrumbCurrent, BreadcrumbItemPart, BreadcrumbLink, BreadcrumbList, BreadcrumbRoot, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, Calendar, Card, CardActions, CardContent, CardDescription, CardFooter, CardHeader, CardHeading, CardRoot, CardTitle, CardTitleRow, Chart, ChartDescription, ChartPlot, ChartRoot, ChartTitle, Checkbox, Combobox, DataTable, DataTableColumn as DataTableColumnPart, DataTableEmpty, DataTableError, DataTableRoot, DataTableSortButton, DataTableStatus, DateField, DatePicker, DateRangeField, DateRangePicker, DateTimeField, DateTimePicker, DateTimeRangeField, DateTimeRangePicker, Description, Dialog, DialogBackdrop as DialogBackdropPart, DialogCloseButton, DialogContent, DialogPanel, DialogRoot, DialogTriggerPart, DropdownHeading, DropdownItem, DropdownItemIndicator, DropdownList, DropdownMenu, DropdownPopover, DropdownRoot, DropdownSection, DropdownSeparator, DropdownSubmenuIndicator, DropdownSubmenuTrigger, DropdownTrigger, Empty, EmptyActions, EmptyDescription, EmptyRoot, EmptyTitle, Field, FieldError, Form, Header, Input, InputClearButton, Label, ListBox, Listbox, MonthPicker, MonthYearNavigation, NumberField, OverlayBody, OverlayDescription, OverlayFooter, OverlayHeader, OverlayHeading, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPageButton, PaginationPrevious, PaginationRoot, PaginationSummary, Popover, PopoverCloseButton, PopoverContent, PopoverDialog, PopoverTrigger, RadioGroup, RangeCalendar, Select, SelectGroup, Separator, Sidebar, SidebarHeader, SidebarItem, SidebarLink, SidebarList, SidebarNavigation, SidebarRoot, SidebarTitle, SidebarToggle, Skeleton, Spinner, Switch, SwitchGroup, Table, TableBody, TableCaption, TableCell, TableColumn, TableFooter, TableHeader, TableRoot, TableRow, TableScrollContainer, Tabs, TabsIndicator, TabsList, TabsListContainer, TabsPanel, TabsRoot, TabsSeparator, TabsTab, Textarea, TimeClock, TimeField, TimeList, TimePicker, TimeRangeField, TimeRangePicker, Toast, ToastActionButton, ToastActions, ToastBody, ToastCloseButton, ToastDescription, ToastIndicator, ToastProgress, ToastProvider, ToastRoot, ToastTitle, ToggleButton, ToggleButtonGroup, ToggleGroup, Tooltip, TooltipContent, TooltipRoot, TooltipTriggerPart, YearPicker, createDateRangePresets, createToastManager, rangeText as formatDateRange, useToast };
5276
7169
 
5277
7170
  //# sourceMappingURL=index.js.map