@xsolla/xui-date-picker 0.208.2 → 0.209.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/README.md CHANGED
@@ -103,6 +103,7 @@ const [date, setDate] = useState<Date | null>(null);
103
103
  | `backgroundColor` | `string` | — | Custom background colour for the input. |
104
104
  | `dropdownPosition` | `'left' \| 'right'` | `'left'` | **Deprecated** — use the alignment suffix on `placement` (`dropdownPosition="right"` → `placement="bottom-end"`). Still honoured as a fallback when `placement` has no suffix. |
105
105
  | `placement` | `DatePickerPlacement` | auto | Where the calendar opens, as `{side}[-alignment]` — same `{side}-{start\|center\|end}` convention as `ContextMenuPlacement`. A bare side aligns to `start`. When omitted, the calendar measures viewport space on open and auto-flips, preferring `bottom` → `top` → `left` → `right`, also flipping the cross-axis edge to stay on screen. When set, it always opens at that placement. Web only. |
106
+ | `closeOnComplete` | `boolean` | `true` | Whether picking a date in the calendar dismisses the panel. `false` keeps it open after a complete selection so a `bottomContent` footer stays reachable — see [Footer actions](#footer-actions). |
106
107
  | `locale` | `CalendarLocaleType` | `'enUS'` | `date-fns` locale identifier. |
107
108
  | `firstDayOfWeek` | `number` | — | First day of the week (0 = Sunday … 6 = Saturday). |
108
109
  | `initialMonth` | `Date` | — | Month shown on first render. |
@@ -112,8 +113,8 @@ const [date, setDate] = useState<Date | null>(null);
112
113
  | `chips` | `CalendarChipOption[]` | — | Preset range chips above the calendar. |
113
114
  | `activeChip` | `string \| null` | — | Currently active chip value. |
114
115
  | `onChipSelect` | `(value: string \| null) => void` | — | Fired when a chip is selected. |
115
- | `topContent` | `(api: { close: () => void }) => ReactNode` | — | Custom content above the calendar. |
116
- | `bottomContent` | `(api: { close: () => void }) => ReactNode` | — | Custom content below the calendar. |
116
+ | `topContent` | `(api: { close: () => void }) => ReactNode` | — | Custom content above the calendar. `close()` dismisses the picker panel. |
117
+ | `bottomContent` | `(api: { close: () => void }) => ReactNode` | — | Custom content below the calendar. `close()` dismisses the picker panel — pair it with `closeOnComplete={false}` for an Apply/Cancel footer. |
117
118
  | `contextMenuMaxHeight` | `number` | — | Max height for the month/year context menus. |
118
119
  | `testID` | `string` | — | Test identifier. |
119
120
  | `overlayThemeMode` | `ThemeMode` | `themeMode` | Theme mode for the calendar overlay. |
@@ -220,6 +221,50 @@ const [end, setEnd] = useState<Date | null>(null);
220
221
  />;
221
222
  ```
222
223
 
224
+ ### Footer actions
225
+
226
+ By default the panel dismisses itself as soon as the selection is complete: one click in single mode, the second day click in range mode. That default is wrong for a picker with an interactive footer — the second click tears the panel down before an Apply button in `bottomContent` can be pressed.
227
+
228
+ `closeOnComplete={false}` keeps the panel open after a complete selection and hands dismissal to the footer. The picker calls `bottomContent`/`topContent` with a `close()` that actually closes it, so Apply/Cancel behave as written. Escape and an outside click still close the panel either way, and typed or pasted entry never closes it regardless of the prop.
229
+
230
+ ```tsx
231
+ const [draft, setDraft] = useState<DateRangeType>([null, null]);
232
+ const [applied, setApplied] = useState<DateRangeType>([null, null]);
233
+
234
+ <DatePicker
235
+ variant="dual"
236
+ closeOnComplete={false}
237
+ startDate={draft[0]}
238
+ endDate={draft[1]}
239
+ onChange={(range) => setDraft(range as DateRangeType)}
240
+ bottomContent={({ close }) => (
241
+ <ButtonGroup split>
242
+ <Button
243
+ size="sm"
244
+ variant="secondary"
245
+ tone="mono"
246
+ onPress={() => {
247
+ setDraft(applied);
248
+ close();
249
+ }}
250
+ >
251
+ Cancel
252
+ </Button>
253
+ <Button
254
+ size="sm"
255
+ disabled={!draft[0] || !draft[1]}
256
+ onPress={() => {
257
+ setApplied(draft);
258
+ close();
259
+ }}
260
+ >
261
+ Apply
262
+ </Button>
263
+ </ButtonGroup>
264
+ )}
265
+ />;
266
+ ```
267
+
223
268
  ### Placement and autoflip
224
269
 
225
270
  ```tsx
@@ -117,6 +117,22 @@ interface DatePickerProps extends Omit<CalendarProps, "onChange"> {
117
117
  * When set, the calendar always opens at that placement. Web only.
118
118
  */
119
119
  placement?: DatePickerPlacement;
120
+ /**
121
+ * Whether picking a date in the calendar dismisses the panel. Defaults to
122
+ * `true`: a single-date pick closes immediately, and a range closes once both
123
+ * ends are set.
124
+ *
125
+ * Pass `false` to keep the panel open after a complete selection. That is
126
+ * what makes an interactive `bottomContent`/`topContent` footer (Apply,
127
+ * Cancel, custom presets) usable in range mode — with the default, the second
128
+ * day click dismisses the panel before the footer can be clicked. Dismissal
129
+ * then belongs to the consumer: call the `close()` the picker hands to
130
+ * `bottomContent`/`topContent`. Escape and an outside click still close the
131
+ * panel either way.
132
+ *
133
+ * Typed and pasted entry never closes the panel, regardless of this prop.
134
+ */
135
+ closeOnComplete?: boolean;
120
136
  testID?: string;
121
137
  /** Theme mode for the calendar overlay. Defaults to themeMode when not set. */
122
138
  overlayThemeMode?: ThemeMode;
package/native/index.d.ts CHANGED
@@ -117,6 +117,22 @@ interface DatePickerProps extends Omit<CalendarProps, "onChange"> {
117
117
  * When set, the calendar always opens at that placement. Web only.
118
118
  */
119
119
  placement?: DatePickerPlacement;
120
+ /**
121
+ * Whether picking a date in the calendar dismisses the panel. Defaults to
122
+ * `true`: a single-date pick closes immediately, and a range closes once both
123
+ * ends are set.
124
+ *
125
+ * Pass `false` to keep the panel open after a complete selection. That is
126
+ * what makes an interactive `bottomContent`/`topContent` footer (Apply,
127
+ * Cancel, custom presets) usable in range mode — with the default, the second
128
+ * day click dismisses the panel before the footer can be clicked. Dismissal
129
+ * then belongs to the consumer: call the `close()` the picker hands to
130
+ * `bottomContent`/`topContent`. Escape and an outside click still close the
131
+ * panel either way.
132
+ *
133
+ * Typed and pasted entry never closes the panel, regardless of this prop.
134
+ */
135
+ closeOnComplete?: boolean;
120
136
  testID?: string;
121
137
  /** Theme mode for the calendar overlay. Defaults to themeMode when not set. */
122
138
  overlayThemeMode?: ThemeMode;
package/native/index.js CHANGED
@@ -629,6 +629,9 @@ var DatePicker = (0, import_react.forwardRef)(
629
629
  showChipLabel = true,
630
630
  dropdownPosition = "left",
631
631
  placement,
632
+ closeOnComplete = true,
633
+ topContent,
634
+ bottomContent,
632
635
  themeMode,
633
636
  themeProductContext,
634
637
  overlayThemeMode,
@@ -740,7 +743,7 @@ var DatePicker = (0, import_react.forwardRef)(
740
743
  const seg = segments.find((s) => caret >= s.start && caret <= s.end) ?? segments.find((s) => caret < s.start) ?? segments[segments.length - 1];
741
744
  return seg ? { group: seg.group, type: seg.type } : null;
742
745
  };
743
- const applySelection = (date, closeOnComplete = true) => {
746
+ const applySelection = (date, closeOnComplete2 = true) => {
744
747
  if (!chipSelectionRef.current) {
745
748
  setInternalChip(null);
746
749
  onChipSelect?.(null);
@@ -748,11 +751,11 @@ var DatePicker = (0, import_react.forwardRef)(
748
751
  chipSelectionRef.current = false;
749
752
  if (!isRange) {
750
753
  onChange?.(date);
751
- if (closeOnComplete) setOpen(false);
754
+ if (closeOnComplete2) setOpen(false);
752
755
  } else {
753
756
  const range = date;
754
757
  onChange?.(range);
755
- if (closeOnComplete && range[0] && range[1]) setOpen(false);
758
+ if (closeOnComplete2 && range[0] && range[1]) setOpen(false);
756
759
  }
757
760
  };
758
761
  const emit = (next) => {
@@ -991,7 +994,10 @@ var DatePicker = (0, import_react.forwardRef)(
991
994
  setInternalChip(value);
992
995
  onChipSelect?.(value);
993
996
  };
994
- const handleDateChange = (date) => applySelection(date);
997
+ const handleDateChange = (date) => applySelection(date, closeOnComplete);
998
+ const closePanel = (0, import_react.useCallback)(() => setOpen(false), []);
999
+ const renderTopContent = topContent ? () => topContent({ close: closePanel }) : void 0;
1000
+ const renderBottomContent = bottomContent ? () => bottomContent({ close: closePanel }) : void 0;
995
1001
  const propKey = `${selectedDate?.getTime() ?? ""}|${startDate?.getTime() ?? ""}|${endDate?.getTime() ?? ""}|${isRange}`;
996
1002
  (0, import_react.useEffect)(() => {
997
1003
  if (focused) return;
@@ -1127,6 +1133,8 @@ var DatePicker = (0, import_react.forwardRef)(
1127
1133
  chips,
1128
1134
  activeChip: activeChipValue,
1129
1135
  onChipSelect: handleChipSelect,
1136
+ topContent: renderTopContent,
1137
+ bottomContent: renderBottomContent,
1130
1138
  ...rest,
1131
1139
  ...overlayThemeProps
1132
1140
  }
@@ -1145,6 +1153,8 @@ var DatePicker = (0, import_react.forwardRef)(
1145
1153
  chips,
1146
1154
  activeChip: activeChipValue,
1147
1155
  onChipSelect: handleChipSelect,
1156
+ topContent: renderTopContent,
1157
+ bottomContent: renderBottomContent,
1148
1158
  ...rest,
1149
1159
  ...overlayThemeProps
1150
1160
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../src/DatePicker.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/index.tsx","../../src/utils.ts"],"sourcesContent":["export {\n Calendar,\n DualCalendar,\n CalendarHeader,\n CalendarGrid,\n CalendarChips,\n // Re-exported, not reimplemented, so consumers keep the `formatDate` this package has always shipped.\n formatDate,\n} from \"@xsolla/xui-calendar\";\nexport type {\n CalendarProps,\n DualCalendarProps,\n CalendarChipOption,\n CalendarChipsProps,\n CalendarGridProps,\n CalendarHeaderProps,\n CalendarLocaleType,\n} from \"@xsolla/xui-calendar\";\nexport * from \"./DatePicker\";\nexport * from \"./types\";\nexport * from \"./utils\";\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type ClipboardEvent,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n} from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, isWeb, isNative } from \"@xsolla/xui-primitives\";\nimport { Input } from \"@xsolla/xui-input\";\nimport { parse, isValid } from \"date-fns\";\nimport { Calendar, DualCalendar } from \"@xsolla/xui-calendar\";\nimport { Calendar as CalendarIcon } from \"@xsolla/xui-icons-base\";\nimport type {\n DatePickerAlignment,\n DatePickerDropdownPosition,\n DatePickerPlacement,\n DatePickerProps,\n DatePickerSide,\n DateRangeType,\n} from \"./types\";\nimport {\n buildSegmentedValue,\n clampDatePart,\n datePartsFromDate,\n datePartsToDate,\n isDatePartsComplete,\n isSegmentComplete,\n resolveDateFormat,\n stepDatePart,\n DEFAULT_DATE_FORMAT,\n type DateParts,\n type DateSegmentType,\n} from \"./utils\";\n\nconst PLACEMENT_OFFSET = 4;\n/** Range separator used when parsing typed/pasted text (accepts hyphen or dashes). */\nconst RANGE_SEPARATOR = /\\s*[-–—]\\s*/;\n/** Range separator used when rendering the field. */\nconst RANGE_DISPLAY_SEP = \" - \";\n\n/**\n * Trailing calendar icon matching the Figma `icon_calendar--line`. Uses the\n * shared `@xsolla/xui-icons-base` `Calendar` glyph. The Input tints trailing\n * icons with the placeholder colour (`control/input/placeholder`), so no\n * colour/opacity override is needed here. `size=\"100%\"` fills the icon slot.\n */\nconst CalendarFieldIcon = () => <CalendarIcon size=\"100%\" />;\n// Estimated calendar size used before the overlay has been painted/measured.\nconst FALLBACK_PANEL_SIZE = { width: 320, height: 360 };\n\ninterface ContainerRect {\n top: number;\n bottom: number;\n left: number;\n right: number;\n}\n\n/**\n * Pick the calendar direction with the most available space, preferring\n * bottom, then top, then left, then right (per FEP-822). If nothing fully\n * fits, fall back to whichever side has the largest gap.\n */\nconst resolveAutoPlacement = (\n container: ContainerRect,\n panel: { width: number; height: number },\n viewport: { width: number; height: number },\n offset: number\n): DatePickerSide => {\n const spaceBelow = viewport.height - container.bottom;\n const spaceAbove = container.top;\n const spaceRight = viewport.width - container.right;\n const spaceLeft = container.left;\n const neededVertical = panel.height + offset;\n const neededHorizontal = panel.width + offset;\n\n if (spaceBelow >= neededVertical) return \"bottom\";\n if (spaceAbove >= neededVertical) return \"top\";\n if (spaceLeft >= neededHorizontal) return \"left\";\n if (spaceRight >= neededHorizontal) return \"right\";\n\n const gaps: Array<{ side: DatePickerSide; space: number }> = [\n { side: \"bottom\", space: spaceBelow },\n { side: \"top\", space: spaceAbove },\n { side: \"left\", space: spaceLeft },\n { side: \"right\", space: spaceRight },\n ];\n return gaps.reduce((best, current) =>\n current.space > best.space ? current : best\n ).side;\n};\n\n/** Split a placement into its side and explicit alignment (if any). */\nconst parsePlacement = (\n placement: DatePickerPlacement\n): { side: DatePickerSide; align: DatePickerAlignment | null } => {\n const [side, align] = placement.split(\"-\") as [\n DatePickerSide,\n DatePickerAlignment | undefined,\n ];\n return { side, align: align ?? null };\n};\n\n/** Map the deprecated `dropdownPosition` to an alignment. */\nconst alignFromDropdownPosition = (\n dropdownPosition: DatePickerDropdownPosition\n): DatePickerAlignment => (dropdownPosition === \"right\" ? \"end\" : \"start\");\n\n/**\n * Resolve the forced layout requested via the `placement` prop. The side is\n * always honoured; alignment comes from the suffix when present, otherwise\n * falls back to `dropdownPosition` for top/bottom (and `start` for left/right).\n */\nconst resolveForcedLayout = (\n placement: DatePickerPlacement,\n dropdownPosition: DatePickerDropdownPosition\n): { side: DatePickerSide; align: DatePickerAlignment } => {\n const { side, align } = parsePlacement(placement);\n if (align) return { side, align };\n if (side === \"top\" || side === \"bottom\")\n return { side, align: alignFromDropdownPosition(dropdownPosition) };\n return { side, align: \"start\" };\n};\n\n/**\n * Pick the cross-axis alignment with the most room, flipping start<->end if the\n * calendar would overflow the preferred edge (mirrors the start/end flip in\n * useContextMenuPosition). `center` never flips. The cross axis is horizontal\n * for top/bottom sides and vertical for left/right sides.\n */\nconst resolveAlignForSide = (\n side: DatePickerSide,\n container: ContainerRect,\n panel: { width: number; height: number },\n viewport: { width: number; height: number },\n preferred: DatePickerAlignment\n): DatePickerAlignment => {\n if (preferred === \"center\") return \"center\";\n const isVerticalSide = side === \"left\" || side === \"right\";\n const fits = (align: DatePickerAlignment) => {\n if (isVerticalSide) {\n return align === \"start\"\n ? container.top + panel.height <= viewport.height\n : container.bottom - panel.height >= 0;\n }\n return align === \"start\"\n ? container.left + panel.width <= viewport.width\n : container.right - panel.width >= 0;\n };\n if (fits(preferred)) return preferred;\n const opposite: DatePickerAlignment = preferred === \"start\" ? \"end\" : \"start\";\n return fits(opposite) ? opposite : preferred;\n};\n\n/**\n * Absolute-position style for the calendar overlay given a resolved side and\n * alignment. The side sets the open direction; the alignment sets the cross-axis\n * edge (or centre). Returned as a style object so `transform`-based centring is\n * applied verbatim (matches the ContextMenu panel's `style` usage).\n */\nconst getPlacementStyle = (\n side: DatePickerSide,\n align: DatePickerAlignment,\n offset: number\n): CSSProperties => {\n if (side === \"top\" || side === \"bottom\") {\n const vertical =\n side === \"bottom\"\n ? { top: \"100%\", bottom: \"auto\", marginTop: offset, marginBottom: 0 }\n : { top: \"auto\", bottom: \"100%\", marginTop: 0, marginBottom: offset };\n const horizontal =\n align === \"center\"\n ? { left: \"50%\", right: \"auto\", transform: \"translateX(-50%)\" }\n : align === \"end\"\n ? { left: \"auto\", right: 0 }\n : { left: 0, right: \"auto\" };\n return { marginLeft: 0, marginRight: 0, ...vertical, ...horizontal };\n }\n\n const horizontal =\n side === \"right\"\n ? { left: \"100%\", right: \"auto\", marginLeft: offset, marginRight: 0 }\n : { left: \"auto\", right: \"100%\", marginLeft: 0, marginRight: offset };\n const vertical =\n align === \"center\"\n ? { top: \"50%\", bottom: \"auto\", transform: \"translateY(-50%)\" }\n : align === \"end\"\n ? { top: \"auto\", bottom: 0 }\n : { top: 0, bottom: \"auto\" };\n return { marginTop: 0, marginBottom: 0, ...horizontal, ...vertical };\n};\n\n/** A segment the keyboard can target, identified by its date group + part. */\ntype SegmentKey = { group: number; type: DateSegmentType };\n/** Active segment being typed into, with its accumulated digit buffer. */\ntype EditState = SegmentKey & { buffer: string };\n\nexport const DatePicker = forwardRef<any, DatePickerProps>(\n (\n {\n onChange,\n size = \"md\",\n locale = \"enUS\",\n variant = \"single\",\n selectsRange = false,\n startDate,\n endDate,\n selectedDate,\n minDate,\n maxDate,\n placeholder,\n dateFormat = DEFAULT_DATE_FORMAT,\n backgroundColor,\n testID,\n chips,\n activeChip,\n onChipSelect,\n showChipLabel = true,\n dropdownPosition = \"left\",\n placement,\n themeMode,\n themeProductContext,\n overlayThemeMode,\n overlayThemeProductContext,\n iconRight = <CalendarFieldIcon />,\n iconLeft,\n error,\n errorMessage,\n readOnly,\n onFocus: onFocusProp,\n onBlur: onBlurProp,\n onClick: onClickProp,\n onKeyDown: onKeyDownProp,\n onPaste: onPasteProp,\n ...rest\n },\n ref\n ) => {\n // Editing is disabled for read-only fields (and disabled fields never fire\n // keydown anyway). `disabled` flows to Input via `...rest`.\n const editable = !readOnly && !(rest as { disabled?: boolean }).disabled;\n const isDual = variant === \"dual\";\n const isRange = isDual || selectsRange;\n\n // Repair miscased tokens and fall back on unusable formats, warning once.\n const resolvedFormat = useMemo(\n () => resolveDateFormat(dateFormat),\n [dateFormat]\n );\n\n // Per-side date parts (single = 1 group, range = [start, end]). This is the\n // field's source of truth; `onChange` fires only when a side is complete.\n const propGroups = useCallback(\n (): DateParts[] =>\n isRange\n ? [datePartsFromDate(startDate), datePartsFromDate(endDate)]\n : [datePartsFromDate(selectedDate)],\n [isRange, startDate, endDate, selectedDate]\n );\n\n const [open, setOpen] = useState(false);\n const [groups, setGroups] = useState<DateParts[]>(propGroups);\n const [edit, setEdit] = useState<EditState | null>(null);\n const [focused, setFocused] = useState(false);\n // The segment the keyboard currently targets. Tracked in state (not read from\n // the DOM caret) because the underlying Input resets the caret to the end\n // whenever its controlled value changes; a rAF effect syncs the visible\n // selection to follow this.\n const [activeSegment, setActiveSegment] = useState<SegmentKey | null>(null);\n const [internalChip, setInternalChip] = useState<string | null>(null);\n // Validation message for typed/pasted input that failed to parse or fell\n // outside minDate/maxDate. Cleared on edit and when the selection changes.\n const [parseError, setParseError] = useState<string | null>(null);\n const [layout, setLayout] = useState<{\n side: DatePickerSide;\n align: DatePickerAlignment;\n }>(() =>\n placement\n ? resolveForcedLayout(placement, dropdownPosition)\n : { side: \"bottom\", align: alignFromDropdownPosition(dropdownPosition) }\n );\n const containerRef = useRef<any>(null);\n const calendarRef = useRef<any>(null);\n const inputRef = useRef<any>(null);\n const chipSelectionRef = useRef(false);\n // Set while we programmatically restore focus to the field on Escape, so the\n // resulting focus event does not re-open the panel via `onFocus`.\n const suppressReopenRef = useRef(false);\n\n const activeChipValue =\n activeChip !== undefined ? activeChip : internalChip;\n\n const chipLabel =\n showChipLabel && activeChipValue && chips\n ? chips.find((c) => c.value === activeChipValue)?.label\n : undefined;\n\n /** Day-granularity bounds check against `minDate`/`maxDate` (time ignored). */\n const isWithinBounds = (date: Date): boolean => {\n const day = new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate()\n ).getTime();\n if (minDate) {\n const min = new Date(\n minDate.getFullYear(),\n minDate.getMonth(),\n minDate.getDate()\n ).getTime();\n if (day < min) return false;\n }\n if (maxDate) {\n const max = new Date(\n maxDate.getFullYear(),\n maxDate.getMonth(),\n maxDate.getDate()\n ).getTime();\n if (day > max) return false;\n }\n return true;\n };\n\n // ----- Field text + segment ranges -----\n\n type FieldSegment = {\n type: DateSegmentType;\n start: number;\n end: number;\n filled: boolean;\n group: number;\n };\n\n // Build the field text and each segment's char range from the current parts\n // + in-progress edit buffer. Range mode joins the two dates with \" - \".\n const composeField = (): { text: string; segments: FieldSegment[] } => {\n const build = (group: number) =>\n buildSegmentedValue(\n resolvedFormat,\n groups[group] ?? { day: null, month: null, year: null },\n edit && edit.group === group\n ? { type: edit.type, buffer: edit.buffer }\n : undefined\n );\n if (!isRange) {\n const { text, ranges } = build(0);\n return { text, segments: ranges.map((r) => ({ ...r, group: 0 })) };\n }\n const a = build(0);\n const b = build(1);\n const text = `${a.text}${RANGE_DISPLAY_SEP}${b.text}`;\n const offset = a.text.length + RANGE_DISPLAY_SEP.length;\n return {\n text,\n segments: [\n ...a.ranges.map((r) => ({ ...r, group: 0 })),\n ...b.ranges.map((r) => ({\n ...r,\n group: 1,\n start: r.start + offset,\n end: r.end + offset,\n })),\n ],\n };\n };\n\n const composed = composeField();\n const hasAnyFilled = groups.some(\n (g) => g.day != null || g.month != null || g.year != null\n );\n // Show the plain placeholder when the field is empty; show the segment mask\n // (mm/dd/yyyy) once partially filled, or while focused on web (segment\n // editing is web-only). A chip label wins over both.\n const showMask = hasAnyFilled || (focused && isWeb);\n const inputValue = chipLabel ?? (showMask ? composed.text : \"\");\n\n const orderedSegments = (): FieldSegment[] => composeField().segments;\n\n const firstSegmentKey = (): SegmentKey | null => {\n const first = orderedSegments()[0];\n return first ? { group: first.group, type: first.type } : null;\n };\n\n const segmentKeyAtCaret = (caret: number): SegmentKey | null => {\n const segments = orderedSegments();\n const seg =\n segments.find((s) => caret >= s.start && caret <= s.end) ??\n segments.find((s) => caret < s.start) ??\n segments[segments.length - 1];\n return seg ? { group: seg.group, type: seg.type } : null;\n };\n\n // ----- onChange emission (only complete, in-bounds dates) -----\n\n const applySelection = (\n date: Date | DateRangeType,\n closeOnComplete = true\n ) => {\n if (!chipSelectionRef.current) {\n setInternalChip(null);\n onChipSelect?.(null);\n }\n chipSelectionRef.current = false;\n if (!isRange) {\n onChange?.(date as Date);\n if (closeOnComplete) setOpen(false);\n } else {\n const range = date as DateRangeType;\n onChange?.(range);\n if (closeOnComplete && range[0] && range[1]) setOpen(false);\n }\n };\n\n const emit = (next: DateParts[]) => {\n if (!isRange) {\n const date = datePartsToDate(next[0]);\n if (date && isWithinBounds(date)) applySelection(date, false);\n return;\n }\n const start = datePartsToDate(next[0]);\n const end = datePartsToDate(next[1]);\n if (start && !isWithinBounds(start)) return;\n if (end && !isWithinBounds(end)) return;\n // Inverted range (start after end): mirror MUI's field behaviour — don't\n // reorder (the calendar day-click path already orders); keep the entered\n // values, flag an error, and withhold the invalid range from onChange.\n if (start && end && start.getTime() > end.getTime()) {\n setParseError(\"End date must be after start date\");\n return;\n }\n if (start || end) applySelection([start, end], false);\n };\n\n // Write one segment's value; reject (with a message) if it completes an\n // out-of-bounds date. Returns the clamped value, or null when rejected.\n const commitPart = (\n group: number,\n type: DateSegmentType,\n rawValue: number\n ): number | null => {\n const clamped = clampDatePart(type, rawValue, groups[group]);\n const next = groups.map((g, i) => {\n if (i !== group) return g;\n const updated = { ...g, [type]: clamped };\n // Changing month/year can leave an existing day out of range for the new\n // month (e.g. Jan 31 -> Feb); clamp it down to the month's length.\n if (type !== \"day\" && updated.day != null) {\n updated.day = clampDatePart(\"day\", updated.day, updated);\n }\n return updated;\n });\n const assembled = datePartsToDate(next[group]);\n if (assembled && !isWithinBounds(assembled)) {\n setParseError(\"Date must be within the allowed range\");\n return null;\n }\n setParseError(null);\n setGroups(next);\n emit(next);\n return clamped;\n };\n\n const commitBuffer = () => {\n if (!edit) return;\n commitPart(edit.group, edit.type, Number(edit.buffer));\n setEdit(null);\n };\n\n const defaultPart = (type: DateSegmentType): number => {\n const now = new Date();\n if (type === \"day\") return now.getDate();\n if (type === \"month\") return now.getMonth() + 1;\n return now.getFullYear();\n };\n\n // ----- Keyboard handlers (web) -----\n\n const advance = (active: SegmentKey) => {\n const segments = orderedSegments();\n const index = segments.findIndex(\n (s) => s.group === active.group && s.type === active.type\n );\n const next = segments[index + 1];\n setActiveSegment(next ? { group: next.group, type: next.type } : active);\n };\n\n const handleDigit = (digit: string) => {\n const active = activeSegment ?? firstSegmentKey();\n if (!active) return;\n const sameActive =\n edit && edit.group === active.group && edit.type === active.type;\n const buffer = (sameActive ? edit!.buffer : \"\") + digit;\n if (isSegmentComplete(active.type, buffer)) {\n const committed = commitPart(active.group, active.type, Number(buffer));\n setEdit(null);\n if (committed !== null) advance(active);\n } else {\n setEdit({ group: active.group, type: active.type, buffer });\n }\n };\n\n const handleArrowStep = (\n e: KeyboardEvent<HTMLInputElement>,\n delta: number\n ) => {\n e.preventDefault();\n const active = activeSegment ?? firstSegmentKey();\n if (!active) return;\n const parts = groups[active.group];\n const current = parts[active.type];\n const value =\n current == null\n ? defaultPart(active.type) // first press reveals today's part\n : stepDatePart(active.type, current, delta, parts);\n commitPart(active.group, active.type, value);\n setEdit(null);\n if (!activeSegment) setActiveSegment(active);\n };\n\n const handleArrowMove = (\n e: KeyboardEvent<HTMLInputElement>,\n direction: -1 | 1\n ) => {\n const segments = orderedSegments();\n if (!segments.length) return;\n const active = activeSegment ?? firstSegmentKey();\n if (!active) return;\n let index = segments.findIndex(\n (s) => s.group === active.group && s.type === active.type\n );\n if (index === -1) index = direction > 0 ? -1 : segments.length;\n const next = index + direction;\n if (next < 0 || next >= segments.length) return; // caret may leave at edges\n e.preventDefault();\n if (edit) {\n commitPart(edit.group, edit.type, Number(edit.buffer));\n setEdit(null);\n }\n const target = segments[next];\n setActiveSegment({ group: target.group, type: target.type });\n };\n\n const handleBackspace = (e: KeyboardEvent<HTMLInputElement>) => {\n e.preventDefault();\n const active = activeSegment ?? firstSegmentKey();\n if (!active) return;\n const sameActive =\n edit && edit.group === active.group && edit.type === active.type;\n if (sameActive && edit!.buffer.length > 0) {\n const buffer = edit!.buffer.slice(0, -1);\n setEdit(buffer ? { ...edit!, buffer } : null);\n return;\n }\n // Clear the segment and retreat to the previous one.\n const next = groups.map((g, i) =>\n i === active.group ? { ...g, [active.type]: null } : g\n );\n setGroups(next);\n setEdit(null);\n setParseError(null);\n emit(next);\n const segments = orderedSegments();\n const index = segments.findIndex(\n (s) => s.group === active.group && s.type === active.type\n );\n const prev = segments[index - 1];\n if (prev) setActiveSegment({ group: prev.group, type: prev.type });\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n onKeyDownProp?.(e);\n if (e.defaultPrevented) return;\n if (e.key === \"Escape\") {\n setOpen(false);\n return;\n }\n if (!isWeb || !editable) return;\n if (e.key === \"Enter\") {\n commitBuffer();\n setOpen(false);\n return;\n }\n if (e.key === \"ArrowUp\") return handleArrowStep(e, 1);\n if (e.key === \"ArrowDown\") return handleArrowStep(e, -1);\n if (e.key === \"ArrowLeft\") return handleArrowMove(e, -1);\n if (e.key === \"ArrowRight\") return handleArrowMove(e, 1);\n if (e.key === \"Backspace\") return handleBackspace(e);\n if (/^[0-9]$/.test(e.key)) {\n e.preventDefault();\n handleDigit(e.key);\n return;\n }\n // Block other printable characters so the segment mask stays intact; let\n // shortcuts (Cmd/Ctrl, e.g. paste) and navigation keys through.\n if (e.key.length === 1 && !e.metaKey && !e.ctrlKey) e.preventDefault();\n };\n\n // ----- Focus / click / blur / paste -----\n\n const handleFieldFocus = (e: FocusEvent<HTMLInputElement>) => {\n onFocusProp?.(e);\n if (suppressReopenRef.current) {\n suppressReopenRef.current = false;\n return;\n }\n setFocused(true);\n setOpen(true);\n if (isWeb && editable) setActiveSegment(firstSegmentKey());\n };\n\n const handleFieldClick = (e: MouseEvent<HTMLInputElement>) => {\n onClickProp?.(e);\n // Empty field: focus already targets the first segment, and the value just\n // became the mask (which resets the caret), so trust focus's default.\n if (!isWeb || !editable || !hasAnyFilled) return;\n const input = inputRef.current;\n if (!input) return;\n // Read the caret synchronously — it's already placed by mousedown and a\n // filled field's value doesn't change on focus, so selectionStart is the\n // click position. (Reading it in a rAF would race the visual-sync effect,\n // which by then has moved the caret, and mis-target the segment.) The\n // visual effect then highlights whatever segment we set here.\n const key = segmentKeyAtCaret(input.selectionStart ?? 0);\n if (key) setActiveSegment(key);\n };\n\n const handleFieldBlur = (e: FocusEvent<HTMLInputElement>) => {\n onBlurProp?.(e);\n setFocused(false);\n setActiveSegment(null);\n if (!editable) return;\n let next = groups;\n if (edit) {\n const clamped = clampDatePart(\n edit.type,\n Number(edit.buffer),\n groups[edit.group]\n );\n next = groups.map((g, i) =>\n i === edit.group ? { ...g, [edit.type]: clamped } : g\n );\n }\n // Revert incomplete sides to the committed prop value (don't leave a\n // half-typed date on screen).\n const props = propGroups();\n next = next.map((g, i) => (isDatePartsComplete(g) ? g : props[i]));\n setEdit(null);\n setParseError(null);\n setGroups(next);\n emit(next);\n };\n\n const parseOne = (token: string): Date | null => {\n const trimmed = token.trim();\n if (!trimmed) return null;\n const parsed = parse(trimmed, resolvedFormat, new Date());\n return isValid(parsed) ? parsed : null;\n };\n\n const handlePaste = (e: ClipboardEvent<HTMLInputElement>) => {\n onPasteProp?.(e);\n if (e.defaultPrevented) return;\n if (!isWeb || !editable) return;\n const text = e.clipboardData?.getData(\"text\") ?? \"\";\n if (!text.trim()) return;\n e.preventDefault();\n let next: DateParts[];\n if (isRange) {\n const [startText, endText] = text.split(RANGE_SEPARATOR);\n const start = parseOne(startText ?? \"\");\n const end = parseOne(endText ?? \"\");\n if (!start) {\n setParseError(\n `Enter a valid date range (${resolvedFormat} - ${resolvedFormat})`\n );\n return;\n }\n next = [datePartsFromDate(start), datePartsFromDate(end)];\n } else {\n const date = parseOne(text);\n if (!date) {\n setParseError(`Enter a valid date (${resolvedFormat})`);\n return;\n }\n next = [datePartsFromDate(date)];\n }\n const outOfBounds = next\n .map(datePartsToDate)\n .some((d): d is Date => d instanceof Date && !isWithinBounds(d));\n if (outOfBounds) {\n setParseError(\"Date must be within the allowed range\");\n return;\n }\n setParseError(null);\n setEdit(null);\n setGroups(next);\n emit(next);\n };\n\n const handleChipSelect = (value: string | null) => {\n chipSelectionRef.current = true;\n setInternalChip(value);\n onChipSelect?.(value);\n };\n\n const handleDateChange = (date: Date | DateRangeType) =>\n applySelection(date);\n\n // ----- Effects -----\n\n // Sync from props when they change externally (ignored while focused so it\n // can't clobber in-progress entry; blur handles reverting incomplete sides).\n const propKey = `${selectedDate?.getTime() ?? \"\"}|${\n startDate?.getTime() ?? \"\"\n }|${endDate?.getTime() ?? \"\"}|${isRange}`;\n useEffect(() => {\n if (focused) return;\n setGroups(propGroups());\n setEdit(null);\n setParseError(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [propKey]);\n\n // Keep the visible selection on the active segment. Setting a controlled\n // input's value resets the caret to the end, and the underlying Input lags\n // the DOM value by one render (internal `passValue` state) — sometimes past\n // the next frame. So we wait (retrying a few frames) until the DOM value\n // matches the intended text, then place the caret; by then no further value\n // write will move it.\n useEffect(() => {\n if (!isWeb || !activeSegment) return;\n const input = inputRef.current;\n if (!input) return;\n const segment = composeField().segments.find(\n (s) => s.group === activeSegment.group && s.type === activeSegment.type\n );\n if (!segment) return;\n let rafId = 0;\n let attempts = 0;\n const apply = () => {\n if (document.activeElement !== input) return;\n if (input.value === inputValue) {\n input.setSelectionRange(segment.start, segment.end);\n } else if (attempts++ < 5) {\n rafId = window.requestAnimationFrame(apply);\n }\n };\n rafId = window.requestAnimationFrame(apply);\n return () => window.cancelAnimationFrame(rafId);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeSegment, inputValue]);\n\n useEffect(() => {\n if (isNative) return;\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n const target = event.target as Node | null;\n const container = containerRef.current;\n if (!target || !container) return;\n // The month/year dropdowns (xui-select) portal their listbox to <body>,\n // outside this container, so a click there reads as an outside click.\n // Only suppress the close when the listbox is one of *ours* — i.e. its\n // owning combobox (linked via aria-controls) lives inside this\n // DatePicker. An unrelated listbox elsewhere on the page still dismisses\n // the calendar, as it did before.\n const path =\n typeof event.composedPath === \"function\" ? event.composedPath() : [];\n const listbox: Element | null = path.length\n ? ((path.find(\n (el) =>\n el instanceof Element && el.getAttribute(\"role\") === \"listbox\"\n ) as Element | undefined) ?? null)\n : target instanceof Element\n ? target.closest('[role=\"listbox\"]')\n : null;\n if (listbox?.id) {\n const owner = document.querySelector(\n `[aria-controls=\"${listbox.id}\"]`\n );\n if (owner && container.contains(owner)) return;\n }\n if (!container.contains(target)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () =>\n document.removeEventListener(\"mousedown\", handleClickOutside);\n }, []);\n\n // Escape dismisses the open dialog regardless of which descendant holds\n // focus (WAI-ARIA dialog pattern), covering the \"awaiting end date\" state\n // where focus has moved off the input into the calendar. A native\n // `document` keydown listener is used (not React synthetic) so behaviour is\n // identical across React 16/17+ event-delegation changes; gated on `open`\n // so it doesn't swallow Escape when closed. Closing returns focus to the\n // field. Web only — mirrors the outside-click listener above.\n useEffect(() => {\n if (!open || !isWeb) return;\n const handleEscape = (event: globalThis.KeyboardEvent) => {\n if (event.key !== \"Escape\") return;\n setOpen(false);\n const input = inputRef.current;\n if (input && document.activeElement !== input) {\n suppressReopenRef.current = true;\n input.focus?.();\n }\n };\n document.addEventListener(\"keydown\", handleEscape);\n return () => document.removeEventListener(\"keydown\", handleEscape);\n }, [open]);\n\n // Resolve the open side + alignment whenever the calendar opens. With an\n // explicit `placement` we honour it (using `dropdownPosition` as the\n // alignment fallback when the placement carries no suffix); otherwise we\n // measure the input and calendar against the viewport after paint and flip\n // to the best-fitting side, flipping the cross-axis edge too so a calendar\n // near a viewport edge doesn't clip.\n useEffect(() => {\n if (!open || !isWeb) return;\n if (placement) {\n const next = resolveForcedLayout(placement, dropdownPosition);\n setLayout((prev) =>\n prev.side === next.side && prev.align === next.align ? prev : next\n );\n return;\n }\n\n const compute = () => {\n const container = containerRef.current;\n if (!container) return;\n const containerRect = container.getBoundingClientRect();\n const panelRect = calendarRef.current\n ? calendarRef.current.getBoundingClientRect()\n : FALLBACK_PANEL_SIZE;\n const panel = { width: panelRect.width, height: panelRect.height };\n const viewport = {\n width: window.innerWidth,\n height: window.innerHeight,\n };\n const side = resolveAutoPlacement(\n containerRect,\n panel,\n viewport,\n PLACEMENT_OFFSET\n );\n const preferred: DatePickerAlignment =\n side === \"top\" || side === \"bottom\"\n ? alignFromDropdownPosition(dropdownPosition)\n : \"start\";\n const align = resolveAlignForSide(\n side,\n containerRect,\n panel,\n viewport,\n preferred\n );\n setLayout((prev) =>\n prev.side === side && prev.align === align ? prev : { side, align }\n );\n };\n\n const rafId = window.requestAnimationFrame(compute);\n const handleResize = () => compute();\n window.addEventListener(\"resize\", handleResize);\n return () => {\n window.cancelAnimationFrame(rafId);\n window.removeEventListener(\"resize\", handleResize);\n };\n }, [open, placement, dropdownPosition]);\n\n const overlayThemeProps = {\n themeMode: overlayThemeMode ?? themeMode,\n themeProductContext: overlayThemeProductContext ?? themeProductContext,\n };\n\n // Drive the calendar's visible month so editing navigates the grid. Anchor\n // on the segment being edited (its group's month/year) — so typing/stepping\n // either side of a range moves the view there — falling back to the\n // committed selection. Memoised on year+month so a consumer re-creating the\n // date object each render doesn't churn the view or block manual prev/next.\n const activeParts = activeSegment ? groups[activeSegment.group] : null;\n const editingAnchor =\n activeParts && activeParts.month != null && activeParts.year != null\n ? new Date(activeParts.year, activeParts.month - 1, 1)\n : null;\n const viewAnchor =\n editingAnchor ?? selectedDate ?? startDate ?? endDate ?? null;\n const viewMonth = useMemo(\n () =>\n viewAnchor\n ? new Date(viewAnchor.getFullYear(), viewAnchor.getMonth(), 1)\n : undefined,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [viewAnchor?.getFullYear(), viewAnchor?.getMonth()]\n );\n\n const renderCalendar = () =>\n isDual ? (\n <DualCalendar\n locale={locale}\n startDate={startDate}\n endDate={endDate}\n minDate={minDate}\n maxDate={maxDate}\n month={viewMonth}\n onChange={handleDateChange}\n chips={chips}\n activeChip={activeChipValue}\n onChipSelect={handleChipSelect}\n {...rest}\n {...overlayThemeProps}\n />\n ) : (\n <Calendar\n locale={locale}\n startDate={startDate}\n endDate={endDate}\n selectedDate={selectedDate}\n minDate={minDate}\n maxDate={maxDate}\n month={viewMonth}\n onChange={handleDateChange}\n selectsRange={selectsRange}\n chips={chips}\n activeChip={activeChipValue}\n onChipSelect={handleChipSelect}\n {...rest}\n {...overlayThemeProps}\n />\n );\n\n return (\n <Box\n ref={(node: any) => {\n containerRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as any).current = node;\n }}\n position=\"relative\"\n width=\"100%\"\n {...(isWeb ? { onClick: () => setOpen(true) } : {})}\n >\n <Input\n {...rest}\n ref={inputRef}\n size={size}\n placeholder={\n placeholder || (isRange ? \"Choose a date range\" : \"Choose a date\")\n }\n value={inputValue}\n readOnly={readOnly}\n onFocus={handleFieldFocus}\n onBlur={handleFieldBlur}\n onKeyDown={handleKeyDown}\n onClick={handleFieldClick}\n onPaste={handlePaste}\n iconRight={iconRight}\n iconLeft={iconLeft}\n error={error || !!parseError}\n errorMessage={parseError ?? errorMessage}\n backgroundColor={backgroundColor}\n testID={testID}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n {open &&\n (isWeb ? (\n <Box\n ref={calendarRef}\n role=\"dialog\"\n aria-modal\n aria-label={isRange ? \"Choose a date range\" : \"Choose a date\"}\n // Stop clicks inside the calendar from bubbling to the container's\n // open-on-click handler, which would re-open the panel right after\n // a single-date selection closes it.\n onClick={(e: any) => e.stopPropagation()}\n position=\"absolute\"\n zIndex={1000}\n style={getPlacementStyle(\n layout.side,\n layout.align,\n PLACEMENT_OFFSET\n )}\n >\n {renderCalendar()}\n </Box>\n ) : (\n <Box marginTop={4}>{renderCalendar()}</Box>\n ))}\n </Box>\n );\n }\n);\n\nDatePicker.displayName = \"DatePicker\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n opacity,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n opacity: opacity ?? (disabled ? 0.5 : undefined),\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": ariaDisabled,\n \"aria-live\": ariaLive,\n \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n","export type DateSegmentType = \"day\" | \"month\" | \"year\";\n\n/** A date broken into editable parts; `null` means \"not yet filled\". */\nexport interface DateParts {\n day: number | null;\n month: number | null; // 1-12\n year: number | null;\n}\n\n/** A rendered segment's character span within the field text. */\nexport interface SegmentRange {\n type: DateSegmentType;\n start: number;\n end: number;\n filled: boolean;\n}\n\ntype FormatToken =\n | { kind: \"segment\"; type: DateSegmentType }\n | { kind: \"literal\"; text: string };\n\nconst SEGMENT_WIDTH: Record<DateSegmentType, number> = {\n day: 2,\n month: 2,\n year: 4,\n};\nconst SEGMENT_TOKEN: Record<DateSegmentType, string> = {\n day: \"dd\",\n month: \"mm\",\n year: \"yyyy\",\n};\n\n/** Default format for rendering/parsing the field's text value (overridable via `dateFormat`). */\nexport const DEFAULT_DATE_FORMAT = \"MM/dd/yyyy\";\n\n/** The `date-fns` letters the segmented field understands. */\nconst SEGMENT_LETTER: Record<string, DateSegmentType | undefined> = {\n d: \"day\",\n M: \"month\",\n y: \"year\",\n};\n\n/** Wrong-case letters mapped to the `date-fns` letter meant; all are real tokens themselves, so a repair applies only when the intended letter is absent. */\nconst CASING_REPAIRS: Record<string, string> = { D: \"d\", Y: \"y\", m: \"M\" };\n\nconst SUPPORTED_TOKENS_HINT =\n \"supported tokens are `d`/`dd` (day), `M`/`MM` (month) and `y`/`yyyy` (year); \" +\n \"any other character is a literal separator. Textual and localised tokens \" +\n \"(`MMM`, `MMMM`, `P`, `PP`) are not supported — the field renders numeric \" +\n \"segments only.\";\n\nconst ALL_SEGMENTS: DateSegmentType[] = [\"day\", \"month\", \"year\"];\n\nconst isLetter = (c: string): boolean => /[A-Za-z]/.test(c);\n\n/** Whether a run of the same letter is a token the field can render. */\nconst isSupportedRun = (letter: string, length: number): boolean => {\n if (letter === \"y\") return true; // any year width; always rendered 4-digit\n if (letter === \"d\" || letter === \"M\") return length <= 2; // 3+ is textual\n return false;\n};\n\n/** What is wrong with one token of a `dateFormat`. */\nexport interface DateFormatIssue {\n /** Offending token as written, or the segment name for `kind: \"missing\"`. */\n token: string;\n kind: \"casing\" | \"unsupported\" | \"missing\";\n /** The `date-fns` token to use instead (`casing` only). */\n suggestion?: string;\n}\n\nexport interface DateFormatAnalysis {\n /** The format the field should actually use (repaired input, or the fallback). */\n format: string;\n usedFallback: boolean;\n issues: DateFormatIssue[];\n}\n\n/** Repair a caller's `dateFormat` where the case is unambiguously wrong, else fall back when it is unusable (unsupported token, or a missing segment). */\nexport function analyzeDateFormat(\n format: string,\n fallback: string = DEFAULT_DATE_FORMAT\n): DateFormatAnalysis {\n const issues: DateFormatIssue[] = [];\n // Letters already used, so a case mistake is told apart from the real token.\n const used = new Set<string>();\n for (let i = 0; i < format.length; i++) {\n if (isLetter(format[i])) used.add(format[i]);\n }\n\n let repaired = \"\";\n let hasUnsupported = false;\n let i = 0;\n while (i < format.length) {\n const c = format[i];\n if (!isLetter(c)) {\n repaired += c;\n i++;\n continue;\n }\n let end = i;\n while (end < format.length && format[end] === c) end++;\n const run = format.slice(i, end);\n i = end;\n\n if (isSupportedRun(c, run.length)) {\n repaired += run;\n continue;\n }\n const repair = CASING_REPAIRS[c];\n if (repair && !used.has(repair) && isSupportedRun(repair, run.length)) {\n const fixed = repair.repeat(run.length);\n issues.push({ token: run, kind: \"casing\", suggestion: fixed });\n repaired += fixed;\n continue;\n }\n issues.push({ token: run, kind: \"unsupported\" });\n hasUnsupported = true;\n repaired += run;\n }\n\n const present = new Set(\n parseDateFormat(repaired)\n .filter(\n (t): t is { kind: \"segment\"; type: DateSegmentType } =>\n t.kind === \"segment\"\n )\n .map((t) => t.type)\n );\n const missing = ALL_SEGMENTS.filter((type) => !present.has(type));\n for (const type of missing) issues.push({ token: type, kind: \"missing\" });\n\n const usable = !hasUnsupported && missing.length === 0;\n return {\n format: usable ? repaired : fallback,\n usedFallback: !usable,\n issues,\n };\n}\n\n/** Human-readable warning for a failed {@link analyzeDateFormat}. */\nexport function describeDateFormatIssues(\n format: string,\n analysis: DateFormatAnalysis\n): string {\n const clauses = analysis.issues.map((issue) => {\n if (issue.kind === \"missing\") {\n return `it has no ${issue.token} segment, so the field can never be completed`;\n }\n if (issue.kind === \"casing\") {\n return `\\`${issue.token}\\` is not a \\`date-fns\\` date token — use \\`${issue.suggestion}\\``;\n }\n return `\\`${issue.token}\\` is not a supported token`;\n });\n const resolution = analysis.usedFallback\n ? `Falling back to \\`${analysis.format}\\`.`\n : `Reading it as \\`${analysis.format}\\`.`;\n return (\n `[DatePicker] Invalid \\`dateFormat\\` \\`${format}\\`: ` +\n `${clauses.join(\"; \")}. ${resolution} Note ${SUPPORTED_TOKENS_HINT}`\n );\n}\n\n/** Formats already warned about, so a re-render can't spam the console. */\nconst warnedFormats = new Set<string>();\n\n/** Resolve a `dateFormat` to one the field can render, warning once per offending format in development. See {@link analyzeDateFormat}. */\nexport function resolveDateFormat(\n format: string,\n fallback: string = DEFAULT_DATE_FORMAT\n): string {\n const analysis = analyzeDateFormat(format, fallback);\n if (analysis.issues.length > 0) {\n const key = `${format}|${fallback}`;\n // Read `process` off `globalThis` rather than as a bare global: it is\n // absent in browsers and native, and this package ships no node types.\n // Warn unless explicitly production.\n const isProduction =\n (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process?.env\n ?.NODE_ENV === \"production\";\n if (!isProduction && !warnedFormats.has(key)) {\n warnedFormats.add(key);\n console.warn(describeDateFormatIssues(format, analysis));\n }\n }\n return analysis.format;\n}\n\n/** Split a date format into ordered segment tokens and literal separators. */\nexport function parseDateFormat(format: string): FormatToken[] {\n const tokens: FormatToken[] = [];\n let i = 0;\n while (i < format.length) {\n const c = format[i];\n const type = SEGMENT_LETTER[c];\n if (type) {\n while (i < format.length && format[i] === c) i++;\n tokens.push({ kind: \"segment\", type });\n } else {\n let text = \"\";\n while (i < format.length && !SEGMENT_LETTER[format[i]]) {\n text += format[i];\n i++;\n }\n tokens.push({ kind: \"literal\", text });\n }\n }\n return tokens;\n}\n\nconst EMPTY_PARTS: DateParts = { day: null, month: null, year: null };\n\nexport function datePartsFromDate(date: Date | null | undefined): DateParts {\n if (!date) return { ...EMPTY_PARTS };\n return {\n day: date.getDate(),\n month: date.getMonth() + 1,\n year: date.getFullYear(),\n };\n}\n\n/** Assemble a `Date`, or null if any part is missing or the date is invalid. */\nexport function datePartsToDate(parts: DateParts): Date | null {\n const { day, month, year } = parts;\n if (day == null || month == null || year == null) return null;\n const date = new Date(year, month - 1, day);\n // Reject overflow (e.g. 31 Feb rolling into March).\n if (\n date.getFullYear() !== year ||\n date.getMonth() !== month - 1 ||\n date.getDate() !== day\n ) {\n return null;\n }\n return date;\n}\n\nexport function isDatePartsComplete(parts: DateParts): boolean {\n return parts.day != null && parts.month != null && parts.year != null;\n}\n\n/** Clamp a raw numeric segment value into its valid range. */\nexport function clampDatePart(\n type: DateSegmentType,\n value: number,\n parts: DateParts\n): number {\n if (type === \"month\") return Math.min(12, Math.max(1, value));\n if (type === \"year\") return Math.max(1, value);\n const year = parts.year ?? new Date().getFullYear();\n const monthIndex = (parts.month ?? new Date().getMonth() + 1) - 1;\n return Math.min(daysInMonth(year, monthIndex), Math.max(1, value));\n}\n\n/** Step a numeric segment value, wrapping within its range (day/month) or ±1 (year). */\nexport function stepDatePart(\n type: DateSegmentType,\n current: number,\n delta: number,\n parts: DateParts\n): number {\n if (type === \"month\") return ((((current - 1 + delta) % 12) + 12) % 12) + 1;\n if (type === \"year\") return Math.max(1, current + delta);\n const year = parts.year ?? new Date().getFullYear();\n const monthIndex = (parts.month ?? new Date().getMonth() + 1) - 1;\n const dim = daysInMonth(year, monthIndex);\n return ((((current - 1 + delta) % dim) + dim) % dim) + 1;\n}\n\n/**\n * Render `parts` into field text using `format`, returning each segment's char\n * range. Filled parts are zero-padded; unfilled parts show a token placeholder\n * (`dd`/`mm`/`yyyy`). `active`, when set, renders the raw in-progress buffer for\n * the segment currently being typed.\n */\nexport function buildSegmentedValue(\n format: string,\n parts: DateParts,\n active?: { type: DateSegmentType; buffer: string }\n): { text: string; ranges: SegmentRange[] } {\n const tokens = parseDateFormat(format);\n let text = \"\";\n const ranges: SegmentRange[] = [];\n for (const token of tokens) {\n if (token.kind === \"literal\") {\n text += token.text;\n continue;\n }\n const { type } = token;\n const width = SEGMENT_WIDTH[type];\n const value = parts[type];\n let rendered: string;\n let filled: boolean;\n if (active && active.type === type && active.buffer.length > 0) {\n rendered = active.buffer;\n filled = false;\n } else if (value != null) {\n rendered = String(value).padStart(width, \"0\");\n filled = true;\n } else {\n rendered = SEGMENT_TOKEN[type];\n filled = false;\n }\n const start = text.length;\n text += rendered;\n ranges.push({ type, start, end: text.length, filled });\n }\n return { text, ranges };\n}\n\n/** Whether a first digit rules out a valid second digit (for early auto-commit). */\nexport function isSegmentComplete(\n type: DateSegmentType,\n buffer: string\n): boolean {\n const width = SEGMENT_WIDTH[type];\n if (buffer.length >= width) return true;\n if (buffer.length === 1 && type !== \"year\") {\n const first = Number(buffer);\n // Month tens digit is 0-1, day tens digit is 0-3; anything higher can't take\n // a second digit, so commit immediately.\n return type === \"month\" ? first > 1 : first > 3;\n }\n return false;\n}\n\nexport interface DateSegment {\n type: DateSegmentType;\n /** Inclusive character index of the segment's first digit in `value`. */\n start: number;\n /** Exclusive character index one past the segment's last digit. */\n end: number;\n}\n\n/** Number of days in the given month (0-indexed) of the given year. */\nexport function daysInMonth(year: number, monthIndex: number): number {\n return new Date(year, monthIndex + 1, 0).getDate();\n}\n\n/**\n * Locate the day/month/year segments within a formatted date `value` by walking\n * the `format` string in parallel: `d`/`M`/`y` token runs consume the matching\n * digit run in `value`, other characters are treated as literal separators.\n * Works for any token order (e.g. `MM/dd/yyyy`, `dd/MM/yyyy`, `yyyy-MM-dd`) and\n * both fixed- and variable-width tokens. Returns segments in display order.\n */\nexport function getDateSegments(format: string, value: string): DateSegment[] {\n const segments: DateSegment[] = [];\n let fi = 0;\n let vi = 0;\n while (fi < format.length && vi < value.length) {\n const fc = format[fi];\n if (fc === \"d\" || fc === \"M\" || fc === \"y\") {\n while (fi < format.length && format[fi] === fc) fi++;\n const start = vi;\n while (vi < value.length && value[vi] >= \"0\" && value[vi] <= \"9\") vi++;\n if (vi > start) {\n segments.push({\n type: fc === \"d\" ? \"day\" : fc === \"M\" ? \"month\" : \"year\",\n start,\n end: vi,\n });\n }\n } else {\n // Literal separator (e.g. \"/\", \"-\", \" \"): advance past one char in each.\n fi++;\n vi++;\n }\n }\n return segments;\n}\n\n/**\n * Step a single date segment by `delta`, isolated to that field (no carry):\n * day wraps within the current month, month wraps within the year (day clamped\n * to the new month's length), year increments freely. Mirrors the segment wrap\n * behaviour of the InputTime segments.\n */\nexport function stepDateSegment(\n date: Date,\n type: DateSegmentType,\n delta: number\n): Date {\n const year = date.getFullYear();\n const month = date.getMonth();\n const day = date.getDate();\n\n if (type === \"year\") {\n const nextYear = year + delta;\n return new Date(\n nextYear,\n month,\n Math.min(day, daysInMonth(nextYear, month))\n );\n }\n if (type === \"month\") {\n const nextMonth = (((month + delta) % 12) + 12) % 12;\n return new Date(\n year,\n nextMonth,\n Math.min(day, daysInMonth(year, nextMonth))\n );\n }\n const dim = daysInMonth(year, month);\n const nextDay = ((((day - 1 + delta) % dim) + dim) % dim) + 1;\n return new Date(year, month, nextDay);\n}\n"],"mappings":"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","names":["import_xui_calendar","i","import_jsx_runtime","CalendarIcon","vertical","horizontal","text"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../src/DatePicker.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/index.tsx","../../src/utils.ts"],"sourcesContent":["export {\n Calendar,\n DualCalendar,\n CalendarHeader,\n CalendarGrid,\n CalendarChips,\n // Re-exported, not reimplemented, so consumers keep the `formatDate` this package has always shipped.\n formatDate,\n} from \"@xsolla/xui-calendar\";\nexport type {\n CalendarProps,\n DualCalendarProps,\n CalendarChipOption,\n CalendarChipsProps,\n CalendarGridProps,\n CalendarHeaderProps,\n CalendarLocaleType,\n} from \"@xsolla/xui-calendar\";\nexport * from \"./DatePicker\";\nexport * from \"./types\";\nexport * from \"./utils\";\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type ClipboardEvent,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n} from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, isWeb, isNative } from \"@xsolla/xui-primitives\";\nimport { Input } from \"@xsolla/xui-input\";\nimport { parse, isValid } from \"date-fns\";\nimport { Calendar, DualCalendar } from \"@xsolla/xui-calendar\";\nimport { Calendar as CalendarIcon } from \"@xsolla/xui-icons-base\";\nimport type {\n DatePickerAlignment,\n DatePickerDropdownPosition,\n DatePickerPlacement,\n DatePickerProps,\n DatePickerSide,\n DateRangeType,\n} from \"./types\";\nimport {\n buildSegmentedValue,\n clampDatePart,\n datePartsFromDate,\n datePartsToDate,\n isDatePartsComplete,\n isSegmentComplete,\n resolveDateFormat,\n stepDatePart,\n DEFAULT_DATE_FORMAT,\n type DateParts,\n type DateSegmentType,\n} from \"./utils\";\n\nconst PLACEMENT_OFFSET = 4;\n/** Range separator used when parsing typed/pasted text (accepts hyphen or dashes). */\nconst RANGE_SEPARATOR = /\\s*[-–—]\\s*/;\n/** Range separator used when rendering the field. */\nconst RANGE_DISPLAY_SEP = \" - \";\n\n/**\n * Trailing calendar icon matching the Figma `icon_calendar--line`. Uses the\n * shared `@xsolla/xui-icons-base` `Calendar` glyph. The Input tints trailing\n * icons with the placeholder colour (`control/input/placeholder`), so no\n * colour/opacity override is needed here. `size=\"100%\"` fills the icon slot.\n */\nconst CalendarFieldIcon = () => <CalendarIcon size=\"100%\" />;\n// Estimated calendar size used before the overlay has been painted/measured.\nconst FALLBACK_PANEL_SIZE = { width: 320, height: 360 };\n\ninterface ContainerRect {\n top: number;\n bottom: number;\n left: number;\n right: number;\n}\n\n/**\n * Pick the calendar direction with the most available space, preferring\n * bottom, then top, then left, then right (per FEP-822). If nothing fully\n * fits, fall back to whichever side has the largest gap.\n */\nconst resolveAutoPlacement = (\n container: ContainerRect,\n panel: { width: number; height: number },\n viewport: { width: number; height: number },\n offset: number\n): DatePickerSide => {\n const spaceBelow = viewport.height - container.bottom;\n const spaceAbove = container.top;\n const spaceRight = viewport.width - container.right;\n const spaceLeft = container.left;\n const neededVertical = panel.height + offset;\n const neededHorizontal = panel.width + offset;\n\n if (spaceBelow >= neededVertical) return \"bottom\";\n if (spaceAbove >= neededVertical) return \"top\";\n if (spaceLeft >= neededHorizontal) return \"left\";\n if (spaceRight >= neededHorizontal) return \"right\";\n\n const gaps: Array<{ side: DatePickerSide; space: number }> = [\n { side: \"bottom\", space: spaceBelow },\n { side: \"top\", space: spaceAbove },\n { side: \"left\", space: spaceLeft },\n { side: \"right\", space: spaceRight },\n ];\n return gaps.reduce((best, current) =>\n current.space > best.space ? current : best\n ).side;\n};\n\n/** Split a placement into its side and explicit alignment (if any). */\nconst parsePlacement = (\n placement: DatePickerPlacement\n): { side: DatePickerSide; align: DatePickerAlignment | null } => {\n const [side, align] = placement.split(\"-\") as [\n DatePickerSide,\n DatePickerAlignment | undefined,\n ];\n return { side, align: align ?? null };\n};\n\n/** Map the deprecated `dropdownPosition` to an alignment. */\nconst alignFromDropdownPosition = (\n dropdownPosition: DatePickerDropdownPosition\n): DatePickerAlignment => (dropdownPosition === \"right\" ? \"end\" : \"start\");\n\n/**\n * Resolve the forced layout requested via the `placement` prop. The side is\n * always honoured; alignment comes from the suffix when present, otherwise\n * falls back to `dropdownPosition` for top/bottom (and `start` for left/right).\n */\nconst resolveForcedLayout = (\n placement: DatePickerPlacement,\n dropdownPosition: DatePickerDropdownPosition\n): { side: DatePickerSide; align: DatePickerAlignment } => {\n const { side, align } = parsePlacement(placement);\n if (align) return { side, align };\n if (side === \"top\" || side === \"bottom\")\n return { side, align: alignFromDropdownPosition(dropdownPosition) };\n return { side, align: \"start\" };\n};\n\n/**\n * Pick the cross-axis alignment with the most room, flipping start<->end if the\n * calendar would overflow the preferred edge (mirrors the start/end flip in\n * useContextMenuPosition). `center` never flips. The cross axis is horizontal\n * for top/bottom sides and vertical for left/right sides.\n */\nconst resolveAlignForSide = (\n side: DatePickerSide,\n container: ContainerRect,\n panel: { width: number; height: number },\n viewport: { width: number; height: number },\n preferred: DatePickerAlignment\n): DatePickerAlignment => {\n if (preferred === \"center\") return \"center\";\n const isVerticalSide = side === \"left\" || side === \"right\";\n const fits = (align: DatePickerAlignment) => {\n if (isVerticalSide) {\n return align === \"start\"\n ? container.top + panel.height <= viewport.height\n : container.bottom - panel.height >= 0;\n }\n return align === \"start\"\n ? container.left + panel.width <= viewport.width\n : container.right - panel.width >= 0;\n };\n if (fits(preferred)) return preferred;\n const opposite: DatePickerAlignment = preferred === \"start\" ? \"end\" : \"start\";\n return fits(opposite) ? opposite : preferred;\n};\n\n/**\n * Absolute-position style for the calendar overlay given a resolved side and\n * alignment. The side sets the open direction; the alignment sets the cross-axis\n * edge (or centre). Returned as a style object so `transform`-based centring is\n * applied verbatim (matches the ContextMenu panel's `style` usage).\n */\nconst getPlacementStyle = (\n side: DatePickerSide,\n align: DatePickerAlignment,\n offset: number\n): CSSProperties => {\n if (side === \"top\" || side === \"bottom\") {\n const vertical =\n side === \"bottom\"\n ? { top: \"100%\", bottom: \"auto\", marginTop: offset, marginBottom: 0 }\n : { top: \"auto\", bottom: \"100%\", marginTop: 0, marginBottom: offset };\n const horizontal =\n align === \"center\"\n ? { left: \"50%\", right: \"auto\", transform: \"translateX(-50%)\" }\n : align === \"end\"\n ? { left: \"auto\", right: 0 }\n : { left: 0, right: \"auto\" };\n return { marginLeft: 0, marginRight: 0, ...vertical, ...horizontal };\n }\n\n const horizontal =\n side === \"right\"\n ? { left: \"100%\", right: \"auto\", marginLeft: offset, marginRight: 0 }\n : { left: \"auto\", right: \"100%\", marginLeft: 0, marginRight: offset };\n const vertical =\n align === \"center\"\n ? { top: \"50%\", bottom: \"auto\", transform: \"translateY(-50%)\" }\n : align === \"end\"\n ? { top: \"auto\", bottom: 0 }\n : { top: 0, bottom: \"auto\" };\n return { marginTop: 0, marginBottom: 0, ...horizontal, ...vertical };\n};\n\n/** A segment the keyboard can target, identified by its date group + part. */\ntype SegmentKey = { group: number; type: DateSegmentType };\n/** Active segment being typed into, with its accumulated digit buffer. */\ntype EditState = SegmentKey & { buffer: string };\n\nexport const DatePicker = forwardRef<any, DatePickerProps>(\n (\n {\n onChange,\n size = \"md\",\n locale = \"enUS\",\n variant = \"single\",\n selectsRange = false,\n startDate,\n endDate,\n selectedDate,\n minDate,\n maxDate,\n placeholder,\n dateFormat = DEFAULT_DATE_FORMAT,\n backgroundColor,\n testID,\n chips,\n activeChip,\n onChipSelect,\n showChipLabel = true,\n dropdownPosition = \"left\",\n placement,\n closeOnComplete = true,\n topContent,\n bottomContent,\n themeMode,\n themeProductContext,\n overlayThemeMode,\n overlayThemeProductContext,\n iconRight = <CalendarFieldIcon />,\n iconLeft,\n error,\n errorMessage,\n readOnly,\n onFocus: onFocusProp,\n onBlur: onBlurProp,\n onClick: onClickProp,\n onKeyDown: onKeyDownProp,\n onPaste: onPasteProp,\n ...rest\n },\n ref\n ) => {\n // Editing is disabled for read-only fields (and disabled fields never fire\n // keydown anyway). `disabled` flows to Input via `...rest`.\n const editable = !readOnly && !(rest as { disabled?: boolean }).disabled;\n const isDual = variant === \"dual\";\n const isRange = isDual || selectsRange;\n\n // Repair miscased tokens and fall back on unusable formats, warning once.\n const resolvedFormat = useMemo(\n () => resolveDateFormat(dateFormat),\n [dateFormat]\n );\n\n // Per-side date parts (single = 1 group, range = [start, end]). This is the\n // field's source of truth; `onChange` fires only when a side is complete.\n const propGroups = useCallback(\n (): DateParts[] =>\n isRange\n ? [datePartsFromDate(startDate), datePartsFromDate(endDate)]\n : [datePartsFromDate(selectedDate)],\n [isRange, startDate, endDate, selectedDate]\n );\n\n const [open, setOpen] = useState(false);\n const [groups, setGroups] = useState<DateParts[]>(propGroups);\n const [edit, setEdit] = useState<EditState | null>(null);\n const [focused, setFocused] = useState(false);\n // The segment the keyboard currently targets. Tracked in state (not read from\n // the DOM caret) because the underlying Input resets the caret to the end\n // whenever its controlled value changes; a rAF effect syncs the visible\n // selection to follow this.\n const [activeSegment, setActiveSegment] = useState<SegmentKey | null>(null);\n const [internalChip, setInternalChip] = useState<string | null>(null);\n // Validation message for typed/pasted input that failed to parse or fell\n // outside minDate/maxDate. Cleared on edit and when the selection changes.\n const [parseError, setParseError] = useState<string | null>(null);\n const [layout, setLayout] = useState<{\n side: DatePickerSide;\n align: DatePickerAlignment;\n }>(() =>\n placement\n ? resolveForcedLayout(placement, dropdownPosition)\n : { side: \"bottom\", align: alignFromDropdownPosition(dropdownPosition) }\n );\n const containerRef = useRef<any>(null);\n const calendarRef = useRef<any>(null);\n const inputRef = useRef<any>(null);\n const chipSelectionRef = useRef(false);\n // Set while we programmatically restore focus to the field on Escape, so the\n // resulting focus event does not re-open the panel via `onFocus`.\n const suppressReopenRef = useRef(false);\n\n const activeChipValue =\n activeChip !== undefined ? activeChip : internalChip;\n\n const chipLabel =\n showChipLabel && activeChipValue && chips\n ? chips.find((c) => c.value === activeChipValue)?.label\n : undefined;\n\n /** Day-granularity bounds check against `minDate`/`maxDate` (time ignored). */\n const isWithinBounds = (date: Date): boolean => {\n const day = new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate()\n ).getTime();\n if (minDate) {\n const min = new Date(\n minDate.getFullYear(),\n minDate.getMonth(),\n minDate.getDate()\n ).getTime();\n if (day < min) return false;\n }\n if (maxDate) {\n const max = new Date(\n maxDate.getFullYear(),\n maxDate.getMonth(),\n maxDate.getDate()\n ).getTime();\n if (day > max) return false;\n }\n return true;\n };\n\n // ----- Field text + segment ranges -----\n\n type FieldSegment = {\n type: DateSegmentType;\n start: number;\n end: number;\n filled: boolean;\n group: number;\n };\n\n // Build the field text and each segment's char range from the current parts\n // + in-progress edit buffer. Range mode joins the two dates with \" - \".\n const composeField = (): { text: string; segments: FieldSegment[] } => {\n const build = (group: number) =>\n buildSegmentedValue(\n resolvedFormat,\n groups[group] ?? { day: null, month: null, year: null },\n edit && edit.group === group\n ? { type: edit.type, buffer: edit.buffer }\n : undefined\n );\n if (!isRange) {\n const { text, ranges } = build(0);\n return { text, segments: ranges.map((r) => ({ ...r, group: 0 })) };\n }\n const a = build(0);\n const b = build(1);\n const text = `${a.text}${RANGE_DISPLAY_SEP}${b.text}`;\n const offset = a.text.length + RANGE_DISPLAY_SEP.length;\n return {\n text,\n segments: [\n ...a.ranges.map((r) => ({ ...r, group: 0 })),\n ...b.ranges.map((r) => ({\n ...r,\n group: 1,\n start: r.start + offset,\n end: r.end + offset,\n })),\n ],\n };\n };\n\n const composed = composeField();\n const hasAnyFilled = groups.some(\n (g) => g.day != null || g.month != null || g.year != null\n );\n // Show the plain placeholder when the field is empty; show the segment mask\n // (mm/dd/yyyy) once partially filled, or while focused on web (segment\n // editing is web-only). A chip label wins over both.\n const showMask = hasAnyFilled || (focused && isWeb);\n const inputValue = chipLabel ?? (showMask ? composed.text : \"\");\n\n const orderedSegments = (): FieldSegment[] => composeField().segments;\n\n const firstSegmentKey = (): SegmentKey | null => {\n const first = orderedSegments()[0];\n return first ? { group: first.group, type: first.type } : null;\n };\n\n const segmentKeyAtCaret = (caret: number): SegmentKey | null => {\n const segments = orderedSegments();\n const seg =\n segments.find((s) => caret >= s.start && caret <= s.end) ??\n segments.find((s) => caret < s.start) ??\n segments[segments.length - 1];\n return seg ? { group: seg.group, type: seg.type } : null;\n };\n\n // ----- onChange emission (only complete, in-bounds dates) -----\n\n const applySelection = (\n date: Date | DateRangeType,\n closeOnComplete = true\n ) => {\n if (!chipSelectionRef.current) {\n setInternalChip(null);\n onChipSelect?.(null);\n }\n chipSelectionRef.current = false;\n if (!isRange) {\n onChange?.(date as Date);\n if (closeOnComplete) setOpen(false);\n } else {\n const range = date as DateRangeType;\n onChange?.(range);\n if (closeOnComplete && range[0] && range[1]) setOpen(false);\n }\n };\n\n const emit = (next: DateParts[]) => {\n if (!isRange) {\n const date = datePartsToDate(next[0]);\n if (date && isWithinBounds(date)) applySelection(date, false);\n return;\n }\n const start = datePartsToDate(next[0]);\n const end = datePartsToDate(next[1]);\n if (start && !isWithinBounds(start)) return;\n if (end && !isWithinBounds(end)) return;\n // Inverted range (start after end): mirror MUI's field behaviour — don't\n // reorder (the calendar day-click path already orders); keep the entered\n // values, flag an error, and withhold the invalid range from onChange.\n if (start && end && start.getTime() > end.getTime()) {\n setParseError(\"End date must be after start date\");\n return;\n }\n if (start || end) applySelection([start, end], false);\n };\n\n // Write one segment's value; reject (with a message) if it completes an\n // out-of-bounds date. Returns the clamped value, or null when rejected.\n const commitPart = (\n group: number,\n type: DateSegmentType,\n rawValue: number\n ): number | null => {\n const clamped = clampDatePart(type, rawValue, groups[group]);\n const next = groups.map((g, i) => {\n if (i !== group) return g;\n const updated = { ...g, [type]: clamped };\n // Changing month/year can leave an existing day out of range for the new\n // month (e.g. Jan 31 -> Feb); clamp it down to the month's length.\n if (type !== \"day\" && updated.day != null) {\n updated.day = clampDatePart(\"day\", updated.day, updated);\n }\n return updated;\n });\n const assembled = datePartsToDate(next[group]);\n if (assembled && !isWithinBounds(assembled)) {\n setParseError(\"Date must be within the allowed range\");\n return null;\n }\n setParseError(null);\n setGroups(next);\n emit(next);\n return clamped;\n };\n\n const commitBuffer = () => {\n if (!edit) return;\n commitPart(edit.group, edit.type, Number(edit.buffer));\n setEdit(null);\n };\n\n const defaultPart = (type: DateSegmentType): number => {\n const now = new Date();\n if (type === \"day\") return now.getDate();\n if (type === \"month\") return now.getMonth() + 1;\n return now.getFullYear();\n };\n\n // ----- Keyboard handlers (web) -----\n\n const advance = (active: SegmentKey) => {\n const segments = orderedSegments();\n const index = segments.findIndex(\n (s) => s.group === active.group && s.type === active.type\n );\n const next = segments[index + 1];\n setActiveSegment(next ? { group: next.group, type: next.type } : active);\n };\n\n const handleDigit = (digit: string) => {\n const active = activeSegment ?? firstSegmentKey();\n if (!active) return;\n const sameActive =\n edit && edit.group === active.group && edit.type === active.type;\n const buffer = (sameActive ? edit!.buffer : \"\") + digit;\n if (isSegmentComplete(active.type, buffer)) {\n const committed = commitPart(active.group, active.type, Number(buffer));\n setEdit(null);\n if (committed !== null) advance(active);\n } else {\n setEdit({ group: active.group, type: active.type, buffer });\n }\n };\n\n const handleArrowStep = (\n e: KeyboardEvent<HTMLInputElement>,\n delta: number\n ) => {\n e.preventDefault();\n const active = activeSegment ?? firstSegmentKey();\n if (!active) return;\n const parts = groups[active.group];\n const current = parts[active.type];\n const value =\n current == null\n ? defaultPart(active.type) // first press reveals today's part\n : stepDatePart(active.type, current, delta, parts);\n commitPart(active.group, active.type, value);\n setEdit(null);\n if (!activeSegment) setActiveSegment(active);\n };\n\n const handleArrowMove = (\n e: KeyboardEvent<HTMLInputElement>,\n direction: -1 | 1\n ) => {\n const segments = orderedSegments();\n if (!segments.length) return;\n const active = activeSegment ?? firstSegmentKey();\n if (!active) return;\n let index = segments.findIndex(\n (s) => s.group === active.group && s.type === active.type\n );\n if (index === -1) index = direction > 0 ? -1 : segments.length;\n const next = index + direction;\n if (next < 0 || next >= segments.length) return; // caret may leave at edges\n e.preventDefault();\n if (edit) {\n commitPart(edit.group, edit.type, Number(edit.buffer));\n setEdit(null);\n }\n const target = segments[next];\n setActiveSegment({ group: target.group, type: target.type });\n };\n\n const handleBackspace = (e: KeyboardEvent<HTMLInputElement>) => {\n e.preventDefault();\n const active = activeSegment ?? firstSegmentKey();\n if (!active) return;\n const sameActive =\n edit && edit.group === active.group && edit.type === active.type;\n if (sameActive && edit!.buffer.length > 0) {\n const buffer = edit!.buffer.slice(0, -1);\n setEdit(buffer ? { ...edit!, buffer } : null);\n return;\n }\n // Clear the segment and retreat to the previous one.\n const next = groups.map((g, i) =>\n i === active.group ? { ...g, [active.type]: null } : g\n );\n setGroups(next);\n setEdit(null);\n setParseError(null);\n emit(next);\n const segments = orderedSegments();\n const index = segments.findIndex(\n (s) => s.group === active.group && s.type === active.type\n );\n const prev = segments[index - 1];\n if (prev) setActiveSegment({ group: prev.group, type: prev.type });\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n onKeyDownProp?.(e);\n if (e.defaultPrevented) return;\n if (e.key === \"Escape\") {\n setOpen(false);\n return;\n }\n if (!isWeb || !editable) return;\n if (e.key === \"Enter\") {\n commitBuffer();\n setOpen(false);\n return;\n }\n if (e.key === \"ArrowUp\") return handleArrowStep(e, 1);\n if (e.key === \"ArrowDown\") return handleArrowStep(e, -1);\n if (e.key === \"ArrowLeft\") return handleArrowMove(e, -1);\n if (e.key === \"ArrowRight\") return handleArrowMove(e, 1);\n if (e.key === \"Backspace\") return handleBackspace(e);\n if (/^[0-9]$/.test(e.key)) {\n e.preventDefault();\n handleDigit(e.key);\n return;\n }\n // Block other printable characters so the segment mask stays intact; let\n // shortcuts (Cmd/Ctrl, e.g. paste) and navigation keys through.\n if (e.key.length === 1 && !e.metaKey && !e.ctrlKey) e.preventDefault();\n };\n\n // ----- Focus / click / blur / paste -----\n\n const handleFieldFocus = (e: FocusEvent<HTMLInputElement>) => {\n onFocusProp?.(e);\n if (suppressReopenRef.current) {\n suppressReopenRef.current = false;\n return;\n }\n setFocused(true);\n setOpen(true);\n if (isWeb && editable) setActiveSegment(firstSegmentKey());\n };\n\n const handleFieldClick = (e: MouseEvent<HTMLInputElement>) => {\n onClickProp?.(e);\n // Empty field: focus already targets the first segment, and the value just\n // became the mask (which resets the caret), so trust focus's default.\n if (!isWeb || !editable || !hasAnyFilled) return;\n const input = inputRef.current;\n if (!input) return;\n // Read the caret synchronously — it's already placed by mousedown and a\n // filled field's value doesn't change on focus, so selectionStart is the\n // click position. (Reading it in a rAF would race the visual-sync effect,\n // which by then has moved the caret, and mis-target the segment.) The\n // visual effect then highlights whatever segment we set here.\n const key = segmentKeyAtCaret(input.selectionStart ?? 0);\n if (key) setActiveSegment(key);\n };\n\n const handleFieldBlur = (e: FocusEvent<HTMLInputElement>) => {\n onBlurProp?.(e);\n setFocused(false);\n setActiveSegment(null);\n if (!editable) return;\n let next = groups;\n if (edit) {\n const clamped = clampDatePart(\n edit.type,\n Number(edit.buffer),\n groups[edit.group]\n );\n next = groups.map((g, i) =>\n i === edit.group ? { ...g, [edit.type]: clamped } : g\n );\n }\n // Revert incomplete sides to the committed prop value (don't leave a\n // half-typed date on screen).\n const props = propGroups();\n next = next.map((g, i) => (isDatePartsComplete(g) ? g : props[i]));\n setEdit(null);\n setParseError(null);\n setGroups(next);\n emit(next);\n };\n\n const parseOne = (token: string): Date | null => {\n const trimmed = token.trim();\n if (!trimmed) return null;\n const parsed = parse(trimmed, resolvedFormat, new Date());\n return isValid(parsed) ? parsed : null;\n };\n\n const handlePaste = (e: ClipboardEvent<HTMLInputElement>) => {\n onPasteProp?.(e);\n if (e.defaultPrevented) return;\n if (!isWeb || !editable) return;\n const text = e.clipboardData?.getData(\"text\") ?? \"\";\n if (!text.trim()) return;\n e.preventDefault();\n let next: DateParts[];\n if (isRange) {\n const [startText, endText] = text.split(RANGE_SEPARATOR);\n const start = parseOne(startText ?? \"\");\n const end = parseOne(endText ?? \"\");\n if (!start) {\n setParseError(\n `Enter a valid date range (${resolvedFormat} - ${resolvedFormat})`\n );\n return;\n }\n next = [datePartsFromDate(start), datePartsFromDate(end)];\n } else {\n const date = parseOne(text);\n if (!date) {\n setParseError(`Enter a valid date (${resolvedFormat})`);\n return;\n }\n next = [datePartsFromDate(date)];\n }\n const outOfBounds = next\n .map(datePartsToDate)\n .some((d): d is Date => d instanceof Date && !isWithinBounds(d));\n if (outOfBounds) {\n setParseError(\"Date must be within the allowed range\");\n return;\n }\n setParseError(null);\n setEdit(null);\n setGroups(next);\n emit(next);\n };\n\n const handleChipSelect = (value: string | null) => {\n chipSelectionRef.current = true;\n setInternalChip(value);\n onChipSelect?.(value);\n };\n\n const handleDateChange = (date: Date | DateRangeType) =>\n applySelection(date, closeOnComplete);\n\n // The calendar packages call `topContent`/`bottomContent` with a no-op\n // `close`, because the panel's open state lives here, not in the calendar.\n // Substitute a real dismisser so a footer action (the Apply button that\n // `closeOnComplete={false}` exists to make reachable) can close the picker.\n const closePanel = useCallback(() => setOpen(false), []);\n const renderTopContent = topContent\n ? () => topContent({ close: closePanel })\n : undefined;\n const renderBottomContent = bottomContent\n ? () => bottomContent({ close: closePanel })\n : undefined;\n\n // ----- Effects -----\n\n // Sync from props when they change externally (ignored while focused so it\n // can't clobber in-progress entry; blur handles reverting incomplete sides).\n const propKey = `${selectedDate?.getTime() ?? \"\"}|${\n startDate?.getTime() ?? \"\"\n }|${endDate?.getTime() ?? \"\"}|${isRange}`;\n useEffect(() => {\n if (focused) return;\n setGroups(propGroups());\n setEdit(null);\n setParseError(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [propKey]);\n\n // Keep the visible selection on the active segment. Setting a controlled\n // input's value resets the caret to the end, and the underlying Input lags\n // the DOM value by one render (internal `passValue` state) — sometimes past\n // the next frame. So we wait (retrying a few frames) until the DOM value\n // matches the intended text, then place the caret; by then no further value\n // write will move it.\n useEffect(() => {\n if (!isWeb || !activeSegment) return;\n const input = inputRef.current;\n if (!input) return;\n const segment = composeField().segments.find(\n (s) => s.group === activeSegment.group && s.type === activeSegment.type\n );\n if (!segment) return;\n let rafId = 0;\n let attempts = 0;\n const apply = () => {\n if (document.activeElement !== input) return;\n if (input.value === inputValue) {\n input.setSelectionRange(segment.start, segment.end);\n } else if (attempts++ < 5) {\n rafId = window.requestAnimationFrame(apply);\n }\n };\n rafId = window.requestAnimationFrame(apply);\n return () => window.cancelAnimationFrame(rafId);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeSegment, inputValue]);\n\n useEffect(() => {\n if (isNative) return;\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n const target = event.target as Node | null;\n const container = containerRef.current;\n if (!target || !container) return;\n // The month/year dropdowns (xui-select) portal their listbox to <body>,\n // outside this container, so a click there reads as an outside click.\n // Only suppress the close when the listbox is one of *ours* — i.e. its\n // owning combobox (linked via aria-controls) lives inside this\n // DatePicker. An unrelated listbox elsewhere on the page still dismisses\n // the calendar, as it did before.\n const path =\n typeof event.composedPath === \"function\" ? event.composedPath() : [];\n const listbox: Element | null = path.length\n ? ((path.find(\n (el) =>\n el instanceof Element && el.getAttribute(\"role\") === \"listbox\"\n ) as Element | undefined) ?? null)\n : target instanceof Element\n ? target.closest('[role=\"listbox\"]')\n : null;\n if (listbox?.id) {\n const owner = document.querySelector(\n `[aria-controls=\"${listbox.id}\"]`\n );\n if (owner && container.contains(owner)) return;\n }\n if (!container.contains(target)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () =>\n document.removeEventListener(\"mousedown\", handleClickOutside);\n }, []);\n\n // Escape dismisses the open dialog regardless of which descendant holds\n // focus (WAI-ARIA dialog pattern), covering the \"awaiting end date\" state\n // where focus has moved off the input into the calendar. A native\n // `document` keydown listener is used (not React synthetic) so behaviour is\n // identical across React 16/17+ event-delegation changes; gated on `open`\n // so it doesn't swallow Escape when closed. Closing returns focus to the\n // field. Web only — mirrors the outside-click listener above.\n useEffect(() => {\n if (!open || !isWeb) return;\n const handleEscape = (event: globalThis.KeyboardEvent) => {\n if (event.key !== \"Escape\") return;\n setOpen(false);\n const input = inputRef.current;\n if (input && document.activeElement !== input) {\n suppressReopenRef.current = true;\n input.focus?.();\n }\n };\n document.addEventListener(\"keydown\", handleEscape);\n return () => document.removeEventListener(\"keydown\", handleEscape);\n }, [open]);\n\n // Resolve the open side + alignment whenever the calendar opens. With an\n // explicit `placement` we honour it (using `dropdownPosition` as the\n // alignment fallback when the placement carries no suffix); otherwise we\n // measure the input and calendar against the viewport after paint and flip\n // to the best-fitting side, flipping the cross-axis edge too so a calendar\n // near a viewport edge doesn't clip.\n useEffect(() => {\n if (!open || !isWeb) return;\n if (placement) {\n const next = resolveForcedLayout(placement, dropdownPosition);\n setLayout((prev) =>\n prev.side === next.side && prev.align === next.align ? prev : next\n );\n return;\n }\n\n const compute = () => {\n const container = containerRef.current;\n if (!container) return;\n const containerRect = container.getBoundingClientRect();\n const panelRect = calendarRef.current\n ? calendarRef.current.getBoundingClientRect()\n : FALLBACK_PANEL_SIZE;\n const panel = { width: panelRect.width, height: panelRect.height };\n const viewport = {\n width: window.innerWidth,\n height: window.innerHeight,\n };\n const side = resolveAutoPlacement(\n containerRect,\n panel,\n viewport,\n PLACEMENT_OFFSET\n );\n const preferred: DatePickerAlignment =\n side === \"top\" || side === \"bottom\"\n ? alignFromDropdownPosition(dropdownPosition)\n : \"start\";\n const align = resolveAlignForSide(\n side,\n containerRect,\n panel,\n viewport,\n preferred\n );\n setLayout((prev) =>\n prev.side === side && prev.align === align ? prev : { side, align }\n );\n };\n\n const rafId = window.requestAnimationFrame(compute);\n const handleResize = () => compute();\n window.addEventListener(\"resize\", handleResize);\n return () => {\n window.cancelAnimationFrame(rafId);\n window.removeEventListener(\"resize\", handleResize);\n };\n }, [open, placement, dropdownPosition]);\n\n const overlayThemeProps = {\n themeMode: overlayThemeMode ?? themeMode,\n themeProductContext: overlayThemeProductContext ?? themeProductContext,\n };\n\n // Drive the calendar's visible month so editing navigates the grid. Anchor\n // on the segment being edited (its group's month/year) — so typing/stepping\n // either side of a range moves the view there — falling back to the\n // committed selection. Memoised on year+month so a consumer re-creating the\n // date object each render doesn't churn the view or block manual prev/next.\n const activeParts = activeSegment ? groups[activeSegment.group] : null;\n const editingAnchor =\n activeParts && activeParts.month != null && activeParts.year != null\n ? new Date(activeParts.year, activeParts.month - 1, 1)\n : null;\n const viewAnchor =\n editingAnchor ?? selectedDate ?? startDate ?? endDate ?? null;\n const viewMonth = useMemo(\n () =>\n viewAnchor\n ? new Date(viewAnchor.getFullYear(), viewAnchor.getMonth(), 1)\n : undefined,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [viewAnchor?.getFullYear(), viewAnchor?.getMonth()]\n );\n\n const renderCalendar = () =>\n isDual ? (\n <DualCalendar\n locale={locale}\n startDate={startDate}\n endDate={endDate}\n minDate={minDate}\n maxDate={maxDate}\n month={viewMonth}\n onChange={handleDateChange}\n chips={chips}\n activeChip={activeChipValue}\n onChipSelect={handleChipSelect}\n topContent={renderTopContent}\n bottomContent={renderBottomContent}\n {...rest}\n {...overlayThemeProps}\n />\n ) : (\n <Calendar\n locale={locale}\n startDate={startDate}\n endDate={endDate}\n selectedDate={selectedDate}\n minDate={minDate}\n maxDate={maxDate}\n month={viewMonth}\n onChange={handleDateChange}\n selectsRange={selectsRange}\n chips={chips}\n activeChip={activeChipValue}\n onChipSelect={handleChipSelect}\n topContent={renderTopContent}\n bottomContent={renderBottomContent}\n {...rest}\n {...overlayThemeProps}\n />\n );\n\n return (\n <Box\n ref={(node: any) => {\n containerRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as any).current = node;\n }}\n position=\"relative\"\n width=\"100%\"\n {...(isWeb ? { onClick: () => setOpen(true) } : {})}\n >\n <Input\n {...rest}\n ref={inputRef}\n size={size}\n placeholder={\n placeholder || (isRange ? \"Choose a date range\" : \"Choose a date\")\n }\n value={inputValue}\n readOnly={readOnly}\n onFocus={handleFieldFocus}\n onBlur={handleFieldBlur}\n onKeyDown={handleKeyDown}\n onClick={handleFieldClick}\n onPaste={handlePaste}\n iconRight={iconRight}\n iconLeft={iconLeft}\n error={error || !!parseError}\n errorMessage={parseError ?? errorMessage}\n backgroundColor={backgroundColor}\n testID={testID}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n {open &&\n (isWeb ? (\n <Box\n ref={calendarRef}\n role=\"dialog\"\n aria-modal\n aria-label={isRange ? \"Choose a date range\" : \"Choose a date\"}\n // Stop clicks inside the calendar from bubbling to the container's\n // open-on-click handler, which would re-open the panel right after\n // a single-date selection closes it.\n onClick={(e: any) => e.stopPropagation()}\n position=\"absolute\"\n zIndex={1000}\n style={getPlacementStyle(\n layout.side,\n layout.align,\n PLACEMENT_OFFSET\n )}\n >\n {renderCalendar()}\n </Box>\n ) : (\n <Box marginTop={4}>{renderCalendar()}</Box>\n ))}\n </Box>\n );\n }\n);\n\nDatePicker.displayName = \"DatePicker\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n opacity,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n opacity: opacity ?? (disabled ? 0.5 : undefined),\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": ariaDisabled,\n \"aria-live\": ariaLive,\n \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n","export type DateSegmentType = \"day\" | \"month\" | \"year\";\n\n/** A date broken into editable parts; `null` means \"not yet filled\". */\nexport interface DateParts {\n day: number | null;\n month: number | null; // 1-12\n year: number | null;\n}\n\n/** A rendered segment's character span within the field text. */\nexport interface SegmentRange {\n type: DateSegmentType;\n start: number;\n end: number;\n filled: boolean;\n}\n\ntype FormatToken =\n | { kind: \"segment\"; type: DateSegmentType }\n | { kind: \"literal\"; text: string };\n\nconst SEGMENT_WIDTH: Record<DateSegmentType, number> = {\n day: 2,\n month: 2,\n year: 4,\n};\nconst SEGMENT_TOKEN: Record<DateSegmentType, string> = {\n day: \"dd\",\n month: \"mm\",\n year: \"yyyy\",\n};\n\n/** Default format for rendering/parsing the field's text value (overridable via `dateFormat`). */\nexport const DEFAULT_DATE_FORMAT = \"MM/dd/yyyy\";\n\n/** The `date-fns` letters the segmented field understands. */\nconst SEGMENT_LETTER: Record<string, DateSegmentType | undefined> = {\n d: \"day\",\n M: \"month\",\n y: \"year\",\n};\n\n/** Wrong-case letters mapped to the `date-fns` letter meant; all are real tokens themselves, so a repair applies only when the intended letter is absent. */\nconst CASING_REPAIRS: Record<string, string> = { D: \"d\", Y: \"y\", m: \"M\" };\n\nconst SUPPORTED_TOKENS_HINT =\n \"supported tokens are `d`/`dd` (day), `M`/`MM` (month) and `y`/`yyyy` (year); \" +\n \"any other character is a literal separator. Textual and localised tokens \" +\n \"(`MMM`, `MMMM`, `P`, `PP`) are not supported — the field renders numeric \" +\n \"segments only.\";\n\nconst ALL_SEGMENTS: DateSegmentType[] = [\"day\", \"month\", \"year\"];\n\nconst isLetter = (c: string): boolean => /[A-Za-z]/.test(c);\n\n/** Whether a run of the same letter is a token the field can render. */\nconst isSupportedRun = (letter: string, length: number): boolean => {\n if (letter === \"y\") return true; // any year width; always rendered 4-digit\n if (letter === \"d\" || letter === \"M\") return length <= 2; // 3+ is textual\n return false;\n};\n\n/** What is wrong with one token of a `dateFormat`. */\nexport interface DateFormatIssue {\n /** Offending token as written, or the segment name for `kind: \"missing\"`. */\n token: string;\n kind: \"casing\" | \"unsupported\" | \"missing\";\n /** The `date-fns` token to use instead (`casing` only). */\n suggestion?: string;\n}\n\nexport interface DateFormatAnalysis {\n /** The format the field should actually use (repaired input, or the fallback). */\n format: string;\n usedFallback: boolean;\n issues: DateFormatIssue[];\n}\n\n/** Repair a caller's `dateFormat` where the case is unambiguously wrong, else fall back when it is unusable (unsupported token, or a missing segment). */\nexport function analyzeDateFormat(\n format: string,\n fallback: string = DEFAULT_DATE_FORMAT\n): DateFormatAnalysis {\n const issues: DateFormatIssue[] = [];\n // Letters already used, so a case mistake is told apart from the real token.\n const used = new Set<string>();\n for (let i = 0; i < format.length; i++) {\n if (isLetter(format[i])) used.add(format[i]);\n }\n\n let repaired = \"\";\n let hasUnsupported = false;\n let i = 0;\n while (i < format.length) {\n const c = format[i];\n if (!isLetter(c)) {\n repaired += c;\n i++;\n continue;\n }\n let end = i;\n while (end < format.length && format[end] === c) end++;\n const run = format.slice(i, end);\n i = end;\n\n if (isSupportedRun(c, run.length)) {\n repaired += run;\n continue;\n }\n const repair = CASING_REPAIRS[c];\n if (repair && !used.has(repair) && isSupportedRun(repair, run.length)) {\n const fixed = repair.repeat(run.length);\n issues.push({ token: run, kind: \"casing\", suggestion: fixed });\n repaired += fixed;\n continue;\n }\n issues.push({ token: run, kind: \"unsupported\" });\n hasUnsupported = true;\n repaired += run;\n }\n\n const present = new Set(\n parseDateFormat(repaired)\n .filter(\n (t): t is { kind: \"segment\"; type: DateSegmentType } =>\n t.kind === \"segment\"\n )\n .map((t) => t.type)\n );\n const missing = ALL_SEGMENTS.filter((type) => !present.has(type));\n for (const type of missing) issues.push({ token: type, kind: \"missing\" });\n\n const usable = !hasUnsupported && missing.length === 0;\n return {\n format: usable ? repaired : fallback,\n usedFallback: !usable,\n issues,\n };\n}\n\n/** Human-readable warning for a failed {@link analyzeDateFormat}. */\nexport function describeDateFormatIssues(\n format: string,\n analysis: DateFormatAnalysis\n): string {\n const clauses = analysis.issues.map((issue) => {\n if (issue.kind === \"missing\") {\n return `it has no ${issue.token} segment, so the field can never be completed`;\n }\n if (issue.kind === \"casing\") {\n return `\\`${issue.token}\\` is not a \\`date-fns\\` date token — use \\`${issue.suggestion}\\``;\n }\n return `\\`${issue.token}\\` is not a supported token`;\n });\n const resolution = analysis.usedFallback\n ? `Falling back to \\`${analysis.format}\\`.`\n : `Reading it as \\`${analysis.format}\\`.`;\n return (\n `[DatePicker] Invalid \\`dateFormat\\` \\`${format}\\`: ` +\n `${clauses.join(\"; \")}. ${resolution} Note ${SUPPORTED_TOKENS_HINT}`\n );\n}\n\n/** Formats already warned about, so a re-render can't spam the console. */\nconst warnedFormats = new Set<string>();\n\n/** Resolve a `dateFormat` to one the field can render, warning once per offending format in development. See {@link analyzeDateFormat}. */\nexport function resolveDateFormat(\n format: string,\n fallback: string = DEFAULT_DATE_FORMAT\n): string {\n const analysis = analyzeDateFormat(format, fallback);\n if (analysis.issues.length > 0) {\n const key = `${format}|${fallback}`;\n // Read `process` off `globalThis` rather than as a bare global: it is\n // absent in browsers and native, and this package ships no node types.\n // Warn unless explicitly production.\n const isProduction =\n (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process?.env\n ?.NODE_ENV === \"production\";\n if (!isProduction && !warnedFormats.has(key)) {\n warnedFormats.add(key);\n console.warn(describeDateFormatIssues(format, analysis));\n }\n }\n return analysis.format;\n}\n\n/** Split a date format into ordered segment tokens and literal separators. */\nexport function parseDateFormat(format: string): FormatToken[] {\n const tokens: FormatToken[] = [];\n let i = 0;\n while (i < format.length) {\n const c = format[i];\n const type = SEGMENT_LETTER[c];\n if (type) {\n while (i < format.length && format[i] === c) i++;\n tokens.push({ kind: \"segment\", type });\n } else {\n let text = \"\";\n while (i < format.length && !SEGMENT_LETTER[format[i]]) {\n text += format[i];\n i++;\n }\n tokens.push({ kind: \"literal\", text });\n }\n }\n return tokens;\n}\n\nconst EMPTY_PARTS: DateParts = { day: null, month: null, year: null };\n\nexport function datePartsFromDate(date: Date | null | undefined): DateParts {\n if (!date) return { ...EMPTY_PARTS };\n return {\n day: date.getDate(),\n month: date.getMonth() + 1,\n year: date.getFullYear(),\n };\n}\n\n/** Assemble a `Date`, or null if any part is missing or the date is invalid. */\nexport function datePartsToDate(parts: DateParts): Date | null {\n const { day, month, year } = parts;\n if (day == null || month == null || year == null) return null;\n const date = new Date(year, month - 1, day);\n // Reject overflow (e.g. 31 Feb rolling into March).\n if (\n date.getFullYear() !== year ||\n date.getMonth() !== month - 1 ||\n date.getDate() !== day\n ) {\n return null;\n }\n return date;\n}\n\nexport function isDatePartsComplete(parts: DateParts): boolean {\n return parts.day != null && parts.month != null && parts.year != null;\n}\n\n/** Clamp a raw numeric segment value into its valid range. */\nexport function clampDatePart(\n type: DateSegmentType,\n value: number,\n parts: DateParts\n): number {\n if (type === \"month\") return Math.min(12, Math.max(1, value));\n if (type === \"year\") return Math.max(1, value);\n const year = parts.year ?? new Date().getFullYear();\n const monthIndex = (parts.month ?? new Date().getMonth() + 1) - 1;\n return Math.min(daysInMonth(year, monthIndex), Math.max(1, value));\n}\n\n/** Step a numeric segment value, wrapping within its range (day/month) or ±1 (year). */\nexport function stepDatePart(\n type: DateSegmentType,\n current: number,\n delta: number,\n parts: DateParts\n): number {\n if (type === \"month\") return ((((current - 1 + delta) % 12) + 12) % 12) + 1;\n if (type === \"year\") return Math.max(1, current + delta);\n const year = parts.year ?? new Date().getFullYear();\n const monthIndex = (parts.month ?? new Date().getMonth() + 1) - 1;\n const dim = daysInMonth(year, monthIndex);\n return ((((current - 1 + delta) % dim) + dim) % dim) + 1;\n}\n\n/**\n * Render `parts` into field text using `format`, returning each segment's char\n * range. Filled parts are zero-padded; unfilled parts show a token placeholder\n * (`dd`/`mm`/`yyyy`). `active`, when set, renders the raw in-progress buffer for\n * the segment currently being typed.\n */\nexport function buildSegmentedValue(\n format: string,\n parts: DateParts,\n active?: { type: DateSegmentType; buffer: string }\n): { text: string; ranges: SegmentRange[] } {\n const tokens = parseDateFormat(format);\n let text = \"\";\n const ranges: SegmentRange[] = [];\n for (const token of tokens) {\n if (token.kind === \"literal\") {\n text += token.text;\n continue;\n }\n const { type } = token;\n const width = SEGMENT_WIDTH[type];\n const value = parts[type];\n let rendered: string;\n let filled: boolean;\n if (active && active.type === type && active.buffer.length > 0) {\n rendered = active.buffer;\n filled = false;\n } else if (value != null) {\n rendered = String(value).padStart(width, \"0\");\n filled = true;\n } else {\n rendered = SEGMENT_TOKEN[type];\n filled = false;\n }\n const start = text.length;\n text += rendered;\n ranges.push({ type, start, end: text.length, filled });\n }\n return { text, ranges };\n}\n\n/** Whether a first digit rules out a valid second digit (for early auto-commit). */\nexport function isSegmentComplete(\n type: DateSegmentType,\n buffer: string\n): boolean {\n const width = SEGMENT_WIDTH[type];\n if (buffer.length >= width) return true;\n if (buffer.length === 1 && type !== \"year\") {\n const first = Number(buffer);\n // Month tens digit is 0-1, day tens digit is 0-3; anything higher can't take\n // a second digit, so commit immediately.\n return type === \"month\" ? first > 1 : first > 3;\n }\n return false;\n}\n\nexport interface DateSegment {\n type: DateSegmentType;\n /** Inclusive character index of the segment's first digit in `value`. */\n start: number;\n /** Exclusive character index one past the segment's last digit. */\n end: number;\n}\n\n/** Number of days in the given month (0-indexed) of the given year. */\nexport function daysInMonth(year: number, monthIndex: number): number {\n return new Date(year, monthIndex + 1, 0).getDate();\n}\n\n/**\n * Locate the day/month/year segments within a formatted date `value` by walking\n * the `format` string in parallel: `d`/`M`/`y` token runs consume the matching\n * digit run in `value`, other characters are treated as literal separators.\n * Works for any token order (e.g. `MM/dd/yyyy`, `dd/MM/yyyy`, `yyyy-MM-dd`) and\n * both fixed- and variable-width tokens. Returns segments in display order.\n */\nexport function getDateSegments(format: string, value: string): DateSegment[] {\n const segments: DateSegment[] = [];\n let fi = 0;\n let vi = 0;\n while (fi < format.length && vi < value.length) {\n const fc = format[fi];\n if (fc === \"d\" || fc === \"M\" || fc === \"y\") {\n while (fi < format.length && format[fi] === fc) fi++;\n const start = vi;\n while (vi < value.length && value[vi] >= \"0\" && value[vi] <= \"9\") vi++;\n if (vi > start) {\n segments.push({\n type: fc === \"d\" ? \"day\" : fc === \"M\" ? \"month\" : \"year\",\n start,\n end: vi,\n });\n }\n } else {\n // Literal separator (e.g. \"/\", \"-\", \" \"): advance past one char in each.\n fi++;\n vi++;\n }\n }\n return segments;\n}\n\n/**\n * Step a single date segment by `delta`, isolated to that field (no carry):\n * day wraps within the current month, month wraps within the year (day clamped\n * to the new month's length), year increments freely. Mirrors the segment wrap\n * behaviour of the InputTime segments.\n */\nexport function stepDateSegment(\n date: Date,\n type: DateSegmentType,\n delta: number\n): Date {\n const year = date.getFullYear();\n const month = date.getMonth();\n const day = date.getDate();\n\n if (type === \"year\") {\n const nextYear = year + delta;\n return new Date(\n nextYear,\n month,\n Math.min(day, daysInMonth(nextYear, month))\n );\n }\n if (type === \"month\") {\n const nextMonth = (((month + delta) % 12) + 12) % 12;\n return new Date(\n year,\n nextMonth,\n Math.min(day, daysInMonth(year, nextMonth))\n );\n }\n const dim = daysInMonth(year, month);\n const nextDay = ((((day - 1 + delta) % dim) + dim) % dim) + 1;\n return new Date(year, month, nextDay);\n}\n"],"mappings":"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","names":["import_xui_calendar","i","import_jsx_runtime","CalendarIcon","vertical","horizontal","text","closeOnComplete"]}