@viasat/beam-react 2.67.1 → 2.69.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.
Files changed (75) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/assets/DateField.css +1 -1
  3. package/chunks/DateField.Segment.BP4uMe6e.js +1 -0
  4. package/chunks/{DateField.Segment.BMXzpxgl.js → DateField.Segment.Dtgriddw.js} +56 -51
  5. package/index.cjs.js +1 -1
  6. package/index.es.js +28 -26
  7. package/lib/DateField/DateField.Segment.cjs.js +1 -0
  8. package/lib/{wip/DateField → DateField}/DateField.Segment.d.ts +1 -1
  9. package/lib/DateField/DateField.Segment.es.js +9 -0
  10. package/lib/DateField/DateField.Segments.cjs.js +1 -0
  11. package/lib/{wip/DateField → DateField}/DateField.Segments.d.ts +3 -1
  12. package/lib/DateField/DateField.Segments.es.js +74 -0
  13. package/lib/DateField/DateField.cjs.js +1 -0
  14. package/lib/DateField/DateField.es.js +274 -0
  15. package/lib/{wip/DateField → DateField}/DateField.types.d.ts +37 -46
  16. package/lib/DateField/DateField.utils.cjs.js +1 -0
  17. package/lib/{wip/DateField → DateField}/DateField.utils.d.ts +10 -22
  18. package/lib/{wip/DateField → DateField}/DateField.utils.es.js +3 -5
  19. package/lib/{wip/DateField → DateField}/DateField.validation.d.ts +2 -2
  20. package/lib/DateField/useDateFieldFocus.cjs.js +1 -0
  21. package/lib/{wip/DateField → DateField}/useDateFieldFocus.es.js +17 -14
  22. package/lib/DateField/useDateFieldForm.cjs.js +1 -0
  23. package/lib/{wip/DateField → DateField}/useDateFieldForm.d.ts +1 -1
  24. package/lib/{wip/DateField → DateField}/useDateFieldForm.es.js +5 -5
  25. package/lib/{wip/DateField → DateField}/useDateFieldKeyboard.d.ts +2 -5
  26. package/lib/{wip/DateField → DateField}/useDateFieldValue.cjs.js +1 -1
  27. package/lib/DateField/useDateFieldValue.d.ts +44 -0
  28. package/lib/{wip/DateField → DateField}/useInvalidState.d.ts +5 -4
  29. package/lib/index.cjs.js +1 -1
  30. package/lib/index.d.ts +1 -0
  31. package/lib/index.es.js +20 -18
  32. package/lib/wip/index.cjs.js +1 -1
  33. package/lib/wip/index.d.ts +0 -2
  34. package/lib/wip/index.es.js +15 -19
  35. package/package.json +7 -7
  36. package/chunks/DateField.Segment.BqMaeKLk.js +0 -1
  37. package/lib/wip/DateField/DateField.Segment.cjs.js +0 -1
  38. package/lib/wip/DateField/DateField.Segment.es.js +0 -9
  39. package/lib/wip/DateField/DateField.Segments.cjs.js +0 -1
  40. package/lib/wip/DateField/DateField.Segments.es.js +0 -71
  41. package/lib/wip/DateField/DateField.cjs.js +0 -1
  42. package/lib/wip/DateField/DateField.es.js +0 -271
  43. package/lib/wip/DateField/DateField.utils.cjs.js +0 -1
  44. package/lib/wip/DateField/useDateFieldFocus.cjs.js +0 -1
  45. package/lib/wip/DateField/useDateFieldForm.cjs.js +0 -1
  46. package/lib/wip/DateField/useDateFieldValue.d.ts +0 -80
  47. /package/lib/{wip/DateField → DateField}/DateField.d.ts +0 -0
  48. /package/lib/{wip/DateField → DateField}/DateField.devWarnings.cjs.js +0 -0
  49. /package/lib/{wip/DateField → DateField}/DateField.devWarnings.d.ts +0 -0
  50. /package/lib/{wip/DateField → DateField}/DateField.devWarnings.es.js +0 -0
  51. /package/lib/{wip/DateField → DateField}/DateField.types.cjs.js +0 -0
  52. /package/lib/{wip/DateField → DateField}/DateField.types.es.js +0 -0
  53. /package/lib/{wip/DateField → DateField}/DateField.validation.cjs.js +0 -0
  54. /package/lib/{wip/DateField → DateField}/DateField.validation.es.js +0 -0
  55. /package/lib/{wip/DateField → DateField}/index.cjs.js +0 -0
  56. /package/lib/{wip/DateField → DateField}/index.d.ts +0 -0
  57. /package/lib/{wip/DateField → DateField}/index.es.js +0 -0
  58. /package/lib/{wip/DateField → DateField}/useDateFieldFocus.d.ts +0 -0
  59. /package/lib/{wip/DateField → DateField}/useDateFieldKeyboard.cjs.js +0 -0
  60. /package/lib/{wip/DateField → DateField}/useDateFieldKeyboard.es.js +0 -0
  61. /package/lib/{wip/DateField → DateField}/useDateFieldSegments.cjs.js +0 -0
  62. /package/lib/{wip/DateField → DateField}/useDateFieldSegments.d.ts +0 -0
  63. /package/lib/{wip/DateField → DateField}/useDateFieldSegments.es.js +0 -0
  64. /package/lib/{wip/DateField → DateField}/useDateFieldValidity.cjs.js +0 -0
  65. /package/lib/{wip/DateField → DateField}/useDateFieldValidity.d.ts +0 -0
  66. /package/lib/{wip/DateField → DateField}/useDateFieldValidity.es.js +0 -0
  67. /package/lib/{wip/DateField → DateField}/useDateFieldValue.es.js +0 -0
  68. /package/lib/{wip/DateField → DateField}/useInvalidState.cjs.js +0 -0
  69. /package/lib/{wip/DateField → DateField}/useInvalidState.es.js +0 -0
  70. /package/lib/{wip/ErrorBoundary → _ErrorBoundary}/ErrorBoundary.cjs.js +0 -0
  71. /package/lib/{wip/ErrorBoundary → _ErrorBoundary}/ErrorBoundary.d.ts +0 -0
  72. /package/lib/{wip/ErrorBoundary → _ErrorBoundary}/ErrorBoundary.es.js +0 -0
  73. /package/lib/{wip/ErrorBoundary → _ErrorBoundary}/index.cjs.js +0 -0
  74. /package/lib/{wip/ErrorBoundary → _ErrorBoundary}/index.d.ts +0 -0
  75. /package/lib/{wip/ErrorBoundary → _ErrorBoundary}/index.es.js +0 -0
