@primer/behaviors 0.0.0-20251215025613 → 0.0.0-20251215032051
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;
|
|
@@ -201,11 +203,13 @@ function focusZone(container, settings) {
|
|
|
201
203
|
activeDescendantCallback === null || activeDescendantCallback === void 0 ? void 0 : activeDescendantCallback(undefined, previouslyActiveElement, false);
|
|
202
204
|
}
|
|
203
205
|
function beginFocusManagement(...elements) {
|
|
204
|
-
const filteredElements =
|
|
206
|
+
const filteredElements = (settings === null || settings === void 0 ? void 0 : settings.focusableElementFilter)
|
|
207
|
+
? elements.filter(e => settings.focusableElementFilter(e))
|
|
208
|
+
: elements;
|
|
205
209
|
if (filteredElements.length === 0) {
|
|
206
210
|
return;
|
|
207
211
|
}
|
|
208
|
-
focusableElements.
|
|
212
|
+
focusableElements.insertAt(findInsertionIndex(filteredElements), ...filteredElements);
|
|
209
213
|
for (const element of filteredElements) {
|
|
210
214
|
if (!savedTabIndex.has(element)) {
|
|
211
215
|
savedTabIndex.set(element, element.getAttribute('tabindex'));
|
|
@@ -218,13 +222,13 @@ function focusZone(container, settings) {
|
|
|
218
222
|
}
|
|
219
223
|
function findInsertionIndex(elementsToInsert) {
|
|
220
224
|
const firstElementToInsert = elementsToInsert[0];
|
|
221
|
-
if (focusableElements.
|
|
225
|
+
if (focusableElements.size === 0)
|
|
222
226
|
return 0;
|
|
223
227
|
let iMin = 0;
|
|
224
|
-
let iMax = focusableElements.
|
|
228
|
+
let iMax = focusableElements.size - 1;
|
|
225
229
|
while (iMin <= iMax) {
|
|
226
230
|
const i = Math.floor((iMin + iMax) / 2);
|
|
227
|
-
const element = focusableElements
|
|
231
|
+
const element = focusableElements.get(i);
|
|
228
232
|
if (followsInDocument(firstElementToInsert, element)) {
|
|
229
233
|
iMax = i - 1;
|
|
230
234
|
}
|
|
@@ -239,10 +243,7 @@ function focusZone(container, settings) {
|
|
|
239
243
|
}
|
|
240
244
|
function endFocusManagement(...elements) {
|
|
241
245
|
for (const element of elements) {
|
|
242
|
-
|
|
243
|
-
if (focusableElementIndex >= 0) {
|
|
244
|
-
focusableElements.splice(focusableElementIndex, 1);
|
|
245
|
-
}
|
|
246
|
+
focusableElements.delete(element);
|
|
246
247
|
const savedIndex = savedTabIndex.get(element);
|
|
247
248
|
if (savedIndex !== undefined) {
|
|
248
249
|
if (savedIndex === null) {
|
|
@@ -298,7 +299,12 @@ function focusZone(container, settings) {
|
|
|
298
299
|
}
|
|
299
300
|
}
|
|
300
301
|
if (elementsToRemove.size > 0) {
|
|
301
|
-
const toRemove = [
|
|
302
|
+
const toRemove = [];
|
|
303
|
+
for (const node of elementsToRemove) {
|
|
304
|
+
for (const el of iterateFocusableElements.iterateFocusableElements(node)) {
|
|
305
|
+
toRemove.push(el);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
302
308
|
if (toRemove.length > 0) {
|
|
303
309
|
endFocusManagement(...toRemove);
|
|
304
310
|
}
|
|
@@ -307,9 +313,12 @@ function focusZone(container, settings) {
|
|
|
307
313
|
endFocusManagement(...attributeRemovals);
|
|
308
314
|
}
|
|
309
315
|
if (elementsToAdd.size > 0) {
|
|
310
|
-
const toAdd = [
|
|
311
|
-
|
|
312
|
-
|
|
316
|
+
const toAdd = [];
|
|
317
|
+
for (const node of elementsToAdd) {
|
|
318
|
+
for (const el of iterateFocusableElements.iterateFocusableElements(node, iterateFocusableElementsOptions)) {
|
|
319
|
+
toAdd.push(el);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
313
322
|
if (toAdd.length > 0) {
|
|
314
323
|
beginFocusManagement(...toAdd);
|
|
315
324
|
}
|
|
@@ -338,7 +347,7 @@ function focusZone(container, settings) {
|
|
|
338
347
|
}, { signal });
|
|
339
348
|
if (activeDescendantControl) {
|
|
340
349
|
container.addEventListener('focusin', event => {
|
|
341
|
-
if (event.target instanceof HTMLElement && focusableElements.
|
|
350
|
+
if (event.target instanceof HTMLElement && focusableElements.has(event.target)) {
|
|
342
351
|
activeDescendantControl.focus({ preventScroll });
|
|
343
352
|
updateFocusedElement(event.target);
|
|
344
353
|
}
|
|
@@ -348,9 +357,8 @@ function focusZone(container, settings) {
|
|
|
348
357
|
if (!(target instanceof Node)) {
|
|
349
358
|
return;
|
|
350
359
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
updateFocusedElement(focusableElements[targetIndex]);
|
|
360
|
+
if (target instanceof HTMLElement && focusableElements.has(target)) {
|
|
361
|
+
updateFocusedElement(target);
|
|
354
362
|
return;
|
|
355
363
|
}
|
|
356
364
|
const focusableElement = focusableElements.find(element => element.contains(target));
|
|
@@ -377,8 +385,9 @@ function focusZone(container, settings) {
|
|
|
377
385
|
if (event.target instanceof HTMLElement) {
|
|
378
386
|
if (elementIndexFocusedByClick !== undefined) {
|
|
379
387
|
if (elementIndexFocusedByClick >= 0) {
|
|
380
|
-
|
|
381
|
-
|
|
388
|
+
const clickedElement = focusableElements.get(elementIndexFocusedByClick);
|
|
389
|
+
if (clickedElement && clickedElement !== currentFocusedElement) {
|
|
390
|
+
updateFocusedElement(clickedElement);
|
|
382
391
|
}
|
|
383
392
|
}
|
|
384
393
|
elementIndexFocusedByClick = undefined;
|
|
@@ -389,8 +398,8 @@ function focusZone(container, settings) {
|
|
|
389
398
|
}
|
|
390
399
|
else if (focusInStrategy === 'closest' || focusInStrategy === 'first') {
|
|
391
400
|
if (event.relatedTarget instanceof Element && !container.contains(event.relatedTarget)) {
|
|
392
|
-
const targetElementIndex = lastKeyboardFocusDirection === 'previous' ? focusableElements.
|
|
393
|
-
const targetElement = focusableElements
|
|
401
|
+
const targetElementIndex = lastKeyboardFocusDirection === 'previous' ? focusableElements.size - 1 : 0;
|
|
402
|
+
const targetElement = focusableElements.get(targetElementIndex);
|
|
394
403
|
targetElement === null || targetElement === void 0 ? void 0 : targetElement.focus({ preventScroll });
|
|
395
404
|
return;
|
|
396
405
|
}
|
|
@@ -401,8 +410,7 @@ function focusZone(container, settings) {
|
|
|
401
410
|
else if (typeof focusInStrategy === 'function') {
|
|
402
411
|
if (event.relatedTarget instanceof Element && !container.contains(event.relatedTarget)) {
|
|
403
412
|
const elementToFocus = focusInStrategy(event.relatedTarget);
|
|
404
|
-
|
|
405
|
-
if (requestedFocusElementIndex >= 0 && elementToFocus instanceof HTMLElement) {
|
|
413
|
+
if (elementToFocus && focusableElements.has(elementToFocus)) {
|
|
406
414
|
elementToFocus.focus({ preventScroll });
|
|
407
415
|
return;
|
|
408
416
|
}
|
|
@@ -461,26 +469,26 @@ function focusZone(container, settings) {
|
|
|
461
469
|
nextFocusedIndex += 1;
|
|
462
470
|
}
|
|
463
471
|
else {
|
|
464
|
-
nextFocusedIndex = focusableElements.
|
|
472
|
+
nextFocusedIndex = focusableElements.size - 1;
|
|
465
473
|
}
|
|
466
474
|
if (nextFocusedIndex < 0) {
|
|
467
475
|
if (focusOutBehavior === 'wrap' && event.key !== 'Tab') {
|
|
468
|
-
nextFocusedIndex = focusableElements.
|
|
476
|
+
nextFocusedIndex = focusableElements.size - 1;
|
|
469
477
|
}
|
|
470
478
|
else {
|
|
471
479
|
nextFocusedIndex = 0;
|
|
472
480
|
}
|
|
473
481
|
}
|
|
474
|
-
if (nextFocusedIndex >= focusableElements.
|
|
482
|
+
if (nextFocusedIndex >= focusableElements.size) {
|
|
475
483
|
if (focusOutBehavior === 'wrap' && event.key !== 'Tab') {
|
|
476
484
|
nextFocusedIndex = 0;
|
|
477
485
|
}
|
|
478
486
|
else {
|
|
479
|
-
nextFocusedIndex = focusableElements.
|
|
487
|
+
nextFocusedIndex = focusableElements.size - 1;
|
|
480
488
|
}
|
|
481
489
|
}
|
|
482
490
|
if (lastFocusedIndex !== nextFocusedIndex) {
|
|
483
|
-
nextElementToFocus = focusableElements
|
|
491
|
+
nextElementToFocus = focusableElements.get(nextFocusedIndex);
|
|
484
492
|
}
|
|
485
493
|
}
|
|
486
494
|
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;
|
|
@@ -199,11 +201,13 @@ function focusZone(container, settings) {
|
|
|
199
201
|
activeDescendantCallback === null || activeDescendantCallback === void 0 ? void 0 : activeDescendantCallback(undefined, previouslyActiveElement, false);
|
|
200
202
|
}
|
|
201
203
|
function beginFocusManagement(...elements) {
|
|
202
|
-
const filteredElements =
|
|
204
|
+
const filteredElements = (settings === null || settings === void 0 ? void 0 : settings.focusableElementFilter)
|
|
205
|
+
? elements.filter(e => settings.focusableElementFilter(e))
|
|
206
|
+
: elements;
|
|
203
207
|
if (filteredElements.length === 0) {
|
|
204
208
|
return;
|
|
205
209
|
}
|
|
206
|
-
focusableElements.
|
|
210
|
+
focusableElements.insertAt(findInsertionIndex(filteredElements), ...filteredElements);
|
|
207
211
|
for (const element of filteredElements) {
|
|
208
212
|
if (!savedTabIndex.has(element)) {
|
|
209
213
|
savedTabIndex.set(element, element.getAttribute('tabindex'));
|
|
@@ -216,13 +220,13 @@ function focusZone(container, settings) {
|
|
|
216
220
|
}
|
|
217
221
|
function findInsertionIndex(elementsToInsert) {
|
|
218
222
|
const firstElementToInsert = elementsToInsert[0];
|
|
219
|
-
if (focusableElements.
|
|
223
|
+
if (focusableElements.size === 0)
|
|
220
224
|
return 0;
|
|
221
225
|
let iMin = 0;
|
|
222
|
-
let iMax = focusableElements.
|
|
226
|
+
let iMax = focusableElements.size - 1;
|
|
223
227
|
while (iMin <= iMax) {
|
|
224
228
|
const i = Math.floor((iMin + iMax) / 2);
|
|
225
|
-
const element = focusableElements
|
|
229
|
+
const element = focusableElements.get(i);
|
|
226
230
|
if (followsInDocument(firstElementToInsert, element)) {
|
|
227
231
|
iMax = i - 1;
|
|
228
232
|
}
|
|
@@ -237,10 +241,7 @@ function focusZone(container, settings) {
|
|
|
237
241
|
}
|
|
238
242
|
function endFocusManagement(...elements) {
|
|
239
243
|
for (const element of elements) {
|
|
240
|
-
|
|
241
|
-
if (focusableElementIndex >= 0) {
|
|
242
|
-
focusableElements.splice(focusableElementIndex, 1);
|
|
243
|
-
}
|
|
244
|
+
focusableElements.delete(element);
|
|
244
245
|
const savedIndex = savedTabIndex.get(element);
|
|
245
246
|
if (savedIndex !== undefined) {
|
|
246
247
|
if (savedIndex === null) {
|
|
@@ -296,7 +297,12 @@ function focusZone(container, settings) {
|
|
|
296
297
|
}
|
|
297
298
|
}
|
|
298
299
|
if (elementsToRemove.size > 0) {
|
|
299
|
-
const toRemove = [
|
|
300
|
+
const toRemove = [];
|
|
301
|
+
for (const node of elementsToRemove) {
|
|
302
|
+
for (const el of iterateFocusableElements(node)) {
|
|
303
|
+
toRemove.push(el);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
300
306
|
if (toRemove.length > 0) {
|
|
301
307
|
endFocusManagement(...toRemove);
|
|
302
308
|
}
|
|
@@ -305,9 +311,12 @@ function focusZone(container, settings) {
|
|
|
305
311
|
endFocusManagement(...attributeRemovals);
|
|
306
312
|
}
|
|
307
313
|
if (elementsToAdd.size > 0) {
|
|
308
|
-
const toAdd = [
|
|
309
|
-
|
|
310
|
-
|
|
314
|
+
const toAdd = [];
|
|
315
|
+
for (const node of elementsToAdd) {
|
|
316
|
+
for (const el of iterateFocusableElements(node, iterateFocusableElementsOptions)) {
|
|
317
|
+
toAdd.push(el);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
311
320
|
if (toAdd.length > 0) {
|
|
312
321
|
beginFocusManagement(...toAdd);
|
|
313
322
|
}
|
|
@@ -336,7 +345,7 @@ function focusZone(container, settings) {
|
|
|
336
345
|
}, { signal });
|
|
337
346
|
if (activeDescendantControl) {
|
|
338
347
|
container.addEventListener('focusin', event => {
|
|
339
|
-
if (event.target instanceof HTMLElement && focusableElements.
|
|
348
|
+
if (event.target instanceof HTMLElement && focusableElements.has(event.target)) {
|
|
340
349
|
activeDescendantControl.focus({ preventScroll });
|
|
341
350
|
updateFocusedElement(event.target);
|
|
342
351
|
}
|
|
@@ -346,9 +355,8 @@ function focusZone(container, settings) {
|
|
|
346
355
|
if (!(target instanceof Node)) {
|
|
347
356
|
return;
|
|
348
357
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
updateFocusedElement(focusableElements[targetIndex]);
|
|
358
|
+
if (target instanceof HTMLElement && focusableElements.has(target)) {
|
|
359
|
+
updateFocusedElement(target);
|
|
352
360
|
return;
|
|
353
361
|
}
|
|
354
362
|
const focusableElement = focusableElements.find(element => element.contains(target));
|
|
@@ -375,8 +383,9 @@ function focusZone(container, settings) {
|
|
|
375
383
|
if (event.target instanceof HTMLElement) {
|
|
376
384
|
if (elementIndexFocusedByClick !== undefined) {
|
|
377
385
|
if (elementIndexFocusedByClick >= 0) {
|
|
378
|
-
|
|
379
|
-
|
|
386
|
+
const clickedElement = focusableElements.get(elementIndexFocusedByClick);
|
|
387
|
+
if (clickedElement && clickedElement !== currentFocusedElement) {
|
|
388
|
+
updateFocusedElement(clickedElement);
|
|
380
389
|
}
|
|
381
390
|
}
|
|
382
391
|
elementIndexFocusedByClick = undefined;
|
|
@@ -387,8 +396,8 @@ function focusZone(container, settings) {
|
|
|
387
396
|
}
|
|
388
397
|
else if (focusInStrategy === 'closest' || focusInStrategy === 'first') {
|
|
389
398
|
if (event.relatedTarget instanceof Element && !container.contains(event.relatedTarget)) {
|
|
390
|
-
const targetElementIndex = lastKeyboardFocusDirection === 'previous' ? focusableElements.
|
|
391
|
-
const targetElement = focusableElements
|
|
399
|
+
const targetElementIndex = lastKeyboardFocusDirection === 'previous' ? focusableElements.size - 1 : 0;
|
|
400
|
+
const targetElement = focusableElements.get(targetElementIndex);
|
|
392
401
|
targetElement === null || targetElement === void 0 ? void 0 : targetElement.focus({ preventScroll });
|
|
393
402
|
return;
|
|
394
403
|
}
|
|
@@ -399,8 +408,7 @@ function focusZone(container, settings) {
|
|
|
399
408
|
else if (typeof focusInStrategy === 'function') {
|
|
400
409
|
if (event.relatedTarget instanceof Element && !container.contains(event.relatedTarget)) {
|
|
401
410
|
const elementToFocus = focusInStrategy(event.relatedTarget);
|
|
402
|
-
|
|
403
|
-
if (requestedFocusElementIndex >= 0 && elementToFocus instanceof HTMLElement) {
|
|
411
|
+
if (elementToFocus && focusableElements.has(elementToFocus)) {
|
|
404
412
|
elementToFocus.focus({ preventScroll });
|
|
405
413
|
return;
|
|
406
414
|
}
|
|
@@ -459,26 +467,26 @@ function focusZone(container, settings) {
|
|
|
459
467
|
nextFocusedIndex += 1;
|
|
460
468
|
}
|
|
461
469
|
else {
|
|
462
|
-
nextFocusedIndex = focusableElements.
|
|
470
|
+
nextFocusedIndex = focusableElements.size - 1;
|
|
463
471
|
}
|
|
464
472
|
if (nextFocusedIndex < 0) {
|
|
465
473
|
if (focusOutBehavior === 'wrap' && event.key !== 'Tab') {
|
|
466
|
-
nextFocusedIndex = focusableElements.
|
|
474
|
+
nextFocusedIndex = focusableElements.size - 1;
|
|
467
475
|
}
|
|
468
476
|
else {
|
|
469
477
|
nextFocusedIndex = 0;
|
|
470
478
|
}
|
|
471
479
|
}
|
|
472
|
-
if (nextFocusedIndex >= focusableElements.
|
|
480
|
+
if (nextFocusedIndex >= focusableElements.size) {
|
|
473
481
|
if (focusOutBehavior === 'wrap' && event.key !== 'Tab') {
|
|
474
482
|
nextFocusedIndex = 0;
|
|
475
483
|
}
|
|
476
484
|
else {
|
|
477
|
-
nextFocusedIndex = focusableElements.
|
|
485
|
+
nextFocusedIndex = focusableElements.size - 1;
|
|
478
486
|
}
|
|
479
487
|
}
|
|
480
488
|
if (lastFocusedIndex !== nextFocusedIndex) {
|
|
481
|
-
nextElementToFocus = focusableElements
|
|
489
|
+
nextElementToFocus = focusableElements.get(nextFocusedIndex);
|
|
482
490
|
}
|
|
483
491
|
}
|
|
484
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,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 };
|