@takeoff-ui/react-spar 0.4.0 → 0.5.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.cjs CHANGED
@@ -8,6 +8,10 @@ var chevronBottom = require('@takeoff-icons/react/chevron-bottom');
8
8
  var chevronTop = require('@takeoff-icons/react/chevron-top');
9
9
  var close = require('@takeoff-icons/react/close');
10
10
  var chevronRight = require('@takeoff-icons/react/chevron-right');
11
+ var chevronLeft = require('@takeoff-icons/react/chevron-left');
12
+ var doubleChevronLeft = require('@takeoff-icons/react/double-chevron-left');
13
+ var doubleChevronRight = require('@takeoff-icons/react/double-chevron-right');
14
+ var reactDayPicker = require('react-day-picker');
11
15
  var check = require('@takeoff-icons/react/check');
12
16
  var remove = require('@takeoff-icons/react/remove');
13
17
  var info = require('@takeoff-icons/react/info');
@@ -19,9 +23,6 @@ var arrowBottom = require('@takeoff-icons/react/arrow-bottom');
19
23
  var arrowTop = require('@takeoff-icons/react/arrow-top');
20
24
  var swap = require('@takeoff-icons/react/swap');
21
25
  var search = require('@takeoff-icons/react/search');
22
- var chevronLeft = require('@takeoff-icons/react/chevron-left');
23
- var doubleChevronLeft = require('@takeoff-icons/react/double-chevron-left');
24
- var doubleChevronRight = require('@takeoff-icons/react/double-chevron-right');
25
26
  var arrowDownload = require('@takeoff-icons/react/arrow-download');
26
27
  var checkCircle = require('@takeoff-icons/react/check-circle');
27
28
  var closeCircle = require('@takeoff-icons/react/close-circle');
@@ -258,6 +259,78 @@ function useControllableState(controlledValue, defaultValue, onChange) {
258
259
  );
259
260
  return [value, setValue, isControlled];
260
261
  }
262
+ var pad = (value) => String(value).padStart(2, "0");
263
+ var toISODate = (value) => `${value.getFullYear()}-${pad(value.getMonth() + 1)}-${pad(value.getDate())}`;
264
+ var fromISODate = (iso) => {
265
+ const [year, month, day] = iso.split("-").map(Number);
266
+ if (!year || !month || !day) return void 0;
267
+ return new Date(year, month - 1, day);
268
+ };
269
+ function useDatePicker({ min, max, defaultValue, delimiter = "/", format, onValueChange } = {}) {
270
+ const formatDate = react.useMemo(
271
+ () => format ?? ((value2) => `${pad(value2.getDate())}${delimiter}${pad(value2.getMonth() + 1)}${delimiter}${value2.getFullYear()}`),
272
+ [format, delimiter]
273
+ );
274
+ const [value, setValueState] = react.useState(defaultValue);
275
+ const [text, setText] = react.useState(() => defaultValue ? formatDate(defaultValue) : "");
276
+ const [open, setOpen] = react.useState(false);
277
+ const mask = react.useMemo(
278
+ () => ({
279
+ date: true,
280
+ delimiter,
281
+ ...min ? { dateMin: toISODate(min) } : {},
282
+ ...max ? { dateMax: toISODate(max) } : {}
283
+ }),
284
+ [delimiter, min, max]
285
+ );
286
+ const commit = react.useCallback(
287
+ (next) => {
288
+ setValueState(next);
289
+ setText(next ? formatDate(next) : "");
290
+ onValueChange?.(next);
291
+ },
292
+ [formatDate, onValueChange]
293
+ );
294
+ const handleTyped = react.useCallback(
295
+ (next, meta) => {
296
+ setText(next);
297
+ if (next === "") {
298
+ setValueState(void 0);
299
+ onValueChange?.(void 0);
300
+ return;
301
+ }
302
+ if (!meta.completed || !meta.iso) {
303
+ setValueState(void 0);
304
+ return;
305
+ }
306
+ const parsed = fromISODate(meta.iso);
307
+ setValueState(parsed);
308
+ onValueChange?.(parsed);
309
+ },
310
+ [onValueChange]
311
+ );
312
+ const handleKeyDown = react.useCallback((event) => {
313
+ if (event.key !== "ArrowDown") return;
314
+ event.preventDefault();
315
+ setOpen(true);
316
+ }, []);
317
+ const handlePicked = react.useCallback(
318
+ (next) => {
319
+ commit(next);
320
+ setOpen(false);
321
+ },
322
+ [commit]
323
+ );
324
+ return {
325
+ value,
326
+ text,
327
+ open,
328
+ setValue: commit,
329
+ popoverProps: { open, onOpenChange: setOpen },
330
+ inputProps: { mask, value: text, onValueChange: handleTyped, onKeyDown: handleKeyDown },
331
+ calendarProps: { value, minDate: min, maxDate: max, onValueChange: handlePicked }
332
+ };
333
+ }
261
334
 
262
335
  // src/components/accordion/context.ts
263
336
  var [AccordionProvider, useAccordionOwnContext] = createSafeContext("AccordionProvider");
@@ -719,6 +792,650 @@ var Button = (props) => {
719
792
  };
720
793
  Button.displayName = "Button";
721
794
 
