@primer/behaviors 0.0.0-20251215025613 → 0.0.0-20251215031129
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/cjs/focus-zone.js
CHANGED
|
@@ -5,6 +5,7 @@ var userAgent = require('./utils/user-agent.js');
|
|
|
5
5
|
var iterateFocusableElements = require('./utils/iterate-focusable-elements.js');
|
|
6
6
|
var uniqueId = require('./utils/unique-id.js');
|
|
7
7
|
var isEditableElement = require('./utils/is-editable-element.js');
|
|
8
|
+
var indexedSet = require('./utils/indexed-set.js');
|
|
8
9
|
|
|
9
10
|
eventListenerSignal.polyfill();
|
|
10
11
|
exports.FocusKeys = void 0;
|
|
@@ -89,17 +90,18 @@ function getDirection(keyboardEvent) {
|
|
|
89
90
|
}
|
|
90
91
|
function shouldIgnoreFocusHandling(keyboardEvent, activeElement) {
|
|
91
92
|
const key = keyboardEvent.key;
|
|
92
|
-
const
|
|
93
|
+
const isSingleChar = key.length === 1 || (key.length === 2 && key.charCodeAt(0) >= 0xd800 && key.charCodeAt(0) <= 0xdbff);
|
|
93
94
|
const isEditable = isEditableElement.isEditableElement(activeElement);
|
|
94
95
|
const isSelect = activeElement instanceof HTMLSelectElement;
|
|
95
|
-
if (isEditable && (
|
|
96
|
+
if (isEditable && (isSingleChar || key === 'Home' || key === 'End')) {
|
|
96
97
|
return true;
|
|
97
98
|
}
|
|
98
99
|
if (isSelect) {
|
|
99
|
-
|
|
100
|
+
const isMac = getIsMac();
|
|
101
|
+
if (key === 'ArrowDown' && isMac && !keyboardEvent.metaKey) {
|
|
100
102
|
return true;
|
|
101
103
|
}
|
|
102
|
-
if (key === 'ArrowDown' && !
|
|
104
|
+
if (key === 'ArrowDown' && !isMac && keyboardEvent.altKey) {
|
|
103
105
|
return true;
|
|
104
106
|
}
|
|
105
107
|
return false;
|
|
@@ -137,7 +139,7 @@ const activeDescendantActivatedIndirectly = 'activated-indirectly';
|
|
|
137
139
|
const hasActiveDescendantAttribute = 'data-has-active-descendant';
|
|
138
140
|
function focusZone(container, settings) {
|
|
139
141
|
var _a, _b, _c, _d, _e, _f;
|
|
140
|
-
const focusableElements =
|
|
142
|
+
const focusableElements = new indexedSet.IndexedSet();
|
|
141
143
|
const savedTabIndex = new WeakMap();
|
|
142
144
|
const bindKeys = (_a = settings === null || settings === void 0 ? void 0 : settings.bindKeys) !== null && _a !== void 0 ? _a : ((settings === null || settings === void 0 ? void 0 : settings.getNextFocusable) ? exports.FocusKeys.ArrowAll : exports.FocusKeys.ArrowVertical) | exports.FocusKeys.HomeAndEnd;
|
|
143
145
|
const focusOutBehavior = (_b = settings === null || settings === void 0 ? void 0 : settings.focusOutBehavior) !== null && _b !== void 0 ? _b : 'stop';
|
|
@@ -149,7 +151,7 @@ function focusZone(container, settings) {
|
|
|
149
151
|
const preventScroll = (_e = settings === null || settings === void 0 ? void 0 : settings.preventScroll) !== null && _e !== void 0 ? _e : false;
|
|
150
152
|
const preventInitialFocus = focusInStrategy === 'initial' && (settings === null || settings === void 0 ? void 0 : settings.activeDescendantControl);
|
|
151
153
|
function getFirstFocusableElement() {
|
|
152
|
-
return focusableElements
|
|
154
|
+
return focusableElements.get(0);
|
|
153
155
|
}
|
|
154
156
|
function isActiveDescendantInputFocused() {
|
|
155
157
|
return document.activeElement === activeDescendantControl;
|
|
@@ -205,7 +207,7 @@ function focusZone(container, settings) {
|
|
|
205
207
|
if (filteredElements.length === 0) {
|
|
206
208
|
return;
|
|
207
209
|
}
|
|
208
|
-
focusableElements.
|
|
210
|
+
focusableElements.insertAt(findInsertionIndex(filteredElements), ...filteredElements);
|
|
209
211
|
for (const element of filteredElements) {
|
|
210
212
|
if (!savedTabIndex.has(element)) {
|
|
211
213
|
savedTabIndex.set(element, element.getAttribute('tabindex'));
|
|
@@ -218,13 +220,13 @@ function focusZone(container, settings) {
|
|
|
218
220
|
}
|
|
219
221
|
function findInsertionIndex(elementsToInsert) {
|
|
220
222
|
const firstElementToInsert = elementsToInsert[0];
|
|
221
|
-
if (focusableElements.
|
|
223
|
+
if (focusableElements.size === 0)
|
|
222
224
|
return 0;
|
|
223
225
|
let iMin = 0;
|
|
224
|
-
let iMax = focusableElements.
|
|
226
|
+
let iMax = focusableElements.size - 1;
|
|
225
227
|
while (iMin <= iMax) {
|
|
226
228
|
const i = Math.floor((iMin + iMax) / 2);
|
|
227
|
-
const element = focusableElements
|
|
229
|
+
const element = focusableElements.get(i);
|
|
228
230
|
if (followsInDocument(firstElementToInsert, element)) {
|
|
229
231
|
iMax = i - 1;
|
|
230
232
|
}
|
|
@@ -239,10 +241,7 @@ function focusZone(container, settings) {
|
|
|
239
241
|
}
|
|
240
242
|
function endFocusManagement(...elements) {
|
|
241
243
|
for (const element of elements) {
|
|
242
|
-
|
|
243
|
-
if (focusableElementIndex >= 0) {
|
|
244
|
-
focusableElements.splice(focusableElementIndex, 1);
|
|
245
|
-
}
|
|
244
|
+
focusableElements.delete(element);
|
|
246
245
|
const savedIndex = savedTabIndex.get(element);
|
|
247
246
|
if (savedIndex !== undefined) {
|
|
248
247
|
if (savedIndex === null) {
|
|
@@ -298,7 +297,12 @@ function focusZone(container, settings) {
|
|
|
298
297
|
}
|
|
299
298
|
}
|
|
300
299
|
if (elementsToRemove.size > 0) {
|
|
301
|
-
const toRemove = [
|
|
300
|
+
const toRemove = [];
|
|
301
|
+
for (const node of elementsToRemove) {
|
|
302
|
+
for (const el of iterateFocusableElements.iterateFocusableElements(node)) {
|
|
303
|
+
toRemove.push(el);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
302
306
|
if (toRemove.length > 0) {
|
|
303
307
|
endFocusManagement(...toRemove);
|
|
304
308
|
}
|
|
@@ -307,9 +311,12 @@ function focusZone(container, settings) {
|
|
|
307
311
|
endFocusManagement(...attributeRemovals);
|
|
308
312
|
}
|
|
309
313
|
if (elementsToAdd.size > 0) {
|
|
310
|
-
const toAdd = [
|
|
311
|
-
|
|
312
|
-
|
|
314
|
+
const toAdd = [];
|
|
315
|
+
for (const node of elementsToAdd) {
|
|
316
|
+
for (const el of iterateFocusableElements.iterateFocusableElements(node, iterateFocusableElementsOptions)) {
|
|
317
|
+
toAdd.push(el);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
313
320
|
if (toAdd.length > 0) {
|
|
314
321
|
beginFocusManagement(...toAdd);
|
|
315
322
|
}
|
|
@@ -338,7 +345,7 @@ function focusZone(container, settings) {
|
|
|
338
345
|
}, { signal });
|
|
339
346
|
if (activeDescendantControl) {
|
|
340
347
|
container.addEventListener('focusin', event => {
|
|
341
|
-
if (event.target instanceof HTMLElement && focusableElements.
|
|
348
|
+
if (event.target instanceof HTMLElement && focusableElements.has(event.target)) {
|
|
342
349
|
activeDescendantControl.focus({ preventScroll });
|
|
343
350
|
updateFocusedElement(event.target);
|
|
344
351
|
}
|
|
@@ -348,9 +355,8 @@ function focusZone(container, settings) {
|
|
|
348
355
|
if (!(target instanceof Node)) {
|
|
349
356
|
return;
|
|
350
357
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
updateFocusedElement(focusableElements[targetIndex]);
|
|
358
|
+
if (target instanceof HTMLElement && focusableElements.has(target)) {
|
|
359
|
+
updateFocusedElement(target);
|
|
354
360
|
return;
|
|
355
361
|
}
|
|
356
362
|
const focusableElement = focusableElements.find(element => element.contains(target));
|
|
@@ -377,8 +383,9 @@ function focusZone(container, settings) {
|
|
|
377
383
|
if (event.target instanceof HTMLElement) {
|
|
378
384
|
if (elementIndexFocusedByClick !== undefined) {
|
|
379
385
|
if (elementIndexFocusedByClick >= 0) {
|
|
380
|
-
|
|
381
|
-
|
|
386
|
+
const clickedElement = focusableElements.get(elementIndexFocusedByClick);
|
|
387
|
+
if (clickedElement && clickedElement !== currentFocusedElement) {
|
|
388
|
+
updateFocusedElement(clickedElement);
|
|
382
389
|
}
|
|
383
390
|
}
|
|
384
391
|
elementIndexFocusedByClick = undefined;
|
|
@@ -389,8 +396,8 @@ function focusZone(container, settings) {
|
|
|
389
396
|
}
|
|
390
397
|
else if (focusInStrategy === 'closest' || focusInStrategy === 'first') {
|
|
391
398
|
if (event.relatedTarget instanceof Element && !container.contains(event.relatedTarget)) {
|
|
392
|
-
const targetElementIndex = lastKeyboardFocusDirection === 'previous' ? focusableElements.
|
|
393
|
-
const targetElement = focusableElements
|
|
399
|
+
const targetElementIndex = lastKeyboardFocusDirection === 'previous' ? focusableElements.size - 1 : 0;
|
|
400
|
+
const targetElement = focusableElements.get(targetElementIndex);
|
|
394
401
|
targetElement === null || targetElement === void 0 ? void 0 : targetElement.focus({ preventScroll });
|
|
395
402
|
return;
|
|
396
403
|
}
|
|
@@ -401,8 +408,7 @@ function focusZone(container, settings) {
|
|
|
401
408
|
else if (typeof focusInStrategy === 'function') {
|
|
402
409
|
if (event.relatedTarget instanceof Element && !container.contains(event.relatedTarget)) {
|
|
403
410
|
const elementToFocus = focusInStrategy(event.relatedTarget);
|
|
404
|
-
|
|
405
|
-
if (requestedFocusElementIndex >= 0 && elementToFocus instanceof HTMLElement) {
|
|
411
|
+
if (elementToFocus && focusableElements.has(elementToFocus)) {
|
|
406
412
|
elementToFocus.focus({ preventScroll });
|
|
407
413
|
return;
|
|
408
414
|
}
|
|
@@ -461,26 +467,26 @@ function focusZone(container, settings) {
|
|
|
461
467
|
nextFocusedIndex += 1;
|
|
462
468
|
}
|
|
463
469
|
else {
|
|
464
|
-
nextFocusedIndex = focusableElements.
|
|
470
|
+
nextFocusedIndex = focusableElements.size - 1;
|
|
465
471
|
}
|
|
466
472
|
if (nextFocusedIndex < 0) {
|
|
467
473
|
if (focusOutBehavior === 'wrap' && event.key !== 'Tab') {
|
|
468
|
-
nextFocusedIndex = focusableElements.
|
|
474
|
+
nextFocusedIndex = focusableElements.size - 1;
|
|
469
475
|
}
|
|
470
476
|
else {
|
|
471
477
|
nextFocusedIndex = 0;
|
|
472
478
|
}
|
|
473
479
|
}
|
|
474
|
-
if (nextFocusedIndex >= focusableElements.
|
|
480
|
+
if (nextFocusedIndex >= focusableElements.size) {
|
|
475
481
|
if (focusOutBehavior === 'wrap' && event.key !== 'Tab') {
|
|
476
482
|
nextFocusedIndex = 0;
|
|
477
483
|
}
|
|
478
484
|
else {
|
|
479
|
-
nextFocusedIndex = focusableElements.
|
|
485
|
+
nextFocusedIndex = focusableElements.size - 1;
|
|
480
486
|
}
|
|
481
487
|
}
|
|
482
488
|
if (lastFocusedIndex !== nextFocusedIndex) {
|
|
483
|
-
nextElementToFocus = focusableElements
|
|
489
|
+
nextElementToFocus = focusableElements.get(nextFocusedIndex);
|
|
484
490
|
}
|
|
485
491
|
}
|
|
486
492
|
if (activeDescendantControl) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class IndexedSet<T> {
|
|
2
|
+
#private;
|
|
3
|
+
insertAt(index: number, ...elements: T[]): void;
|
|
4
|
+
delete(element: T): boolean;
|
|
5
|
+
has(element: T): boolean;
|
|
6
|
+
indexOf(element: T): number;
|
|
7
|
+
get(index: number): T | undefined;
|
|
8
|
+
get size(): number;
|
|
9
|
+
[Symbol.iterator](): Iterator<T>;
|
|
10
|
+
clear(): void;
|
|
11
|
+
find(predicate: (element: T) => boolean): T | undefined;
|
|
12
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var tslib = require('tslib');
|
|
4
|
+
|
|
5
|
+
var _IndexedSet_items, _IndexedSet_itemSet;
|
|
6
|
+
class IndexedSet {
|
|
7
|
+
constructor() {
|
|
8
|
+
_IndexedSet_items.set(this, []);
|
|
9
|
+
_IndexedSet_itemSet.set(this, new Set());
|
|
10
|
+
}
|
|
11
|
+
insertAt(index, ...elements) {
|
|
12
|
+
const newElements = elements.filter(e => !tslib.__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").has(e));
|
|
13
|
+
if (newElements.length === 0)
|
|
14
|
+
return;
|
|
15
|
+
tslib.__classPrivateFieldGet(this, _IndexedSet_items, "f").splice(index, 0, ...newElements);
|
|
16
|
+
for (const element of newElements) {
|
|
17
|
+
tslib.__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").add(element);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
delete(element) {
|
|
21
|
+
if (!tslib.__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").has(element))
|
|
22
|
+
return false;
|
|
23
|
+
const index = tslib.__classPrivateFieldGet(this, _IndexedSet_items, "f").indexOf(element);
|
|
24
|
+
if (index >= 0) {
|
|
25
|
+
tslib.__classPrivateFieldGet(this, _IndexedSet_items, "f").splice(index, 1);
|
|
26
|
+
}
|
|
27
|
+
tslib.__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").delete(element);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
has(element) {
|
|
31
|
+
return tslib.__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").has(element);
|
|
32
|
+
}
|
|
33
|
+
indexOf(element) {
|
|
34
|
+
if (!tslib.__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").has(element))
|
|
35
|
+
return -1;
|
|
36
|
+
return tslib.__classPrivateFieldGet(this, _IndexedSet_items, "f").indexOf(element);
|
|
37
|
+
}
|
|
38
|
+
get(index) {
|
|
39
|
+
return tslib.__classPrivateFieldGet(this, _IndexedSet_items, "f")[index];
|
|
40
|
+
}
|
|
41
|
+
get size() {
|
|
42
|
+
return tslib.__classPrivateFieldGet(this, _IndexedSet_items, "f").length;
|
|
43
|
+
}
|
|
44
|
+
[(_IndexedSet_items = new WeakMap(), _IndexedSet_itemSet = new WeakMap(), Symbol.iterator)]() {
|
|
45
|
+
return tslib.__classPrivateFieldGet(this, _IndexedSet_items, "f")[Symbol.iterator]();
|
|
46
|
+
}
|
|
47
|
+
clear() {
|
|
48
|
+
tslib.__classPrivateFieldSet(this, _IndexedSet_items, [], "f");
|
|
49
|
+
tslib.__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").clear();
|
|
50
|
+
}
|
|
51
|
+
find(predicate) {
|
|
52
|
+
return tslib.__classPrivateFieldGet(this, _IndexedSet_items, "f").find(predicate);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
exports.IndexedSet = IndexedSet;
|
package/dist/esm/focus-zone.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { isMacOS } from './utils/user-agent.mjs';
|
|
|
3
3
|
import { iterateFocusableElements } from './utils/iterate-focusable-elements.mjs';
|
|
4
4
|
import { uniqueId } from './utils/unique-id.mjs';
|
|
5
5
|
import { isEditableElement } from './utils/is-editable-element.mjs';
|
|
6
|
+
import { IndexedSet } from './utils/indexed-set.mjs';
|
|
6
7
|
|
|
7
8
|
polyfill();
|
|
8
9
|
var FocusKeys;
|
|
@@ -87,17 +88,18 @@ function getDirection(keyboardEvent) {
|
|
|
87
88
|
}
|
|
88
89
|
function shouldIgnoreFocusHandling(keyboardEvent, activeElement) {
|
|
89
90
|
const key = keyboardEvent.key;
|
|
90
|
-
const
|
|
91
|
+
const isSingleChar = key.length === 1 || (key.length === 2 && key.charCodeAt(0) >= 0xd800 && key.charCodeAt(0) <= 0xdbff);
|
|
91
92
|
const isEditable = isEditableElement(activeElement);
|
|
92
93
|
const isSelect = activeElement instanceof HTMLSelectElement;
|
|
93
|
-
if (isEditable && (
|
|
94
|
+
if (isEditable && (isSingleChar || key === 'Home' || key === 'End')) {
|
|
94
95
|
return true;
|
|
95
96
|
}
|
|
96
97
|
if (isSelect) {
|
|
97
|
-
|
|
98
|
+
const isMac = getIsMac();
|
|
99
|
+
if (key === 'ArrowDown' && isMac && !keyboardEvent.metaKey) {
|
|
98
100
|
return true;
|
|
99
101
|
}
|
|
100
|
-
if (key === 'ArrowDown' && !
|
|
102
|
+
if (key === 'ArrowDown' && !isMac && keyboardEvent.altKey) {
|
|
101
103
|
return true;
|
|
102
104
|
}
|
|
103
105
|
return false;
|
|
@@ -135,7 +137,7 @@ const activeDescendantActivatedIndirectly = 'activated-indirectly';
|
|
|
135
137
|
const hasActiveDescendantAttribute = 'data-has-active-descendant';
|
|
136
138
|
function focusZone(container, settings) {
|
|
137
139
|
var _a, _b, _c, _d, _e, _f;
|
|
138
|
-
const focusableElements =
|
|
140
|
+
const focusableElements = new IndexedSet();
|
|
139
141
|
const savedTabIndex = new WeakMap();
|
|
140
142
|
const bindKeys = (_a = settings === null || settings === void 0 ? void 0 : settings.bindKeys) !== null && _a !== void 0 ? _a : ((settings === null || settings === void 0 ? void 0 : settings.getNextFocusable) ? FocusKeys.ArrowAll : FocusKeys.ArrowVertical) | FocusKeys.HomeAndEnd;
|
|
141
143
|
const focusOutBehavior = (_b = settings === null || settings === void 0 ? void 0 : settings.focusOutBehavior) !== null && _b !== void 0 ? _b : 'stop';
|
|
@@ -147,7 +149,7 @@ function focusZone(container, settings) {
|
|
|
147
149
|
const preventScroll = (_e = settings === null || settings === void 0 ? void 0 : settings.preventScroll) !== null && _e !== void 0 ? _e : false;
|
|
148
150
|
const preventInitialFocus = focusInStrategy === 'initial' && (settings === null || settings === void 0 ? void 0 : settings.activeDescendantControl);
|
|
149
151
|
function getFirstFocusableElement() {
|
|
150
|
-
return focusableElements
|
|
152
|
+
return focusableElements.get(0);
|
|
151
153
|
}
|
|
152
154
|
function isActiveDescendantInputFocused() {
|
|
153
155
|
return document.activeElement === activeDescendantControl;
|
|
@@ -203,7 +205,7 @@ function focusZone(container, settings) {
|
|
|
203
205
|
if (filteredElements.length === 0) {
|
|
204
206
|
return;
|
|
205
207
|
}
|
|
206
|
-
focusableElements.
|
|
208
|
+
focusableElements.insertAt(findInsertionIndex(filteredElements), ...filteredElements);
|
|
207
209
|
for (const element of filteredElements) {
|
|
208
210
|
if (!savedTabIndex.has(element)) {
|
|
209
211
|
savedTabIndex.set(element, element.getAttribute('tabindex'));
|
|
@@ -216,13 +218,13 @@ function focusZone(container, settings) {
|
|
|
216
218
|
}
|
|
217
219
|
function findInsertionIndex(elementsToInsert) {
|
|
218
220
|
const firstElementToInsert = elementsToInsert[0];
|
|
219
|
-
if (focusableElements.
|
|
221
|
+
if (focusableElements.size === 0)
|
|
220
222
|
return 0;
|
|
221
223
|
let iMin = 0;
|
|
222
|
-
let iMax = focusableElements.
|
|
224
|
+
let iMax = focusableElements.size - 1;
|
|
223
225
|
while (iMin <= iMax) {
|
|
224
226
|
const i = Math.floor((iMin + iMax) / 2);
|
|
225
|
-
const element = focusableElements
|
|
227
|
+
const element = focusableElements.get(i);
|
|
226
228
|
if (followsInDocument(firstElementToInsert, element)) {
|
|
227
229
|
iMax = i - 1;
|
|
228
230
|
}
|
|
@@ -237,10 +239,7 @@ function focusZone(container, settings) {
|
|
|
237
239
|
}
|
|
238
240
|
function endFocusManagement(...elements) {
|
|
239
241
|
for (const element of elements) {
|
|
240
|
-
|
|
241
|
-
if (focusableElementIndex >= 0) {
|
|
242
|
-
focusableElements.splice(focusableElementIndex, 1);
|
|
243
|
-
}
|
|
242
|
+
focusableElements.delete(element);
|
|
244
243
|
const savedIndex = savedTabIndex.get(element);
|
|
245
244
|
if (savedIndex !== undefined) {
|
|
246
245
|
if (savedIndex === null) {
|
|
@@ -296,7 +295,12 @@ function focusZone(container, settings) {
|
|
|
296
295
|
}
|
|
297
296
|
}
|
|
298
297
|
if (elementsToRemove.size > 0) {
|
|
299
|
-
const toRemove = [
|
|
298
|
+
const toRemove = [];
|
|
299
|
+
for (const node of elementsToRemove) {
|
|
300
|
+
for (const el of iterateFocusableElements(node)) {
|
|
301
|
+
toRemove.push(el);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
300
304
|
if (toRemove.length > 0) {
|
|
301
305
|
endFocusManagement(...toRemove);
|
|
302
306
|
}
|
|
@@ -305,9 +309,12 @@ function focusZone(container, settings) {
|
|
|
305
309
|
endFocusManagement(...attributeRemovals);
|
|
306
310
|
}
|
|
307
311
|
if (elementsToAdd.size > 0) {
|
|
308
|
-
const toAdd = [
|
|
309
|
-
|
|
310
|
-
|
|
312
|
+
const toAdd = [];
|
|
313
|
+
for (const node of elementsToAdd) {
|
|
314
|
+
for (const el of iterateFocusableElements(node, iterateFocusableElementsOptions)) {
|
|
315
|
+
toAdd.push(el);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
311
318
|
if (toAdd.length > 0) {
|
|
312
319
|
beginFocusManagement(...toAdd);
|
|
313
320
|
}
|
|
@@ -336,7 +343,7 @@ function focusZone(container, settings) {
|
|
|
336
343
|
}, { signal });
|
|
337
344
|
if (activeDescendantControl) {
|
|
338
345
|
container.addEventListener('focusin', event => {
|
|
339
|
-
if (event.target instanceof HTMLElement && focusableElements.
|
|
346
|
+
if (event.target instanceof HTMLElement && focusableElements.has(event.target)) {
|
|
340
347
|
activeDescendantControl.focus({ preventScroll });
|
|
341
348
|
updateFocusedElement(event.target);
|
|
342
349
|
}
|
|
@@ -346,9 +353,8 @@ function focusZone(container, settings) {
|
|
|
346
353
|
if (!(target instanceof Node)) {
|
|
347
354
|
return;
|
|
348
355
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
updateFocusedElement(focusableElements[targetIndex]);
|
|
356
|
+
if (target instanceof HTMLElement && focusableElements.has(target)) {
|
|
357
|
+
updateFocusedElement(target);
|
|
352
358
|
return;
|
|
353
359
|
}
|
|
354
360
|
const focusableElement = focusableElements.find(element => element.contains(target));
|
|
@@ -375,8 +381,9 @@ function focusZone(container, settings) {
|
|
|
375
381
|
if (event.target instanceof HTMLElement) {
|
|
376
382
|
if (elementIndexFocusedByClick !== undefined) {
|
|
377
383
|
if (elementIndexFocusedByClick >= 0) {
|
|
378
|
-
|
|
379
|
-
|
|
384
|
+
const clickedElement = focusableElements.get(elementIndexFocusedByClick);
|
|
385
|
+
if (clickedElement && clickedElement !== currentFocusedElement) {
|
|
386
|
+
updateFocusedElement(clickedElement);
|
|
380
387
|
}
|
|
381
388
|
}
|
|
382
389
|
elementIndexFocusedByClick = undefined;
|
|
@@ -387,8 +394,8 @@ function focusZone(container, settings) {
|
|
|
387
394
|
}
|
|
388
395
|
else if (focusInStrategy === 'closest' || focusInStrategy === 'first') {
|
|
389
396
|
if (event.relatedTarget instanceof Element && !container.contains(event.relatedTarget)) {
|
|
390
|
-
const targetElementIndex = lastKeyboardFocusDirection === 'previous' ? focusableElements.
|
|
391
|
-
const targetElement = focusableElements
|
|
397
|
+
const targetElementIndex = lastKeyboardFocusDirection === 'previous' ? focusableElements.size - 1 : 0;
|
|
398
|
+
const targetElement = focusableElements.get(targetElementIndex);
|
|
392
399
|
targetElement === null || targetElement === void 0 ? void 0 : targetElement.focus({ preventScroll });
|
|
393
400
|
return;
|
|
394
401
|
}
|
|
@@ -399,8 +406,7 @@ function focusZone(container, settings) {
|
|
|
399
406
|
else if (typeof focusInStrategy === 'function') {
|
|
400
407
|
if (event.relatedTarget instanceof Element && !container.contains(event.relatedTarget)) {
|
|
401
408
|
const elementToFocus = focusInStrategy(event.relatedTarget);
|
|
402
|
-
|
|
403
|
-
if (requestedFocusElementIndex >= 0 && elementToFocus instanceof HTMLElement) {
|
|
409
|
+
if (elementToFocus && focusableElements.has(elementToFocus)) {
|
|
404
410
|
elementToFocus.focus({ preventScroll });
|
|
405
411
|
return;
|
|
406
412
|
}
|
|
@@ -459,26 +465,26 @@ function focusZone(container, settings) {
|
|
|
459
465
|
nextFocusedIndex += 1;
|
|
460
466
|
}
|
|
461
467
|
else {
|
|
462
|
-
nextFocusedIndex = focusableElements.
|
|
468
|
+
nextFocusedIndex = focusableElements.size - 1;
|
|
463
469
|
}
|
|
464
470
|
if (nextFocusedIndex < 0) {
|
|
465
471
|
if (focusOutBehavior === 'wrap' && event.key !== 'Tab') {
|
|
466
|
-
nextFocusedIndex = focusableElements.
|
|
472
|
+
nextFocusedIndex = focusableElements.size - 1;
|
|
467
473
|
}
|
|
468
474
|
else {
|
|
469
475
|
nextFocusedIndex = 0;
|
|
470
476
|
}
|
|
471
477
|
}
|
|
472
|
-
if (nextFocusedIndex >= focusableElements.
|
|
478
|
+
if (nextFocusedIndex >= focusableElements.size) {
|
|
473
479
|
if (focusOutBehavior === 'wrap' && event.key !== 'Tab') {
|
|
474
480
|
nextFocusedIndex = 0;
|
|
475
481
|
}
|
|
476
482
|
else {
|
|
477
|
-
nextFocusedIndex = focusableElements.
|
|
483
|
+
nextFocusedIndex = focusableElements.size - 1;
|
|
478
484
|
}
|
|
479
485
|
}
|
|
480
486
|
if (lastFocusedIndex !== nextFocusedIndex) {
|
|
481
|
-
nextElementToFocus = focusableElements
|
|
487
|
+
nextElementToFocus = focusableElements.get(nextFocusedIndex);
|
|
482
488
|
}
|
|
483
489
|
}
|
|
484
490
|
if (activeDescendantControl) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class IndexedSet<T> {
|
|
2
|
+
#private;
|
|
3
|
+
insertAt(index: number, ...elements: T[]): void;
|
|
4
|
+
delete(element: T): boolean;
|
|
5
|
+
has(element: T): boolean;
|
|
6
|
+
indexOf(element: T): number;
|
|
7
|
+
get(index: number): T | undefined;
|
|
8
|
+
get size(): number;
|
|
9
|
+
[Symbol.iterator](): Iterator<T>;
|
|
10
|
+
clear(): void;
|
|
11
|
+
find(predicate: (element: T) => boolean): T | undefined;
|
|
12
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { __classPrivateFieldGet, __classPrivateFieldSet } from 'tslib';
|
|
2
|
+
|
|
3
|
+
var _IndexedSet_items, _IndexedSet_itemSet;
|
|
4
|
+
class IndexedSet {
|
|
5
|
+
constructor() {
|
|
6
|
+
_IndexedSet_items.set(this, []);
|
|
7
|
+
_IndexedSet_itemSet.set(this, new Set());
|
|
8
|
+
}
|
|
9
|
+
insertAt(index, ...elements) {
|
|
10
|
+
const newElements = elements.filter(e => !__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").has(e));
|
|
11
|
+
if (newElements.length === 0)
|
|
12
|
+
return;
|
|
13
|
+
__classPrivateFieldGet(this, _IndexedSet_items, "f").splice(index, 0, ...newElements);
|
|
14
|
+
for (const element of newElements) {
|
|
15
|
+
__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").add(element);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
delete(element) {
|
|
19
|
+
if (!__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").has(element))
|
|
20
|
+
return false;
|
|
21
|
+
const index = __classPrivateFieldGet(this, _IndexedSet_items, "f").indexOf(element);
|
|
22
|
+
if (index >= 0) {
|
|
23
|
+
__classPrivateFieldGet(this, _IndexedSet_items, "f").splice(index, 1);
|
|
24
|
+
}
|
|
25
|
+
__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").delete(element);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
has(element) {
|
|
29
|
+
return __classPrivateFieldGet(this, _IndexedSet_itemSet, "f").has(element);
|
|
30
|
+
}
|
|
31
|
+
indexOf(element) {
|
|
32
|
+
if (!__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").has(element))
|
|
33
|
+
return -1;
|
|
34
|
+
return __classPrivateFieldGet(this, _IndexedSet_items, "f").indexOf(element);
|
|
35
|
+
}
|
|
36
|
+
get(index) {
|
|
37
|
+
return __classPrivateFieldGet(this, _IndexedSet_items, "f")[index];
|
|
38
|
+
}
|
|
39
|
+
get size() {
|
|
40
|
+
return __classPrivateFieldGet(this, _IndexedSet_items, "f").length;
|
|
41
|
+
}
|
|
42
|
+
[(_IndexedSet_items = new WeakMap(), _IndexedSet_itemSet = new WeakMap(), Symbol.iterator)]() {
|
|
43
|
+
return __classPrivateFieldGet(this, _IndexedSet_items, "f")[Symbol.iterator]();
|
|
44
|
+
}
|
|
45
|
+
clear() {
|
|
46
|
+
__classPrivateFieldSet(this, _IndexedSet_items, [], "f");
|
|
47
|
+
__classPrivateFieldGet(this, _IndexedSet_itemSet, "f").clear();
|
|
48
|
+
}
|
|
49
|
+
find(predicate) {
|
|
50
|
+
return __classPrivateFieldGet(this, _IndexedSet_items, "f").find(predicate);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { IndexedSet };
|