@astryxdesign/core 0.7.6-canary.8d0a847 → 0.7.6-canary.9d7cffe
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DateInput/Wheel.d.ts.map +1 -1
- package/dist/DateInput/Wheel.js +11 -7
- package/dist/DateInput/usePointerDragScroll.d.ts +10 -1
- package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -1
- package/dist/DateInput/usePointerDragScroll.js +25 -9
- package/dist/DateInput/useScrollSettle.d.ts +3 -1
- package/dist/DateInput/useScrollSettle.d.ts.map +1 -1
- package/dist/DateInput/useScrollSettle.js +37 -8
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +8 -3
- package/dist/Markdown/plugins/headingLinks.a11y.chromium.spec.js +1 -1
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +6 -1
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +5 -2
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +19 -3
- package/dist/Typeahead/BaseTypeahead.d.ts +4 -4
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +43 -7
- package/dist/gestures/GestureArena.d.ts +1 -1
- package/dist/gestures/GestureArena.d.ts.map +1 -1
- package/dist/gestures/GestureArena.js +2 -1
- package/dist/gestures/GestureHost.d.ts +2 -3
- package/dist/gestures/GestureHost.d.ts.map +1 -1
- package/dist/gestures/GestureHost.js +7 -7
- package/package.json +4 -4
- package/src/Chat/ChatDictationButton.spec.md +126 -81
- package/src/DateInput/DateInputTouch.test.tsx +44 -0
- package/src/DateInput/Wheel.tsx +9 -6
- package/src/DateInput/usePointerDragScroll.ts +34 -10
- package/src/DateInput/useScrollSettle.ts +38 -7
- package/src/Link/Link.spec.md +3 -2
- package/src/Link/Link.tsx +11 -0
- package/src/Link/__tests__/Link.truncation.a11y.chromium.spec.ts +58 -0
- package/src/Markdown/plugins/headingLinks.a11y.chromium.spec.ts +1 -1
- package/src/OverflowList/OverflowList.spec.md +102 -55
- package/src/Pagination/Pagination.spec.md +158 -84
- package/src/RadioList/RadioList.spec.md +1 -1
- package/src/RadioList/RadioList.test.tsx +28 -0
- package/src/RadioList/RadioListItem.tsx +6 -0
- package/src/Switch/Switch.spec.md +1 -1
- package/src/Switch/Switch.test.tsx +21 -1
- package/src/Switch/Switch.tsx +5 -1
- package/src/TimeInput/TimeInput.spec.md +13 -13
- package/src/Toast/Toast.spec.md +2 -5
- package/src/Toast/ToastViewport.test.tsx +79 -0
- package/src/Toast/ToastViewport.tsx +21 -3
- package/src/Typeahead/BaseTypeahead.doc.mjs +3 -3
- package/src/Typeahead/BaseTypeahead.spec.md +45 -45
- package/src/Typeahead/BaseTypeahead.tsx +48 -9
- package/src/Typeahead/Typeahead.test.tsx +120 -0
- package/src/gestures/GestureArena.ts +1 -1
- package/src/gestures/GestureHost.ts +6 -7
- package/src/motion/README.md +2 -1
- package/src/motion/roles.test.ts +5 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Wheel.d.ts","sourceRoot":"","sources":["../../src/DateInput/Wheel.tsx"],"names":[],"mappings":"AA8MA,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACpC,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,QAAe,GAChB,EAAE,UAAU,+
|
|
1
|
+
{"version":3,"file":"Wheel.d.ts","sourceRoot":"","sources":["../../src/DateInput/Wheel.tsx"],"names":[],"mappings":"AA8MA,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACpC,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,QAAe,GAChB,EAAE,UAAU,+BAmOZ;yBAzOe,KAAK"}
|
package/dist/DateInput/Wheel.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* rubber-banding, and the settle animation are the platform's; all this adds
|
|
13
13
|
* is `scroll-snap-align: center` on each option, half a viewport of padding at
|
|
14
14
|
* each end so the first and last option can reach the middle, and a commit
|
|
15
|
-
* when the scrolling stops.
|
|
15
|
+
* when the scrolling stops and no finger or mouse drag still holds it.
|
|
16
16
|
*
|
|
17
17
|
* The falloff (rows fading and tipping away from the centre) is a CSS
|
|
18
18
|
* scroll-driven animation on a `view()` timeline — the browser interpolates it
|
|
@@ -99,6 +99,15 @@ export function Wheel({
|
|
|
99
99
|
// `selectedIndex` only catches up when the wheel settles.
|
|
100
100
|
const [activeIndex, setActiveIndex] = useState(selectedIndex);
|
|
101
101
|
|
|
102
|
+
// A mouse cannot drag a scroll container, so without this the wheel ignores
|
|
103
|
+
// the one gesture its shape invites. Touch is untouched — it pans natively,
|
|
104
|
+
// with momentum this could not match. See usePointerDragScroll. The drag it
|
|
105
|
+
// holds is not rest either: the settle below waits for its release, as it
|
|
106
|
+
// waits for a finger's (useScrollSettle).
|
|
107
|
+
const {
|
|
108
|
+
isDraggingRef
|
|
109
|
+
} = usePointerDragScroll(scrollerRef, isActive);
|
|
110
|
+
|
|
102
111
|
// Row height in px, read from layout rather than assumed, so a theme that
|
|
103
112
|
// retunes --date-input-touch-wheel-item-size still lands on the right row.
|
|
104
113
|
const itemBlockSize = useCallback(() => {
|
|
@@ -138,7 +147,7 @@ export function Wheel({
|
|
|
138
147
|
if (option.value !== value) {
|
|
139
148
|
onChange(option.value);
|
|
140
149
|
}
|
|
141
|
-
}, isActive);
|
|
150
|
+
}, isActive, isDraggingRef);
|
|
142
151
|
|
|
143
152
|
// Park the committed row under the band whenever the wheel is shown, or the
|
|
144
153
|
// value is changed from outside (the calendar scrolled to another month).
|
|
@@ -210,11 +219,6 @@ export function Wheel({
|
|
|
210
219
|
useOwnScrollGesture(scrollerRef, 'all', {
|
|
211
220
|
isEnabled: isActive
|
|
212
221
|
});
|
|
213
|
-
|
|
214
|
-
// A mouse cannot drag a scroll container, so without this the wheel ignores
|
|
215
|
-
// the one gesture its shape invites. Touch is untouched — it pans natively,
|
|
216
|
-
// with momentum this could not match. See usePointerDragScroll.
|
|
217
|
-
usePointerDragScroll(scrollerRef, isActive);
|
|
218
222
|
const moveBy = useCallback(delta => {
|
|
219
223
|
const next = Math.min(options.length - 1, Math.max(0, activeIndex + delta));
|
|
220
224
|
const option = options[next];
|
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
* press of the button itself, and a wheel row is a click target.
|
|
4
4
|
*/
|
|
5
5
|
export declare const DRAG_SLOP = 4;
|
|
6
|
+
/** What {@link usePointerDragScroll} reports back about the drag. */
|
|
7
|
+
export type PointerDragScrollState = {
|
|
8
|
+
/**
|
|
9
|
+
* True while a mouse drag holds the container: from the press that moved
|
|
10
|
+
* past {@link DRAG_SLOP} until its release. Pass it to `useScrollSettle`,
|
|
11
|
+
* which treats a held drag as it treats a finger still down.
|
|
12
|
+
*/
|
|
13
|
+
isDraggingRef: React.RefObject<boolean>;
|
|
14
|
+
};
|
|
6
15
|
/**
|
|
7
16
|
* Let a mouse drag `ref`'s contents, on a container that already scrolls and
|
|
8
17
|
* snaps for touch.
|
|
@@ -11,5 +20,5 @@ export declare const DRAG_SLOP = 4;
|
|
|
11
20
|
* @param isEnabled - skip while the wheel is hidden; a hidden panel keeps its
|
|
12
21
|
* layout box, so its listeners would otherwise still be live
|
|
13
22
|
*/
|
|
14
|
-
export declare function usePointerDragScroll(ref: React.RefObject<HTMLElement | null>, isEnabled?: boolean):
|
|
23
|
+
export declare function usePointerDragScroll(ref: React.RefObject<HTMLElement | null>, isEnabled?: boolean): PointerDragScrollState;
|
|
15
24
|
//# sourceMappingURL=usePointerDragScroll.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePointerDragScroll.d.ts","sourceRoot":"","sources":["../../src/DateInput/usePointerDragScroll.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"usePointerDragScroll.d.ts","sourceRoot":"","sources":["../../src/DateInput/usePointerDragScroll.ts"],"names":[],"mappings":"AAwDA;;;GAGG;AACH,eAAO,MAAM,SAAS,IAAI,CAAC;AAK3B,qEAAqE;AACrE,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;;OAIG;IACH,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;CACzC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EACxC,SAAS,GAAE,OAAc,GACxB,sBAAsB,CAmJxB"}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @file usePointerDragScroll.ts
|
|
7
7
|
* @input A scroll container ref
|
|
8
|
-
* @output Lets a mouse drag the container's contents the way a finger does
|
|
8
|
+
* @output Lets a mouse drag the container's contents the way a finger does,
|
|
9
|
+
* and reports while a drag holds it (`isDraggingRef`)
|
|
9
10
|
* @position Internal behavior hook; consumed by Wheel.tsx
|
|
10
11
|
*
|
|
11
12
|
* ## Why this exists
|
|
@@ -38,11 +39,19 @@
|
|
|
38
39
|
* then jumps a whole one. The drag therefore suspends snapping, and restores
|
|
39
40
|
* it once the release has settled somewhere legal.
|
|
40
41
|
*
|
|
42
|
+
* ## A held drag is not rest
|
|
43
|
+
*
|
|
44
|
+
* Every `scrollTop` the drag assigns is a programmatic scroll, and Chromium
|
|
45
|
+
* ends each one with a `scrollend` — 14 moves, 14 of them. A settle listening
|
|
46
|
+
* for `scrollend` alone would commit the row under the band at every step,
|
|
47
|
+
* with the button still down. `isDraggingRef` tells `useScrollSettle` the
|
|
48
|
+
* drag is still held, the way a touch that has not ended does.
|
|
49
|
+
*
|
|
41
50
|
* SYNC: When modified, update:
|
|
42
51
|
* - /packages/core/src/DateInput/Wheel.tsx
|
|
43
52
|
* - /packages/core/src/DateInput/DateInputTouch.test.tsx
|
|
44
53
|
*/
|
|
45
|
-
import { useEffect } from 'react';
|
|
54
|
+
import { useEffect, useRef } from 'react';
|
|
46
55
|
|
|
47
56
|
/**
|
|
48
57
|
* Movement below this stays a click. A mouse shifts a pixel or two under the
|
|
@@ -53,6 +62,8 @@ export const DRAG_SLOP = 4;
|
|
|
53
62
|
/** How long to wait for a release's settle before restoring snapping. */
|
|
54
63
|
const SETTLE_FALLBACK_MS = 260;
|
|
55
64
|
|
|
65
|
+
/** What {@link usePointerDragScroll} reports back about the drag. */
|
|
66
|
+
|
|
56
67
|
/**
|
|
57
68
|
* Let a mouse drag `ref`'s contents, on a container that already scrolls and
|
|
58
69
|
* snaps for touch.
|
|
@@ -62,6 +73,7 @@ const SETTLE_FALLBACK_MS = 260;
|
|
|
62
73
|
* layout box, so its listeners would otherwise still be live
|
|
63
74
|
*/
|
|
64
75
|
export function usePointerDragScroll(ref, isEnabled = true) {
|
|
76
|
+
const isDraggingRef = useRef(false);
|
|
65
77
|
useEffect(() => {
|
|
66
78
|
const element = ref.current;
|
|
67
79
|
if (element == null || !isEnabled) {
|
|
@@ -70,9 +82,9 @@ export function usePointerDragScroll(ref, isEnabled = true) {
|
|
|
70
82
|
let pointerId = null;
|
|
71
83
|
let originY = 0;
|
|
72
84
|
let originScrollTop = 0;
|
|
73
|
-
|
|
85
|
+
isDraggingRef.current = false;
|
|
74
86
|
// Survives from the drag's end to the click it produces, which is the
|
|
75
|
-
// whole reason it is not just `
|
|
87
|
+
// whole reason it is not just `isDraggingRef`.
|
|
76
88
|
let wasDragged = false;
|
|
77
89
|
let restoreTimer;
|
|
78
90
|
const restoreSnap = () => {
|
|
@@ -112,7 +124,7 @@ export function usePointerDragScroll(ref, isEnabled = true) {
|
|
|
112
124
|
pointerId = event.pointerId;
|
|
113
125
|
originY = event.clientY;
|
|
114
126
|
originScrollTop = element.scrollTop;
|
|
115
|
-
|
|
127
|
+
isDraggingRef.current = false;
|
|
116
128
|
// Not captured yet: a press that never moves has to stay a click on the
|
|
117
129
|
// row under it, and capturing here would retarget that click.
|
|
118
130
|
};
|
|
@@ -121,11 +133,11 @@ export function usePointerDragScroll(ref, isEnabled = true) {
|
|
|
121
133
|
return;
|
|
122
134
|
}
|
|
123
135
|
const delta = event.clientY - originY;
|
|
124
|
-
if (!
|
|
136
|
+
if (!isDraggingRef.current) {
|
|
125
137
|
if (Math.abs(delta) < DRAG_SLOP) {
|
|
126
138
|
return;
|
|
127
139
|
}
|
|
128
|
-
|
|
140
|
+
isDraggingRef.current = true;
|
|
129
141
|
element.setPointerCapture(event.pointerId);
|
|
130
142
|
suspendSnap();
|
|
131
143
|
// Dragging across rows would otherwise select their text, leaving the
|
|
@@ -141,10 +153,10 @@ export function usePointerDragScroll(ref, isEnabled = true) {
|
|
|
141
153
|
return;
|
|
142
154
|
}
|
|
143
155
|
pointerId = null;
|
|
144
|
-
if (!
|
|
156
|
+
if (!isDraggingRef.current) {
|
|
145
157
|
return;
|
|
146
158
|
}
|
|
147
|
-
|
|
159
|
+
isDraggingRef.current = false;
|
|
148
160
|
wasDragged = true;
|
|
149
161
|
element.style.removeProperty('user-select');
|
|
150
162
|
if (element.hasPointerCapture(event.pointerId)) {
|
|
@@ -200,9 +212,13 @@ export function usePointerDragScroll(ref, isEnabled = true) {
|
|
|
200
212
|
element.removeEventListener('click', onClickCapture, {
|
|
201
213
|
capture: true
|
|
202
214
|
});
|
|
215
|
+
isDraggingRef.current = false;
|
|
203
216
|
restoreSnap();
|
|
204
217
|
};
|
|
205
218
|
}, [ref, isEnabled]);
|
|
219
|
+
return {
|
|
220
|
+
isDraggingRef
|
|
221
|
+
};
|
|
206
222
|
}
|
|
207
223
|
|
|
208
224
|
/**
|
|
@@ -21,6 +21,8 @@ export type ScrollSettleState = {
|
|
|
21
21
|
* @param ref - the scroll container
|
|
22
22
|
* @param onSettle - called with the settled element; may change every render
|
|
23
23
|
* @param isEnabled - skip attaching while false (e.g. a hidden panel)
|
|
24
|
+
* @param isHeldRef - true while a mouse drag holds the scroller
|
|
25
|
+
* (usePointerDragScroll's `isDraggingRef`): not rest, however quiet
|
|
24
26
|
*/
|
|
25
|
-
export declare function useScrollSettle(ref: React.RefObject<HTMLElement | null>, onSettle: (element: HTMLElement) => void, isEnabled?: boolean): ScrollSettleState;
|
|
27
|
+
export declare function useScrollSettle(ref: React.RefObject<HTMLElement | null>, onSettle: (element: HTMLElement) => void, isEnabled?: boolean, isHeldRef?: React.RefObject<boolean>): ScrollSettleState;
|
|
26
28
|
//# sourceMappingURL=useScrollSettle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useScrollSettle.d.ts","sourceRoot":"","sources":["../../src/DateInput/useScrollSettle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useScrollSettle.d.ts","sourceRoot":"","sources":["../../src/DateInput/useScrollSettle.ts"],"names":[],"mappings":"AA0DA;;;;;GAKG;AACH,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,4EAA4E;AAC5E,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;;OAKG;IACH,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;CACvC,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EACxC,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,EACxC,SAAS,GAAE,OAAc,EACzB,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,GACnC,iBAAiB,CAuGnB"}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file useScrollSettle.ts
|
|
7
|
-
* @input A scroll container ref
|
|
7
|
+
* @input A scroll container ref, a settle callback, and optionally whether a
|
|
8
|
+
* mouse drag holds it (usePointerDragScroll's `isDraggingRef`)
|
|
8
9
|
* @output Calls back once, after scrolling (including momentum) stops
|
|
9
10
|
* @position Internal behavior hook; consumed by Wheel.tsx and MonthScroller.tsx
|
|
10
11
|
*
|
|
@@ -27,7 +28,10 @@
|
|
|
27
28
|
* moment without lifting and the scroll events stop, so the timer fires
|
|
28
29
|
* and the value commits to whatever is under the band. Chrome hides this
|
|
29
30
|
* because it has `scrollend`, which does not fire until the touch is
|
|
30
|
-
* released.
|
|
31
|
+
* released. A mouse drag (usePointerDragScroll) is held the same way, and
|
|
32
|
+
* there Chrome gives no cover at all: each `scrollTop` the drag assigns
|
|
33
|
+
* ends in its own `scrollend`, so the settle waits for the drag's
|
|
34
|
+
* `pointerup` as it waits for `touchend`.
|
|
31
35
|
*
|
|
32
36
|
* 2. **Momentum is not rest either.** iOS momentum runs on the UI thread and
|
|
33
37
|
* keeps going for a second or more after the finger is gone, and its scroll
|
|
@@ -41,7 +45,7 @@
|
|
|
41
45
|
* underneath, and the fresh scroll events start the next premature settle —
|
|
42
46
|
* each one landing a row further along, which is why the month climbed.
|
|
43
47
|
*
|
|
44
|
-
* So: the settle waits for the touch to end, and then for a quiet period
|
|
48
|
+
* So: the settle waits for the touch or the mouse drag to end, and then for a quiet period
|
|
45
49
|
* measured from the LAST scroll event, which is what makes it outlast
|
|
46
50
|
* momentum however long it runs. {@link useScrollSettle} also reports whether
|
|
47
51
|
* the scroller is at rest, so a caller can refuse to reposition one that is
|
|
@@ -67,8 +71,10 @@ export const SCROLL_QUIET_MS = 220;
|
|
|
67
71
|
* @param ref - the scroll container
|
|
68
72
|
* @param onSettle - called with the settled element; may change every render
|
|
69
73
|
* @param isEnabled - skip attaching while false (e.g. a hidden panel)
|
|
74
|
+
* @param isHeldRef - true while a mouse drag holds the scroller
|
|
75
|
+
* (usePointerDragScroll's `isDraggingRef`): not rest, however quiet
|
|
70
76
|
*/
|
|
71
|
-
export function useScrollSettle(ref, onSettle, isEnabled = true) {
|
|
77
|
+
export function useScrollSettle(ref, onSettle, isEnabled = true, isHeldRef) {
|
|
72
78
|
// The callback closes over render-fresh values (the option list, the current
|
|
73
79
|
// value); keeping it in a ref means the listeners attach once instead of
|
|
74
80
|
// re-attaching mid-scroll, which would drop an in-flight settle.
|
|
@@ -84,10 +90,17 @@ export function useScrollSettle(ref, onSettle, isEnabled = true) {
|
|
|
84
90
|
let timer;
|
|
85
91
|
let hasSettled = false;
|
|
86
92
|
let isTouching = false;
|
|
93
|
+
// Whether a mouse drag held this gesture, so its release re-arms the
|
|
94
|
+
// settle; a plain click does not.
|
|
95
|
+
let wasHeld = false;
|
|
87
96
|
const settle = () => {
|
|
88
|
-
// A finger still on the glass
|
|
89
|
-
// has gone. The release re-arms
|
|
90
|
-
|
|
97
|
+
// A finger still on the glass, or a mouse button still holding a drag,
|
|
98
|
+
// is not rest, however quiet the scroller has gone. The release re-arms
|
|
99
|
+
// this.
|
|
100
|
+
if (isHeldRef?.current) {
|
|
101
|
+
wasHeld = true;
|
|
102
|
+
}
|
|
103
|
+
if (hasSettled || isTouching || isHeldRef?.current) {
|
|
91
104
|
return;
|
|
92
105
|
}
|
|
93
106
|
hasSettled = true;
|
|
@@ -106,6 +119,9 @@ export function useScrollSettle(ref, onSettle, isEnabled = true) {
|
|
|
106
119
|
// the last of it however long it runs.
|
|
107
120
|
hasSettled = false;
|
|
108
121
|
isAtRestRef.current = false;
|
|
122
|
+
if (isHeldRef?.current) {
|
|
123
|
+
wasHeld = true;
|
|
124
|
+
}
|
|
109
125
|
arm();
|
|
110
126
|
};
|
|
111
127
|
const onTouchStart = () => {
|
|
@@ -121,6 +137,15 @@ export function useScrollSettle(ref, onSettle, isEnabled = true) {
|
|
|
121
137
|
// produces no further scroll events at all.
|
|
122
138
|
arm();
|
|
123
139
|
};
|
|
140
|
+
const onPointerEnd = () => {
|
|
141
|
+
// The drag's release: its glide to the nearest row re-arms this on its
|
|
142
|
+
// own, and the timer covers a release already on a row, which scrolls
|
|
143
|
+
// no further.
|
|
144
|
+
if (wasHeld) {
|
|
145
|
+
wasHeld = false;
|
|
146
|
+
arm();
|
|
147
|
+
}
|
|
148
|
+
};
|
|
124
149
|
element.addEventListener('scroll', onScroll, {
|
|
125
150
|
passive: true
|
|
126
151
|
});
|
|
@@ -134,6 +159,8 @@ export function useScrollSettle(ref, onSettle, isEnabled = true) {
|
|
|
134
159
|
element.addEventListener('touchcancel', onTouchEnd, {
|
|
135
160
|
passive: true
|
|
136
161
|
});
|
|
162
|
+
element.addEventListener('pointerup', onPointerEnd);
|
|
163
|
+
element.addEventListener('pointercancel', onPointerEnd);
|
|
137
164
|
return () => {
|
|
138
165
|
clearTimeout(timer);
|
|
139
166
|
element.removeEventListener('scroll', onScroll);
|
|
@@ -141,8 +168,10 @@ export function useScrollSettle(ref, onSettle, isEnabled = true) {
|
|
|
141
168
|
element.removeEventListener('touchstart', onTouchStart);
|
|
142
169
|
element.removeEventListener('touchend', onTouchEnd);
|
|
143
170
|
element.removeEventListener('touchcancel', onTouchEnd);
|
|
171
|
+
element.removeEventListener('pointerup', onPointerEnd);
|
|
172
|
+
element.removeEventListener('pointercancel', onPointerEnd);
|
|
144
173
|
};
|
|
145
|
-
}, [ref, isEnabled]);
|
|
174
|
+
}, [ref, isEnabled, isHeldRef]);
|
|
146
175
|
return {
|
|
147
176
|
isAtRestRef
|
|
148
177
|
};
|
package/dist/Link/Link.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/Link/Link.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAc5C,OAAO,KAAK,EACV,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,UAAU,EACV,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/Link/Link.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAc5C,OAAO,KAAK,EACV,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,UAAU,EACV,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,SAAS,CAAC;AA8G/C,MAAM,WAAW,SAAU,SAAQ,SAAS,CAC1C,iBAAiB,GAAG,iBAAiB,CACtC;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,GAAG,iBAAiB,CAAC,CAAC;IACvD;;;;;OAKG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B;;OAEG;IACH,cAAc,CAAC,EAAE,KAAK,CAAC,2BAA2B,CAAC;IACnD;;;OAGG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,GAAG,iBAAiB,CAAC,CAAC;IACzE;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;OAEG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;OAEG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAAC,EACnB,EAAE,EACF,KAAK,EACL,IAAI,EACJ,YAAoB,EACpB,UAAkB,EAClB,cAAsB,EACtB,WAAW,EAAE,oBAAoB,EACjC,MAAM,EAAE,eAAe,EACvB,OAAO,EACP,OAAO,EACP,YAAoB,EACpB,IAAa,EACb,IAAI,EACJ,MAAM,EACN,KAAgB,EAChB,OAAkB,EAClB,QAAY,EACZ,QAAQ,EACR,GAAG,EAAE,YAAY,EACjB,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,SAAS,+BAuJX;yBAhLe,IAAI"}
|
package/dist/Link/Link.js
CHANGED
|
@@ -53,6 +53,11 @@ const styles = {
|
|
|
53
53
|
kAMwcw: "xlr8y92",
|
|
54
54
|
$$css: true
|
|
55
55
|
},
|
|
56
|
+
truncating: {
|
|
57
|
+
ks0D6T: "x193iq5w",
|
|
58
|
+
k7Eaqz: "xeuugli",
|
|
59
|
+
$$css: true
|
|
60
|
+
},
|
|
56
61
|
buttonReset: {
|
|
57
62
|
kWkggS: "xjbqb8w",
|
|
58
63
|
ksu8eU: "xng3xce",
|
|
@@ -206,7 +211,7 @@ export function Link({
|
|
|
206
211
|
}), focusOutlineProps.focusVisible(styles.base, styles.buttonReset, linkColorStyles[color],
|
|
207
212
|
// The system's pressed overlay behind the text; the hover stays the
|
|
208
213
|
// colour change above, so a press is the one background it paints.
|
|
209
|
-
!isDisabled && interactionOverlayStyles.pressedBackgroundColor, hasUnderline && styles.hasUnderline, isStandalone && styles.standalone, isDisabled && styles.disabled, xstyle), className, style),
|
|
214
|
+
!isDisabled && interactionOverlayStyles.pressedBackgroundColor, hasUnderline && styles.hasUnderline, isStandalone && styles.standalone, isDisabled && styles.disabled, maxLines > 0 && styles.truncating, xstyle), className, style),
|
|
210
215
|
...props,
|
|
211
216
|
...(isDisabled ? disabledInteractionProps(props.onKeyDown) : null),
|
|
212
217
|
children: sharedContent
|
|
@@ -226,7 +231,7 @@ export function Link({
|
|
|
226
231
|
tabIndex: 0,
|
|
227
232
|
...mergeProps(themeProps('link', {
|
|
228
233
|
color
|
|
229
|
-
}), focusOutlineProps.focusVisible(styles.base, linkColorStyles[color], hasUnderline && styles.hasUnderline, isStandalone && styles.standalone, styles.disabled, xstyle), className, style),
|
|
234
|
+
}), focusOutlineProps.focusVisible(styles.base, linkColorStyles[color], hasUnderline && styles.hasUnderline, isStandalone && styles.standalone, styles.disabled, maxLines > 0 && styles.truncating, xstyle), className, style),
|
|
230
235
|
...props,
|
|
231
236
|
...disabledInteractionProps(props.onKeyDown),
|
|
232
237
|
children: sharedContent
|
|
@@ -244,7 +249,7 @@ export function Link({
|
|
|
244
249
|
tabIndex: isDisabled ? -1 : undefined,
|
|
245
250
|
...mergeProps(themeProps('link', {
|
|
246
251
|
color
|
|
247
|
-
}), focusOutlineProps.focusVisible(styles.base, linkColorStyles[color], !isDisabled && interactionOverlayStyles.pressedBackgroundColor, hasUnderline && styles.hasUnderline, isStandalone && styles.standalone, isDisabled && styles.disabled, xstyle), className, style),
|
|
252
|
+
}), focusOutlineProps.focusVisible(styles.base, linkColorStyles[color], !isDisabled && interactionOverlayStyles.pressedBackgroundColor, hasUnderline && styles.hasUnderline, isStandalone && styles.standalone, isDisabled && styles.disabled, maxLines > 0 && styles.truncating, xstyle), className, style),
|
|
248
253
|
...props,
|
|
249
254
|
children: sharedContent
|
|
250
255
|
});
|
|
@@ -16,7 +16,7 @@ import * as fs from 'node:fs';
|
|
|
16
16
|
import * as path from 'node:path';
|
|
17
17
|
import { expect, test } from '@playwright/test';
|
|
18
18
|
import { DEFAULT_STORYBOOK_DIR, serveStorybook } from '@astryxdesign/a11y-spec/storybook';
|
|
19
|
-
const STORY = 'core-markdown
|
|
19
|
+
const STORY = 'core-markdown--heading-links';
|
|
20
20
|
const OUTPUT = path.resolve('test-results/markdown-heading-links');
|
|
21
21
|
const GEOMETRY_TOLERANCE_PX = 1;
|
|
22
22
|
let storybook;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadioListItem.d.ts","sourceRoot":"","sources":["../../src/RadioList/RadioListItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,EAAqB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAGhE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAQ5C,OAAO,EAAO,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AA0I7C,MAAM,WAAW,kBAAmB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACnE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;;;;;;OAUG;IACH,KAAK,EAAE,SAAS,CAAC;IACjB;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,EAC5B,GAAG,EACH,KAAK,EACL,YAAY,EAAE,SAAS,EACvB,KAAK,EACL,WAAW,EACX,UAAU,EAAE,cAAsB,EAClC,YAAY,EACZ,UAAU,EACV,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,OAAO,EACP,GAAG,IAAI,EACR,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"RadioListItem.d.ts","sourceRoot":"","sources":["../../src/RadioList/RadioListItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,EAAqB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAGhE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAQ5C,OAAO,EAAO,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AA0I7C,MAAM,WAAW,kBAAmB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACnE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;;;;;;OAUG;IACH,KAAK,EAAE,SAAS,CAAC;IACjB;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,EAC5B,GAAG,EACH,KAAK,EACL,YAAY,EAAE,SAAS,EACvB,KAAK,EACL,WAAW,EACX,UAAU,EAAE,cAAsB,EAClC,YAAY,EACZ,UAAU,EACV,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,OAAO,EACP,GAAG,IAAI,EACR,EAAE,kBAAkB,qBA2KpB;yBA1Le,aAAa"}
|
|
@@ -198,7 +198,12 @@ export function RadioListItem({
|
|
|
198
198
|
// from submission, matching a natively disabled control.
|
|
199
199
|
,
|
|
200
200
|
form: keepsFocusableForMessage ? '' : undefined,
|
|
201
|
-
required: context.isRequired
|
|
201
|
+
required: context.isRequired
|
|
202
|
+
// Chromium reports an unanswered native-required radio invalid before
|
|
203
|
+
// any interaction; the invalid state follows the group's status
|
|
204
|
+
// instead (RadioList FR6).
|
|
205
|
+
,
|
|
206
|
+
"aria-invalid": context.isRequired ? context.status?.type === 'error' : undefined,
|
|
202
207
|
onChange: () => {
|
|
203
208
|
if (isDisabled) {
|
|
204
209
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../src/Switch/Switch.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../src/Switch/Switch.tsx"],"names":[],"mappings":"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"}
|
package/dist/Switch/Switch.js
CHANGED
|
@@ -401,8 +401,11 @@ export function Switch({
|
|
|
401
401
|
// than the field wrapper via `...rest`.
|
|
402
402
|
,
|
|
403
403
|
"aria-labelledby": ariaLabelledByProp,
|
|
404
|
-
"aria-describedby": ariaDescribedBy
|
|
405
|
-
|
|
404
|
+
"aria-describedby": ariaDescribedBy
|
|
405
|
+
// Chromium reports an unchecked native-required checkbox invalid before
|
|
406
|
+
// any interaction; the invalid state follows status instead.
|
|
407
|
+
,
|
|
408
|
+
"aria-invalid": status?.type === 'error' ? true : isRequired ? false : undefined,
|
|
406
409
|
"aria-busy": isBusy || undefined,
|
|
407
410
|
...stylex.props(styles.input, rtlStyles.centerInline('-50%'), styles.inputCoarse, inputSizeStyles[size], isDisabled && styles.inputDisabled, isBusy && styles.inputBusy, switchFocusInput)
|
|
408
411
|
}), /*#__PURE__*/_jsx("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToastViewport.d.ts","sourceRoot":"","sources":["../../src/Toast/ToastViewport.tsx"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAa,aAAa,EAAqB,MAAM,SAAS,CAAC;AAG3E,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAiItD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC;IACtE;;;OAGG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAyGD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAsB,EACtB,UAAc,EACd,KAAK,EACL,UAAU,EACV,UAAiB,EACjB,QAAQ,GACT,EAAE,kBAAkB,+
|
|
1
|
+
{"version":3,"file":"ToastViewport.d.ts","sourceRoot":"","sources":["../../src/Toast/ToastViewport.tsx"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAa,aAAa,EAAqB,MAAM,SAAS,CAAC;AAG3E,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAiItD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC;IACtE;;;OAGG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAyGD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAsB,EACtB,UAAc,EACd,KAAK,EACL,UAAU,EACV,UAAiB,EACjB,QAAQ,GACT,EAAE,kBAAkB,+BAmhBpB;yBA1hBe,aAAa"}
|
|
@@ -243,10 +243,13 @@ export function ToastViewport({
|
|
|
243
243
|
// Toasts dispatched since the last commit, by id: a dismiss() called
|
|
244
244
|
// before the toast first renders still finds it (and its onHide).
|
|
245
245
|
const pendingEntriesRef = useRef(new Map());
|
|
246
|
-
// The element that was focused before
|
|
247
|
-
//
|
|
248
|
-
// never falls to <body
|
|
246
|
+
// The element that was focused before focus entered the viewport, by F6,
|
|
247
|
+
// Tab or a click. Used to restore focus once all toasts are dismissed so
|
|
248
|
+
// focus never falls to <body> (FR10).
|
|
249
249
|
const prevFocusRef = useRef(null);
|
|
250
|
+
// The element focus last reached inside the viewport's React tree,
|
|
251
|
+
// portaled toast content included.
|
|
252
|
+
const lastFocusedWithinRef = useRef(null);
|
|
250
253
|
// When a toast is dismissed while focus lives inside it, we need to move
|
|
251
254
|
// focus to a sensible neighbor after that toast unmounts. This holds the
|
|
252
255
|
// id of the toast whose removal should trigger a focus handoff.
|
|
@@ -626,6 +629,19 @@ export function ToastViewport({
|
|
|
626
629
|
const isReversed = position === 'topEnd' || position === 'topStart';
|
|
627
630
|
const viewport = /*#__PURE__*/_jsx("div", {
|
|
628
631
|
ref: viewportRef,
|
|
632
|
+
onFocus: event => {
|
|
633
|
+
// Focus entering from outside, however it came, is where a dismissal
|
|
634
|
+
// of the last toast returns it. React also delivers focus inside a
|
|
635
|
+
// toast's portaled content here, so focus coming back from the last
|
|
636
|
+
// element focused within is not an entry, though it sits outside
|
|
637
|
+
// this element.
|
|
638
|
+
const from = event.relatedTarget;
|
|
639
|
+
const fromWithin = from === lastFocusedWithinRef.current || from instanceof Node && event.currentTarget.contains(from);
|
|
640
|
+
lastFocusedWithinRef.current = event.target;
|
|
641
|
+
if (from instanceof HTMLElement && !fromWithin) {
|
|
642
|
+
prevFocusRef.current = from;
|
|
643
|
+
}
|
|
644
|
+
},
|
|
629
645
|
role: hasToasts ? 'region' : undefined,
|
|
630
646
|
"aria-label": hasToasts ? t('@astryx.toast.viewport') : undefined,
|
|
631
647
|
tabIndex: hasToasts ? -1 : undefined
|
|
@@ -86,10 +86,10 @@ export interface BaseTypeaheadProps<T extends SearchableItem> extends Omit<BaseP
|
|
|
86
86
|
* When disabled with a reason, keeps the input focusable via `aria-disabled`
|
|
87
87
|
* (instead of the native `disabled` attribute) and `readOnly` so an
|
|
88
88
|
* associated disabled-reason tooltip stays discoverable by keyboard and
|
|
89
|
-
* assistive technology. Query and text mutation
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* wrapper.
|
|
89
|
+
* assistive technology. Query and text mutation, opening the list, and a
|
|
90
|
+
* pick by Enter or a press are blocked, also from a list that was open
|
|
91
|
+
* before this state applied; Escape or Tab still closes it. Consumers
|
|
92
|
+
* (Typeahead) own the tooltip and wrapper.
|
|
93
93
|
* @default false
|
|
94
94
|
*/
|
|
95
95
|
isFocusableDisabled?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseTypeahead.d.ts","sourceRoot":"","sources":["../../src/Typeahead/BaseTypeahead.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AA2BnD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,cAAc,EAAE,YAAY,EAAC,MAAM,SAAS,CAAC;AAY1D,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,cAAc,CAAE,SAAQ,IAAI,CACxE,SAAS,CAAC,WAAW,CAAC,EACtB,UAAU,CACX;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IAE9B;;OAEG;IACH,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;IAEpC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC;IAE5B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;;;OASG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;IAEtD;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;IAE3B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE1C;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAE/D;;;;OAIG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAC3B;AAoKD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"BaseTypeahead.d.ts","sourceRoot":"","sources":["../../src/Typeahead/BaseTypeahead.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AA2BnD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,cAAc,EAAE,YAAY,EAAC,MAAM,SAAS,CAAC;AAY1D,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,cAAc,CAAE,SAAQ,IAAI,CACxE,SAAS,CAAC,WAAW,CAAC,EACtB,UAAU,CACX;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IAE9B;;OAEG;IACH,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;IAEpC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC;IAE5B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;;;OASG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;IAEtD;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;IAE3B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE1C;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAE/D;;;;OAIG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAC3B;AAoKD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,aAAa,EAi7BrB,CAAC,CAAC,SAAS,cAAc,EAC5B,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,KACzB,KAAK,CAAC,YAAY,CAAC"}
|
|
@@ -397,9 +397,22 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
397
397
|
// Show the layer, deferring past the active click if a pointer is down.
|
|
398
398
|
// Without this, popover="auto" light-dismiss immediately closes the
|
|
399
399
|
// dropdown when it opens between pointerdown and pointerup/click.
|
|
400
|
+
// Read at show time, so a search or bootstrap that settles after the field
|
|
401
|
+
// became disabled does not open the list (spec:AST-085 FR2).
|
|
402
|
+
const isDisabledRef = useRef(isDisabled);
|
|
403
|
+
useIsomorphicLayoutEffect(() => {
|
|
404
|
+
isDisabledRef.current = isDisabled;
|
|
405
|
+
}, [isDisabled]);
|
|
400
406
|
const showLayer = useCallback(() => {
|
|
407
|
+
if (isDisabledRef.current) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
401
410
|
if (pointerActiveRef.current) {
|
|
402
|
-
document.addEventListener('click', () => requestAnimationFrame(() =>
|
|
411
|
+
document.addEventListener('click', () => requestAnimationFrame(() => {
|
|
412
|
+
if (!isDisabledRef.current) {
|
|
413
|
+
popover.show();
|
|
414
|
+
}
|
|
415
|
+
}), {
|
|
403
416
|
once: true
|
|
404
417
|
});
|
|
405
418
|
} else {
|
|
@@ -574,6 +587,11 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
574
587
|
|
|
575
588
|
// Handle item selection
|
|
576
589
|
const handleSelect = useCallback(item => {
|
|
590
|
+
// A disabled field changes nothing, also from a list that was open
|
|
591
|
+
// before it became disabled (spec:AST-085 FR2).
|
|
592
|
+
if (isDisabled) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
577
595
|
// Bump generation to invalidate any in-flight async searches
|
|
578
596
|
searchGenRef.current++;
|
|
579
597
|
if (searchTimeoutRef.current) {
|
|
@@ -591,7 +609,7 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
591
609
|
setLoading(false);
|
|
592
610
|
popover.hide();
|
|
593
611
|
inputRef.current?.focus();
|
|
594
|
-
}, [onChange, popover, searchSource, setLoading]);
|
|
612
|
+
}, [isDisabled, onChange, popover, searchSource, setLoading]);
|
|
595
613
|
|
|
596
614
|
// Shared by handleFocus and handleClick: bootstrap entries if none are
|
|
597
615
|
// loaded yet, or re-show cached results that haven't been invalidated by
|
|
@@ -625,7 +643,7 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
625
643
|
// dropdown never reopens until the user clicks away and back (#6845). See
|
|
626
644
|
// wasAlreadyFocusedRef above for how the two cases are told apart.
|
|
627
645
|
const handleClick = useCallback(() => {
|
|
628
|
-
if (!wasAlreadyFocusedRef.current || popover.isOpen) {
|
|
646
|
+
if (isDisabled || !wasAlreadyFocusedRef.current || popover.isOpen) {
|
|
629
647
|
return;
|
|
630
648
|
}
|
|
631
649
|
if (hasEntriesOnFocus && query.length === 0 && resultsGenRef.current !== searchGenRef.current) {
|
|
@@ -633,7 +651,7 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
633
651
|
return;
|
|
634
652
|
}
|
|
635
653
|
openIfEligible();
|
|
636
|
-
}, [popover.isOpen, hasEntriesOnFocus, query.length, performBootstrap, openIfEligible]);
|
|
654
|
+
}, [isDisabled, popover.isOpen, hasEntriesOnFocus, query.length, performBootstrap, openIfEligible]);
|
|
637
655
|
|
|
638
656
|
// Handle blur — close the dropdown when focus leaves the input for an
|
|
639
657
|
// element that is neither inside the field wrapper (anchor) nor inside the
|
|
@@ -676,6 +694,24 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
676
694
|
if (isImeKeyEvent(e.nativeEvent)) {
|
|
677
695
|
return;
|
|
678
696
|
}
|
|
697
|
+
|
|
698
|
+
// A focusable-disabled field opens no list and picks nothing; it only
|
|
699
|
+
// lets a list that was open before it became disabled close
|
|
700
|
+
// (spec:AST-085 FR2).
|
|
701
|
+
if (isDisabled) {
|
|
702
|
+
// Enter on a list that is still open picks nothing, and must not
|
|
703
|
+
// submit an enclosing form either, as it would not while enabled.
|
|
704
|
+
if (popover.isOpen && e.key === 'Enter') {
|
|
705
|
+
e.preventDefault();
|
|
706
|
+
}
|
|
707
|
+
if (popover.isOpen && (e.key === 'Escape' || e.key === 'Tab')) {
|
|
708
|
+
if (e.key === 'Escape') {
|
|
709
|
+
e.preventDefault();
|
|
710
|
+
}
|
|
711
|
+
popover.hide();
|
|
712
|
+
}
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
679
715
|
if (!popover.isOpen) {
|
|
680
716
|
if (e.key === 'ArrowDown' && (hasEntriesOnFocus || query.length > 0)) {
|
|
681
717
|
e.preventDefault();
|
|
@@ -740,7 +776,7 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
740
776
|
}
|
|
741
777
|
break;
|
|
742
778
|
}
|
|
743
|
-
}, [popover, results, highlightedIndex, handleSelect, hasEntriesOnFocus, query, minQueryLength, performBootstrap, externalOnKeyDown]);
|
|
779
|
+
}, [isDisabled, popover, results, highlightedIndex, handleSelect, hasEntriesOnFocus, query, minQueryLength, performBootstrap, externalOnKeyDown]);
|
|
744
780
|
|
|
745
781
|
// Generate item ID for accessibility
|
|
746
782
|
const getItemId = useCallback(index => `${listboxId}-option-${index}`, [listboxId]);
|
|
@@ -805,8 +841,8 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
805
841
|
placeholder: placeholder
|
|
806
842
|
// When a disabled-reason tooltip is shown the input keeps focusability
|
|
807
843
|
// via aria-disabled + readOnly instead of the native disabled
|
|
808
|
-
// attribute. Query and text mutation
|
|
809
|
-
//
|
|
844
|
+
// attribute. Query and text mutation, opening and picking are blocked
|
|
845
|
+
// by the handlers above (spec:AST-085 FR2).
|
|
810
846
|
,
|
|
811
847
|
disabled: isDisabled && !isFocusableDisabled,
|
|
812
848
|
readOnly: isFocusableDisabled || undefined,
|
|
@@ -138,7 +138,6 @@ export declare class GestureArena {
|
|
|
138
138
|
setTimer(recognizer: GestureRecognizer, deadline: number, callback: () => void): void;
|
|
139
139
|
/** @internal */
|
|
140
140
|
clearTimer(recognizer: GestureRecognizer): void;
|
|
141
|
-
/** Cancel an active recognizer, or fail a possible one. */
|
|
142
141
|
/**
|
|
143
142
|
* Runs `body`, code outside input that stops recognizers (an Effect that
|
|
144
143
|
* turns one off or detaches it), without resolving what those stops
|
|
@@ -151,6 +150,7 @@ export declare class GestureArena {
|
|
|
151
150
|
deferResolution(body: () => void): void;
|
|
152
151
|
/** The last event's time, or now before any event. */
|
|
153
152
|
private lastEventTime;
|
|
153
|
+
/** Cancel an active recognizer, or fail a possible one. */
|
|
154
154
|
stop(recognizer: GestureRecognizer): void;
|
|
155
155
|
private attemptRecognition;
|
|
156
156
|
/** Whether `winner` being recognized prevents `other`. */
|