@shoper/phoenix_design_system 1.18.23-0 → 1.18.23-2
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 +14 -77
- package/build/cjs/packages/phoenix/src/components/dropdown/dropdown.js.map +1 -1
- package/build/cjs/packages/phoenix/src/components/form/search/search.js +27 -0
- package/build/cjs/packages/phoenix/src/components/form/search/search.js.map +1 -1
- package/build/cjs/packages/phoenix/src/components/modal/modal.js +13 -59
- package/build/cjs/packages/phoenix/src/components/modal/modal.js.map +1 -1
- package/build/cjs/packages/phoenix/src/components/modal/modal_constants.js +1 -3
- package/build/cjs/packages/phoenix/src/components/modal/modal_constants.js.map +1 -1
- package/build/cjs/packages/phoenix/src/components/sheet/sheet.js +9 -55
- package/build/cjs/packages/phoenix/src/components/sheet/sheet.js.map +1 -1
- package/build/cjs/packages/phoenix/src/components/sheet/sheet_constants.js +1 -3
- package/build/cjs/packages/phoenix/src/components/sheet/sheet_constants.js.map +1 -1
- package/build/cjs/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller.js +200 -0
- package/build/cjs/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller.js.map +1 -0
- package/build/esm/packages/phoenix/src/components/dropdown/dropdown.d.ts +1 -6
- package/build/esm/packages/phoenix/src/components/dropdown/dropdown.js +14 -77
- package/build/esm/packages/phoenix/src/components/dropdown/dropdown.js.map +1 -1
- package/build/esm/packages/phoenix/src/components/form/search/search.d.ts +4 -0
- package/build/esm/packages/phoenix/src/components/form/search/search.js +27 -0
- package/build/esm/packages/phoenix/src/components/form/search/search.js.map +1 -1
- package/build/esm/packages/phoenix/src/components/modal/modal.d.ts +1 -5
- package/build/esm/packages/phoenix/src/components/modal/modal.js +15 -61
- package/build/esm/packages/phoenix/src/components/modal/modal.js.map +1 -1
- package/build/esm/packages/phoenix/src/components/modal/modal_constants.js +2 -3
- package/build/esm/packages/phoenix/src/components/modal/modal_constants.js.map +1 -1
- package/build/esm/packages/phoenix/src/components/sheet/sheet.d.ts +1 -5
- package/build/esm/packages/phoenix/src/components/sheet/sheet.js +11 -57
- package/build/esm/packages/phoenix/src/components/sheet/sheet.js.map +1 -1
- package/build/esm/packages/phoenix/src/components/sheet/sheet_constants.js +2 -3
- package/build/esm/packages/phoenix/src/components/sheet/sheet_constants.js.map +1 -1
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller.d.ts +24 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller.js +196 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller.js.map +1 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller_types.d.ts +14 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller_types.js +2 -0
- package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller_types.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { __decorate, __metadata } from '../../../../../external/tslib/tslib.es6.js';
|
|
2
|
-
import { UiDomUtils } from '@dreamcommerce/utilities';
|
|
3
2
|
import { PhoenixLightLitElement } from '../../core/phoenix_light_lit_element/phoenix_light_lit_element.js';
|
|
4
3
|
import { phoenixCustomElement } from '../../core/decorators/phoenix_custom_element.js';
|
|
5
|
-
import { property
|
|
4
|
+
import { property } from '@lit/reactive-element/decorators.js';
|
|
6
5
|
import '@lit/reactive-element';
|
|
7
6
|
import { html } from 'lit-html';
|
|
8
7
|
import { createRef, ref } from 'lit-html/directives/ref.js';
|
|
9
8
|
import { PORTAL_TARGET_COMPONENT_NAME, PORTAL_TARGET_NAME_PROP } from '../portal/portal_constants.js';
|
|
10
9
|
import { BACKDROP_EVENTS } from '../backdrop/backdrop_constants.js';
|
|
11
10
|
import { BackdropController } from '../backdrop/controller/backdrop_controller.js';
|
|
12
|
-
import {
|
|
11
|
+
import { FocusTrapController } from '../../controllers/focus_trap_controller/focus_trap_controller.js';
|
|
12
|
+
import { MODAL_OPENED_PROP, MODALS_PORTAL_NAME, MODAL_EVENTS } from './modal_constants.js';
|
|
13
13
|
import { HModalClose } from './modal_close.js';
|
|
14
14
|
|
|
15
15
|
var HModal_1;
|
|
@@ -21,9 +21,6 @@ let HModal = HModal_1 = class HModal extends PhoenixLightLitElement {
|
|
|
21
21
|
this.transition = 'scale';
|
|
22
22
|
this.modalLabel = '';
|
|
23
23
|
this.noAutofocus = false;
|
|
24
|
-
this._firstFocusableElement = undefined;
|
|
25
|
-
this._focusableElements = null;
|
|
26
|
-
this._lastFocusableElement = undefined;
|
|
27
24
|
this._focusedToggler = null;
|
|
28
25
|
this._contentRef = createRef();
|
|
29
26
|
this._focusSentinelStart = createRef();
|
|
@@ -31,44 +28,26 @@ let HModal = HModal_1 = class HModal extends PhoenixLightLitElement {
|
|
|
31
28
|
this._propsChangeStrategies = {
|
|
32
29
|
[MODAL_OPENED_PROP]: {
|
|
33
30
|
true: () => {
|
|
34
|
-
const scrollY = window.scrollY;
|
|
35
31
|
HModal_1.openModals = [...HModal_1.openModals, this];
|
|
36
32
|
document.addEventListener('keydown', this._bindCloseOnEsc);
|
|
37
33
|
document.addEventListener(BACKDROP_EVENTS.clicked, this.close);
|
|
38
34
|
this._dispatchModalOpenedEvent();
|
|
39
|
-
|
|
40
|
-
setTimeout(() => {
|
|
41
|
-
var _a;
|
|
42
|
-
(_a = this._firstFocusableElement) === null || _a === void 0 ? void 0 : _a.focus();
|
|
43
|
-
window.scrollTo(0, scrollY);
|
|
44
|
-
}, 0);
|
|
45
|
-
}
|
|
35
|
+
this._focusTrapController.activate();
|
|
46
36
|
},
|
|
47
37
|
false: () => {
|
|
48
38
|
HModal_1.openModals = HModal_1.openModals.filter((modal) => modal !== this);
|
|
49
39
|
document.removeEventListener('keydown', this._bindCloseOnEsc);
|
|
50
40
|
document.removeEventListener(BACKDROP_EVENTS.clicked, this.close);
|
|
41
|
+
this._focusTrapController.deactivate();
|
|
51
42
|
}
|
|
52
43
|
}
|
|
53
44
|
};
|
|
54
45
|
this._backdropController = new BackdropController();
|
|
55
|
-
this.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (document.activeElement === this._firstFocusableElement) {
|
|
61
|
-
const focusableElements = UiDomUtils.getFocusableElements(this._contentRef.value);
|
|
62
|
-
(_a = focusableElements[focusableElements.length - 1]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
63
|
-
ev.preventDefault();
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
else if (document.activeElement === this._lastFocusableElement) {
|
|
67
|
-
UiDomUtils.setFocusToFirstFocusableElementInContainer(this._contentRef.value);
|
|
68
|
-
ev.preventDefault();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
};
|
|
46
|
+
this._focusTrapController = new FocusTrapController({
|
|
47
|
+
host: this,
|
|
48
|
+
getContainer: () => this._contentRef.value,
|
|
49
|
+
noAutofocus: this.noAutofocus
|
|
50
|
+
});
|
|
72
51
|
this._handleCloseFromCloseComponent = async (ev) => {
|
|
73
52
|
var _a;
|
|
74
53
|
ev.stopPropagation();
|
|
@@ -129,7 +108,6 @@ let HModal = HModal_1 = class HModal extends PhoenixLightLitElement {
|
|
|
129
108
|
});
|
|
130
109
|
};
|
|
131
110
|
this.hidden = true;
|
|
132
|
-
this._focusableElements = [...this.querySelectorAll(FOCUSABLE_ELEMENTS_WITHIN_MODAL)];
|
|
133
111
|
}
|
|
134
112
|
static _appendModalsPortal() {
|
|
135
113
|
const $modalsPortalTarget = document.querySelector(`h-portal-target[name="${MODALS_PORTAL_NAME}"]`);
|
|
@@ -145,7 +123,6 @@ let HModal = HModal_1 = class HModal extends PhoenixLightLitElement {
|
|
|
145
123
|
connectedCallback() {
|
|
146
124
|
super.connectedCallback();
|
|
147
125
|
HModal_1._appendModalsPortal();
|
|
148
|
-
document.addEventListener('keyup', this._keepFocusWithinModal);
|
|
149
126
|
document.addEventListener(MODAL_EVENTS.close, this._handleCloseFromCloseComponent);
|
|
150
127
|
}
|
|
151
128
|
disconnectedCallback() {
|
|
@@ -154,29 +131,18 @@ let HModal = HModal_1 = class HModal extends PhoenixLightLitElement {
|
|
|
154
131
|
this.close();
|
|
155
132
|
document.removeEventListener(MODAL_EVENTS.close, this._handleCloseFromCloseComponent);
|
|
156
133
|
document.removeEventListener('keydown', this._bindCloseOnEsc);
|
|
157
|
-
document.removeEventListener('keyup', this._keepFocusWithinModal);
|
|
158
134
|
}
|
|
159
135
|
firstUpdated(props) {
|
|
160
136
|
super.firstUpdated(props);
|
|
161
|
-
this.
|
|
162
|
-
this._lastFocusableElement = this._focusSentinelEnd.value;
|
|
137
|
+
this._focusTrapController.setSentinels(this._focusSentinelStart.value, this._focusSentinelEnd.value);
|
|
163
138
|
}
|
|
164
139
|
updated(changedProps) {
|
|
165
140
|
if (changedProps.has(MODAL_OPENED_PROP)) {
|
|
166
141
|
this._propsChangeStrategies[MODAL_OPENED_PROP][String(this[MODAL_OPENED_PROP])]();
|
|
167
142
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
return;
|
|
172
|
-
requestAnimationFrame(() => {
|
|
173
|
-
if (this._contentRef.value) {
|
|
174
|
-
const focusableElements = UiDomUtils.getFocusableElements(this._contentRef.value);
|
|
175
|
-
if (focusableElements.length > 0) {
|
|
176
|
-
focusableElements.length > 1 ? focusableElements[1].focus() : focusableElements[0].focus();
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
});
|
|
143
|
+
if (changedProps.has('noAutofocus')) {
|
|
144
|
+
this._focusTrapController.noAutofocus = this.noAutofocus;
|
|
145
|
+
}
|
|
180
146
|
}
|
|
181
147
|
async open() {
|
|
182
148
|
this._focusedToggler = document.activeElement;
|
|
@@ -193,7 +159,7 @@ let HModal = HModal_1 = class HModal extends PhoenixLightLitElement {
|
|
|
193
159
|
setTimeout(() => {
|
|
194
160
|
var _a;
|
|
195
161
|
(_a = this._contentRef.value) === null || _a === void 0 ? void 0 : _a.classList.remove(`modal_show-${this.transition}-start`, `modal_show-${this.transition}-end`);
|
|
196
|
-
this.
|
|
162
|
+
this._focusTrapController.focusFirst();
|
|
197
163
|
resolve();
|
|
198
164
|
}, transitionDuration);
|
|
199
165
|
});
|
|
@@ -252,18 +218,6 @@ __decorate([
|
|
|
252
218
|
property({ type: Boolean, attribute: 'no-autofocus' }),
|
|
253
219
|
__metadata("design:type", Object)
|
|
254
220
|
], HModal.prototype, "noAutofocus", void 0);
|
|
255
|
-
__decorate([
|
|
256
|
-
state(),
|
|
257
|
-
__metadata("design:type", Object)
|
|
258
|
-
], HModal.prototype, "_firstFocusableElement", void 0);
|
|
259
|
-
__decorate([
|
|
260
|
-
state(),
|
|
261
|
-
__metadata("design:type", Object)
|
|
262
|
-
], HModal.prototype, "_focusableElements", void 0);
|
|
263
|
-
__decorate([
|
|
264
|
-
state(),
|
|
265
|
-
__metadata("design:type", Object)
|
|
266
|
-
], HModal.prototype, "_lastFocusableElement", void 0);
|
|
267
221
|
HModal = HModal_1 = __decorate([
|
|
268
222
|
phoenixCustomElement('h-modal'),
|
|
269
223
|
__metadata("design:paramtypes", [])
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA,uCAAuC,4CAAgD;AACvF;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;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;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;
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA,uCAAuC,4CAAgD;AACvF;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;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;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;"}
|
|
@@ -5,8 +5,7 @@ const MODAL_EVENTS = {
|
|
|
5
5
|
opened: 'opened',
|
|
6
6
|
closed: 'closed'
|
|
7
7
|
};
|
|
8
|
-
const MODAL_OPENED_PROP = 'opened';
|
|
9
|
-
const FOCUSABLE_ELEMENTS_WITHIN_MODAL = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
|
|
8
|
+
const MODAL_OPENED_PROP = 'opened';
|
|
10
9
|
|
|
11
|
-
export {
|
|
10
|
+
export { MODALS_PORTAL_NAME, MODAL_EVENTS, MODAL_OPENED_PROP };
|
|
12
11
|
//# sourceMappingURL=modal_constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;"}
|
|
@@ -6,9 +6,6 @@ export declare class HSheet extends PhoenixLightLitElement {
|
|
|
6
6
|
class: string;
|
|
7
7
|
transition: string;
|
|
8
8
|
sheetLabel: string;
|
|
9
|
-
_firstFocusableElement: HTMLElement | undefined;
|
|
10
|
-
_focusableElements: HTMLElement[] | null;
|
|
11
|
-
_lastFocusableElement: HTMLElement | undefined;
|
|
12
9
|
private _focusedToggler;
|
|
13
10
|
private _contentRef;
|
|
14
11
|
private _focusSentinelStart;
|
|
@@ -16,6 +13,7 @@ export declare class HSheet extends PhoenixLightLitElement {
|
|
|
16
13
|
private _propsChangeStrategies;
|
|
17
14
|
private static openSheets;
|
|
18
15
|
private _backdropController;
|
|
16
|
+
private _focusTrapController;
|
|
19
17
|
private static _appendSheetPortal;
|
|
20
18
|
static isSomeSheetOpen(): boolean;
|
|
21
19
|
constructor();
|
|
@@ -23,8 +21,6 @@ export declare class HSheet extends PhoenixLightLitElement {
|
|
|
23
21
|
disconnectedCallback(): void;
|
|
24
22
|
firstUpdated(props: PropertyValues): void;
|
|
25
23
|
updated(changedProps: Map<string, any>): void;
|
|
26
|
-
private _setFocusToFirstFocusableElementInSheetOrCloseBtn;
|
|
27
|
-
private _keepFocusWithinSheet;
|
|
28
24
|
private _handleCloseFromCloseComponent;
|
|
29
25
|
private _bindCloseOnEsc;
|
|
30
26
|
open(): Promise<void>;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { __decorate, __metadata } from '../../../../../external/tslib/tslib.es6.js';
|
|
2
|
-
import { UiDomUtils } from '@dreamcommerce/utilities';
|
|
3
2
|
import { PhoenixLightLitElement } from '../../core/phoenix_light_lit_element/phoenix_light_lit_element.js';
|
|
4
3
|
import { phoenixCustomElement } from '../../core/decorators/phoenix_custom_element.js';
|
|
5
|
-
import { property
|
|
4
|
+
import { property } from '@lit/reactive-element/decorators.js';
|
|
6
5
|
import '@lit/reactive-element';
|
|
7
6
|
import { html } from 'lit-html';
|
|
8
7
|
import { createRef, ref } from 'lit-html/directives/ref.js';
|
|
9
8
|
import { PORTAL_TARGET_COMPONENT_NAME, PORTAL_TARGET_NAME_PROP } from '../portal/portal_constants.js';
|
|
10
9
|
import { BACKDROP_EVENTS } from '../backdrop/backdrop_constants.js';
|
|
11
10
|
import { BackdropController } from '../backdrop/controller/backdrop_controller.js';
|
|
12
|
-
import {
|
|
11
|
+
import { FocusTrapController } from '../../controllers/focus_trap_controller/focus_trap_controller.js';
|
|
12
|
+
import { SHEET_OPENED_PROP, SHEETS_PORTAL_NAME, SHEET_EVENTS } from './sheet_constants.js';
|
|
13
13
|
import { HSheetClose } from './sheet_close.js';
|
|
14
14
|
|
|
15
15
|
var HSheet_1;
|
|
@@ -20,9 +20,6 @@ let HSheet = HSheet_1 = class HSheet extends PhoenixLightLitElement {
|
|
|
20
20
|
this.class = '';
|
|
21
21
|
this.transition = 'scale';
|
|
22
22
|
this.sheetLabel = '';
|
|
23
|
-
this._firstFocusableElement = undefined;
|
|
24
|
-
this._focusableElements = null;
|
|
25
|
-
this._lastFocusableElement = undefined;
|
|
26
23
|
this._focusedToggler = null;
|
|
27
24
|
this._contentRef = createRef();
|
|
28
25
|
this._focusSentinelStart = createRef();
|
|
@@ -30,42 +27,25 @@ let HSheet = HSheet_1 = class HSheet extends PhoenixLightLitElement {
|
|
|
30
27
|
this._propsChangeStrategies = {
|
|
31
28
|
[SHEET_OPENED_PROP]: {
|
|
32
29
|
true: () => {
|
|
33
|
-
const scrollY = window.scrollY;
|
|
34
30
|
HSheet_1.openSheets = [...HSheet_1.openSheets, this];
|
|
35
31
|
document.addEventListener('keydown', this._bindCloseOnEsc);
|
|
36
32
|
document.addEventListener(BACKDROP_EVENTS.clicked, this.close);
|
|
37
33
|
this._dispatchSheetOpenedEvent();
|
|
38
|
-
|
|
39
|
-
var _a;
|
|
40
|
-
(_a = this._firstFocusableElement) === null || _a === void 0 ? void 0 : _a.focus();
|
|
41
|
-
window.scrollTo(0, scrollY);
|
|
42
|
-
}, 0);
|
|
34
|
+
this._focusTrapController.activate();
|
|
43
35
|
},
|
|
44
36
|
false: () => {
|
|
45
37
|
HSheet_1.openSheets = HSheet_1.openSheets.filter((sheet) => sheet !== this);
|
|
46
38
|
document.removeEventListener('keydown', this._bindCloseOnEsc);
|
|
47
39
|
document.removeEventListener(BACKDROP_EVENTS.clicked, this.close);
|
|
40
|
+
this._focusTrapController.deactivate();
|
|
48
41
|
}
|
|
49
42
|
}
|
|
50
43
|
};
|
|
51
44
|
this._backdropController = new BackdropController();
|
|
52
|
-
this.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (ev.shiftKey) {
|
|
57
|
-
if (document.activeElement === this._firstFocusableElement) {
|
|
58
|
-
const focusableElements = UiDomUtils.getFocusableElements(this._contentRef.value);
|
|
59
|
-
(_a = focusableElements[focusableElements.length - 1]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
60
|
-
ev.preventDefault();
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
else if (document.activeElement === this._lastFocusableElement) {
|
|
64
|
-
UiDomUtils.setFocusToFirstFocusableElementInContainer(this._contentRef.value);
|
|
65
|
-
ev.preventDefault();
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
};
|
|
45
|
+
this._focusTrapController = new FocusTrapController({
|
|
46
|
+
host: this,
|
|
47
|
+
getContainer: () => this._contentRef.value
|
|
48
|
+
});
|
|
69
49
|
this._handleCloseFromCloseComponent = async (ev) => {
|
|
70
50
|
var _a;
|
|
71
51
|
ev.stopPropagation();
|
|
@@ -126,7 +106,6 @@ let HSheet = HSheet_1 = class HSheet extends PhoenixLightLitElement {
|
|
|
126
106
|
});
|
|
127
107
|
};
|
|
128
108
|
this.hidden = true;
|
|
129
|
-
this._focusableElements = [...this.querySelectorAll(FOCUSABLE_ELEMENTS_WITHIN_SHEET)];
|
|
130
109
|
}
|
|
131
110
|
static _appendSheetPortal() {
|
|
132
111
|
const $modalsPortalTarget = document.querySelector(`h-portal-target[name="${SHEETS_PORTAL_NAME}"]`);
|
|
@@ -142,7 +121,6 @@ let HSheet = HSheet_1 = class HSheet extends PhoenixLightLitElement {
|
|
|
142
121
|
connectedCallback() {
|
|
143
122
|
super.connectedCallback();
|
|
144
123
|
HSheet_1._appendSheetPortal();
|
|
145
|
-
document.addEventListener('keyup', this._keepFocusWithinSheet);
|
|
146
124
|
document.addEventListener(SHEET_EVENTS.close, this._handleCloseFromCloseComponent);
|
|
147
125
|
}
|
|
148
126
|
disconnectedCallback() {
|
|
@@ -151,28 +129,16 @@ let HSheet = HSheet_1 = class HSheet extends PhoenixLightLitElement {
|
|
|
151
129
|
this.close();
|
|
152
130
|
document.removeEventListener(SHEET_EVENTS.close, this._handleCloseFromCloseComponent);
|
|
153
131
|
document.removeEventListener('keydown', this._bindCloseOnEsc);
|
|
154
|
-
document.removeEventListener('keyup', this._keepFocusWithinSheet);
|
|
155
132
|
}
|
|
156
133
|
firstUpdated(props) {
|
|
157
134
|
super.firstUpdated(props);
|
|
158
|
-
this.
|
|
159
|
-
this._lastFocusableElement = this._focusSentinelEnd.value;
|
|
135
|
+
this._focusTrapController.setSentinels(this._focusSentinelStart.value, this._focusSentinelEnd.value);
|
|
160
136
|
}
|
|
161
137
|
updated(changedProps) {
|
|
162
138
|
if (changedProps.has(SHEET_OPENED_PROP)) {
|
|
163
139
|
this._propsChangeStrategies[SHEET_OPENED_PROP][String(this[SHEET_OPENED_PROP])]();
|
|
164
140
|
}
|
|
165
141
|
}
|
|
166
|
-
_setFocusToFirstFocusableElementInSheetOrCloseBtn() {
|
|
167
|
-
requestAnimationFrame(() => {
|
|
168
|
-
if (this._contentRef.value) {
|
|
169
|
-
const focusableElements = UiDomUtils.getFocusableElements(this._contentRef.value);
|
|
170
|
-
if (focusableElements.length > 0) {
|
|
171
|
-
focusableElements.length > 1 ? focusableElements[1].focus() : focusableElements[0].focus();
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
142
|
async open() {
|
|
177
143
|
this._focusedToggler = document.activeElement;
|
|
178
144
|
return new Promise((resolve) => {
|
|
@@ -188,7 +154,7 @@ let HSheet = HSheet_1 = class HSheet extends PhoenixLightLitElement {
|
|
|
188
154
|
setTimeout(() => {
|
|
189
155
|
var _a;
|
|
190
156
|
(_a = this._contentRef.value) === null || _a === void 0 ? void 0 : _a.classList.remove(`sheet_show-${this.transition}-start`, `sheet_show-${this.transition}-end`);
|
|
191
|
-
this.
|
|
157
|
+
this._focusTrapController.focusFirst();
|
|
192
158
|
resolve();
|
|
193
159
|
}, transitionDuration);
|
|
194
160
|
});
|
|
@@ -241,18 +207,6 @@ __decorate([
|
|
|
241
207
|
property({ type: String, attribute: 'sheet-label' }),
|
|
242
208
|
__metadata("design:type", Object)
|
|
243
209
|
], HSheet.prototype, "sheetLabel", void 0);
|
|
244
|
-
__decorate([
|
|
245
|
-
state(),
|
|
246
|
-
__metadata("design:type", Object)
|
|
247
|
-
], HSheet.prototype, "_firstFocusableElement", void 0);
|
|
248
|
-
__decorate([
|
|
249
|
-
state(),
|
|
250
|
-
__metadata("design:type", Object)
|
|
251
|
-
], HSheet.prototype, "_focusableElements", void 0);
|
|
252
|
-
__decorate([
|
|
253
|
-
state(),
|
|
254
|
-
__metadata("design:type", Object)
|
|
255
|
-
], HSheet.prototype, "_lastFocusableElement", void 0);
|
|
256
210
|
HSheet = HSheet_1 = __decorate([
|
|
257
211
|
phoenixCustomElement('h-sheet'),
|
|
258
212
|
__metadata("design:paramtypes", [])
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA,uCAAuC,4CAAgD;AACvF;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;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;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;
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA,uCAAuC,4CAAgD;AACvF;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;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;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;"}
|
|
@@ -5,8 +5,7 @@ const SHEET_EVENTS = {
|
|
|
5
5
|
opened: 'opened',
|
|
6
6
|
closed: 'closed'
|
|
7
7
|
};
|
|
8
|
-
const SHEET_OPENED_PROP = 'opened';
|
|
9
|
-
const FOCUSABLE_ELEMENTS_WITHIN_SHEET = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
|
|
8
|
+
const SHEET_OPENED_PROP = 'opened';
|
|
10
9
|
|
|
11
|
-
export {
|
|
10
|
+
export { SHEETS_PORTAL_NAME, SHEET_EVENTS, SHEET_OPENED_PROP };
|
|
12
11
|
//# sourceMappingURL=sheet_constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;"}
|
package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ReactiveController } from 'lit';
|
|
2
|
+
import { TFocusTrapControllerProps } from './focus_trap_controller_types';
|
|
3
|
+
export declare class FocusTrapController implements ReactiveController {
|
|
4
|
+
#private;
|
|
5
|
+
noAutofocus: boolean;
|
|
6
|
+
constructor({ host, getContainer, noAutofocus, getToggler, cyclicKeydown }: TFocusTrapControllerProps);
|
|
7
|
+
hostConnected(): void;
|
|
8
|
+
hostDisconnected(): void;
|
|
9
|
+
/** Sentinel mode only: call once in firstUpdated with the two bookend elements. */
|
|
10
|
+
setSentinels(start: HTMLElement, end: HTMLElement): void;
|
|
11
|
+
activate(): void;
|
|
12
|
+
deactivate(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Sentinel mode: move focus to the first real interactive element after the
|
|
15
|
+
* open transition completes (skips sentinelStart at index 0).
|
|
16
|
+
*/
|
|
17
|
+
focusFirst(): void;
|
|
18
|
+
private _getFocusableElements;
|
|
19
|
+
getFocusableElements(container: HTMLElement): HTMLElement[];
|
|
20
|
+
private _isElementTrulyFocusable;
|
|
21
|
+
private _handleSentinelModeKeyUp;
|
|
22
|
+
private _handleCyclicKeyDown;
|
|
23
|
+
private _handleTogglerModeKeyDown;
|
|
24
|
+
}
|
package/build/esm/packages/phoenix/src/controllers/focus_trap_controller/focus_trap_controller.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { __classPrivateFieldGet, __classPrivateFieldSet } from '../../../../../external/tslib/tslib.es6.js';
|
|
2
|
+
import 'lit';
|
|
3
|
+
import { UiDomUtils } from '@dreamcommerce/utilities';
|
|
4
|
+
|
|
5
|
+
var _FocusTrapController_getContainer, _FocusTrapController_getToggler, _FocusTrapController_cyclicKeydown, _FocusTrapController_active, _FocusTrapController_sentinelStart, _FocusTrapController_sentinelEnd;
|
|
6
|
+
class FocusTrapController {
|
|
7
|
+
constructor({ host, getContainer, noAutofocus = false, getToggler, cyclicKeydown = false }) {
|
|
8
|
+
_FocusTrapController_getContainer.set(this, void 0);
|
|
9
|
+
_FocusTrapController_getToggler.set(this, void 0);
|
|
10
|
+
_FocusTrapController_cyclicKeydown.set(this, void 0);
|
|
11
|
+
_FocusTrapController_active.set(this, false);
|
|
12
|
+
_FocusTrapController_sentinelStart.set(this, void 0);
|
|
13
|
+
_FocusTrapController_sentinelEnd.set(this, void 0);
|
|
14
|
+
// ─── Sentinel mode ───────────────────────────────────────────────────────
|
|
15
|
+
this._handleSentinelModeKeyUp = (ev) => {
|
|
16
|
+
var _a;
|
|
17
|
+
if (!__classPrivateFieldGet(this, _FocusTrapController_active, "f") || ev.code !== 'Tab')
|
|
18
|
+
return;
|
|
19
|
+
const container = __classPrivateFieldGet(this, _FocusTrapController_getContainer, "f").call(this);
|
|
20
|
+
if (!container)
|
|
21
|
+
return;
|
|
22
|
+
if (ev.shiftKey) {
|
|
23
|
+
if (document.activeElement === __classPrivateFieldGet(this, _FocusTrapController_sentinelStart, "f")) {
|
|
24
|
+
const focusableElements = this._getFocusableElements(container);
|
|
25
|
+
(_a = focusableElements[focusableElements.length - 1]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
26
|
+
ev.preventDefault();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else if (document.activeElement === __classPrivateFieldGet(this, _FocusTrapController_sentinelEnd, "f")) {
|
|
30
|
+
UiDomUtils.setFocusToFirstFocusableElementInContainer(container);
|
|
31
|
+
ev.preventDefault();
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
// ─── Cyclic keydown mode ─────────────────────────────────────────────────
|
|
35
|
+
//
|
|
36
|
+
// No sentinel elements. Tab past the last focusable element wraps to the
|
|
37
|
+
// first; Shift+Tab past the first wraps to the last. Uses keydown +
|
|
38
|
+
// preventDefault so the browser never moves focus outside the container.
|
|
39
|
+
this._handleCyclicKeyDown = (ev) => {
|
|
40
|
+
if (!__classPrivateFieldGet(this, _FocusTrapController_active, "f") || ev.code !== 'Tab')
|
|
41
|
+
return;
|
|
42
|
+
const container = __classPrivateFieldGet(this, _FocusTrapController_getContainer, "f").call(this);
|
|
43
|
+
if (!container)
|
|
44
|
+
return;
|
|
45
|
+
const focusableElements = this._getFocusableElements(container);
|
|
46
|
+
if (focusableElements.length === 0)
|
|
47
|
+
return;
|
|
48
|
+
const $target = ev.target;
|
|
49
|
+
if (ev.shiftKey) {
|
|
50
|
+
if ($target === focusableElements[0]) {
|
|
51
|
+
ev.preventDefault();
|
|
52
|
+
focusableElements[focusableElements.length - 1].focus();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if ($target === focusableElements[focusableElements.length - 1]) {
|
|
57
|
+
ev.preventDefault();
|
|
58
|
+
focusableElements[0].focus();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
// ─── Toggler mode ────────────────────────────────────────────────────────
|
|
63
|
+
//
|
|
64
|
+
// Cycle: toggler → content[0] → … → content[last] → toggler (and reverse).
|
|
65
|
+
// Uses keydown + preventDefault so the browser never moves focus on its own.
|
|
66
|
+
this._handleTogglerModeKeyDown = (ev) => {
|
|
67
|
+
var _a;
|
|
68
|
+
if (!__classPrivateFieldGet(this, _FocusTrapController_active, "f") || ev.code !== 'Tab')
|
|
69
|
+
return;
|
|
70
|
+
const container = __classPrivateFieldGet(this, _FocusTrapController_getContainer, "f").call(this);
|
|
71
|
+
const toggler = (_a = __classPrivateFieldGet(this, _FocusTrapController_getToggler, "f")) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
72
|
+
if (!container || !toggler)
|
|
73
|
+
return;
|
|
74
|
+
const $target = ev.target;
|
|
75
|
+
const focusableElements = this._getFocusableElements(container);
|
|
76
|
+
if (ev.shiftKey) {
|
|
77
|
+
// Shift+Tab on toggler → last content element
|
|
78
|
+
if (toggler.contains($target)) {
|
|
79
|
+
const last = focusableElements[focusableElements.length - 1];
|
|
80
|
+
if (!last)
|
|
81
|
+
return;
|
|
82
|
+
ev.preventDefault();
|
|
83
|
+
last.focus();
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// Shift+Tab on first content element → toggler
|
|
87
|
+
if ($target === focusableElements[0]) {
|
|
88
|
+
ev.preventDefault();
|
|
89
|
+
toggler.focus();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// Tab on toggler → first content element
|
|
94
|
+
if (toggler.contains($target)) {
|
|
95
|
+
const first = focusableElements[0];
|
|
96
|
+
if (!first)
|
|
97
|
+
return;
|
|
98
|
+
ev.preventDefault();
|
|
99
|
+
first.focus();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// Tab on last content element → toggler
|
|
103
|
+
if ($target === focusableElements[focusableElements.length - 1]) {
|
|
104
|
+
ev.preventDefault();
|
|
105
|
+
toggler.focus();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
__classPrivateFieldSet(this, _FocusTrapController_getContainer, getContainer, "f");
|
|
110
|
+
__classPrivateFieldSet(this, _FocusTrapController_getToggler, getToggler, "f");
|
|
111
|
+
__classPrivateFieldSet(this, _FocusTrapController_cyclicKeydown, cyclicKeydown, "f");
|
|
112
|
+
this.noAutofocus = noAutofocus;
|
|
113
|
+
host.addController(this);
|
|
114
|
+
}
|
|
115
|
+
hostConnected() {
|
|
116
|
+
if (__classPrivateFieldGet(this, _FocusTrapController_cyclicKeydown, "f")) {
|
|
117
|
+
document.addEventListener('keydown', this._handleCyclicKeyDown);
|
|
118
|
+
}
|
|
119
|
+
else if (__classPrivateFieldGet(this, _FocusTrapController_getToggler, "f")) {
|
|
120
|
+
document.addEventListener('keydown', this._handleTogglerModeKeyDown);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
document.addEventListener('keyup', this._handleSentinelModeKeyUp);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
hostDisconnected() {
|
|
127
|
+
if (__classPrivateFieldGet(this, _FocusTrapController_cyclicKeydown, "f")) {
|
|
128
|
+
document.removeEventListener('keydown', this._handleCyclicKeyDown);
|
|
129
|
+
}
|
|
130
|
+
else if (__classPrivateFieldGet(this, _FocusTrapController_getToggler, "f")) {
|
|
131
|
+
document.removeEventListener('keydown', this._handleTogglerModeKeyDown);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
document.removeEventListener('keyup', this._handleSentinelModeKeyUp);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/** Sentinel mode only: call once in firstUpdated with the two bookend elements. */
|
|
138
|
+
setSentinels(start, end) {
|
|
139
|
+
__classPrivateFieldSet(this, _FocusTrapController_sentinelStart, start, "f");
|
|
140
|
+
__classPrivateFieldSet(this, _FocusTrapController_sentinelEnd, end, "f");
|
|
141
|
+
}
|
|
142
|
+
activate() {
|
|
143
|
+
__classPrivateFieldSet(this, _FocusTrapController_active, true, "f");
|
|
144
|
+
// Sentinel mode: move focus to sentinelStart to prime the trap.
|
|
145
|
+
if (!__classPrivateFieldGet(this, _FocusTrapController_getToggler, "f") && !this.noAutofocus) {
|
|
146
|
+
const scrollY = window.scrollY;
|
|
147
|
+
setTimeout(() => {
|
|
148
|
+
var _a;
|
|
149
|
+
(_a = __classPrivateFieldGet(this, _FocusTrapController_sentinelStart, "f")) === null || _a === void 0 ? void 0 : _a.focus();
|
|
150
|
+
window.scrollTo(0, scrollY);
|
|
151
|
+
}, 0);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
deactivate() {
|
|
155
|
+
__classPrivateFieldSet(this, _FocusTrapController_active, false, "f");
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Sentinel mode: move focus to the first real interactive element after the
|
|
159
|
+
* open transition completes (skips sentinelStart at index 0).
|
|
160
|
+
*/
|
|
161
|
+
focusFirst() {
|
|
162
|
+
if (this.noAutofocus)
|
|
163
|
+
return;
|
|
164
|
+
requestAnimationFrame(() => {
|
|
165
|
+
const container = __classPrivateFieldGet(this, _FocusTrapController_getContainer, "f").call(this);
|
|
166
|
+
if (!container)
|
|
167
|
+
return;
|
|
168
|
+
const focusableElements = this._getFocusableElements(container);
|
|
169
|
+
if (focusableElements.length > 0) {
|
|
170
|
+
focusableElements.length > 1 ? focusableElements[1].focus() : focusableElements[0].focus();
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
_getFocusableElements(container) {
|
|
175
|
+
return UiDomUtils.getFocusableElements(container).filter(($el) => this._isElementTrulyFocusable($el));
|
|
176
|
+
}
|
|
177
|
+
getFocusableElements(container) {
|
|
178
|
+
return this._getFocusableElements(container);
|
|
179
|
+
}
|
|
180
|
+
_isElementTrulyFocusable($el) {
|
|
181
|
+
const style = window.getComputedStyle($el);
|
|
182
|
+
if (style.display === 'none' || style.visibility === 'hidden') {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
if ($el.nodeName === 'H-PORTAL')
|
|
186
|
+
return true;
|
|
187
|
+
const $parent = $el.parentElement;
|
|
188
|
+
if (!$parent)
|
|
189
|
+
return true;
|
|
190
|
+
return this._isElementTrulyFocusable($parent);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
_FocusTrapController_getContainer = new WeakMap(), _FocusTrapController_getToggler = new WeakMap(), _FocusTrapController_cyclicKeydown = new WeakMap(), _FocusTrapController_active = new WeakMap(), _FocusTrapController_sentinelStart = new WeakMap(), _FocusTrapController_sentinelEnd = new WeakMap();
|
|
194
|
+
|
|
195
|
+
export { FocusTrapController };
|
|
196
|
+
//# sourceMappingURL=focus_trap_controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA,+DAA+D,4CAAgD;AAC/G;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;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;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,14 @@
|
|
|
1
|
+
import { ReactiveControllerHost } from 'lit';
|
|
2
|
+
export declare type TFocusTrapControllerProps = {
|
|
3
|
+
host: ReactiveControllerHost & HTMLElement;
|
|
4
|
+
getContainer: () => HTMLElement | undefined;
|
|
5
|
+
noAutofocus?: boolean;
|
|
6
|
+
/** When provided, enables toggler mode: focus cycles between the toggler and the container's focusable elements. */
|
|
7
|
+
getToggler?: () => HTMLElement | null | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* When true, enables cyclic keydown mode: Tab past the last focusable element wraps to the
|
|
10
|
+
* first, and Shift+Tab past the first wraps to the last. No sentinel DOM elements required.
|
|
11
|
+
* Use this when the host element is not portaled and `inert` is not applied to background content.
|
|
12
|
+
*/
|
|
13
|
+
cyclicKeydown?: boolean;
|
|
14
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus_trap_controller_types.js","sourceRoot":"","sources":["../../../../../../../src/controllers/focus_trap_controller/focus_trap_controller_types.ts"],"names":[],"mappings":"AAAA,OAAuC,KAAK,CAAC"}
|