@@ -0,0 +1,274 @@
1
+ import { jsxs as W, jsx as s } from "react/jsx-runtime";
2
+ import $e from "clsx";
3
+ import { forwardRef as He, useRef as u, useMemo as Ke, useCallback as o } from "react";
4
+ import { s as t, b as je, c as i, a as g } from "../../chunks/DateField.Segment.Dtgriddw.js";
5
+ import { d as qe } from "../../chunks/input.f81KzcGZ.js";
6
+ import { t as We } from "../../chunks/constants.Cruz2A1w.js";
7
+ import { i as Ye } from "../../chunks/helpers.CiQfGwdc.js";
8
+ import { H as _e } from "../../chunks/form.context.BDYA2JQs.js";
9
+ import { LabelProvider as ke } from "../Form/contexts/label.context.es.js";
10
+ import { HelperTextProvider as ze } from "../Form/contexts/helperText.context.es.js";
11
+ import { useIsMounted as Ue } from "../../utils/hooks/useIsMounted.es.js";
12
+ import { mergeRefs as Ge } from "../../utils/functions.es.js";
13
+ import { ErrorBoundary as Je } from "../_ErrorBoundary/ErrorBoundary.es.js";
14
+ import { DateFieldSegments as Qe } from "./DateField.Segments.es.js";
15
+ import { useDevMinMaxWarning as Xe, useDevInvalidValueWarning as Ze } from "./DateField.devWarnings.es.js";
16
+ import { getDateParts as er, getSegmentOrder as rr, toISODateString as ar, DEFAULT_LOCALE as Y } from "./DateField.utils.es.js";
17
+ import { useDateFieldFocus as tr } from "./useDateFieldFocus.es.js";
18
+ import { useDateFieldForm as sr } from "./useDateFieldForm.es.js";
19
+ import { useDateFieldKeyboard as nr } from "./useDateFieldKeyboard.es.js";
20
+ import { useDateFieldSegments as lr } from "./useDateFieldSegments.es.js";
21
+ import { useDateFieldValidity as or } from "./useDateFieldValidity.es.js";
22
+ import { useDateFieldValue as ir } from "./useDateFieldValue.es.js";
23
+ import { useInvalidState as dr } from "./useInvalidState.es.js";
24
+ const cr = "MM/DD/YYYY", ur = () => {
25
+ process.env.NODE_ENV !== "production" && console.warn("DateField: segments failed to render; showing a static fallback.");
26
+ }, Ar = He(
27
+ function({
28
+ value: v,
29
+ defaultValue: D,
30
+ onChange: _,
31
+ minDate: F,
32
+ maxDate: h,
33
+ getClampAnnouncement: k,
34
+ locale: z,
35
+ label: S = null,
36
+ helperText: x = null,
37
+ error: I,
38
+ hideRequiredMarker: U = !1,
39
+ validationRules: G,
40
+ width: J,
41
+ theme: y,
42
+ fluid: Q = !1,
43
+ size: X = qe,
44
+ disabled: Z = !1,
45
+ readOnly: ee = !1,
46
+ required: re = !1,
47
+ name: M,
48
+ id: ae,
49
+ className: te,
50
+ style: se,
51
+ "aria-label": ne,
52
+ "aria-describedby": le,
53
+ "aria-labelledby": oe,
54
+ ...ie
55
+ }, R) {
56
+ const {
57
+ disabled: e,
58
+ readOnly: n,
59
+ required: E,
60
+ invalid: de,
61
+ errorMessageProvided: N,
62
+ defaultValue: ce,
63
+ errorId: O,
64
+ helperTextId: ue,
65
+ validationErrorsId: me,
66
+ labelId: w,
67
+ ariaDescribedBy: fe,
68
+ ariaLabelledBy: pe,
69
+ showErrors: be
70
+ } = sr({
71
+ name: M,
72
+ disabled: Z,
73
+ readOnly: ee,
74
+ required: re,
75
+ defaultValue: D,
76
+ error: I,
77
+ hasHelperText: !!x,
78
+ hasLabel: !!S,
79
+ validationRules: G,
80
+ ariaDescribedBy: le,
81
+ ariaLabelledBy: oe
82
+ });
83
+ Xe(F, h), Ze(v, D);
84
+ const l = u(null), { segmentRefs: ge, registerSegmentRef: ve } = lr(), De = z ?? Y, C = Ue(), m = er(C ? De : Y), d = Ke(() => rr(m), [m]), {
85
+ segmentText: Fe,
86
+ segmentValues: L,
87
+ currentValue: B,
88
+ wasTouched: he,
89
+ appendDigit: V,
90
+ adjustSegment: Se,
91
+ clearSegment: xe,
92
+ clearAll: T,
93
+ beginSegmentEdit: Ie,
94
+ commitOnBlur: ye,
95
+ clampAnnouncement: Me
96
+ } = ir({
97
+ value: v,
98
+ defaultValue: ce,
99
+ onChange: _,
100
+ minDate: F,
101
+ maxDate: h,
102
+ getClampAnnouncement: k
103
+ }), {
104
+ focusedSegment: A,
105
+ fieldTabIndex: Re,
106
+ handleSegmentFocus: c,
107
+ handleFieldFocus: Ee,
108
+ handleFieldBlur: Ne,
109
+ handleFieldMouseDown: Oe,
110
+ focusNext: f,
111
+ focusPrevious: we
112
+ } = tr({
113
+ disabled: e,
114
+ fieldRef: l,
115
+ segmentRefs: ge,
116
+ partsOrder: d,
117
+ onSegmentFocusChange: Ie,
118
+ onFieldBlur: ye
119
+ }), Ce = nr({
120
+ disabled: e,
121
+ readOnly: n,
122
+ fieldRef: l,
123
+ focusNext: f,
124
+ focusPrevious: we,
125
+ adjustSegment: Se,
126
+ clearSegment: xe
127
+ }), { isInvalid: Le } = or({
128
+ segments: L,
129
+ currentValue: B,
130
+ wasTouched: he,
131
+ isFocused: A !== null
132
+ }), Be = o(
133
+ (r, a) => {
134
+ const { advanced: b } = V(r, a);
135
+ b && f(r);
136
+ },
137
+ [V, f]
138
+ ), p = dr({
139
+ formInvalid: de,
140
+ valueInvalid: Le
141
+ }), Ve = C && Ye() ? "textbox" : "spinbutton", P = o(
142
+ (r) => {
143
+ e || c(d[0], r);
144
+ },
145
+ [e, c, d]
146
+ ), $ = o(() => {
147
+ var a;
148
+ if (e) return;
149
+ const r = document.activeElement;
150
+ r instanceof HTMLElement && r !== l.current && ((a = l.current) != null && a.contains(r)) && r.blur();
151
+ }, [e]), H = o(() => {
152
+ e || n || T();
153
+ }, [e, n, T]), K = u(P), j = u($), q = u(H);
154
+ K.current = P, j.current = $, q.current = H;
155
+ const Te = o(
156
+ (r) => {
157
+ const a = r ? Object.assign(r, {
158
+ focus: (b) => K.current(b),
159
+ blur: () => j.current(),
160
+ clear: () => q.current()
161
+ }) : null;
162
+ Ge(
163
+ l,
164
+ R
165
+ )(a);
166
+ },
167
+ [R]
168
+ ), Ae = (r) => {
169
+ if (e) return;
170
+ const a = r.target.closest("label");
171
+ !a || a.id !== w || (r.preventDefault(), c(d[0]));
172
+ }, Pe = $e(
173
+ t[je],
174
+ y && We(y),
175
+ t[`${i}${X}`],
176
+ Q && t[`${i}fluid`],
177
+ p && t[`${i}error`],
178
+ e && t[`${i}disabled`],
179
+ n && t[`${i}read-only`],
180
+ te
181
+ );
182
+ return /* @__PURE__ */ W(
183
+ "div",
184
+ {
185
+ className: Pe,
186
+ style: { ...se, maxWidth: J },
187
+ onMouseDownCapture: Ae,
188
+ children: [
189
+ /* @__PURE__ */ s(
190
+ ke,
191
+ {
192
+ ctxId: w,
193
+ ctxDisabled: e,
194
+ ctxRequired: E && !U,
195
+ children: S
196
+ }
197
+ ),
198
+ /* @__PURE__ */ s(
199
+ "div",
200
+ {
201
+ ...ie,
202
+ ref: Te,
203
+ id: ae,
204
+ role: "group",
205
+ "aria-label": ne,
206
+ "aria-labelledby": pe,
207
+ "aria-disabled": e || void 0,
208
+ "aria-invalid": p || void 0,
209
+ "aria-describedby": fe,
210
+ "aria-errormessage": N ? O : void 0,
211
+ tabIndex: Re,
212
+ className: t[g.field],
213
+ onMouseDown: Oe,
214
+ onFocus: Ee,
215
+ children: /* @__PURE__ */ s(
216
+ Je,
217
+ {
218
+ fallback: /* @__PURE__ */ s("span", { className: t[g.segments], children: cr }),
219
+ onError: ur,
220
+ children: /* @__PURE__ */ s(
221
+ Qe,
222
+ {
223
+ parts: m,
224
+ segmentText: Fe,
225
+ segmentValues: L,
226
+ focusedSegment: A,
227
+ disabled: e,
228
+ readOnly: n,
229
+ required: E,
230
+ invalid: p,
231
+ role: Ve,
232
+ onSegmentFocus: c,
233
+ onSegmentBlur: Ne,
234
+ onSegmentInput: Be,
235
+ onSegmentKeyDown: Ce,
236
+ registerSegmentRef: ve
237
+ }
238
+ )
239
+ }
240
+ )
241
+ }
242
+ ),
243
+ /* @__PURE__ */ s(
244
+ "span",
245
+ {
246
+ role: "status",
247
+ "aria-live": "polite",
248
+ "aria-atomic": "true",
249
+ className: t[g.srStatus],
250
+ children: Me
251
+ }
252
+ ),
253
+ /* @__PURE__ */ s(
254
+ "input",
255
+ {
256
+ type: "hidden",
257
+ name: M,
258
+ value: ar(B),
259
+ disabled: e
260
+ }
261
+ ),
262
+ /* @__PURE__ */ W(ze, { ctxId: ue, ctxDisabled: e, children: [
263
+ x,
264
+ N && /* @__PURE__ */ s(_e, { id: O, appearance: "negative", children: I })
265
+ ] }),
266
+ be(me)
267
+ ]
268
+ }
269
+ );
270
+ }
271
+ );
272
+ export {
273
+ Ar as DateField
274
+ };
@@ -1,7 +1,8 @@
1
- import { ComponentPropsWithRef, ReactElement, FocusEvent, KeyboardEvent } from 'react';
1
+ import { ComponentPropsWithRef, FocusEvent, KeyboardEvent, ReactNode } from 'react';
2
2
  import { Nullable } from '@viasat/beam-shared/utils/types';