795
+ // src/components/calendar/base.ts
796
+ var CalendarBase = createComponentBase({
797
+ name: "Calendar",
798
+ slots: [
799
+ "root",
800
+ "months",
801
+ "month",
802
+ "nav",
803
+ "previousMonthButton",
804
+ "nextMonthButton",
805
+ "previousYearButton",
806
+ "nextYearButton",
807
+ "chevron",
808
+ "monthCaption",
809
+ "captionLabel",
810
+ "captionTrigger",
811
+ "dropdowns",
812
+ "dropdownRoot",
813
+ "dropdown",
814
+ "monthGrid",
815
+ "monthYearGrid",
816
+ "monthYearCell",
817
+ "weekdays",
818
+ "weekday",
819
+ "weeks",
820
+ "week",
821
+ "weekNumber",
822
+ "weekNumberHeader",
823
+ "day",
824
+ "dayButton",
825
+ "footer"
826
+ ],
827
+ classes: {
828
+ root: "tk-calendar",
829
+ months: "tk-calendar-months",
830
+ month: "tk-calendar-month",
831
+ nav: "tk-calendar-nav",
832
+ previousMonthButton: "tk-calendar-nav-previous-month",
833
+ nextMonthButton: "tk-calendar-nav-next-month",
834
+ previousYearButton: "tk-calendar-nav-previous-year",
835
+ nextYearButton: "tk-calendar-nav-next-year",
836
+ chevron: "tk-calendar-chevron",
837
+ monthCaption: "tk-calendar-month-caption",
838
+ captionLabel: "tk-calendar-caption-label",
839
+ captionTrigger: "tk-calendar-caption-trigger",
840
+ dropdowns: "tk-calendar-dropdowns",
841
+ dropdownRoot: "tk-calendar-dropdown-root",
842
+ dropdown: "tk-calendar-dropdown",
843
+ monthGrid: "tk-calendar-month-grid",
844
+ monthYearGrid: "tk-calendar-month-year-grid",
845
+ monthYearCell: "tk-calendar-month-year-cell",
846
+ weekdays: "tk-calendar-weekdays",
847
+ weekday: "tk-calendar-weekday",
848
+ weeks: "tk-calendar-weeks",
849
+ week: "tk-calendar-week",
850
+ weekNumber: "tk-calendar-week-number",
851
+ weekNumberHeader: "tk-calendar-week-number-header",
852
+ day: "tk-calendar-day",
853
+ dayButton: "tk-calendar-day-button",
854
+ footer: "tk-calendar-footer"
855
+ }
856
+ });
857
+ var calendarRangeClassNames = {
858
+ range_start: "tk-calendar-day-range-start",
859
+ range_middle: "tk-calendar-day-range-middle",
860
+ range_end: "tk-calendar-day-range-end"
861
+ };
862
+
863
+ // src/components/calendar/defaults.ts
864
+ var DEFAULT_MODE2 = "single";
865
+ var DEFAULT_SIZE5 = "base";
866
+ var DEFAULT_HEADER_TYPE = "basic";
867
+ var DEFAULT_VIEW = "day";
868
+
869
+ // src/components/calendar/helpers.ts
870
+ var isSameCalendarDay = (left, right) => left.getFullYear() === right.getFullYear() && left.getMonth() === right.getMonth() && left.getDate() === right.getDate();
871
+ var isSameCalendarMonth = (left, right) => left.getFullYear() === right.getFullYear() && left.getMonth() === right.getMonth();
872
+ var selectionAnchor = (value) => {
873
+ if (!value) return void 0;
874
+ if (value instanceof Date) return value;
875
+ if (Array.isArray(value)) return value.length ? value[value.length - 1] : void 0;
876
+ return value.from;
877
+ };
878
+ var buildDisabledMatchers = ({ minDate, maxDate, disabledDates, allowedDates, disabledWeekDays }) => {
879
+ const matchers = [];
880
+ if (minDate) matchers.push({ before: minDate });
881
+ if (maxDate) matchers.push({ after: maxDate });
882
+ if (disabledDates?.length) matchers.push(disabledDates);
883
+ if (disabledWeekDays?.length) matchers.push({ dayOfWeek: disabledWeekDays });
884
+ if (allowedDates?.length) {
885
+ const allowed = allowedDates;
886
+ matchers.push((date) => !allowed.some((candidate) => isSameCalendarDay(candidate, date)));
887
+ }
888
+ return matchers.length ? matchers : void 0;
889
+ };
890
+ var assignRef = (ref, node) => {
891
+ if (typeof ref === "function") {
892
+ ref(node);
893
+ } else if (ref) {
894
+ ref.current = node;
895
+ }
896
+ };
897
+ var YEARS_PER_PAGE = 12;
898
+ var yearPageStart = (year) => Math.floor(year / YEARS_PER_PAGE) * YEARS_PER_PAGE;
899
+ var isMonthInBounds = (year, month, minDate, maxDate) => {
900
+ if (minDate && new Date(year, month + 1, 0, 23, 59, 59, 999) < minDate) return false;
901
+ if (maxDate && new Date(year, month, 1) > maxDate) return false;
902
+ return true;
903
+ };
904
+ var isYearInBounds = (year, minDate, maxDate) => {
905
+ if (minDate && year < minDate.getFullYear()) return false;
906
+ if (maxDate && year > maxDate.getFullYear()) return false;
907
+ return true;
908
+ };
909
+ var isYearPageInBounds = (year, minDate, maxDate) => {
910
+ const start = yearPageStart(year);
911
+ return isYearInBounds(start + YEARS_PER_PAGE - 1, minDate, void 0) && isYearInBounds(start, void 0, maxDate);
912
+ };
913
+ var SLOT_TO_UI = {
914
+ root: reactDayPicker.UI.Root,
915
+ months: reactDayPicker.UI.Months,
916
+ month: reactDayPicker.UI.Month,
917
+ nav: reactDayPicker.UI.Nav,
918
+ previousMonthButton: reactDayPicker.UI.PreviousMonthButton,
919
+ nextMonthButton: reactDayPicker.UI.NextMonthButton,
920
+ chevron: reactDayPicker.UI.Chevron,
921
+ monthCaption: reactDayPicker.UI.MonthCaption,
922
+ captionLabel: reactDayPicker.UI.CaptionLabel,
923
+ dropdowns: reactDayPicker.UI.Dropdowns,
924
+ dropdownRoot: reactDayPicker.UI.DropdownRoot,
925
+ dropdown: reactDayPicker.UI.Dropdown,
926
+ monthGrid: reactDayPicker.UI.MonthGrid,
927
+ weekdays: reactDayPicker.UI.Weekdays,
928
+ weekday: reactDayPicker.UI.Weekday,
929
+ weeks: reactDayPicker.UI.Weeks,
930
+ week: reactDayPicker.UI.Week,
931
+ weekNumber: reactDayPicker.UI.WeekNumber,
932
+ weekNumberHeader: reactDayPicker.UI.WeekNumberHeader,
933
+ day: reactDayPicker.UI.Day,
934
+ dayButton: reactDayPicker.UI.DayButton,
935
+ footer: reactDayPicker.UI.Footer
936
+ };
937
+ var ENGINE_CLASSNAME_RESET = Object.fromEntries(
938
+ [...Object.values(reactDayPicker.UI), ...Object.values(reactDayPicker.DayFlag), ...Object.values(reactDayPicker.SelectionState), ...Object.values(reactDayPicker.Animation)].map((key) => [key, ""])
939
+ );
940
+ var mergeSlotAttrs = (slotAttrs, engineProps) => {
941
+ const merged = { ...slotAttrs };
942
+ for (const key in engineProps) {
943
+ const value = engineProps[key];
944
+ if (value !== void 0) merged[key] = value;
945
+ }
946
+ return merged;
947
+ };
948
+ var CaptionMonthContext = react.createContext(null);
949
+ var PANEL_COLUMNS = 4;
950
+ var visuallyHidden = {
951
+ position: "absolute",
952
+ width: 1,
953
+ height: 1,
954
+ margin: -1,
955
+ padding: 0,
956
+ overflow: "hidden",
957
+ clip: "rect(0 0 0 0)",
958
+ whiteSpace: "nowrap",
959
+ border: 0
960
+ };
961
+ var displayContents = { display: "contents" };
962
+ var createEngineComponents = (attrsRef, refRef, viewRef, renderDayRef) => {
963
+ const withSlot = (Component, slot) => {
964
+ const Slotted = (props) => /* @__PURE__ */ jsxRuntime.jsx(Component, { ...mergeSlotAttrs(attrsRef.current[slot], props) });
965
+ Slotted.displayName = `Calendar.${slot}`;
966
+ return Slotted;
967
+ };
968
+ const Root = ({ rootRef, ...engineProps }) => /* @__PURE__ */ jsxRuntime.jsx(
969
+ "div",
970
+ {
971
+ ...mergeSlotAttrs(attrsRef.current.root, engineProps),
972
+ ref: (node) => {
973
+ assignRef(refRef.current, node);
974
+ assignRef(rootRef, node);
975
+ }
976
+ }
977
+ );
978
+ Root.displayName = "Calendar.root";
979
+ const Chevron = ({ orientation = "left", size, ...engineProps }) => {
980
+ const Icon = orientation === "left" ? chevronLeft.ChevronLeftIconOutlinedRounded : orientation === "right" ? chevronRight.ChevronRightIconOutlinedRounded : orientation === "up" ? chevronTop.ChevronTopIconOutlinedRounded : chevronBottom.ChevronBottomIconOutlinedRounded;
981
+ const { disabled: _disabled, ...svgProps } = engineProps;
982
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon, { "aria-hidden": "true", ...mergeSlotAttrs(attrsRef.current.chevron, { ...svgProps, width: size, height: size }) });
983
+ };
984
+ Chevron.displayName = "Calendar.chevron";
985
+ const useDisplayedMonth = () => {
986
+ const { months, dayPickerProps } = reactDayPicker.useDayPicker();
987
+ const first = dayPickerProps.reverseMonths ? months[months.length - 1] : months[0];
988
+ return first?.date ?? /* @__PURE__ */ new Date();
989
+ };
990
+ const useDateLib = () => {
991
+ const { locale, timeZone, numerals, dateLib } = reactDayPicker.useDayPicker().dayPickerProps;
992
+ return react.useMemo(
993
+ // The same merge the engine makes, so a partial `locale` still resolves
994
+ // against `en-US` rather than leaving fields undefined.
995
+ () => new reactDayPicker.DateLib({ locale: { ...reactDayPicker.defaultLocale, ...locale }, timeZone, numerals }, dateLib),
996
+ [locale, timeZone, numerals, dateLib]
997
+ );
998
+ };
999
+ const MonthCaption = ({ calendarMonth, displayIndex, ...engineProps }) => /* @__PURE__ */ jsxRuntime.jsx(CaptionMonthContext.Provider, { value: calendarMonth.date, children: /* @__PURE__ */ jsxRuntime.jsx(
1000
+ reactDayPicker.MonthCaption,
1001
+ {
1002
+ calendarMonth,
1003
+ displayIndex,
1004
+ ...mergeSlotAttrs(attrsRef.current.monthCaption, engineProps)
1005
+ }
1006
+ ) });
1007
+ MonthCaption.displayName = "Calendar.monthCaption";
1008
+ const CaptionLabel = ({ children, ...engineProps }) => {
1009
+ const { triggersEnabled, view, setView, navigationDisabled, panelId, pendingFocusRef, restoreRef } = viewRef.current;
1010
+ const { formatters, labels } = reactDayPicker.useDayPicker();
1011
+ const caption = react.useContext(CaptionMonthContext);
1012
+ const anchor = useDisplayedMonth();
1013
+ const dateLib = useDateLib();
1014
+ const displayed = caption ?? anchor;
1015
+ const slotProps = mergeSlotAttrs(attrsRef.current.captionLabel, engineProps);
1016
+ if (!triggersEnabled || displayed.getTime() !== anchor.getTime())
1017
+ return /* @__PURE__ */ jsxRuntime.jsx(reactDayPicker.CaptionLabel, { ...slotProps, children });
1018
+ const trigger = (target, label, describe) => {
1019
+ const opens = view !== target;
1020
+ const disabled = navigationDisabled && opens;
1021
+ return /* @__PURE__ */ jsxRuntime.jsx(
1022
+ "button",
1023
+ {
1024
+ type: "button",
1025
+ ...mergeSlotAttrs(attrsRef.current.captionTrigger, {
1026
+ "data-view": target,
1027
+ // The engine's own label, so `labels` translates the panel too; a
1028
+ // per-instance override still wins through `slotProps`.
1029
+ "aria-label": attrsRef.current.captionTrigger["aria-label"] ?? `${label}, ${describe}`,
1030
+ "aria-expanded": view === target,
1031
+ "aria-controls": view === target ? panelId : void 0,
1032
+ "aria-disabled": disabled || void 0,
1033
+ "onClick": (event) => {
1034
+ if (disabled) return;
1035
+ const next = opens ? target : "day";
1036
+ restoreRef.current = next === "day" ? null : event.currentTarget;
1037
+ pendingFocusRef.current = next !== "day";
1038
+ setView(next);
1039
+ }
1040
+ }),
1041
+ children: label
1042
+ }
1043
+ );
1044
+ };
1045
+ const monthLabel = formatters.formatMonthDropdown(displayed, dateLib);
1046
+ const yearLabel = formatters.formatYearDropdown(displayed, dateLib);
1047
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1048
+ reactDayPicker.CaptionLabel,
1049
+ {
1050
+ ...slotProps,
1051
+ role: void 0,
1052
+ "aria-live": void 0,
1053
+ children: [
1054
+ trigger("month", monthLabel, labels.labelMonthDropdown()),
1055
+ trigger("year", yearLabel, labels.labelYearDropdown()),
1056
+ /* @__PURE__ */ jsxRuntime.jsx("span", { role: "status", "aria-live": "polite", style: visuallyHidden, children: view === "day" ? `${monthLabel} ${yearLabel}` : view === "month" ? labels.labelMonthDropdown() : labels.labelYearDropdown() })
1057
+ ]
1058
+ }
1059
+ );
1060
+ };
1061
+ CaptionLabel.displayName = "Calendar.captionLabel";
1062
+ const MonthGrid = ({ children, ...engineProps }) => {
1063
+ const { view, setView, navigationDisabled, minDate, maxDate, panelId, panelRef, pendingFocusRef, restoreRef } = viewRef.current;
1064
+ const { dayPickerProps, formatters, goToMonth, labels } = reactDayPicker.useDayPicker();
1065
+ const displayed = useDisplayedMonth();
1066
+ const dateLib = useDateLib();
1067
+ react.useEffect(() => {
1068
+ if (view === "day" || !pendingFocusRef.current) return;
1069
+ pendingFocusRef.current = false;
1070
+ panelRef.current?.querySelector('[role="gridcell"][tabindex="0"]')?.focus();
1071
+ }, [view, panelRef, pendingFocusRef]);
1072
+ if (view === "day") {
1073
+ return /* @__PURE__ */ jsxRuntime.jsx(reactDayPicker.MonthGrid, { ...mergeSlotAttrs(attrsRef.current.monthGrid, { ...engineProps, children }) });
1074
+ }
1075
+ const year = displayed.getFullYear();
1076
+ const pageStart = yearPageStart(year);
1077
+ const restoreFocus = () => {
1078
+ const trigger = panelRef.current?.closest('[data-slot="root"]')?.querySelector(`[data-slot="caption-trigger"][data-view="${view}"]`);
1079
+ (restoreRef.current ?? trigger)?.focus();
1080
+ };
1081
+ const items = view === "month" ? Array.from({ length: 12 }, (_, month) => {
1082
+ const date = new Date(year, month, 1);
1083
+ return {
1084
+ key: String(month),
1085
+ // No engine formatter abbreviates a month — the dropdown spells
1086
+ // it out — so this is the one label built from a pattern; the
1087
+ // date library is still the engine's, so locale and numerals
1088
+ // hold.
1089
+ label: dateLib.format(date, "LLL"),
1090
+ name: formatters.formatCaption(date, dateLib.options, dateLib),
1091
+ current: displayed.getMonth() === month,
1092
+ // Picking a cell is navigation, so `disableNavigation` takes the
1093
+ // whole board down with the arrows — `goToMonth` would no-op and
1094
+ // leave an enabled-looking cell that does nothing.
1095
+ enabled: !navigationDisabled && isMonthInBounds(year, month, minDate, maxDate),
1096
+ select: () => {
1097
+ goToMonth(date);
1098
+ setView("day");
1099
+ restoreFocus();
1100
+ }
1101
+ };
1102
+ }) : Array.from({ length: YEARS_PER_PAGE }, (_, offset) => {
1103
+ const candidate = pageStart + offset;
1104
+ const label2 = formatters.formatYearDropdown(new Date(candidate, 0, 1), dateLib);
1105
+ return {
1106
+ key: String(candidate),
1107
+ label: label2,
1108
+ name: label2,
1109
+ current: candidate === year,
1110
+ enabled: !navigationDisabled && isYearInBounds(candidate, minDate, maxDate),
1111
+ select: () => {
1112
+ goToMonth(new Date(candidate, displayed.getMonth(), 1));
1113
+ restoreRef.current = null;
1114
+ pendingFocusRef.current = true;
1115
+ setView("month");
1116
+ }
1117
+ };
1118
+ });
1119
+ const seek = (start, delta, min = 0, max = items.length - 1) => {
1120
+ for (let index = start; index >= min && index <= max; index += delta) if (items[index]?.enabled) return index;
1121
+ return void 0;
1122
+ };
1123
+ const current = items.findIndex((item) => item.current && item.enabled);
1124
+ const activeIndex = current >= 0 ? current : seek(0, 1) ?? -1;
1125
+ const inline = dayPickerProps.dir === "rtl" ? -1 : 1;
1126
+ const move = (event, from) => {
1127
+ const step = { ArrowLeft: -inline, ArrowRight: inline, ArrowUp: -PANEL_COLUMNS, ArrowDown: PANEL_COLUMNS }[event.key];
1128
+ const rowStart = from - from % PANEL_COLUMNS;
1129
+ const rowEnd = rowStart + PANEL_COLUMNS - 1;
1130
+ let next;
1131
+ if (step !== void 0) next = seek(from + step, step);
1132
+ else if (event.key === "Home") next = seek(rowStart, 1, rowStart, rowEnd);
1133
+ else if (event.key === "End") next = seek(rowEnd, -1, rowStart, rowEnd);
1134
+ if (next === void 0) return;
1135
+ event.preventDefault();
1136
+ const cells = event.currentTarget.querySelectorAll('[role="gridcell"]');
1137
+ cells[next]?.focus();
1138
+ };
1139
+ const label = view === "month" ? `${labels.labelMonthDropdown()}, ${formatters.formatYearDropdown(displayed, dateLib)}` : `${labels.labelYearDropdown()}, ${dateLib.formatNumber(pageStart)}\u2013${dateLib.formatNumber(pageStart + YEARS_PER_PAGE - 1)}`;
1140
+ return /* @__PURE__ */ jsxRuntime.jsx(
1141
+ "div",
1142
+ {
1143
+ ...mergeSlotAttrs(attrsRef.current.monthYearGrid, {
1144
+ "id": panelId,
1145
+ "role": "grid",
1146
+ "aria-label": attrsRef.current.monthYearGrid["aria-label"] ?? label,
1147
+ "data-view": view,
1148
+ "ref": panelRef,
1149
+ "onKeyDown": (event) => {
1150
+ if (event.key === "Escape") {
1151
+ event.stopPropagation();
1152
+ setView("day");
1153
+ restoreFocus();
1154
+ return;
1155
+ }
1156
+ const cells = [...event.currentTarget.querySelectorAll('[role="gridcell"]')];
1157
+ const from = cells.indexOf(event.target);
1158
+ if (from >= 0) move(event, from);
1159
+ }
1160
+ }),
1161
+ children: Array.from({ length: items.length / PANEL_COLUMNS }, (_, row) => /* @__PURE__ */ jsxRuntime.jsx("div", { role: "row", style: displayContents, children: items.slice(row * PANEL_COLUMNS, row * PANEL_COLUMNS + PANEL_COLUMNS).map((item, column) => {
1162
+ const index = row * PANEL_COLUMNS + column;
1163
+ return /* @__PURE__ */ jsxRuntime.jsx(
1164
+ "button",
1165
+ {
1166
+ type: "button",
1167
+ disabled: !item.enabled,
1168
+ ...mergeSlotAttrs(attrsRef.current.monthYearCell, {
1169
+ "role": "gridcell",
1170
+ "aria-label": item.name,
1171
+ "aria-selected": item.current,
1172
+ "data-selected": item.current || void 0,
1173
+ "data-disabled": item.enabled ? void 0 : true,
1174
+ "tabIndex": index === activeIndex ? 0 : -1,
1175
+ "onClick": item.select
1176
+ }),
1177
+ children: item.label
1178
+ },
1179
+ item.key
1180
+ );
1181
+ }) }, row))
1182
+ }
1183
+ );
1184
+ };
1185
+ MonthGrid.displayName = "Calendar.monthGrid";
1186
+ const aroundArrow = (slot) => {
1187
+ const Engine = slot === "previousMonthButton" ? reactDayPicker.PreviousMonthButton : reactDayPicker.NextMonthButton;
1188
+ const Arrow = ({ children, ...engineProps }) => {
1189
+ const { view, navigationDisabled, minDate, maxDate } = viewRef.current;
1190
+ const { formatters, goToMonth } = reactDayPicker.useDayPicker();
1191
+ const displayed = useDisplayedMonth();
1192
+ const dateLib = useDateLib();
1193
+ const slotProps = mergeSlotAttrs(attrsRef.current[slot], engineProps);
1194
+ if (view !== "year") return /* @__PURE__ */ jsxRuntime.jsx(Engine, { ...slotProps, children });
1195
+ const target = new Date(displayed.getFullYear() + (slot === "previousMonthButton" ? -1 : 1), displayed.getMonth(), 1);
1196
+ const disabled = navigationDisabled || !isYearInBounds(target.getFullYear(), minDate, maxDate);
1197
+ return /* @__PURE__ */ jsxRuntime.jsx(
1198
+ Engine,
1199
+ {
1200
+ ...slotProps,
1201
+ "aria-label": formatters.formatYearDropdown(target, dateLib),
1202
+ "aria-disabled": disabled || void 0,
1203
+ tabIndex: disabled ? -1 : void 0,
1204
+ onClick: () => {
1205
+ if (!disabled) goToMonth(target);
1206
+ },
1207
+ children
1208
+ }
1209
+ );
1210
+ };
1211
+ Arrow.displayName = `Calendar.${slot}`;
1212
+ return Arrow;
1213
+ };
1214
+ const Nav = (engineProps) => {
1215
+ const { triggersEnabled, view, navigationDisabled, minDate, maxDate } = viewRef.current;
1216
+ const { classNames: engineClassNames, components, formatters, goToMonth, labels } = reactDayPicker.useDayPicker();
1217
+ const displayed = useDisplayedMonth();
1218
+ const dateLib = useDateLib();
1219
+ const slotProps = mergeSlotAttrs(attrsRef.current.nav, engineProps);
1220
+ const { onPreviousClick, onNextClick, previousMonth, nextMonth, ...navAttrs } = slotProps;
1221
+ const singleStep = view === "year" ? 12 : 1;
1222
+ const doubleStep = view === "year" ? YEARS_PER_PAGE * 12 : 12;
1223
+ const singleGrain = view === "year" ? "year" : "month";
1224
+ const doubleGrain = view === "year" ? "page" : "year";
1225
+ const shift = (months) => new Date(displayed.getFullYear(), displayed.getMonth() + months, 1);
1226
+ const reachable = (target, grain) => grain === "month" ? isMonthInBounds(target.getFullYear(), target.getMonth(), minDate, maxDate) : grain === "year" ? isYearInBounds(target.getFullYear(), minDate, maxDate) : isYearPageInBounds(target.getFullYear(), minDate, maxDate);
1227
+ const formatYear = (target) => formatters.formatYearDropdown(target, dateLib);
1228
+ const formatPage = (target) => {
1229
+ const start = yearPageStart(target.getFullYear());
1230
+ return `${dateLib.formatNumber(start)}\u2013${dateLib.formatNumber(start + YEARS_PER_PAGE - 1)}`;
1231
+ };
1232
+ const arrowLabel = (grain, target, previous) => grain === "month" ? previous ? labels.labelPrevious(target) : labels.labelNext(target) : grain === "year" ? formatYear(target) : formatPage(target);
1233
+ const arrow = (slot, months, grain, icon) => {
1234
+ const target = shift(months);
1235
+ const label = arrowLabel(grain, target, months < 0);
1236
+ const engineOwned = slot === "previousMonthButton" || slot === "nextMonthButton";
1237
+ const delegated = engineOwned && view === "day";
1238
+ const disabled = navigationDisabled || (delegated ? !(months < 0 ? previousMonth : nextMonth) : !reachable(target, grain));
1239
+ const Button2 = slot.startsWith("previous") ? reactDayPicker.PreviousMonthButton : reactDayPicker.NextMonthButton;
1240
+ return /* @__PURE__ */ jsxRuntime.jsx(
1241
+ Button2,
1242
+ {
1243
+ type: "button",
1244
+ ...mergeSlotAttrs(attrsRef.current[slot], {
1245
+ "className": engineOwned ? engineClassNames[slot === "previousMonthButton" ? reactDayPicker.UI.PreviousMonthButton : reactDayPicker.UI.NextMonthButton] : void 0,
1246
+ "aria-label": label,
1247
+ "aria-disabled": disabled || void 0,
1248
+ "tabIndex": disabled ? -1 : void 0,
1249
+ "onClick": (event) => {
1250
+ if (disabled) return;
1251
+ if (delegated) return months < 0 ? onPreviousClick?.(event) : onNextClick?.(event);
1252
+ goToMonth(target);
1253
+ }
1254
+ }),
1255
+ children: icon
1256
+ }
1257
+ );
1258
+ };
1259
+ const chevron = (orientation) => /* @__PURE__ */ jsxRuntime.jsx(components.Chevron, { orientation, className: engineClassNames[reactDayPicker.UI.Chevron] });
1260
+ const doubleChevron = (Icon) => /* @__PURE__ */ jsxRuntime.jsx(Icon, { "aria-hidden": "true", ...mergeSlotAttrs(attrsRef.current.chevron, { className: engineClassNames[reactDayPicker.UI.Chevron] }) });
1261
+ return /* @__PURE__ */ jsxRuntime.jsxs("nav", { ...navAttrs, children: [
1262
+ triggersEnabled && arrow("previousYearButton", -doubleStep, doubleGrain, doubleChevron(doubleChevronLeft.DoubleChevronLeftIconOutlinedRounded)),
1263
+ arrow("previousMonthButton", -singleStep, singleGrain, chevron("left")),
1264
+ arrow("nextMonthButton", singleStep, singleGrain, chevron("right")),
1265
+ triggersEnabled && arrow("nextYearButton", doubleStep, doubleGrain, doubleChevron(doubleChevronRight.DoubleChevronRightIconOutlinedRounded))
1266
+ ] });
1267
+ };
1268
+ Nav.displayName = "Calendar.nav";
1269
+ const DayButton = ({ day, modifiers, children, ...engineProps }) => {
1270
+ const slotProps = mergeSlotAttrs(attrsRef.current.dayButton, engineProps);
1271
+ return /* @__PURE__ */ jsxRuntime.jsx(reactDayPicker.DayButton, { ...slotProps, day, modifiers, children: renderDayRef.current ? renderDayRef.current(day.date, modifiers) : children });
1272
+ };
1273
+ DayButton.displayName = "Calendar.dayButton";
1274
+ return {
1275
+ Root,
1276
+ Chevron,
1277
+ CaptionLabel,
1278
+ MonthCaption,
1279
+ MonthGrid,
1280
+ Nav,
1281
+ Months: withSlot(reactDayPicker.Months, "months"),
1282
+ Month: withSlot(reactDayPicker.Month, "month"),
1283
+ PreviousMonthButton: aroundArrow("previousMonthButton"),
1284
+ NextMonthButton: aroundArrow("nextMonthButton"),
1285
+ DropdownNav: withSlot(reactDayPicker.DropdownNav, "dropdowns"),
1286
+ // The engine hands these props to its own `<select>`, so `dropdown` is the
1287
+ // select's anchor. Its wrapping span (`dropdownRoot`) is class-only — see
1288
+ // `base.ts`.
1289
+ Dropdown: withSlot(reactDayPicker.Dropdown, "dropdown"),
1290
+ Weekdays: withSlot(reactDayPicker.Weekdays, "weekdays"),
1291
+ Weekday: withSlot(reactDayPicker.Weekday, "weekday"),
1292
+ Weeks: withSlot(reactDayPicker.Weeks, "weeks"),
1293
+ Week: withSlot(reactDayPicker.Week, "week"),
1294
+ WeekNumber: withSlot(reactDayPicker.WeekNumber, "weekNumber"),
1295
+ WeekNumberHeader: withSlot(reactDayPicker.WeekNumberHeader, "weekNumberHeader"),
1296
+ Day: withSlot(reactDayPicker.Day, "day"),
1297
+ DayButton,
1298
+ Footer: withSlot(reactDayPicker.Footer, "footer")
1299
+ };
1300
+ };
1301
+ var Calendar = (props) => {
1302
+ const theme = useComponentTheme("Calendar");
1303
+ const { rootAttrs, rest } = composeRootAttrs(CalendarBase, props, theme, {
1304
+ // `data-size` is takeoff-v2's own visual vocabulary. The engine's root
1305
+ // already emits `data-mode`, `data-multiple-months`, `data-week-numbers`
1306
+ // and `data-nav-layout`, so those are not mirrored here (rule 7).
1307
+ stateAttrs: ({ size = DEFAULT_SIZE5, headerType = DEFAULT_HEADER_TYPE }) => ({
1308
+ "data-size": size,
1309
+ "data-header-type": headerType
1310
+ })
1311
+ });
1312
+ const {
1313
+ mode = DEFAULT_MODE2,
1314
+ value,
1315
+ defaultValue,
1316
+ onValueChange,
1317
+ minDate,
1318
+ maxDate,
1319
+ disabledDates,
1320
+ allowedDates,
1321
+ disabledWeekDays,
1322
+ firstDayOfWeekIndex,
1323
+ size: _size,
1324
+ headerType: _headerType,
1325
+ view: viewProp,
1326
+ defaultView = DEFAULT_VIEW,
1327
+ onViewChange,
1328
+ ref,
1329
+ min,
1330
+ max,
1331
+ excludeDisabled,
1332
+ renderDay,
1333
+ ...engine
1334
+ } = rest;
1335
+ const isControlled = "value" in props;
1336
+ const [uncontrolledValue, setUncontrolledValue] = react.useState(isControlled ? void 0 : value ?? defaultValue);
1337
+ const selected = isControlled ? value : uncontrolledValue;
1338
+ const setSelected = (next) => {
1339
+ if (!isControlled) setUncontrolledValue(next);
1340
+ onValueChange?.(next);
1341
+ };
1342
+ const isMonthControlled = engine.month !== void 0;
1343
+ const anchor = selectionAnchor(selected);
1344
+ const [followedMonth, setFollowedMonth] = react.useState(void 0);
1345
+ const displayedMonthRef = react.useRef(void 0);
1346
+ const anchorYear = anchor?.getFullYear();
1347
+ const anchorMonth = anchor?.getMonth();
1348
+ react.useEffect(() => {
1349
+ if (isMonthControlled || anchorYear === void 0 || anchorMonth === void 0) return;
1350
+ const displayed = displayedMonthRef.current;
1351
+ const target = new Date(anchorYear, anchorMonth, 1);
1352
+ if (displayed && isSameCalendarMonth(displayed, target)) return;
1353
+ displayedMonthRef.current = target;
1354
+ setFollowedMonth(target);
1355
+ }, [isMonthControlled, anchorYear, anchorMonth]);
1356
+ const handleMonthChange = (next) => {
1357
+ displayedMonthRef.current = next;
1358
+ setFollowedMonth(next);
1359
+ engine.onMonthChange?.(next);
1360
+ };
1361
+ const triggersEnabled = !engine.captionLayout?.startsWith("dropdown");
1362
+ const isViewControlled = props.view !== void 0;
1363
+ const [uncontrolledView, setUncontrolledView] = react.useState(viewProp ?? defaultView);
1364
+ const view = isViewControlled ? props.view : uncontrolledView;
1365
+ const setView = (next) => {
1366
+ if (!isViewControlled) setUncontrolledView(next);
1367
+ onViewChange?.(next);
1368
+ };
1369
+ const panelId = react.useId();
1370
+ const panelRef = react.useRef(null);
1371
+ const restoreRef = react.useRef(null);
1372
+ const pendingFocusRef = react.useRef(false);
1373
+ const navigationDisabled = Boolean(engine.disableNavigation);
1374
+ const viewState = { triggersEnabled, view, setView, navigationDisabled, minDate, maxDate, panelId, panelRef, restoreRef, pendingFocusRef };
1375
+ const viewRef = react.useRef(viewState);
1376
+ viewRef.current = viewState;
1377
+ const slotAttrs = {};
1378
+ const classNames = { ...ENGINE_CLASSNAME_RESET, ...calendarRangeClassNames };
1379
+ for (const slot of CalendarBase.slots) {
1380
+ const composed = slot === "root" ? (
1381
+ // `data-view` is live state, not a resolved prop, so it is layered on
1382
+ // here rather than through `stateAttrs`.
1383
+ { ...rootAttrs, "data-view": view }
1384
+ ) : buildSlotAttrs(CalendarBase.getSlotProps(slot), slot, {
1385
+ themeSlotProps: theme?.slotProps,
1386
+ themeClassNames: theme?.classNames,
1387
+ instanceSlotProps: props.slotProps,
1388
+ instanceClassNames: props.classNames
1389
+ });
1390
+ const uiKey = SLOT_TO_UI[slot];
1391
+ if (uiKey === void 0) {
1392
+ slotAttrs[slot] = composed;
1393
+ continue;
1394
+ }
1395
+ const { className, ...attrs } = composed;
1396
+ slotAttrs[slot] = attrs;
1397
+ classNames[uiKey] = className ?? "";
1398
+ }
1399
+ const attrsRef = react.useRef(slotAttrs);
1400
+ attrsRef.current = slotAttrs;
1401
+ const refRef = react.useRef(ref);
1402
+ refRef.current = ref;
1403
+ const renderDayRef = react.useRef(renderDay);
1404
+ renderDayRef.current = renderDay;
1405
+ const components = react.useMemo(() => createEngineComponents(attrsRef, refRef, viewRef, renderDayRef), []);
1406
+ const disabled = buildDisabledMatchers({ minDate, maxDate, disabledDates, allowedDates, disabledWeekDays });
1407
+ const engineProps = {
1408
+ ...engine,
1409
+ // A board belongs to the calendar, not to a month, so only one month is
1410
+ // displayed while one is open — the board would otherwise be repeated per
1411
+ // month, `id` and all. Mapped on the prop rather than by dropping the extra
1412
+ // months from the `Month` override, which would take the engine's
1413
+ // navigation down with them: `navLayout="after"` and `"around"` render it
1414
+ // inside a month.
1415
+ numberOfMonths: view === "day" ? engine.numberOfMonths : 1,
1416
+ // A passed `month` stays in charge; otherwise the month the grid follows is
1417
+ // whatever it was last moved to — by the user's own navigation or by the
1418
+ // selection above. `defaultMonth` still seeds the first render, because
1419
+ // `followedMonth` is undefined until something moves.
1420
+ month: isMonthControlled ? engine.month : followedMonth,
1421
+ onMonthChange: handleMonthChange,
1422
+ mode,
1423
+ selected,
1424
+ onSelect: setSelected,
1425
+ disabled,
1426
+ startMonth: minDate,
1427
+ endMonth: maxDate,
1428
+ weekStartsOn: firstDayOfWeekIndex,
1429
+ min,
1430
+ max,
1431
+ excludeDisabled,
1432
+ classNames,
1433
+ components
1434
+ };
1435
+ return /* @__PURE__ */ jsxRuntime.jsx(reactDayPicker.DayPicker, { ...engineProps });
1436
+ };
1437
+ Calendar.displayName = "Calendar";
1438
+
722
1439
  // src/components/card/base.ts
