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