3
3
  import { ThemeTypes } from '@viasat/beam-shared/utils/constants';
4
4
  import { FormValidator } from '@viasat/beam-shared/components/form';
5
+ import { InputSize } from '@viasat/beam-shared/components/input';
5
6
  type DateFieldInputAttributes = Omit<ComponentPropsWithRef<'input'>, 'value' | 'defaultValue' | 'onChange' | 'min' | 'max' | 'type' | 'size' | 'ref' | 'form' | 'autoComplete' | 'inputMode'>;
6
7
  export type SegmentType = 'day' | 'month' | 'year';
7
8
  /**
@@ -32,18 +33,11 @@ export type DateFieldPart = {
32
33
  value: string;
33
34
  };
34
35
  /**
35
- * The DateField `ref` value (DF-16): the field's **root DOM element**
36
- * (`role="group"`) augmented with a `clear()` method. Keeping the ref a real
37
- * element (not a separate handle object) means it works anywhere a DOM node is
38
- * expected — a `Popover` / `FloatingUI` trigger, measuring, `scrollIntoView` —
39
- * while also carrying the field's imperative API.
40
- *
41
- * `focus()` and `blur()` are field-aware overrides of the native element methods:
42
- * `focus()` moves to the first segment; `blur()` exits the field (running the
43
- * same commit / normalize / clamp as a user blur). Both no-op when the field is
44
- * disabled. `clear()` empties every segment and fires `onChange(null)` (only
45
- * when a value was present), and no-ops when disabled or read-only.
46
- * (`selectAll()` is reserved for DF-13.)
36
+ * The DateField `ref`: the field's root element augmented with `clear()`. It
37
+ * stays a real DOM node so it works anywhere one is expected — a `Popover`
38
+ * trigger, measuring, `scrollIntoView` — while `focus()` and `blur()` become
39
+ * field-aware overrides that move to the first segment and exit the field.
40
+ * All three no-op when disabled; `clear()` also no-ops when read-only.
47
41
  */