723
1440
  var CardBase = createComponentBase({
724
1441
  name: "Card",
@@ -760,12 +1477,12 @@ var Card = (props) => {
760
1477
  Card.displayName = "Card";
761
1478
 
762
1479
  // src/components/card/defaults.ts
763
- var DEFAULT_HEADER_TYPE = "basic";
1480
+ var DEFAULT_HEADER_TYPE2 = "basic";
764
1481
  var DEFAULT_FOOTER_TYPE = "basic";
765
1482
  var CardHeader = (props) => {
766
1483
  const theme = useComponentTheme("CardHeader");
767
1484
  const { rootAttrs, rest } = composeRootAttrs(CardHeaderBase, props, theme, {
768
- stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE }) => ({
1485
+ stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE2 }) => ({
769
1486
  "data-header-type": headerType
770
1487
  })
771
1488
  });
@@ -843,11 +1560,11 @@ var CheckboxBase = createComponentBase({
843
1560
  var [CheckboxProvider, useCheckboxOwnContext] = createSafeContext("CheckboxProvider");
844
1561
 
845
1562
  // src/components/checkbox/defaults.ts
846
- var DEFAULT_SIZE5 = "base";
1563
+ var DEFAULT_SIZE6 = "base";
847
1564
  var Checkbox = (props) => {
848
1565
  const theme = useComponentTheme("Checkbox");
849
1566
  const { rootAttrs, rest } = composeRootAttrs(CheckboxBase, props, theme, {
850
- stateAttrs: ({ size = DEFAULT_SIZE5 }) => ({
1567
+ stateAttrs: ({ size = DEFAULT_SIZE6 }) => ({
851
1568
  "data-size": size
852
1569
  })
853
1570
  });
@@ -939,13 +1656,13 @@ var ChipBase = createComponentBase({
939
1656
  // src/components/chip/defaults.ts
940
1657
  var DEFAULT_VARIANT4 = "primary";
941
1658
  var DEFAULT_APPEARANCE4 = "filled";
942
- var DEFAULT_SIZE6 = "base";
1659
+ var DEFAULT_SIZE7 = "base";
943
1660
  var DEFAULT_REMOVE_LABEL = "Remove";
944
1661
  var Chip = (props) => {
945
1662
  const theme = useComponentTheme("Chip");
946
1663
  const [dismissed, setDismissed] = react.useState(false);
947
1664
  const { rootAttrs, rest } = composeRootAttrs(ChipBase, props, theme, {
948
- stateAttrs: ({ variant = DEFAULT_VARIANT4, appearance = DEFAULT_APPEARANCE4, size = DEFAULT_SIZE6, clickable: clickable2 = false, disabled: disabled2 = false, removable: removable2 = false }) => ({
1665
+ stateAttrs: ({ variant = DEFAULT_VARIANT4, appearance = DEFAULT_APPEARANCE4, size = DEFAULT_SIZE7, clickable: clickable2 = false, disabled: disabled2 = false, removable: removable2 = false }) => ({
949
1666
  "data-variant": variant,
950
1667
  "data-type": appearance,
951
1668
  "data-size": size,
@@ -1052,15 +1769,15 @@ var [DrawerProvider, useDrawerOwnContext] = createSafeContext("DrawerProvider");
1052
1769
 
1053
1770
  // src/components/drawer/defaults.ts
1054
1771
  var DEFAULT_PLACEMENT = "right";
1055
- var DEFAULT_HEADER_TYPE2 = "basic";
1772
+ var DEFAULT_HEADER_TYPE3 = "basic";
1056
1773
  var DEFAULT_FOOTER_TYPE2 = "basic";
1057
1774
  var DEFAULT_INTENSITY = "base";
1058
1775
  var DEFAULT_CLOSE_LABEL2 = "Close";
1059
1776
  var Drawer = (props) => {
1060
1777
  const theme = useComponentTheme("Drawer");
1061
1778
  const merged = { ...theme?.defaultProps, ...props };
1062
- const { placement = DEFAULT_PLACEMENT, dismissible = true, disabled = false, children, ...sparProps } = merged;
1063
- return /* @__PURE__ */ jsxRuntime.jsx(DrawerProvider, { value: { placement, dismissible }, children: /* @__PURE__ */ jsxRuntime.jsx(spar.Dialog, { ...sparProps, disabled, forceMount: true, children }) });
1779
+ const { placement = DEFAULT_PLACEMENT, dismissible = true, disabled = false, forceMount = true, children, ...sparProps } = merged;
1780
+ return /* @__PURE__ */ jsxRuntime.jsx(DrawerProvider, { value: { placement, dismissible }, children: /* @__PURE__ */ jsxRuntime.jsx(spar.Dialog, { ...sparProps, disabled, forceMount, children }) });
1064
1781
  };
1065
1782
  Drawer.displayName = "Drawer";
1066
1783
 
@@ -1155,7 +1872,7 @@ DrawerPanel.displayName = "Drawer.Panel";
1155
1872
  var DrawerHeader = (props) => {
1156
1873
  const theme = useComponentTheme("DrawerHeader");
1157
1874
  const { rootAttrs, rest } = composeRootAttrs(DrawerHeaderBase, props, theme, {
1158
- stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE2 }) => ({
1875
+ stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE3 }) => ({
1159
1876
  "data-header-type": headerType
1160
1877
  })
1161
1878
  });
@@ -1304,7 +2021,7 @@ DialogTrigger.displayName = "Dialog.Trigger";
1304
2021
 
1305
2022
  // src/components/dialog/defaults.ts
1306
2023
  var DEFAULT_INTENSITY2 = "base";
1307
- var DEFAULT_HEADER_TYPE3 = "basic";
2024
+ var DEFAULT_HEADER_TYPE4 = "basic";
1308
2025
  var DEFAULT_FOOTER_TYPE3 = "basic";
1309
2026
  var DEFAULT_CLOSE_LABEL3 = "Close";
1310
2027
  var DialogOverlay = (props) => {
@@ -1336,7 +2053,7 @@ DialogPanel.displayName = "Dialog.Panel";
1336
2053
  var DialogHeader = (props) => {
1337
2054
  const theme = useComponentTheme("DialogHeader");
1338
2055
  const { rootAttrs, rest } = composeRootAttrs(DialogHeaderBase, props, theme, {
1339
- stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE3 }) => ({
2056
+ stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE4 }) => ({
1340
2057
  "data-header-type": headerType
1341
2058
  })
1342
2059
  });
@@ -1443,12 +2160,12 @@ Divider.displayName = "Divider";
1443
2160
  var [DropdownProvider, useDropdownOwnContext] = createSafeContext("DropdownProvider");
1444
2161
 
1445
2162
  // src/components/dropdown/defaults.ts
1446
- var DEFAULT_SIZE7 = "base";
2163
+ var DEFAULT_SIZE8 = "base";
1447
2164
  var DEFAULT_CONTENT_WIDTH = "content";
1448
2165
  var Dropdown = (props) => {
1449
2166
  const theme = useComponentTheme("Dropdown");
1450
2167
  const merged = { ...theme?.defaultProps, ...props };
1451
- const { size = DEFAULT_SIZE7, contentWidth = DEFAULT_CONTENT_WIDTH, children, ...sparProps } = merged;
2168
+ const { size = DEFAULT_SIZE8, contentWidth = DEFAULT_CONTENT_WIDTH, children, ...sparProps } = merged;
1452
2169
  return /* @__PURE__ */ jsxRuntime.jsx(DropdownProvider, { value: { size, contentWidth }, children: /* @__PURE__ */ jsxRuntime.jsx(spar.DropdownMenu, { ...sparProps, children }) });
1453
2170
  };
1454
2171
  Dropdown.displayName = "Dropdown";
@@ -1740,7 +2457,7 @@ var InputChipsBase = createComponentBase({
1740
2457
  var [InputProvider, useInputOwnContext] = createSafeContext("InputProvider");
1741
2458
 
1742
2459
  // src/components/input/defaults.ts
1743
- var DEFAULT_SIZE8 = "base";
2460
+ var DEFAULT_SIZE9 = "base";
1744
2461
  var SEGMENT_COUNT = 4;
1745
2462
  var computeStrength = (value) => {
1746
2463
  let strength = 0;
@@ -1792,11 +2509,11 @@ var Input = (props) => {
1792
2509
  for (const value of clearablesRef.current.values()) value.clear();
1793
2510
  }, []);
1794
2511
  const { rootAttrs, rest } = composeRootAttrs(InputBase, props, theme, {
1795
- stateAttrs: ({ size: size2 = DEFAULT_SIZE8 }) => ({
2512
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE9 }) => ({
1796
2513
  "data-size": size2
1797
2514
  })
1798
2515
  });
1799
- const { size = DEFAULT_SIZE8, children, ref, ...sparProps } = rest;
2516
+ const { size = DEFAULT_SIZE9, children, ref, ...sparProps } = rest;
1800
2517
  const contextValue = react.useMemo(
1801
2518
  () => ({
1802
2519
  size,
@@ -2020,7 +2737,7 @@ var InputField = (props) => {
2020
2737
  const theme = useComponentTheme("InputField");
2021
2738
  const { fieldRef, setFieldNode, setFieldValue, revealed, setRevealed } = useInputOwnContext("Input.Field");
2022
2739
  const { rootAttrs, rest } = composeRootAttrs(InputFieldBase, props, theme);
2023
- const { as, ref, type, onInput, onChange, ...spar$1 } = rest;
2740
+ const { as, ref, type, onInput, onChange, onValueChange, ...spar$1 } = rest;
2024
2741
  const effectiveType = type === "password" && revealed ? "text" : type;
2025
2742
  const renderedType = as === "textarea" ? void 0 : effectiveType;
2026
2743
  const setFieldRef = react.useCallback(
@@ -2049,6 +2766,10 @@ var InputField = (props) => {
2049
2766
  onChange?.(event);
2050
2767
  setFieldValue(event.currentTarget.value);
2051
2768
  };
2769
+ const handleValueChange = (value, meta) => {
2770
+ setFieldValue(value);
2771
+ onValueChange?.(value, meta);
2772
+ };
2052
2773
  return /* @__PURE__ */ jsxRuntime.jsx(
2053
2774
  spar.InputField,
2054
2775
  {
@@ -2057,6 +2778,7 @@ var InputField = (props) => {
2057
2778
  type: renderedType,
2058
2779
  onInput: handleInput,
2059
2780
  onChange: handleChange,
2781
+ onValueChange: handleValueChange,
2060
2782
  ref: setFieldRef,
2061
2783
  ...rootAttrs
2062
2784
  }
@@ -2189,8 +2911,6 @@ var InputTrailingIcon = (props) => {
2189
2911
  return /* @__PURE__ */ jsxRuntime.jsx(Component, { "aria-hidden": "true", ...rendered, ref, ...rootAttrs, children });
2190
2912
  };
2191
2913
  InputTrailingIcon.displayName = "Input.TrailingIcon";
2192
-
2193
- // src/components/input/index.ts
2194
2914
  var Input2 = Object.assign(Input, {
2195
2915
  Field: InputField,
2196
2916
  Prefix: InputPrefix,
@@ -2252,19 +2972,19 @@ var RADIO_ITEM_CONTEXT_VALUE = { inside: true };
2252
2972
  var [RadioItemProvider, useRadioItemOwnContext] = createSafeContext("RadioItemProvider");
2253
2973
 
2254
2974
  // src/components/radio/defaults.ts
2255
- var DEFAULT_SIZE9 = "base";
2975
+ var DEFAULT_SIZE10 = "base";
2256
2976
  var DEFAULT_POSITION = "left";
2257
2977
  var Radio = (props) => {
2258
2978
  const theme = useComponentTheme("Radio");
2259
2979
  const { rootAttrs, rest } = composeRootAttrs(RadioBase, props, theme, {
2260
- stateAttrs: ({ size: size2 = DEFAULT_SIZE9, position: position2 = DEFAULT_POSITION, spread }) => ({
2980
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE10, position: position2 = DEFAULT_POSITION, spread }) => ({
2261
2981
  "data-size": size2,
2262
2982
  "data-position": position2,
2263
2983
  "data-spread": spread ? "" : void 0
2264
2984
  })
2265
2985
  });
2266
2986
  const {
2267
- size = DEFAULT_SIZE9,
2987
+ size = DEFAULT_SIZE10,
2268
2988
  position = DEFAULT_POSITION,
2269
2989
  invalid,
2270
2990
  // `spread` is consumed only as a data-attr above; destructure to keep it
@@ -2462,7 +3182,7 @@ var [ProgressProvider, useProgressContext] = createSafeContext("ProgressProvider
2462
3182
 
2463
3183
  // src/components/progress/defaults.ts
2464
3184
  var DEFAULT_APPEARANCE6 = "linear";
2465
- var DEFAULT_SIZE10 = "base";
3185
+ var DEFAULT_SIZE11 = "base";
2466
3186
  var DEFAULT_VARIANT6 = "primary";
2467
3187
  var DEFAULT_MIN = 0;
2468
3188
  var DEFAULT_MAX = 100;
@@ -2543,7 +3263,7 @@ var Progress = (props) => {
2543
3263
  const resolveState = ({
2544
3264
  indeterminate: indeterminate2 = false,
2545
3265
  appearance: appearance2 = DEFAULT_APPEARANCE6,
2546
- size: size2 = DEFAULT_SIZE10,
3266
+ size: size2 = DEFAULT_SIZE11,
2547
3267
  variant: variant2 = DEFAULT_VARIANT6,
2548
3268
  disabled: disabled2 = field?.disabled ?? false
2549
3269
  }) => ({ indeterminate: indeterminate2, appearance: appearance2, size: size2, variant: variant2, disabled: disabled2 });
@@ -2687,17 +3407,17 @@ var SelectArrowBase = createComponentBase({
2687
3407
  var [SelectProvider, useSelectOwnContext] = createSafeContext("SelectProvider");
2688
3408
 
2689
3409
  // src/components/select/defaults.ts
2690
- var DEFAULT_SIZE11 = "base";
3410
+ var DEFAULT_SIZE12 = "base";
2691
3411
  var DEFAULT_CONTENT_WIDTH2 = "trigger";
2692
3412
  var Select = (props) => {
2693
3413
  const theme = useComponentTheme("Select");
2694
3414
  const { rootAttrs, rest } = composeRootAttrs(SelectBase, props, theme, {
2695
- stateAttrs: ({ size: size2 = DEFAULT_SIZE11, invalid: invalid2 }) => ({
3415
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE12, invalid: invalid2 }) => ({
2696
3416
  "data-size": size2,
2697
3417
  "data-invalid": invalid2 ? "" : void 0
2698
3418
  })
2699
3419
  });
2700
- const { size = DEFAULT_SIZE11, invalid = false, contentWidth = DEFAULT_CONTENT_WIDTH2, children, ref, ...sparProps } = rest;
3420
+ const { size = DEFAULT_SIZE12, invalid = false, contentWidth = DEFAULT_CONTENT_WIDTH2, children, ref, ...sparProps } = rest;
2701
3421
  return /* @__PURE__ */ jsxRuntime.jsx(SelectProvider, { value: { size, invalid, contentWidth }, children: /* @__PURE__ */ jsxRuntime.jsx(spar.Select, { ...sparProps, ref, ...rootAttrs, children }) });
2702
3422
  };
2703
3423
  Select.displayName = "Select";
@@ -2857,7 +3577,7 @@ var [SliderProvider, useSliderContext] = createSafeContext("SliderProvider");
2857
3577
 
2858
3578
  // src/components/slider/defaults.ts
2859
3579
  var DEFAULT_ORIENTATION2 = "horizontal";
2860
- var DEFAULT_SIZE12 = "base";
3580
+ var DEFAULT_SIZE13 = "base";
2861
3581
  var DEFAULT_VARIANT7 = "primary";
2862
3582
  var DEFAULT_TOOLTIP = "auto";
2863
3583
  var DEFAULT_TRACK = "normal";
@@ -3157,7 +3877,7 @@ var Slider = (props) => {
3157
3877
  const { rootAttrs, rest } = composeRootAttrs(SliderBase, props, theme, {
3158
3878
  stateAttrs: (merged) => {
3159
3879
  const {
3160
- size = DEFAULT_SIZE12,
3880
+ size = DEFAULT_SIZE13,
3161
3881
  variant = DEFAULT_VARIANT7,
3162
3882
  orientation: orientation2 = DEFAULT_ORIENTATION2,
3163
3883
  tooltip = DEFAULT_TOOLTIP,
@@ -3445,7 +4165,7 @@ var SpinnerBase = createComponentBase({
3445
4165
 
3446
4166
  // src/components/spinner/defaults.ts
3447
4167
  var DEFAULT_APPEARANCE7 = "rounded";
3448
- var DEFAULT_SIZE13 = "base";
4168
+ var DEFAULT_SIZE14 = "base";
3449
4169
  var DEFAULT_VARIANT8 = "neutral";
3450
4170
  var DEFAULT_ARIA_LABEL2 = "Loading";
3451
4171
  var SPINNER_RADIAL_PARTS = 8;
@@ -3484,7 +4204,7 @@ var renderIndicatorContent = (appearance) => {
3484
4204
  var Spinner = (props) => {
3485
4205
  const theme = useComponentTheme("Spinner");
3486
4206
  const { rootAttrs, rest } = composeRootAttrs(SpinnerBase, props, theme, {
3487
- stateAttrs: ({ variant = DEFAULT_VARIANT8, size = DEFAULT_SIZE13, appearance: appearance2 = DEFAULT_APPEARANCE7 }) => ({
4207
+ stateAttrs: ({ variant = DEFAULT_VARIANT8, size = DEFAULT_SIZE14, appearance: appearance2 = DEFAULT_APPEARANCE7 }) => ({
3488
4208
  "data-variant": variant,
3489
4209
  "data-size": size,
3490
4210
  "data-type": appearance2
@@ -3541,8 +4261,8 @@ var [StepperItemProvider, useStepperItem] = createSafeContext("Stepper.Item");
3541
4261
 
3542
4262
  // src/components/stepper/defaults.ts
3543
4263
  var DEFAULT_ORIENTATION3 = "horizontal";
3544
- var DEFAULT_MODE2 = "default";
3545
- var DEFAULT_SIZE14 = "base";
4264
+ var DEFAULT_MODE3 = "default";
4265
+ var DEFAULT_SIZE15 = "base";
3546
4266
  var DEFAULT_ACTIVE = 0;
3547
4267
  var DEFAULT_COMPLETED_LABEL = "completed";
3548
4268
  var DEFAULT_ERROR_LABEL = "error";
@@ -3550,7 +4270,7 @@ var FOCUSABLE_TRIGGER_SELECTOR = '.tk-stepper-trigger:not(:disabled):not([tabind
3550
4270
  var Stepper = (props) => {
3551
4271
  const theme = useComponentTheme("Stepper");
3552
4272
  const { rootAttrs, rest } = composeRootAttrs(StepperBase, props, theme, {
3553
- stateAttrs: ({ orientation: orientation2 = DEFAULT_ORIENTATION3, mode: mode2 = DEFAULT_MODE2, size = DEFAULT_SIZE14, linear: linear2 = false, reverse = false }) => ({
4273
+ stateAttrs: ({ orientation: orientation2 = DEFAULT_ORIENTATION3, mode: mode2 = DEFAULT_MODE3, size = DEFAULT_SIZE15, linear: linear2 = false, reverse = false }) => ({
3554
4274
  "data-orientation": orientation2,
3555
4275
  "data-mode": mode2,
3556
4276
  "data-size": size,
@@ -3564,7 +4284,7 @@ var Stepper = (props) => {
3564
4284
  onActiveChange,
3565
4285
  onStepClick,
3566
4286
  orientation = DEFAULT_ORIENTATION3,
3567
- mode = DEFAULT_MODE2,
4287
+ mode = DEFAULT_MODE3,
3568
4288
  // Consumed only as root data-* hooks above; destructured so the <ol>
3569
4289
  // doesn't receive unknown DOM attributes.
3570
4290
  size: _size,
@@ -3681,7 +4401,7 @@ var StepperTitle = (props) => {
3681
4401
  return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...nativeProps, ...rootAttrs, ref, children });
3682
4402
  };
3683
4403
  StepperTitle.displayName = "Stepper.Title";
3684
- var visuallyHidden = {
4404
+ var visuallyHidden2 = {
3685
4405
  position: "absolute",
3686
4406
  width: 1,
3687
4407
  height: 1,
@@ -3767,7 +4487,7 @@ var StepperItem = (props) => {
3767
4487
  children: [
3768
4488
  /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", ...indicatorAttrs, children: indicatorContent }),
3769
4489
  /* @__PURE__ */ jsxRuntime.jsx("span", { ...contentAttrs, children }),
3770
- statusLabel ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: visuallyHidden, children: `, ${statusLabel}` }) : null
4490
+ statusLabel ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: visuallyHidden2, children: `, ${statusLabel}` }) : null
3771
4491
  ]
3772
4492
  }
3773
4493
  )
@@ -3818,12 +4538,12 @@ var SwitchBase = createComponentBase({
3818
4538
  var [SwitchProvider, useSwitchOwnContext] = createSafeContext("SwitchProvider");
3819
4539
 
3820
4540
  // src/components/switch/defaults.ts
3821
- var DEFAULT_SIZE15 = "base";
4541
+ var DEFAULT_SIZE16 = "base";
3822
4542
  var DEFAULT_VARIANT9 = "info";
3823
4543
  var Switch = (props) => {
3824
4544
  const theme = useComponentTheme("Switch");
3825
4545
  const { rootAttrs, rest } = composeRootAttrs(SwitchBase, props, theme, {
3826
- stateAttrs: ({ size = DEFAULT_SIZE15, variant = DEFAULT_VARIANT9 }) => ({
4546
+ stateAttrs: ({ size = DEFAULT_SIZE16, variant = DEFAULT_VARIANT9 }) => ({
3827
4547
  "data-size": size,
3828
4548
  "data-variant": variant
3829
4549
  })
@@ -3950,7 +4670,7 @@ var TableBase = createComponentBase({
3950
4670
  var [TableProvider, useTableContext] = createSafeContext("Table");
3951
4671
 
3952
4672
  // src/components/table/defaults.ts
3953
- var DEFAULT_SIZE16 = "base";
4673
+ var DEFAULT_SIZE17 = "base";
3954
4674
  var DEFAULT_PAGE_SIZE = 10;
3955
4675
  var DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];
3956
4676
  var DEFAULT_COLUMN_WIDTH = 150;
@@ -4476,7 +5196,7 @@ var Table = (props) => {
4476
5196
  // Visual vocabulary lives on the root so recipes cascade
4477
5197
  // to the portal-free table descendants. `data-loading` mirrors the
4478
5198
  // boolean-presence convention (rule 5).
4479
- stateAttrs: ({ size: size2 = DEFAULT_SIZE16, striped: striped2, bordered: bordered2, stickyHeader: stickyHeader2, loading: loading2 }) => ({
5199
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE17, striped: striped2, bordered: bordered2, stickyHeader: stickyHeader2, loading: loading2 }) => ({
4480
5200
  "data-size": size2,
4481
5201
  "data-striped": striped2 ? "" : void 0,
4482
5202
  "data-bordered": bordered2 ? "" : void 0,
@@ -4490,7 +5210,7 @@ var Table = (props) => {
4490
5210
  getRowId,
4491
5211
  manual = false,
4492
5212
  loading = false,
4493
- size = DEFAULT_SIZE16,
5213
+ size = DEFAULT_SIZE17,
4494
5214
  striped = false,
4495
5215
  bordered = false,
4496
5216
  stickyHeader = false,
@@ -4690,19 +5410,19 @@ var TabsContentBase = createComponentBase({
4690
5410
  var [TabsOwnProvider, useTabsOwnContext] = createSafeContext("Tabs");
4691
5411
 
4692
5412
  // src/components/tabs/defaults.ts
4693
- var DEFAULT_SIZE17 = "base";
5413
+ var DEFAULT_SIZE18 = "base";
4694
5414
  var DEFAULT_VARIANT10 = "primary";
4695
5415
  var DEFAULT_APPEARANCE8 = "basic";
4696
5416
  var Tabs = (props) => {
4697
5417
  const theme = useComponentTheme("Tabs");
4698
5418
  const { rootAttrs, rest } = composeRootAttrs(TabsBase, props, theme, {
4699
- stateAttrs: ({ size: size2 = DEFAULT_SIZE17, variant: variant2 = DEFAULT_VARIANT10, appearance: appearance2 = DEFAULT_APPEARANCE8 }) => ({
5419
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE18, variant: variant2 = DEFAULT_VARIANT10, appearance: appearance2 = DEFAULT_APPEARANCE8 }) => ({
4700
5420
  "data-size": size2,
4701
5421
  "data-variant": variant2,
4702
5422
  "data-type": appearance2
4703
5423
  })
4704
5424
  });
4705
- const { size = DEFAULT_SIZE17, variant = DEFAULT_VARIANT10, appearance = DEFAULT_APPEARANCE8, children, ref, ...sparProps } = rest;
5425
+ const { size = DEFAULT_SIZE18, variant = DEFAULT_VARIANT10, appearance = DEFAULT_APPEARANCE8, children, ref, ...sparProps } = rest;
4706
5426
  return /* @__PURE__ */ jsxRuntime.jsx(TabsOwnProvider, { value: { size, variant, appearance }, children: /* @__PURE__ */ jsxRuntime.jsx(spar.Tabs, { ...sparProps, ...rootAttrs, ref, children }) });
4707
5427
  };
4708
5428
  Tabs.displayName = "Tabs";
@@ -5991,6 +6711,18 @@ var Upload2 = Object.assign(Upload, {
5991
6711
  ItemAction: UploadItemAction
5992
6712
  });
5993
6713
 
6714
+ Object.defineProperty(exports, "createDateMask", {
6715
+ enumerable: true,
6716
+ get: function () { return spar.createDateMask; }
6717
+ });
6718
+ Object.defineProperty(exports, "createNumberMask", {
6719
+ enumerable: true,
6720
+ get: function () { return spar.createNumberMask; }
6721
+ });
6722
+ Object.defineProperty(exports, "createTimeMask", {
6723
+ enumerable: true,
6724
+ get: function () { return spar.createTimeMask; }
6725
+ });
5994
6726
  Object.defineProperty(exports, "createToaster", {
5995
6727
  enumerable: true,
5996
6728
  get: function () { return spar.createToaster; }
@@ -6000,6 +6732,7 @@ exports.Alert = Alert2;
6000
6732
  exports.Badge = Badge;
6001
6733
  exports.Breadcrumb = Breadcrumb2;
6002
6734
  exports.Button = Button;
6735
+ exports.Calendar = Calendar;
6003
6736
  exports.Card = Card2;
6004
6737
  exports.Checkbox = Checkbox2;
6005
6738
  exports.Chip = Chip;
@@ -6028,4 +6761,5 @@ exports.Tooltip = Tooltip2;
6028
6761
  exports.Upload = Upload2;
6029
6762
  exports.getExportRows = getExportRows;
6030
6763
  exports.useComponentTheme = useComponentTheme;
6764
+ exports.useDatePicker = useDatePicker;
6031
6765
  exports.useTheme = useTheme;