@shoper/phoenix_design_system 1.18.23-3 → 1.18.23-5
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/build/cjs/packages/phoenix/src/components/dropdown/dropdown.js +2 -2
- package/build/cjs/packages/phoenix/src/components/form/search/search.js +7 -9
- package/build/cjs/packages/phoenix/src/components/form/search/search.js.map +1 -1
- package/build/cjs/packages/phoenix/src/components/form/search/subcomponents/input/search_input.js +3 -13
- package/build/cjs/packages/phoenix/src/components/form/search/subcomponents/input/search_input.js.map +1 -1
- package/build/cjs/packages/phoenix/src/components/modal/modal.js +5 -5
- package/build/cjs/packages/phoenix/src/components/sheet/sheet.js +4 -4
- package/build/cjs/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller.js +32 -176
- package/build/cjs/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller.js.map +1 -1
- package/build/cjs/packages/phoenix/src/controllers/focus_trap_controller/strategies/cyclic_focus_trap_strategy.js +53 -0
- package/build/cjs/packages/phoenix/src/controllers/focus_trap_controller/strategies/cyclic_focus_trap_strategy.js.map +1 -0
- package/build/cjs/packages/phoenix/src/controllers/focus_trap_controller/strategies/focus_trap_strategy.js +36 -0
- package/build/cjs/packages/phoenix/src/controllers/focus_trap_controller/strategies/focus_trap_strategy.js.map +1 -0
- package/build/cjs/packages/phoenix/src/controllers/focus_trap_controller/strategies/sentinel_focus_trap_strategy.js +89 -0
- package/build/cjs/packages/phoenix/src/controllers/focus_trap_controller/strategies/sentinel_focus_trap_strategy.js.map +1 -0
- package/build/cjs/packages/phoenix/src/controllers/focus_trap_controller/strategies/toggler_focus_trap_strategy.js +77 -0
- package/build/cjs/packages/phoenix/src/controllers/focus_trap_controller/strategies/toggler_focus_trap_strategy.js.map +1 -0
- package/build/esm/packages/phoenix/src/components/dropdown/dropdown.js +2 -2
- package/build/esm/packages/phoenix/src/components/form/search/search.js +7 -9
- package/build/esm/packages/phoenix/src/components/form/search/search.js.map +1 -1
- package/build/esm/packages/phoenix/src/components/form/search/subcomponents/input/search_input.js +3 -13
- package/build/esm/packages/phoenix/src/components/form/search/subcomponents/input/search_input.js.map +1 -1
- package/build/esm/packages/phoenix/src/components/modal/modal.js +5 -5
- package/build/esm/packages/phoenix/src/components/sheet/sheet.js +4 -4
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller.d.ts +19 -17
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller.js +33 -177
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller.js.map +1 -1
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller_types.d.ts +12 -11
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller_types.js +1 -1
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller_types.js.map +1 -1
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/cyclic_focus_trap_strategy.d.ts +17 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/cyclic_focus_trap_strategy.js +49 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/cyclic_focus_trap_strategy.js.map +1 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/focus_trap_strategy.d.ts +11 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/focus_trap_strategy.js +32 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/focus_trap_strategy.js.map +1 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/index.d.ts +6 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/index.js +5 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/index.js.map +1 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/sentinel_focus_trap_strategy.d.ts +31 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/sentinel_focus_trap_strategy.js +85 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/sentinel_focus_trap_strategy.js.map +1 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/toggler_focus_trap_strategy.d.ts +21 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/toggler_focus_trap_strategy.js +73 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/toggler_focus_trap_strategy.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { FocusTrapStrategy } from './focus_trap_strategy.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cyclic keydown focus trap.
|
|
5
|
+
*
|
|
6
|
+
* No sentinel DOM elements. Tab past the last focusable element wraps to the first;
|
|
7
|
+
* Shift+Tab past the first wraps to the last. Uses `keydown` + `preventDefault` so the
|
|
8
|
+
* browser never moves focus outside the container.
|
|
9
|
+
*
|
|
10
|
+
* Suitable when the host is not portaled and `inert` is not applied to background content
|
|
11
|
+
* (e.g. a full-screen search overlay on mobile).
|
|
12
|
+
*/
|
|
13
|
+
class CyclicFocusTrapStrategy extends FocusTrapStrategy {
|
|
14
|
+
constructor(getContainer) {
|
|
15
|
+
super(getContainer);
|
|
16
|
+
this._handleKeyDown = (ev) => {
|
|
17
|
+
if (!this.active || ev.code !== 'Tab')
|
|
18
|
+
return;
|
|
19
|
+
const container = this.getContainer();
|
|
20
|
+
if (!container)
|
|
21
|
+
return;
|
|
22
|
+
const focusableElements = this.getFocusableElements(container);
|
|
23
|
+
if (focusableElements.length === 0)
|
|
24
|
+
return;
|
|
25
|
+
const $target = ev.target;
|
|
26
|
+
if (ev.shiftKey) {
|
|
27
|
+
if ($target === focusableElements[0]) {
|
|
28
|
+
ev.preventDefault();
|
|
29
|
+
focusableElements[focusableElements.length - 1].focus();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
if ($target === focusableElements[focusableElements.length - 1]) {
|
|
34
|
+
ev.preventDefault();
|
|
35
|
+
focusableElements[0].focus();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
attach() {
|
|
41
|
+
document.addEventListener('keydown', this._handleKeyDown);
|
|
42
|
+
}
|
|
43
|
+
detach() {
|
|
44
|
+
document.removeEventListener('keydown', this._handleKeyDown);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { CyclicFocusTrapStrategy };
|
|
49
|
+
//# sourceMappingURL=cyclic_focus_trap_strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare abstract class FocusTrapStrategy {
|
|
2
|
+
protected readonly getContainer: () => HTMLElement | undefined;
|
|
3
|
+
protected active: boolean;
|
|
4
|
+
constructor(getContainer: () => HTMLElement | undefined);
|
|
5
|
+
abstract attach(): void;
|
|
6
|
+
abstract detach(): void;
|
|
7
|
+
activate(): void;
|
|
8
|
+
deactivate(): void;
|
|
9
|
+
getFocusableElements(container: HTMLElement): HTMLElement[];
|
|
10
|
+
private _isElementTrulyFocusable;
|
|
11
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { UiDomUtils } from '@dreamcommerce/utilities';
|
|
2
|
+
|
|
3
|
+
class FocusTrapStrategy {
|
|
4
|
+
constructor(getContainer) {
|
|
5
|
+
this.getContainer = getContainer;
|
|
6
|
+
this.active = false;
|
|
7
|
+
}
|
|
8
|
+
activate() {
|
|
9
|
+
this.active = true;
|
|
10
|
+
}
|
|
11
|
+
deactivate() {
|
|
12
|
+
this.active = false;
|
|
13
|
+
}
|
|
14
|
+
getFocusableElements(container) {
|
|
15
|
+
return UiDomUtils.getFocusableElements(container).filter(($el) => this._isElementTrulyFocusable($el));
|
|
16
|
+
}
|
|
17
|
+
_isElementTrulyFocusable($el) {
|
|
18
|
+
const style = window.getComputedStyle($el);
|
|
19
|
+
if (style.display === 'none' || style.visibility === 'hidden') {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if ($el.nodeName === 'H-PORTAL')
|
|
23
|
+
return true;
|
|
24
|
+
const $parent = $el.parentElement;
|
|
25
|
+
if (!$parent)
|
|
26
|
+
return true;
|
|
27
|
+
return this._isElementTrulyFocusable($parent);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { FocusTrapStrategy };
|
|
32
|
+
//# sourceMappingURL=focus_trap_strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;"}
|
package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { FocusTrapStrategy } from './focus_trap_strategy';
|
|
2
|
+
export { SentinelFocusTrapStrategy } from './sentinel_focus_trap_strategy';
|
|
3
|
+
export type { TSentinelFocusTrapStrategyProps } from './sentinel_focus_trap_strategy';
|
|
4
|
+
export { CyclicFocusTrapStrategy } from './cyclic_focus_trap_strategy';
|
|
5
|
+
export { TogglerFocusTrapStrategy } from './toggler_focus_trap_strategy';
|
|
6
|
+
export type { TTogglerFocusTrapStrategyProps } from './toggler_focus_trap_strategy';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { FocusTrapStrategy } from './focus_trap_strategy';
|
|
2
|
+
export { SentinelFocusTrapStrategy } from './sentinel_focus_trap_strategy';
|
|
3
|
+
export { CyclicFocusTrapStrategy } from './cyclic_focus_trap_strategy';
|
|
4
|
+
export { TogglerFocusTrapStrategy } from './toggler_focus_trap_strategy';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/strategies/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../src/controllers/focus_trap_controller/strategies/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { FocusTrapStrategy } from './focus_trap_strategy';
|
|
2
|
+
export declare type TSentinelFocusTrapStrategyProps = {
|
|
3
|
+
getContainer: () => HTMLElement | undefined;
|
|
4
|
+
noAutofocus?: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Sentinel mode focus trap.
|
|
8
|
+
*
|
|
9
|
+
* Uses two inert bookend elements (sentinelStart / sentinelEnd) to detect when focus
|
|
10
|
+
* escapes the container and cycle it back. Appropriate for modal dialogs and sheets where
|
|
11
|
+
* background content is marked `inert`, giving the browser an extra safety net.
|
|
12
|
+
*
|
|
13
|
+
* Reacts on `keyup` so that the browser's native focus movement has already completed
|
|
14
|
+
* before we redirect it.
|
|
15
|
+
*/
|
|
16
|
+
export declare class SentinelFocusTrapStrategy extends FocusTrapStrategy {
|
|
17
|
+
#private;
|
|
18
|
+
noAutofocus: boolean;
|
|
19
|
+
constructor({ getContainer, noAutofocus }: TSentinelFocusTrapStrategyProps);
|
|
20
|
+
/** Call once in firstUpdated with the two bookend sentinel elements. */
|
|
21
|
+
setSentinels(start: HTMLElement, end: HTMLElement): void;
|
|
22
|
+
/**
|
|
23
|
+
* Move focus to the first real interactive element after the open transition
|
|
24
|
+
* completes (skips sentinelStart at index 0).
|
|
25
|
+
*/
|
|
26
|
+
focusFirst(): void;
|
|
27
|
+
attach(): void;
|
|
28
|
+
detach(): void;
|
|
29
|
+
activate(): void;
|
|
30
|
+
private _handleKeyUp;
|
|
31
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { __classPrivateFieldGet, __classPrivateFieldSet } from '../../../../../../external/tslib/tslib.es6.js';
|
|
2
|
+
import { UiDomUtils } from '@dreamcommerce/utilities';
|
|
3
|
+
import { FocusTrapStrategy } from './focus_trap_strategy.js';
|
|
4
|
+
|
|
5
|
+
var _SentinelFocusTrapStrategy_sentinelStart, _SentinelFocusTrapStrategy_sentinelEnd;
|
|
6
|
+
/**
|
|
7
|
+
* Sentinel mode focus trap.
|
|
8
|
+
*
|
|
9
|
+
* Uses two inert bookend elements (sentinelStart / sentinelEnd) to detect when focus
|
|
10
|
+
* escapes the container and cycle it back. Appropriate for modal dialogs and sheets where
|
|
11
|
+
* background content is marked `inert`, giving the browser an extra safety net.
|
|
12
|
+
*
|
|
13
|
+
* Reacts on `keyup` so that the browser's native focus movement has already completed
|
|
14
|
+
* before we redirect it.
|
|
15
|
+
*/
|
|
16
|
+
class SentinelFocusTrapStrategy extends FocusTrapStrategy {
|
|
17
|
+
constructor({ getContainer, noAutofocus = false }) {
|
|
18
|
+
super(getContainer);
|
|
19
|
+
_SentinelFocusTrapStrategy_sentinelStart.set(this, void 0);
|
|
20
|
+
_SentinelFocusTrapStrategy_sentinelEnd.set(this, void 0);
|
|
21
|
+
this._handleKeyUp = (ev) => {
|
|
22
|
+
var _a;
|
|
23
|
+
if (!this.active || ev.code !== 'Tab')
|
|
24
|
+
return;
|
|
25
|
+
const container = this.getContainer();
|
|
26
|
+
if (!container)
|
|
27
|
+
return;
|
|
28
|
+
if (ev.shiftKey) {
|
|
29
|
+
if (document.activeElement === __classPrivateFieldGet(this, _SentinelFocusTrapStrategy_sentinelStart, "f")) {
|
|
30
|
+
const focusableElements = this.getFocusableElements(container);
|
|
31
|
+
(_a = focusableElements[focusableElements.length - 1]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
32
|
+
ev.preventDefault();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else if (document.activeElement === __classPrivateFieldGet(this, _SentinelFocusTrapStrategy_sentinelEnd, "f")) {
|
|
36
|
+
UiDomUtils.setFocusToFirstFocusableElementInContainer(container);
|
|
37
|
+
ev.preventDefault();
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
this.noAutofocus = noAutofocus;
|
|
41
|
+
}
|
|
42
|
+
/** Call once in firstUpdated with the two bookend sentinel elements. */
|
|
43
|
+
setSentinels(start, end) {
|
|
44
|
+
__classPrivateFieldSet(this, _SentinelFocusTrapStrategy_sentinelStart, start, "f");
|
|
45
|
+
__classPrivateFieldSet(this, _SentinelFocusTrapStrategy_sentinelEnd, end, "f");
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Move focus to the first real interactive element after the open transition
|
|
49
|
+
* completes (skips sentinelStart at index 0).
|
|
50
|
+
*/
|
|
51
|
+
focusFirst() {
|
|
52
|
+
if (this.noAutofocus)
|
|
53
|
+
return;
|
|
54
|
+
requestAnimationFrame(() => {
|
|
55
|
+
const container = this.getContainer();
|
|
56
|
+
if (!container)
|
|
57
|
+
return;
|
|
58
|
+
const focusableElements = this.getFocusableElements(container);
|
|
59
|
+
if (focusableElements.length > 0) {
|
|
60
|
+
focusableElements.length > 1 ? focusableElements[1].focus() : focusableElements[0].focus();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
attach() {
|
|
65
|
+
document.addEventListener('keyup', this._handleKeyUp);
|
|
66
|
+
}
|
|
67
|
+
detach() {
|
|
68
|
+
document.removeEventListener('keyup', this._handleKeyUp);
|
|
69
|
+
}
|
|
70
|
+
activate() {
|
|
71
|
+
this.active = true;
|
|
72
|
+
if (!this.noAutofocus) {
|
|
73
|
+
const scrollY = window.scrollY;
|
|
74
|
+
setTimeout(() => {
|
|
75
|
+
var _a;
|
|
76
|
+
(_a = __classPrivateFieldGet(this, _SentinelFocusTrapStrategy_sentinelStart, "f")) === null || _a === void 0 ? void 0 : _a.focus();
|
|
77
|
+
window.scrollTo(0, scrollY);
|
|
78
|
+
}, 0);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
_SentinelFocusTrapStrategy_sentinelStart = new WeakMap(), _SentinelFocusTrapStrategy_sentinelEnd = new WeakMap();
|
|
83
|
+
|
|
84
|
+
export { SentinelFocusTrapStrategy };
|
|
85
|
+
//# sourceMappingURL=sentinel_focus_trap_strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA,+DAA+D,+CAAmD;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FocusTrapStrategy } from './focus_trap_strategy';
|
|
2
|
+
export declare type TTogglerFocusTrapStrategyProps = {
|
|
3
|
+
getContainer: () => HTMLElement | undefined;
|
|
4
|
+
getToggler: () => HTMLElement | null | undefined;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Toggler mode focus trap.
|
|
8
|
+
*
|
|
9
|
+
* Focus cycles: toggler → content[0] → … → content[last] → toggler (and reverse).
|
|
10
|
+
* Uses `keydown` + `preventDefault` so the browser never moves focus on its own.
|
|
11
|
+
*
|
|
12
|
+
* Suitable for dropdowns where the toggler button should stay in the Tab cycle
|
|
13
|
+
* alongside the dropdown content.
|
|
14
|
+
*/
|
|
15
|
+
export declare class TogglerFocusTrapStrategy extends FocusTrapStrategy {
|
|
16
|
+
#private;
|
|
17
|
+
constructor({ getContainer, getToggler }: TTogglerFocusTrapStrategyProps);
|
|
18
|
+
attach(): void;
|
|
19
|
+
detach(): void;
|
|
20
|
+
private _handleKeyDown;
|
|
21
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { __classPrivateFieldGet, __classPrivateFieldSet } from '../../../../../../external/tslib/tslib.es6.js';
|
|
2
|
+
import { FocusTrapStrategy } from './focus_trap_strategy.js';
|
|
3
|
+
|
|
4
|
+
var _TogglerFocusTrapStrategy_getToggler;
|
|
5
|
+
/**
|
|
6
|
+
* Toggler mode focus trap.
|
|
7
|
+
*
|
|
8
|
+
* Focus cycles: toggler → content[0] → … → content[last] → toggler (and reverse).
|
|
9
|
+
* Uses `keydown` + `preventDefault` so the browser never moves focus on its own.
|
|
10
|
+
*
|
|
11
|
+
* Suitable for dropdowns where the toggler button should stay in the Tab cycle
|
|
12
|
+
* alongside the dropdown content.
|
|
13
|
+
*/
|
|
14
|
+
class TogglerFocusTrapStrategy extends FocusTrapStrategy {
|
|
15
|
+
constructor({ getContainer, getToggler }) {
|
|
16
|
+
super(getContainer);
|
|
17
|
+
_TogglerFocusTrapStrategy_getToggler.set(this, void 0);
|
|
18
|
+
this._handleKeyDown = (ev) => {
|
|
19
|
+
var _a;
|
|
20
|
+
if (!this.active || ev.code !== 'Tab')
|
|
21
|
+
return;
|
|
22
|
+
const container = this.getContainer();
|
|
23
|
+
const toggler = (_a = __classPrivateFieldGet(this, _TogglerFocusTrapStrategy_getToggler, "f")) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
24
|
+
if (!container || !toggler)
|
|
25
|
+
return;
|
|
26
|
+
const $target = ev.target;
|
|
27
|
+
const focusableElements = this.getFocusableElements(container);
|
|
28
|
+
if (ev.shiftKey) {
|
|
29
|
+
// Shift+Tab on toggler → last content element
|
|
30
|
+
if (toggler.contains($target)) {
|
|
31
|
+
const last = focusableElements[focusableElements.length - 1];
|
|
32
|
+
if (!last)
|
|
33
|
+
return;
|
|
34
|
+
ev.preventDefault();
|
|
35
|
+
last.focus();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
// Shift+Tab on first content element → toggler
|
|
39
|
+
if ($target === focusableElements[0]) {
|
|
40
|
+
ev.preventDefault();
|
|
41
|
+
toggler.focus();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Tab on toggler → first content element
|
|
46
|
+
if (toggler.contains($target)) {
|
|
47
|
+
const first = focusableElements[0];
|
|
48
|
+
if (!first)
|
|
49
|
+
return;
|
|
50
|
+
ev.preventDefault();
|
|
51
|
+
first.focus();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// Tab on last content element → toggler
|
|
55
|
+
if ($target === focusableElements[focusableElements.length - 1]) {
|
|
56
|
+
ev.preventDefault();
|
|
57
|
+
toggler.focus();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
__classPrivateFieldSet(this, _TogglerFocusTrapStrategy_getToggler, getToggler, "f");
|
|
62
|
+
}
|
|
63
|
+
attach() {
|
|
64
|
+
document.addEventListener('keydown', this._handleKeyDown);
|
|
65
|
+
}
|
|
66
|
+
detach() {
|
|
67
|
+
document.removeEventListener('keydown', this._handleKeyDown);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
_TogglerFocusTrapStrategy_getToggler = new WeakMap();
|
|
71
|
+
|
|
72
|
+
export { TogglerFocusTrapStrategy };
|
|
73
|
+
//# sourceMappingURL=toggler_focus_trap_strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA,+DAA+D,+CAAmD;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;"}
|