48
42
  export type DateFieldHandle = HTMLDivElement & {
49
43
  clear(): void;
@@ -52,7 +46,7 @@ export interface DateFieldProps extends DateFieldInputAttributes {
52
46
  /**
53
47
  * Specify HelperText for DateField
54
48
  */
55
- helperText?: Nullable<ReactElement>;
49
+ helperText?: Nullable<ReactNode>;
56
50
  /**
57
51
  * Specify if DateField is a required input
58
52
  * @default false
@@ -66,7 +60,7 @@ export interface DateFieldProps extends DateFieldInputAttributes {
66
60
  /**
67
61
  * Specify Label for DateField
68
62
  */
69
- label?: Nullable<ReactElement>;
63
+ label?: Nullable<ReactNode>;
70
64
  /**
71
65
  * Specify error text and display error state of a DateField
72
66
  */
@@ -86,6 +80,11 @@ export interface DateFieldProps extends DateFieldInputAttributes {
86
80
  * @default false
87
81
  */
88
82
  fluid?: boolean;
83
+ /**
84
+ * Specify the size of DateField
85
+ * @default 'md'
86
+ */
87
+ size?: InputSize;
89
88
  /**
90
89
  * Specify the width of DateField
91
90
  */
@@ -99,35 +98,36 @@ export interface DateFieldProps extends DateFieldInputAttributes {
99
98
  */
100
99
  validationRules?: Array<FormValidator>;
101
100
  /**
102
- * Controlled date value. Pass `null` to clear.
101
+ * Specify the controlled date value of DateField; pass `null` to clear
103
102
  */
104
103
  value?: Nullable<Date>;
105
104
  /**
106
- * Uncontrolled initial date value. Ignored when `value` is provided.
105
+ * Specify the initial date value of an uncontrolled DateField
107
106
  */
108
107
  defaultValue?: Nullable<Date>;
109
108
  /**
110
- * Fires when the derived `Date | null` value transitions.
109
+ * Specify the handler called when the date value changes
111
110
  */
112
111
  onChange?: (value: Nullable<Date>) => void;
113
112
  /**
114
- * Lower bound; on blur, a touched value springs up to it. Use `validationRules` for validation.
113
+ * Specify the earliest date; a touched value springs up to it on blur
114
+ * (add a `validationRules` entry to block submit)
115
115
  */
116
116
  minDate?: Date;
117
117
  /**
118
- * Upper bound; on blur, a touched value springs down to it. Use `validationRules` for validation.
118
+ * Specify the latest date; a touched value springs down to it on blur
119
+ * (add a `validationRules` entry to block submit)
119
120
  */
120
121
  maxDate?: Date;
121
122
  /**
122
- * Called when a touched value springs to a bound on blur; return a localized
123
- * message announced politely to screen readers. Omit → no announcement.
123
+ * Specify a localized message, announced politely to screen readers when a
124
+ * touched value springs to a bound; omit for no announcement
124
125
  */
125
126
  getClampAnnouncement?: (clampedDate: Date) => string;
126
127
  /**
127
- * BCP-47 locale tag driving segment order + separators (e.g. `en-GB` →
128
- * DD/MM/YYYY, `de-DE` → DD.MM.YYYY). A future `DatesProvider` will supply the
129
- * default.
130
- * @default en-US
128
+ * Specify the BCP-47 locale tag driving segment order and separators
129
+ * (e.g. `en-GB` → DD/MM/YYYY, `de-DE` → DD.MM.YYYY)
130
+ * @default 'en-US'
131
131
  */
132
132
  locale?: string;
133
133
  }
@@ -140,17 +140,11 @@ export interface DateFieldSegmentProps {
140
140
  type: SegmentType;
141
141
  /** Numeric segment value — used for `aria-valuenow`. `null` when the segment has no committed value. */
142
142
  value: Nullable<number>;
143
- /**
144
- * The lower bound announced as `aria-valuemin` — an intrinsic calendar
145
- * range, NOT the `minDate` prop (day/month: always 1; year: always 1).
146
- * Computed by `DateField.Segments` so the segment itself stays a pure renderer.
147
- */
143
+ /** `aria-valuemin` — the intrinsic calendar floor, not the `minDate` prop. */
148
144
  valueMin: number;
149
145
  /**
150
- * The upper bound announced as `aria-valuemax` — an intrinsic calendar
151
- * range, NOT the `maxDate` prop (day: month-aware, e.g. 28 for Feb
152
- * non-leap; month: 12; year: always 9999).
153
- * Computed by `DateField.Segments` so the segment itself stays a pure renderer.
146
+ * `aria-valuemax` — the intrinsic calendar ceiling, not the `maxDate` prop:
147
+ * month-aware for day (28 for a non-leap February), 12 for month, 9999 for year.
154
148
  */
155
149
  valueMax: number;
156
150
  /** Pre-computed text to render inside the segment (buffer, formatted value, or placeholder). */
@@ -166,22 +160,19 @@ export interface DateFieldSegmentProps {
166
160
  isActive: boolean;
167
161
  disabled: boolean;
168
162
  readOnly: boolean;
163
+ /**
164
+ * Drives `aria-required`, which lives on the segments rather than the field
165
+ * root: it is role-specific, and `group` does not support it while
166
+ * `spinbutton` and `textbox` do.
167
+ */
168
+ required: boolean;
169
169
  /** Fires when the segment gains focus (Tab, click, or programmatic). */
170
170
  onFocus: () => void;
171
171
  /** Fires when focus leaves the segment; `relatedTarget` drives field-exit detection. */
172
172
  onBlur: (event: FocusEvent<HTMLSpanElement>) => void;
173
- /**
174
- * Single-character input callback. DF-2 single-digit typing path. The
175
- * orchestrator routes this into `appendDigit` and (on advance) `focusNext`.
176
- * Multi-character input (paste, IME composition commit) is ignored here —
177
- * DF-13 will add a paste-aware branch for whole-value parsing.
178
- */
173
+ /** Fires per typed character; multi-character input (paste, IME commit) is ignored. */
179
174
  onInput: (type: SegmentType, char: string) => void;
180
- /**
181
- * Fires on segment keydown. The orchestrator routes it into
182
- * `useDateFieldKeyboard` (DF-3: ArrowLeft/Right segment nav, RTL-aware;
183
- * DF-4/DF-5 extend with increment/clear).
184
- */
175
+ /** Fires on segment keydown; the orchestrator routes it into `useDateFieldKeyboard`. */
185
176
  onKeyDown: (type: SegmentType, event: KeyboardEvent<HTMLSpanElement>) => void;
186
177
  segmentRef: (element: HTMLSpanElement | null) => void;
187
178
  }
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("../../chunks/constants.CgMu0_1M.js");const A=require("../../chunks/helpers.BIckGIbP.js"),d=require("./DateField.validation.cjs.js"),l="en-US",N=new Intl.DateTimeFormat("en-US",{month:"long"}),w=e=>N.format(new Date(2e3,e-1,1)),u=31,i=12,m=1,f=9999,M=(e,t,n)=>Math.min(n,Math.max(t,e)),T=(e,t)=>((e-1)%t+t)%t+1,F=2024,P=(e,t)=>t==null?31:new Date(e??F,t,0).getDate(),R=()=>{const e=new Date;return{day:e.getDate(),month:e.getMonth()+1,year:e.getFullYear()}},o=e=>e instanceof Date&&!Number.isNaN(e.getTime()),I=(e,t,n,r)=>{if(n==="min")return e==="year"?null:1;if(n==="max")return e==="year"?null:e==="day"?r.daysInMonth:i;if(t==null){if(e==="year")return r.today.year;const E=e==="day"?u:i;return n>0?1:E}if(e==="year")return M(t+n,m,f);const a=e==="day"?u:i;return T(t+n,a)},L={day:"",month:"",year:""},h=e=>{const{day:t,month:n,year:r}=e;if(t==null||n==null||r==null)return null;const a=new Date(r,n-1,t);return a.setFullYear(r),Number.isNaN(a.getTime())||a.getFullYear()!==r||a.getMonth()!==n-1||a.getDate()!==t?null:a},Y=(e,t)=>e==null&&t==null?!0:e==null||t==null?!1:e.getTime()===t.getTime(),s=A.dateToDayKey,O=e=>o(e)?s(e):null,V=(e,t,n)=>{const r=s(e);return!(o(t)&&r<s(t)||o(n)&&r>s(n))},_=(e,t)=>o(e)&&o(t)&&s(e)>s(t),C=(e,t,n)=>{if(_(t,n))return e;const r=s(e);return o(t)&&r<s(t)?new Date(t.getFullYear(),t.getMonth(),t.getDate()):o(n)&&r>s(n)?new Date(n.getFullYear(),n.getMonth(),n.getDate()):e},X=e=>{if(!o(e))return"";const t=String(e.getFullYear()).padStart(4,"0"),n=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0");return`${t}-${n}-${r}`},p=e=>e.type==="literal",D=e=>e.filter(t=>!p(t)).map(t=>t.type),b=new Date(2020,0,2),G=new Set([8206,8207,8234,8235,8236,8237,8238,8294,8295,8296,8297]),H=e=>[...e].filter(t=>!G.has(t.codePointAt(0)??-1)).join(""),K=new Set(["day","month","year","literal"]),y=3,S=e=>{try{const t=new Intl.DateTimeFormat(e,{year:"numeric",month:"2-digit",day:"2-digit",calendar:"gregory"}).formatToParts(b).filter(r=>K.has(r.type)).map(r=>({type:r.type,value:r.type==="literal"?H(r.value):""})),n=D(t);return n.length===y&&new Set(n).size===y?t:null}catch{return null}},g=new Map,$=e=>{try{return new Intl.Locale(e).toString()}catch{return e.toLowerCase()}},k=e=>{try{return Intl.DateTimeFormat.supportedLocalesOf([e]).length>0}catch{return!1}},U=e=>{const t=$(e),n=g.get(t);if(n)return n;const r=k(e);!r&&process.env.NODE_ENV!=="production"&&console.warn(`DateField: locale "${e}" is not supported; falling back to ${l}.`);const a=(r?S(e):null)??S(l);if(!a)throw new Error(`DateField: Intl cannot resolve ${l} date parts`);return g.set(t,a),a},j=()=>g.clear(),q=e=>o(e)?{day:String(e.getDate()).padStart(2,"0"),month:String(e.getMonth()+1).padStart(2,"0"),year:String(e.getFullYear()).padStart(4,"0")}:L,c=(e,t)=>{if(t===""||e==="year"&&t.length<d.SEGMENT_MAX_LENGTH.year)return null;const n=parseInt(t,10);return Number.isNaN(n)||n===0?null:n},v=e=>h({day:c("day",e.day),month:c("month",e.month),year:c("year",e.year)}),z=(e,t)=>t===""?"":t.padStart(d.SEGMENT_MAX_LENGTH[e],"0"),B=(e,t,n)=>t===""?{displayValue:n,isPlaceholder:!0}:{displayValue:t.padStart(d.SEGMENT_MAX_LENGTH[e],"0"),isPlaceholder:!1},W=e=>{const t=window.getSelection();if(!t)return;const n=document.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n)},J=e=>{var n;if(!e)return;const t=(n=window.getSelection)==null?void 0:n.call(window);t&&t.rangeCount>0&&e.contains(t.anchorNode)&&t.removeAllRanges()};exports.DAY_SPIN_MAX=u;exports.DEFAULT_LOCALE=l;exports.MONTH_MAX=i;exports.YEAR_MAX=f;exports.YEAR_MIN=m;exports.__clearDatePartsCache=j;exports.adjustSegmentValue=I;exports.clamp=M;exports.clampDateToRange=C;exports.clearSelectionWithin=J;exports.dateKeyOrNull=O;exports.deriveValue=h;exports.deriveValueFromText=v;exports.getDateParts=U;exports.getDaysInMonth=P;exports.getMonthName=w;exports.getSegmentDisplay=B;exports.getSegmentOrder=D;exports.isDateInRange=V;exports.isLiteralPart=p;exports.isMinMaxMisconfigured=_;exports.isSameDateValue=Y;exports.isValidDate=o;exports.normalizeSegmentText=z;exports.segmentNumber=c;exports.segmentTextFromValue=q;exports.selectElementContents=W;exports.toISODateString=X;exports.todayParts=R;exports.wrapInRange=T;
@@ -18,9 +18,8 @@ export declare const DAY_SPIN_MAX = 31;
18
18
  /** Absolute maximum for month (1-based). */
19
19
  export declare const MONTH_MAX = 12;
20
20
  /**
21
- * Absolute floor/ceiling for the free-spinning year segment. `minDate`/
22
- * `maxDate` no longer bound the year directly (DF-10: the whole date clamps
23
- * to those bounds on blur instead — see `commitOnBlur`).
21
+ * Absolute floor/ceiling for the free-spinning year segment. `minDate`/`maxDate`
22
+ * don't bound the year directly — the whole date clamps to them on blur instead.
24
23
  */
25
24
  export declare const YEAR_MIN = 1;
26
25
  export declare const YEAR_MAX = 9999;
@@ -40,10 +39,7 @@ export declare const wrapInRange: (n: number, max: number) => number;
40
39
  * so February correctly reports 29 days (leap-safe fallback).
41
40
  */
42
41
  export declare const getDaysInMonth: (year: Nullable<number>, month: Nullable<number>) => number;
43
- /**
44
- * Returns today's date parts as a plain object.
45
- * Extracted so callers in the value hook and DF-8 can share the same helper.
46
- */
42
+ /** Returns today's date parts as a plain object. */
47
43
  export declare const todayParts: () => {
48
44
  day: number;
49
45
  month: number;
@@ -70,20 +66,12 @@ export interface AdjustSegmentContext {
70
66
  * Computes the next numeric value for a date segment after an increment,
71
67
  * decrement, or boundary jump.
72
68
  *
73
- * Day and month wrap modularly within their absolute ranges (day:
74
- * `[1, DAY_SPIN_MAX]`; month: `[1, MONTH_MAX]`); out-of-range dates (e.g. Feb
75
- * 31) are flagged by the validity layer, not clamped here. Year clamps (no
76
- * wrap) within `[YEAR_MIN, YEAR_MAX]` and spins free of `minDate`/`maxDate`
77
- * (DF-10: those clamp the whole date on blur instead — see `commitOnBlur`);
78
- * year `'min'`/`'max'` (Home/End) are a no-op (`null`). An empty segment seeds
79
- * on the first numeric press: day/month to a direction-based first/last valid
80
- * value (positive amount → `1`, negative → `DAY_SPIN_MAX`/`MONTH_MAX`;
81
- * EPTOOLS-2766), year to `ctx.today.year`.
82
- *
83
- * @param type - Segment kind (`'day'`, `'month'`, or `'year'`).
84
- * @param current - Current numeric value of the segment, or `null` when empty.
85
- * @param amount - Numeric delta (e.g. ±1, ±5) or `'min'`/`'max'` for Home/End.
86
- * @param ctx - Pure context: days-in-month and today's date parts.
69
+ * Day and month wrap modularly within their absolute ranges; an impossible
70
+ * combination such as Feb 31 is left for the validity layer rather than clamped
71
+ * here. The year clamps without wrapping and spins free of `minDate`/`maxDate`,
72
+ * which bound the whole date on blur instead, so year `'min'`/`'max'` returns
73
+ * `null`. An empty segment seeds on the first press: day and month follow the
74
+ * direction of travel, the year starts at today.
87
75
  */
88
76
  export declare const adjustSegmentValue: (type: SegmentType, current: Nullable<number>, amount: SegmentAdjustment, ctx: AdjustSegmentContext) => Nullable<number>;
89
77
  export declare const deriveValue: (segments: SegmentValues) => Nullable<Date>;
@@ -126,7 +114,7 @@ export declare const isLiteralPart: (part: DateFieldPart) => part is DateFieldPa
126
114
  /** Ordered segment types from a parts array (literals stripped). */
127
115
  export declare const getSegmentOrder: (parts: ReadonlyArray<DateFieldPart>) => ReadonlyArray<SegmentType>;
128
116
  /**
129
- * Locale-derived segment order + separators (DF-8), memoized per locale. Falls
117
+ * Locale-derived segment order and separators, memoized per locale. Falls
130
118
  * back to {@link DEFAULT_LOCALE} for any locale Intl can't resolve to the three
131
119
  * date segments. Resolved lazily on first use, so a broken Intl (which can't
132
120
  * render the field anyway — `getMonthName` needs it too) surfaces at render,
@@ -1,5 +1,5 @@
1
- import "../../../chunks/constants.Cruz2A1w.js";
2
- import { a as S } from "../../../chunks/helpers.CiQfGwdc.js";
1
+ import "../../chunks/constants.Cruz2A1w.js";
2
+ import { a as S } from "../../chunks/helpers.CiQfGwdc.js";
3
3
  import { SEGMENT_MAX_LENGTH as g } from "./DateField.validation.es.js";
4
4
  const l = "en-US", h = new Intl.DateTimeFormat("en-US", { month: "long" }), $ = (t) => h.format(new Date(2e3, t - 1, 1)), d = 31, c = 12, p = 1, T = 9999, M = (t, e, n) => Math.min(n, Math.max(e, t)), A = (t, e) => ((t - 1) % e + e) % e + 1, E = 2024, k = (t, e) => e == null ? 31 : new Date(t ?? E, e, 0).getDate(), X = () => {
5
5
  const t = /* @__PURE__ */ new Date();
@@ -82,9 +82,7 @@ const l = "en-US", h = new Intl.DateTimeFormat("en-US", { month: "long" }), $ =
82
82
  );
83
83
  const a = (r ? f(t) : null) ?? f(l);
84
84
  if (!a)
85
- throw new Error(
86
- `DateField: Intl cannot resolve ${l} date parts`
87
- );
85
+ throw new Error(`DateField: Intl cannot resolve ${l} date parts`);
88
86
  return u.set(e, a), a;
89
87
  }, W = () => u.clear(), q = (t) => s(t) ? {
90
88
  day: String(t.getDate()).padStart(2, "0"),
@@ -17,8 +17,8 @@ export interface TryAppendDigitResult {
17
17
  *
18
18
  * - Day uses a fixed max of 31; month-dependent day max is intentionally
19
19
  * deferred — invalid combinations surface as cross-segment errors.
20
- * - Year accepts any 4-digit value 0000-9999; min/max range tightening lands
21
- * in DF-10 via dedicated `minDate` / `maxDate` props.
20
+ * - Year accepts any 4-digit value 0000-9999; `minDate`/`maxDate` narrow the
21
+ * date as a whole on blur, not the digits accepted here.
22
22
  */
23
23
  export declare const tryAppendDigit: (type: SegmentType, buffer: string, digit: string) => TryAppendDigitResult;
24
24
  /** Re-export so `formatSegment` and `tryAppendDigit` share the same max-length
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),j=require("./DateField.utils.cjs.js");function w({disabled:l,fieldRef:a,segmentRefs:v,partsOrder:b,onSegmentFocusChange:D,onFieldBlur:x}){const[n,o]=e.useState(null),i=b[0],y=e.useRef(n);y.current=n;const r=e.useRef(D),d=e.useRef(x);e.useEffect(()=>{r.current=D,d.current=x},[D,x]);const T=e.useRef(void 0);e.useEffect(()=>{if(n===null||n==="all")return;const t=v.current.get(n);t&&(document.activeElement!==t&&t.focus(T.current),T.current=void 0)},[n,v]);const E=e.useCallback((t,c)=>{var u;l||(T.current=c,o(t),(u=r.current)==null||u.call(r,t))},[l]),_=e.useCallback(t=>{var c;l||t.target===a.current&&(o(i),(c=r.current)==null||c.call(r,i))},[l,a,i]),q=e.useCallback(t=>{var u,s,f,p;if((u=a.current)!=null&&u.contains(t.relatedTarget))return;const c=(f=(s=t.target)==null?void 0:s.getAttribute)==null?void 0:f.call(s,"data-segment");c&&c!==y.current||(o(null),(p=d.current)==null||p.call(d),j.clearSelectionWithin(a.current))},[a]),I=e.useCallback(t=>{var u;if(l){t.preventDefault();return}t.target.closest("[data-segment]")||(t.preventDefault(),o(i),(u=r.current)==null||u.call(r,i))},[l,i]),k=e.useCallback((t,c)=>{var f;const u=b.indexOf(t);if(u===-1)return;const s=b[u+c];s!=null&&(o(s),(f=r.current)==null||f.call(r,s))},[b]),M=e.useCallback(t=>{k(t,1)},[k]),P=e.useCallback(t=>{k(t,-1)},[k]);return{focusedSegment:n,fieldTabIndex:l?-1:n===null?0:-1,handleSegmentFocus:E,handleFieldFocus:_,handleFieldBlur:q,handleFieldMouseDown:I,focusNext:M,focusPrevious:P}}exports.useDateFieldFocus=w;
@@ -1,20 +1,20 @@
1
- import { useState as j, useRef as d, useEffect as k, useCallback as s } from "react";
1
+ import { useState as j, useRef as T, useEffect as k, useCallback as s } from "react";
2
2
  import { clearSelectionWithin as q } from "./DateField.utils.es.js";
3
3
  function J({
4
4
  disabled: o,
5
5
  fieldRef: f,
6
6
  segmentRefs: y,
7
7
  partsOrder: x,
8
- onSegmentFocusChange: v,
9
- onFieldBlur: D
8
+ onSegmentFocusChange: d,
9
+ onFieldBlur: v
10
10
  }) {
11
- const [u, l] = j(null), i = x[0], E = d(u);
11
+ const [u, l] = j(null), i = x[0], E = T(u);
12
12
  E.current = u;
13
- const r = d(v), p = d(D);
13
+ const r = T(d), p = T(v);
14
14
  k(() => {
15
- r.current = v, p.current = D;
16
- }, [v, D]);
17
- const m = d(void 0);
15
+ r.current = d, p.current = v;
16
+ }, [d, v]);
17
+ const m = T(void 0);
18
18
  k(() => {
19
19
  if (u === null || u === "all") return;
20
20
  const t = y.current.get(u);
@@ -43,11 +43,14 @@ function J({
43
43
  ), N = s(
44
44
  (t) => {
45
45
  var c;
46
- if (o) return;
46
+ if (o) {
47
+ t.preventDefault();
48
+ return;
49
+ }
47
50
  t.target.closest("[data-segment]") || (t.preventDefault(), l(i), (c = r.current) == null || c.call(r, i));
48
51
  },
49
52
  [o, i]
50
- ), T = s(
53
+ ), D = s(
51
54
  (t, n) => {
52
55
  var a;
53
56
  const c = x.indexOf(t);
@@ -58,14 +61,14 @@ function J({
58
61
  [x]
59
62
  ), P = s(
60
63
  (t) => {
61
- T(t, 1);
64
+ D(t, 1);
62
65
  },
63
- [T]
66
+ [D]
64
67
  ), W = s(
65
68
  (t) => {
66
- T(t, -1);
69
+ D(t, -1);
67
70
  },
68
- [T]
71
+ [D]
69
72
  );
70
73
  return {
71
74
  focusedSegment: u,
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("clsx"),T=require("react"),u=require("../../chunks/form.context.CkC0TwMb.js");require("../Form/contexts/label.context.cjs.js");require("../Form/contexts/helperText.context.cjs.js");const s=require("../Form/hooks/useAccessibleId.hook.cjs.js");require("../../chunks/constants.CgMu0_1M.js");require("react/jsx-runtime");function L({name:i,disabled:b=!1,readOnly:q=!1,required:y=!1,defaultValue:I,error:e,hasHelperText:p,hasLabel:h,validationRules:F=[],ariaDescribedBy:f,ariaLabelledBy:m}){const{showErrors:v,isInvalid:x,errorShown:g,disabled:B,readOnly:_,required:A}=u.useFormField({name:i,validationRules:F,disabledProp:b,readOnlyProp:q,requiredProp:y}),{ctxInitialValues:D}=T.useContext(u.FormContext),{id:r}=s.useAccessibleId(),{id:d}=s.useAccessibleId(),{id:l}=s.useAccessibleId(),{id:o}=s.useAccessibleId(),t=!!(e!=null&&e.length),P=!!e||x,O=I??D[i],a=n(p&&d,t&&r,g&&l,f),c=n(h&&o,m);return{disabled:B,readOnly:_,required:A,invalid:P,errorMessageProvided:t,defaultValue:O,errorId:r,helperTextId:d,validationErrorsId:l,labelId:o,ariaDescribedBy:a.length>0?a:void 0,ariaLabelledBy:c.length>0?c:void 0,showErrors:v}}exports.useDateFieldForm=L;
@@ -1,6 +1,6 @@
1
1
  import { FormValidator } from '@viasat/beam-shared/components/form';
2
2
  import { Nullable } from '@viasat/beam-shared/utils/types';
3
- import { useFormField } from '../../Form/contexts';
3
+ import { useFormField } from '../Form/contexts';
4
4
  export interface UseDateFieldFormArgs {
5
5
  name?: string;
6
6
  disabled?: boolean;
@@ -1,10 +1,10 @@
1
1
  import c from "clsx";
2
2
  import { useContext as V } from "react";
3
- import { b as w, F as C } from "../../../chunks/form.context.BDYA2JQs.js";
4
- import "../../Form/contexts/label.context.es.js";
5
- import "../../Form/contexts/helperText.context.es.js";
6
- import { useAccessibleId as o } from "../../Form/hooks/useAccessibleId.hook.es.js";
7
- import "../../../chunks/constants.Cruz2A1w.js";
3
+ import { b as w, F as C } from "../../chunks/form.context.BDYA2JQs.js";
4
+ import "../Form/contexts/label.context.es.js";
5
+ import "../Form/contexts/helperText.context.es.js";
6
+ import { useAccessibleId as o } from "../Form/hooks/useAccessibleId.hook.es.js";
7
+ import "../../chunks/constants.Cruz2A1w.js";
8
8
  import "react/jsx-runtime";
9
9
  function G({
10
10
  name: d,
@@ -33,11 +33,8 @@ export interface UseDateFieldKeyboardArgs {
33
33
  /** Move focus to the previous segment in the locale-derived `partsOrder`. */
34
34
  focusPrevious: (segment: SegmentType) => void;
35
35
  /**
36
- * Increment, decrement, or jump a segment to its min/max boundary.
37
- * Provided by `useDateFieldValue`. Numeric `amount` wraps day/month and
38
- * clamps year; `'min'`/`'max'` map to Home/End respectively. Returns `false`
39
- * on a no-op (year `'min'`/`'max'` until DF-10 adds year bounds) so the
40
- * dispatcher leaves the key to native page scroll.
36
+ * Steps a segment, or jumps it to a boundary for Home/End. Returns `false` on
37
+ * a no-op so the dispatcher leaves the key to native page scroll.
41
38
  */
42
39
  adjustSegment: (type: SegmentType, amount: SegmentAdjustment) => boolean;
43
40
  /**