@viasat/beam-react 2.47.0 → 2.48.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/CHANGELOG.md +20 -0
- package/assets/DateField.css +1 -1
- package/chunks/{DateField.Segment.C2qoaY0Z.js → DateField.Segment.BVe6TzWY.js} +48 -45
- package/chunks/DateField.Segment.CnDrSK1L.js +1 -0
- package/lib/wip/DateField/DateField.Segment.cjs.js +1 -1
- package/lib/wip/DateField/DateField.Segment.d.ts +1 -1
- package/lib/wip/DateField/DateField.Segment.es.js +1 -1
- package/lib/wip/DateField/DateField.Segments.cjs.js +1 -1
- package/lib/wip/DateField/DateField.Segments.es.js +36 -31
- package/lib/wip/DateField/DateField.cjs.js +1 -1
- package/lib/wip/DateField/DateField.es.js +185 -164
- package/lib/wip/DateField/DateField.types.d.ts +22 -3
- package/lib/wip/DateField/DateField.utils.cjs.js +1 -1
- package/lib/wip/DateField/DateField.utils.d.ts +49 -21
- package/lib/wip/DateField/DateField.utils.es.js +78 -66
- package/lib/wip/DateField/useDateFieldFocus.cjs.js +1 -1
- package/lib/wip/DateField/useDateFieldFocus.es.js +56 -49
- package/lib/wip/DateField/useDateFieldKeyboard.cjs.js +1 -1
- package/lib/wip/DateField/useDateFieldKeyboard.d.ts +6 -10
- package/lib/wip/DateField/useDateFieldKeyboard.es.js +39 -41
- package/lib/wip/DateField/useDateFieldValidity.d.ts +5 -3
- package/lib/wip/DateField/useDateFieldValue.cjs.js +1 -1
- package/lib/wip/DateField/useDateFieldValue.d.ts +38 -22
- package/lib/wip/DateField/useDateFieldValue.es.js +92 -85
- package/package.json +7 -7
- package/chunks/DateField.Segment.CY0jg03_.js +0 -1
|
@@ -1,74 +1,86 @@
|
|
|
1
|
-
import { SEGMENT_MAX_LENGTH as
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
month:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const t = /* @__PURE__ */ new Date();
|
|
8
|
-
return { day: t.getDate(), month: t.getMonth() + 1, year: t.getFullYear() };
|
|
9
|
-
}, M = (t, e, n, r) => {
|
|
10
|
-
if (n === "min") return t === "year" ? null : 1;
|
|
1
|
+
import { SEGMENT_MAX_LENGTH as u } from "./DateField.validation.es.js";
|
|
2
|
+
const c = 31, s = 12, d = 1, y = 9999, f = (e, t, n) => Math.min(n, Math.max(t, e)), S = (e, t) => ((e - 1) % t + t) % t + 1, h = 2024, T = (e, t) => t == null ? 31 : new Date(e ?? h, t, 0).getDate(), A = () => {
|
|
3
|
+
const e = /* @__PURE__ */ new Date();
|
|
4
|
+
return { day: e.getDate(), month: e.getMonth() + 1, year: e.getFullYear() };
|
|
5
|
+
}, o = (e) => e instanceof Date && !Number.isNaN(e.getTime()), Y = (e, t, n, r) => {
|
|
6
|
+
if (n === "min") return e === "year" ? null : 1;
|
|
11
7
|
if (n === "max")
|
|
12
|
-
return
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (
|
|
24
|
-
const
|
|
25
|
-
return
|
|
26
|
-
},
|
|
27
|
-
(e)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
8
|
+
return e === "year" ? null : e === "day" ? r.daysInMonth : s;
|
|
9
|
+
if (t == null) {
|
|
10
|
+
if (e === "year") return r.today.year;
|
|
11
|
+
const g = e === "day" ? c : s;
|
|
12
|
+
return n > 0 ? 1 : g;
|
|
13
|
+
}
|
|
14
|
+
if (e === "year") return f(t + n, d, y);
|
|
15
|
+
const l = e === "day" ? c : s;
|
|
16
|
+
return S(t + n, l);
|
|
17
|
+
}, M = { day: "", month: "", year: "" }, m = (e) => {
|
|
18
|
+
const { day: t, month: n, year: r } = e;
|
|
19
|
+
if (t == null || n == null || r == null) return null;
|
|
20
|
+
const l = new Date(r, n - 1, t);
|
|
21
|
+
return l.setFullYear(r), Number.isNaN(l.getTime()) || l.getFullYear() !== r || l.getMonth() !== n - 1 || l.getDate() !== t ? null : l;
|
|
22
|
+
}, F = (e, t) => e == null && t == null ? !0 : e == null || t == null ? !1 : e.getTime() === t.getTime(), a = (e) => e.getFullYear() * 1e4 + (e.getMonth() + 1) * 100 + e.getDate(), w = (e) => o(e) ? a(e) : null, E = (e, t, n) => {
|
|
23
|
+
const r = a(e);
|
|
24
|
+
return !(o(t) && r < a(t) || o(n) && r > a(n));
|
|
25
|
+
}, N = (e, t) => o(e) && o(t) && a(e) > a(t), R = (e, t, n) => {
|
|
26
|
+
if (N(t, n)) return e;
|
|
27
|
+
const r = a(e);
|
|
28
|
+
return o(t) && r < a(t) ? new Date(t.getFullYear(), t.getMonth(), t.getDate()) : o(n) && r > a(n) ? new Date(n.getFullYear(), n.getMonth(), n.getDate()) : e;
|
|
29
|
+
}, _ = (e) => {
|
|
30
|
+
if (!o(e)) return "";
|
|
31
|
+
const t = String(e.getFullYear()).padStart(4, "0"), n = String(e.getMonth() + 1).padStart(2, "0"), r = String(e.getDate()).padStart(2, "0");
|
|
32
|
+
return `${t}-${n}-${r}`;
|
|
33
|
+
}, D = (e) => e.filter(
|
|
34
|
+
(t) => t.type !== "literal"
|
|
35
|
+
).map((t) => t.type), I = (e) => o(e) ? {
|
|
36
|
+
day: String(e.getDate()).padStart(2, "0"),
|
|
37
|
+
month: String(e.getMonth() + 1).padStart(2, "0"),
|
|
38
|
+
year: String(e.getFullYear()).padStart(4, "0")
|
|
39
|
+
} : M, i = (e, t) => {
|
|
40
|
+
if (t === "" || e === "year" && t.length < u.year) return null;
|
|
41
|
+
const n = parseInt(t, 10);
|
|
35
42
|
return Number.isNaN(n) || n === 0 ? null : n;
|
|
36
|
-
},
|
|
37
|
-
day:
|
|
38
|
-
month:
|
|
39
|
-
year:
|
|
40
|
-
}),
|
|
41
|
-
displayValue:
|
|
43
|
+
}, V = (e) => m({
|
|
44
|
+
day: i("day", e.day),
|
|
45
|
+
month: i("month", e.month),
|
|
46
|
+
year: i("year", e.year)
|
|
47
|
+
}), P = (e, t) => t === "" ? "" : t.padStart(u[e], "0"), X = (e, t, n) => t === "" ? { displayValue: n, isPlaceholder: !0 } : {
|
|
48
|
+
displayValue: t.padStart(u[e], "0"),
|
|
42
49
|
isPlaceholder: !1
|
|
43
|
-
},
|
|
44
|
-
const
|
|
45
|
-
if (!
|
|
50
|
+
}, C = (e) => {
|
|
51
|
+
const t = window.getSelection();
|
|
52
|
+
if (!t) return;
|
|
46
53
|
const n = document.createRange();
|
|
47
|
-
n.selectNodeContents(
|
|
48
|
-
},
|
|
54
|
+
n.selectNodeContents(e), t.removeAllRanges(), t.addRange(n);
|
|
55
|
+
}, L = (e) => {
|
|
49
56
|
var n;
|
|
50
|
-
if (!
|
|
51
|
-
const
|
|
52
|
-
|
|
57
|
+
if (!e) return;
|
|
58
|
+
const t = (n = window.getSelection) == null ? void 0 : n.call(window);
|
|
59
|
+
t && t.rangeCount > 0 && e.contains(t.anchorNode) && t.removeAllRanges();
|
|
53
60
|
};
|
|
54
61
|
export {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
62
|
+
c as DAY_SPIN_MAX,
|
|
63
|
+
s as MONTH_MAX,
|
|
64
|
+
y as YEAR_MAX,
|
|
65
|
+
d as YEAR_MIN,
|
|
66
|
+
Y as adjustSegmentValue,
|
|
67
|
+
f as clamp,
|
|
68
|
+
R as clampDateToRange,
|
|
69
|
+
L as clearSelectionWithin,
|
|
70
|
+
w as dateKeyOrNull,
|
|
71
|
+
m as deriveValue,
|
|
72
|
+
V as deriveValueFromText,
|
|
73
|
+
T as getDaysInMonth,
|
|
74
|
+
X as getSegmentDisplay,
|
|
75
|
+
D as getSegmentOrder,
|
|
76
|
+
E as isDateInRange,
|
|
77
|
+
N as isMinMaxMisconfigured,
|
|
78
|
+
F as isSameDateValue,
|
|
79
|
+
P as normalizeSegmentText,
|
|
80
|
+
i as segmentNumber,
|
|
81
|
+
I as segmentTextFromValue,
|
|
82
|
+
C as selectElementContents,
|
|
83
|
+
_ as toISODateString,
|
|
84
|
+
A as todayParts,
|
|
85
|
+
S as wrapInRange
|
|
74
86
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react"),P=require("./DateField.utils.cjs.js");function j({disabled:l,fieldRef:i,segmentRefs:T,partsOrder:b,onSegmentFocusChange:d,onFieldBlur:x}){const[c,o]=r.useState(null),a=b[0],y=r.useRef(c);y.current=c;const e=r.useRef(d),k=r.useRef(x);r.useEffect(()=>{e.current=d,k.current=x},[d,x]),r.useEffect(()=>{if(c===null||c==="all")return;const t=T.current.get(c);t&&document.activeElement!==t&&t.focus()},[c,T]);const E=r.useCallback(t=>{var u;l||(o(t),(u=e.current)==null||u.call(e,t))},[l]),q=r.useCallback(t=>{var u;l||t.target===i.current&&(o(a),(u=e.current)==null||u.call(e,a))},[l,i,a]),v=r.useCallback(t=>{var n,s,f,_;if((n=i.current)!=null&&n.contains(t.relatedTarget))return;const u=(f=(s=t.target)==null?void 0:s.getAttribute)==null?void 0:f.call(s,"data-segment");u&&u!==y.current||(o(null),(_=k.current)==null||_.call(k),P.clearSelectionWithin(i.current))},[i]),w=r.useCallback(t=>{var n;if(l)return;t.target.closest("[data-segment]")||(t.preventDefault(),o(a),(n=e.current)==null||n.call(e,a))},[l,a]),D=r.useCallback((t,u)=>{var f;const n=b.indexOf(t);if(n===-1)return;const s=b[n+u];s!=null&&(o(s),(f=e.current)==null||f.call(e,s))},[b]),I=r.useCallback(t=>{D(t,1)},[D]),M=r.useCallback(t=>{D(t,-1)},[D]);return{focusedSegment:c,fieldTabIndex:l?-1:c===null?0:-1,handleSegmentFocus:E,handleFieldFocus:q,handleFieldBlur:v,handleFieldMouseDown:w,focusNext:I,focusPrevious:M}}exports.useDateFieldFocus=j;
|
|
@@ -1,71 +1,78 @@
|
|
|
1
|
-
import { useState as
|
|
2
|
-
import { clearSelectionWithin as
|
|
3
|
-
function
|
|
4
|
-
disabled:
|
|
5
|
-
fieldRef:
|
|
6
|
-
segmentRefs:
|
|
7
|
-
partsOrder:
|
|
8
|
-
onSegmentFocusChange:
|
|
9
|
-
onFieldBlur:
|
|
1
|
+
import { useState as d, useRef as y, useEffect as v, useCallback as o } from "react";
|
|
2
|
+
import { clearSelectionWithin as j } from "./DateField.utils.es.js";
|
|
3
|
+
function H({
|
|
4
|
+
disabled: s,
|
|
5
|
+
fieldRef: l,
|
|
6
|
+
segmentRefs: E,
|
|
7
|
+
partsOrder: x,
|
|
8
|
+
onSegmentFocusChange: m,
|
|
9
|
+
onFieldBlur: p
|
|
10
10
|
}) {
|
|
11
|
-
const [
|
|
12
|
-
I
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
const [u, f] = d(null), i = x[0], I = y(u);
|
|
12
|
+
I.current = u;
|
|
13
|
+
const r = y(m), T = y(p);
|
|
14
|
+
v(() => {
|
|
15
|
+
r.current = m, T.current = p;
|
|
16
|
+
}, [m, p]), v(() => {
|
|
17
|
+
if (u === null || u === "all") return;
|
|
18
|
+
const t = E.current.get(u);
|
|
17
19
|
t && document.activeElement !== t && t.focus();
|
|
18
|
-
}, [
|
|
19
|
-
const
|
|
20
|
+
}, [u, E]);
|
|
21
|
+
const w = o(
|
|
20
22
|
(t) => {
|
|
21
23
|
var c;
|
|
22
|
-
|
|
24
|
+
s || (f(t), (c = r.current) == null || c.call(r, t));
|
|
23
25
|
},
|
|
24
|
-
[
|
|
25
|
-
),
|
|
26
|
+
[s]
|
|
27
|
+
), A = o(
|
|
26
28
|
(t) => {
|
|
27
29
|
var c;
|
|
28
|
-
|
|
30
|
+
s || t.target === l.current && (f(i), (c = r.current) == null || c.call(r, i));
|
|
29
31
|
},
|
|
30
|
-
[
|
|
31
|
-
), M =
|
|
32
|
+
[s, l, i]
|
|
33
|
+
), M = o(
|
|
32
34
|
(t) => {
|
|
33
|
-
var
|
|
34
|
-
(
|
|
35
|
+
var n, e, a, k;
|
|
36
|
+
if ((n = l.current) != null && n.contains(t.relatedTarget)) return;
|
|
37
|
+
const c = (a = (e = t.target) == null ? void 0 : e.getAttribute) == null ? void 0 : a.call(
|
|
38
|
+
e,
|
|
39
|
+
"data-segment"
|
|
40
|
+
);
|
|
41
|
+
c && c !== I.current || (f(null), (k = T.current) == null || k.call(T), j(l.current));
|
|
35
42
|
},
|
|
36
|
-
[
|
|
37
|
-
), N =
|
|
43
|
+
[l]
|
|
44
|
+
), N = o(
|
|
38
45
|
(t) => {
|
|
39
|
-
var
|
|
40
|
-
if (
|
|
41
|
-
t.target.closest("[data-segment]") || (t.preventDefault(),
|
|
46
|
+
var n;
|
|
47
|
+
if (s) return;
|
|
48
|
+
t.target.closest("[data-segment]") || (t.preventDefault(), f(i), (n = r.current) == null || n.call(r, i));
|
|
42
49
|
},
|
|
43
|
-
[
|
|
44
|
-
),
|
|
50
|
+
[s, i]
|
|
51
|
+
), D = o(
|
|
45
52
|
(t, c) => {
|
|
46
|
-
var
|
|
47
|
-
const
|
|
48
|
-
if (
|
|
49
|
-
const
|
|
50
|
-
|
|
53
|
+
var a;
|
|
54
|
+
const n = x.indexOf(t);
|
|
55
|
+
if (n === -1) return;
|
|
56
|
+
const e = x[n + c];
|
|
57
|
+
e != null && (f(e), (a = r.current) == null || a.call(r, e));
|
|
51
58
|
},
|
|
52
|
-
[
|
|
53
|
-
), P =
|
|
59
|
+
[x]
|
|
60
|
+
), P = o(
|
|
54
61
|
(t) => {
|
|
55
|
-
|
|
62
|
+
D(t, 1);
|
|
56
63
|
},
|
|
57
|
-
[
|
|
58
|
-
), W =
|
|
64
|
+
[D]
|
|
65
|
+
), W = o(
|
|
59
66
|
(t) => {
|
|
60
|
-
|
|
67
|
+
D(t, -1);
|
|
61
68
|
},
|
|
62
|
-
[
|
|
69
|
+
[D]
|
|
63
70
|
);
|
|
64
71
|
return {
|
|
65
|
-
focusedSegment:
|
|
66
|
-
fieldTabIndex:
|
|
67
|
-
handleSegmentFocus:
|
|
68
|
-
handleFieldFocus:
|
|
72
|
+
focusedSegment: u,
|
|
73
|
+
fieldTabIndex: s ? -1 : u === null ? 0 : -1,
|
|
74
|
+
handleSegmentFocus: w,
|
|
75
|
+
handleFieldFocus: A,
|
|
69
76
|
handleFieldBlur: M,
|
|
70
77
|
handleFieldMouseDown: N,
|
|
71
78
|
focusNext: P,
|
|
@@ -73,5 +80,5 @@ function G({
|
|
|
73
80
|
};
|
|
74
81
|
}
|
|
75
82
|
export {
|
|
76
|
-
|
|
83
|
+
H as useDateFieldFocus
|
|
77
84
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const w=require("react");function d({disabled:a,readOnly:c,fieldRef:y,focusNext:o,focusPrevious:e,adjustSegment:t,clearSegment:l}){const p=w.useMemo(()=>{const n={ArrowRight:({segment:r,isRTL:i})=>((i?e:o)(r),!0),ArrowLeft:({segment:r,isRTL:i})=>((i?o:e)(r),!0)};return c?n:{...n,ArrowUp:({segment:r})=>t(r,1),ArrowDown:({segment:r})=>t(r,-1),PageUp:({segment:r})=>t(r,5),PageDown:({segment:r})=>t(r,-5),Home:({segment:r})=>t(r,"min"),End:({segment:r})=>t(r,"max"),Backspace:({segment:r})=>(l(r).wasEmpty&&e(r),!0),Delete:({segment:r})=>(l(r),!0)}},[t,l,o,e,c]);return w.useCallback((n,r)=>{if(a||r.altKey||r.ctrlKey||r.metaKey||r.shiftKey)return;const i=p[r.key];if(!i)return;const u=y.current,b=!!u&&(getComputedStyle(u).direction==="rtl"||!!u.closest('[dir="rtl"]'));i({segment:n,event:r,isRTL:b})&&r.preventDefault()},[a,p,y])}exports.useDateFieldKeyboard=d;
|
|
@@ -41,18 +41,14 @@ export interface UseDateFieldKeyboardArgs {
|
|
|
41
41
|
*/
|
|
42
42
|
adjustSegment: (type: SegmentType, amount: SegmentAdjustment) => boolean;
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
45
|
-
* Returns `{ wasEmpty: true }` when the buffer was already
|
|
46
|
-
*
|
|
44
|
+
* Clears the entire segment buffer to `''` — shared by Backspace and Delete.
|
|
45
|
+
* Returns `{ wasEmpty: true }` when the buffer was already
|
|
46
|
+
* empty, signalling Backspace to move focus to the previous segment instead;
|
|
47
|
+
* Delete ignores the result and leaves focus on the current segment.
|
|
47
48
|
* Provided by `useDateFieldValue`.
|
|
48
49
|
*/
|
|
49
|
-
|
|
50
|
+
clearSegment: (type: SegmentType) => {
|
|
50
51
|
wasEmpty: boolean;
|
|
51
52
|
};
|
|
52
|
-
/**
|
|
53
|
-
* Clears the entire segment buffer to `''` (Delete). Focus stays on the
|
|
54
|
-
* current segment. Provided by `useDateFieldValue`.
|
|
55
|
-
*/
|
|
56
|
-
clearSegment: (type: SegmentType) => void;
|
|
57
53
|
}
|
|
58
|
-
export declare function useDateFieldKeyboard({ disabled, readOnly, fieldRef, focusNext, focusPrevious, adjustSegment,
|
|
54
|
+
export declare function useDateFieldKeyboard({ disabled, readOnly, fieldRef, focusNext, focusPrevious, adjustSegment, clearSegment, }: UseDateFieldKeyboardArgs): (segment: SegmentType, event: KeyboardEvent<HTMLSpanElement>) => void;
|
|
@@ -1,49 +1,47 @@
|
|
|
1
|
-
import { useMemo as
|
|
2
|
-
function
|
|
3
|
-
disabled:
|
|
4
|
-
readOnly:
|
|
5
|
-
fieldRef:
|
|
1
|
+
import { useMemo as D, useCallback as K } from "react";
|
|
2
|
+
function A({
|
|
3
|
+
disabled: e,
|
|
4
|
+
readOnly: u,
|
|
5
|
+
fieldRef: w,
|
|
6
6
|
focusNext: l,
|
|
7
|
-
focusPrevious:
|
|
8
|
-
adjustSegment:
|
|
9
|
-
|
|
10
|
-
clearSegment: y
|
|
7
|
+
focusPrevious: n,
|
|
8
|
+
adjustSegment: t,
|
|
9
|
+
clearSegment: p
|
|
11
10
|
}) {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return h(
|
|
11
|
+
const y = D(() => {
|
|
12
|
+
const o = {
|
|
13
|
+
// Nav keys always own the event (arrows are contentEditable caret keys we
|
|
14
|
+
// suppress even at the first/last segment), so they always report handled.
|
|
15
|
+
ArrowRight: ({ segment: r, isRTL: i }) => ((i ? n : l)(r), !0),
|
|
16
|
+
ArrowLeft: ({ segment: r, isRTL: i }) => ((i ? l : n)(r), !0)
|
|
17
|
+
};
|
|
18
|
+
return u ? o : {
|
|
19
|
+
...o,
|
|
20
|
+
ArrowUp: ({ segment: r }) => t(r, 1),
|
|
21
|
+
ArrowDown: ({ segment: r }) => t(r, -1),
|
|
22
|
+
PageUp: ({ segment: r }) => t(r, 5),
|
|
23
|
+
PageDown: ({ segment: r }) => t(r, -5),
|
|
24
|
+
Home: ({ segment: r }) => t(r, "min"),
|
|
25
|
+
End: ({ segment: r }) => t(r, "max"),
|
|
26
|
+
// Backspace and Delete both clear the whole segment to
|
|
27
|
+
// placeholder. Backspace on an already-empty segment moves focus to the
|
|
28
|
+
// previous segment instead (MUI parity); Delete just clears.
|
|
29
|
+
// Both always own the key (clear or focus-hop), so they report handled.
|
|
30
|
+
Backspace: ({ segment: r }) => (p(r).wasEmpty && n(r), !0),
|
|
31
|
+
Delete: ({ segment: r }) => (p(r), !0)
|
|
32
|
+
};
|
|
33
|
+
}, [t, p, l, n, u]);
|
|
34
|
+
return K(
|
|
37
35
|
(o, r) => {
|
|
38
|
-
if (
|
|
39
|
-
const
|
|
40
|
-
if (!
|
|
41
|
-
const c =
|
|
42
|
-
|
|
36
|
+
if (e || r.altKey || r.ctrlKey || r.metaKey || r.shiftKey) return;
|
|
37
|
+
const i = y[r.key];
|
|
38
|
+
if (!i) return;
|
|
39
|
+
const c = w.current, a = !!c && (getComputedStyle(c).direction === "rtl" || !!c.closest('[dir="rtl"]'));
|
|
40
|
+
i({ segment: o, event: r, isRTL: a }) && r.preventDefault();
|
|
43
41
|
},
|
|
44
|
-
[
|
|
42
|
+
[e, y, w]
|
|
45
43
|
);
|
|
46
44
|
}
|
|
47
45
|
export {
|
|
48
|
-
|
|
46
|
+
A as useDateFieldKeyboard
|
|
49
47
|
};
|
|
@@ -15,9 +15,11 @@ export interface UseDateFieldValidityReturn {
|
|
|
15
15
|
allFilled: boolean;
|
|
16
16
|
hasPartialValue: boolean;
|
|
17
17
|
/** "Show error?" for value-driven invalidity. True when the user has
|
|
18
|
-
* touched the field AND
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* touched the field AND (all segments filled but combine to an invalid
|
|
19
|
+
* date (Feb 30), OR some filled/some empty and focus has left).
|
|
20
|
+
* `minDate`/`maxDate` out-of-range values aren't flagged here — the
|
|
21
|
+
* built-in bound is a blur clamp (see `commitOnBlur`), not a validity
|
|
22
|
+
* constraint; use a `validationRule` for range errors/submit-blocking. */
|
|
21
23
|
isInvalid: boolean;
|
|
22
24
|
}
|
|
23
25
|
export declare function useDateFieldValidity({ segments, currentValue, wasTouched, isFocused, }: UseDateFieldValidityArgs): UseDateFieldValidityReturn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react"),t=require("./DateField.utils.cjs.js"),j=require("./DateField.validation.cjs.js");function G({value:a,defaultValue:A,onChange:x,minDate:R,maxDate:y,getClampAnnouncement:V}){const N=r.useRef(a!==void 0),F=N.current,[m,h]=r.useState(()=>t.segmentTextFromValue(F?a??null:A??null)),[D,_]=r.useState(!1),[C,M]=r.useState(""),c=r.useRef(m),f=r.useRef(new Set),d=r.useRef(!1),l=r.useRef(null),v={day:t.segmentNumber("day",m.day),month:t.segmentNumber("month",m.month),year:t.segmentNumber("year",m.year)},k=t.deriveValue(v),E=r.useRef(k),p=r.useRef(F?a??null:null),g=r.useRef(x),S=r.useRef(V);r.useEffect(()=>{g.current=x,S.current=V},[x,V]),r.useEffect(()=>()=>{l.current!=null&&cancelAnimationFrame(l.current)},[]),r.useEffect(()=>{if(!N.current||d.current||t.isSameDateValue(a??null,p.current))return;p.current=a??null;const e=t.segmentTextFromValue(a??null);c.current=e,h(e),E.current=t.deriveValueFromText(e)},[a]);const b=r.useCallback(e=>{var n;const s=t.deriveValueFromText(e);t.isSameDateValue(s,E.current)||(E.current=s,(n=g.current)==null||n.call(g,s))},[]),o=r.useCallback((e,s,{replace:n})=>{const u={...c.current,[e]:s};c.current=u,h(u),_(!0),b(u),n?f.current.add(e):f.current.delete(e)},[b]),q=r.useCallback((e,s)=>{const n=f.current.has(e)?"":c.current[e],u=j.tryAppendDigit(e,n,s);return u.rejected?{advanced:!1,rejected:!0}:(o(e,u.newBuffer,{replace:u.shouldAdvance}),{advanced:u.shouldAdvance,rejected:!1})},[o]),z=r.useCallback((e,s)=>{const n=c.current,u=t.segmentNumber(e,n[e]),T=t.getDaysInMonth(t.segmentNumber("year",n.year),t.segmentNumber("month",n.month)),i=t.adjustSegmentValue(e,u,s,{daysInMonth:T,today:t.todayParts()});return i==null?!1:(d.current=!0,o(e,String(i).padStart(j.SEGMENT_MAX_LENGTH[e],"0"),{replace:!0}),!0)},[o]),I=r.useCallback(e=>c.current[e]===""?{wasEmpty:!0}:(d.current=!0,o(e,"",{replace:!1}),{wasEmpty:!1}),[o]),O=r.useCallback(e=>{d.current=!0,f.current.add(e)},[]),B=r.useCallback(()=>{var T;d.current=!1;const e=c.current,s={day:t.normalizeSegmentText("day",e.day),month:t.normalizeSegmentText("month",e.month),year:t.normalizeSegmentText("year",e.year)},n=t.deriveValueFromText(s);let u=s;if(n!=null&&D&&!t.isDateInRange(n,R,y)){const i=t.clampDateToRange(n,R,y);if(u=t.segmentTextFromValue(i),!t.isSameDateValue(i,n)){const w=((T=S.current)==null?void 0:T.call(S,i))??"";w&&(l.current!=null&&cancelAnimationFrame(l.current),l.current=requestAnimationFrame(()=>{l.current=null,M(w)}))}}c.current=u,h(u),_(!0),b(u)},[b,D,t.dateKeyOrNull(R),t.dateKeyOrNull(y)]);return{segmentText:m,segmentValues:v,currentValue:k,isControlled:F,wasTouched:D,appendDigit:q,adjustSegment:z,clearSegment:I,beginSegmentEdit:O,commitOnBlur:B,clampAnnouncement:C}}exports.useDateFieldValue=G;
|
|
@@ -5,6 +5,23 @@ export interface UseDateFieldValueArgs {
|
|
|
5
5
|
defaultValue?: Nullable<Date>;
|
|
6
6
|
/** Fires on user-driven value transitions only, never on controlled `value` changes. */
|
|
7
7
|
onChange?: (value: Nullable<Date>) => void;
|
|
8
|
+
/**
|
|
9
|
+
* Earliest allowed date (inclusive, compared by calendar day). Springs a
|
|
10
|
+
* touched value to this bound on blur (see `commitOnBlur`) — does not bound
|
|
11
|
+
* the year segment's spin/Home/End, which is free (see `adjustSegment`).
|
|
12
|
+
*/
|
|
13
|
+
minDate?: Nullable<Date>;
|
|
14
|
+
/**
|
|
15
|
+
* Latest allowed date (inclusive, compared by calendar day). Springs a
|
|
16
|
+
* touched value to this bound on blur (see `commitOnBlur`) — does not bound
|
|
17
|
+
* the year segment's spin/Home/End, which is free (see `adjustSegment`).
|
|
18
|
+
*/
|
|
19
|
+
maxDate?: Nullable<Date>;
|
|
20
|
+
/**
|
|
21
|
+
* Called when a touched value springs to a bound on blur; returns a localized
|
|
22
|
+
* message set on the polite live region. Omit → no announcement.
|
|
23
|
+
*/
|
|
24
|
+
getClampAnnouncement?: (clampedDate: Date) => string;
|
|
8
25
|
}
|
|
9
26
|
export interface UseDateFieldValueReturn {
|
|
10
27
|
segmentText: SegmentText;
|
|
@@ -17,41 +34,40 @@ export interface UseDateFieldValueReturn {
|
|
|
17
34
|
* Increments, decrements, or jumps a segment to its min/max boundary.
|
|
18
35
|
*
|
|
19
36
|
* - Numeric `amount` (e.g. ±1, ±5): day/month wrap modularly; year clamps
|
|
20
|
-
* to [
|
|
21
|
-
*
|
|
22
|
-
*
|
|
37
|
+
* to `[YEAR_MIN, YEAR_MAX]` (free-spinning, independent of `minDate`/
|
|
38
|
+
* `maxDate` — see `DateField.utils.adjustSegmentValue`). An empty day/month
|
|
39
|
+
* segment seeds to a direction-based first/last valid value; an empty year
|
|
40
|
+
* seeds to the current year.
|
|
41
|
+
* - `'min'` / `'max'`: jump to the lower/upper bound. No-op on year (Home/End
|
|
42
|
+
* don't bound the year to `minDate`/`maxDate`).
|
|
23
43
|
*
|
|
24
44
|
* Follows the `appendDigit` mutation pattern: writes zero-padded `segmentText`,
|
|
25
45
|
* sets `wasTouched`, calls `emitIfChanged`, and marks the segment in
|
|
26
46
|
* `replaceNextRef` so a digit typed immediately after replaces rather than
|
|
27
47
|
* appends.
|
|
28
48
|
*
|
|
29
|
-
* @returns `true` if the segment was adjusted, `false` on a no-op (
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* the key to native (e.g. page scroll).
|
|
49
|
+
* @returns `true` if the segment was adjusted, `false` on a no-op (year
|
|
50
|
+
* `'min'`/`'max'`). The keyboard dispatcher uses this to decide whether to
|
|
51
|
+
* `preventDefault` — a no-op leaves the key to native (e.g. page scroll).
|
|
33
52
|
*/
|
|
34
53
|
adjustSegment: (type: SegmentType, amount: SegmentAdjustment) => boolean;
|
|
35
54
|
/**
|
|
36
|
-
*
|
|
55
|
+
* Clears the entire segment buffer to `''` — the shared Backspace and
|
|
56
|
+
* Delete behaviour.
|
|
37
57
|
*
|
|
38
|
-
* Returns `{ wasEmpty: true }` when the buffer was already empty
|
|
39
|
-
* caller (keyboard handler) knows
|
|
40
|
-
*
|
|
41
|
-
*
|
|
58
|
+
* Returns `{ wasEmpty: true }` when the buffer was already empty, without
|
|
59
|
+
* mutating, so the caller (keyboard handler) knows Backspace should move
|
|
60
|
+
* focus to the previous segment instead of clearing. Otherwise focus stays
|
|
61
|
+
* on the current segment. Fires `onChange(null)` via `emitIfChanged` when
|
|
62
|
+
* the cleared segment was part of a complete date. Clears `replaceNextRef`
|
|
63
|
+
* for the segment so the next digit appends.
|
|
42
64
|
*/
|
|
43
|
-
|
|
65
|
+
clearSegment: (type: SegmentType) => {
|
|
44
66
|
wasEmpty: boolean;
|
|
45
67
|
};
|
|
46
|
-
/**
|
|
47
|
-
* Clears the entire segment buffer to `''` (Delete behaviour).
|
|
48
|
-
*
|
|
49
|
-
* Focus stays on the current segment. Fires `onChange(null)` via
|
|
50
|
-
* `emitIfChanged` when the cleared segment was part of a complete date.
|
|
51
|
-
* Clears `replaceNextRef` for the segment so the next digit appends.
|
|
52
|
-
*/
|
|
53
|
-
clearSegment: (type: SegmentType) => void;
|
|
54
68
|
beginSegmentEdit: (type: SegmentType) => void;
|
|
55
69
|
commitOnBlur: () => void;
|
|
70
|
+
/** Polite live-region message set when the blur clamp springs a value to a bound. */
|
|
71
|
+
clampAnnouncement: string;
|
|
56
72
|
}
|
|
57
|
-
export declare function useDateFieldValue({ value, defaultValue, onChange, }: UseDateFieldValueArgs): UseDateFieldValueReturn;
|
|
73
|
+
export declare function useDateFieldValue({ value, defaultValue, onChange, minDate, maxDate, getClampAnnouncement, }: UseDateFieldValueArgs): UseDateFieldValueReturn;
|