mtrl 0.8.0-next.38 → 0.8.0-next.39
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/components/drawer/config.js +2 -3
- package/dist/components/drawer/features/headline.js +3 -0
- package/dist/components/drawer/features/items.js +19 -42
- package/dist/components/drawer/features/state.d.ts +1 -9
- package/dist/components/drawer/features/state.js +143 -68
- package/dist/index.cjs +12 -12
- package/dist/package.json +1 -1
- package/dist/styles/badge.css +1 -1
- package/dist/styles/base.css +1 -1
- package/dist/styles/bottom-app-bar.css +1 -1
- package/dist/styles/bottom-sheet.css +1 -1
- package/dist/styles/button-group.css +1 -1
- package/dist/styles/button.css +1 -1
- package/dist/styles/card.css +1 -1
- package/dist/styles/carousel.css +1 -1
- package/dist/styles/checkbox.css +1 -1
- package/dist/styles/chips.css +1 -1
- package/dist/styles/dialog.css +1 -1
- package/dist/styles/divider.css +1 -1
- package/dist/styles/drawer.css +2 -2
- package/dist/styles/extended-fab.css +1 -1
- package/dist/styles/fab.css +1 -1
- package/dist/styles/icon-button.css +1 -1
- package/dist/styles/list.css +1 -1
- package/dist/styles/loading-indicator.css +1 -1
- package/dist/styles/menu.css +1 -1
- package/dist/styles/navigation.css +1 -1
- package/dist/styles/progress.css +1 -1
- package/dist/styles/radios.css +1 -1
- package/dist/styles/search.css +1 -1
- package/dist/styles/segmented-button.css +1 -1
- package/dist/styles/select.css +1 -1
- package/dist/styles/side-sheet.css +1 -1
- package/dist/styles/slider.css +1 -1
- package/dist/styles/snackbar.css +1 -1
- package/dist/styles/split-button.css +1 -1
- package/dist/styles/switch.css +1 -1
- package/dist/styles/tabs.css +1 -1
- package/dist/styles/textfield.css +1 -1
- package/dist/styles/timepicker.css +1 -1
- package/dist/styles/top-app-bar.css +1 -1
- package/dist/styles/utilities.css +1 -1
- package/dist/styles.css +2 -2
- package/dist/themes/autumn.css +1 -1
- package/dist/themes/baseline.css +1 -1
- package/dist/themes/brownbeige.css +1 -1
- package/dist/themes/browngreen.css +1 -1
- package/dist/themes/desert.css +1 -1
- package/dist/themes/forest.css +1 -1
- package/dist/themes/highcontrast.css +1 -1
- package/dist/themes/legacy.css +1 -1
- package/dist/themes/material.css +1 -1
- package/dist/themes/ocean.css +1 -1
- package/dist/themes/sageivory.css +1 -1
- package/dist/themes/spring.css +1 -1
- package/dist/themes/summer.css +1 -1
- package/dist/themes/sunset.css +1 -1
- package/dist/themes/tealcaramel.css +1 -1
- package/dist/themes/winter.css +1 -1
- package/package.json +2 -1
- package/src/styles/components/_drawer.scss +5 -1
- package/src/styles/components/_slider.scss +7 -6
|
@@ -19,9 +19,8 @@ export const getElementConfig = (config) => {
|
|
|
19
19
|
else {
|
|
20
20
|
attributes.role = "navigation";
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
22
|
+
attributes["aria-label"] = config.ariaLabel || config.headline || "Navigation";
|
|
23
|
+
attributes.tabindex = "-1";
|
|
25
24
|
return createElementConfig(config, {
|
|
26
25
|
tag: "aside",
|
|
27
26
|
attributes,
|
|
@@ -8,12 +8,15 @@ export const withHeadline = (config) => (component) => {
|
|
|
8
8
|
}
|
|
9
9
|
const setHeadline = (text) => {
|
|
10
10
|
headlineText = text;
|
|
11
|
+
if (!config.ariaLabel)
|
|
12
|
+
component.element.setAttribute("aria-label", text || "Navigation");
|
|
11
13
|
if (text) {
|
|
12
14
|
if (!headlineElement) {
|
|
13
15
|
headlineElement = document.createElement("div");
|
|
14
16
|
headlineElement.className = component.getClass("drawer__headline");
|
|
15
17
|
}
|
|
16
18
|
headlineElement.textContent = text;
|
|
19
|
+
component.element.querySelector(`.${component.getClass("drawer__sheet")}`)?.prepend(headlineElement);
|
|
17
20
|
}
|
|
18
21
|
else if (headlineElement && headlineElement.parentNode) {
|
|
19
22
|
headlineElement.parentNode.removeChild(headlineElement);
|
|
@@ -2,8 +2,8 @@ import { DRAWER_EVENTS } from "../constants.js";
|
|
|
2
2
|
const createItemElement = (item, getClass) => {
|
|
3
3
|
const el = document.createElement("button");
|
|
4
4
|
el.className = getClass("drawer__item");
|
|
5
|
-
el.
|
|
6
|
-
el.setAttribute("tabindex", "-1");
|
|
5
|
+
el.type = "button";
|
|
6
|
+
el.setAttribute("tabindex", item.disabled ? "-1" : "0");
|
|
7
7
|
if (item.id) {
|
|
8
8
|
el.dataset.id = item.id;
|
|
9
9
|
}
|
|
@@ -18,6 +18,7 @@ const createItemElement = (item, getClass) => {
|
|
|
18
18
|
const iconEl = document.createElement("span");
|
|
19
19
|
iconEl.className = getClass("drawer__item-icon");
|
|
20
20
|
iconEl.innerHTML = item.icon;
|
|
21
|
+
iconEl.setAttribute("aria-hidden", "true");
|
|
21
22
|
el.appendChild(iconEl);
|
|
22
23
|
}
|
|
23
24
|
if (item.label) {
|
|
@@ -34,11 +35,7 @@ const createItemElement = (item, getClass) => {
|
|
|
34
35
|
}
|
|
35
36
|
if (item.active) {
|
|
36
37
|
el.classList.add(`${getClass("drawer__item")}--active`);
|
|
37
|
-
el.setAttribute("aria-
|
|
38
|
-
el.setAttribute("tabindex", "0");
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
el.setAttribute("aria-selected", "false");
|
|
38
|
+
el.setAttribute("aria-current", "page");
|
|
42
39
|
}
|
|
43
40
|
return el;
|
|
44
41
|
};
|
|
@@ -58,7 +55,7 @@ export const withItems = (config) => (component) => {
|
|
|
58
55
|
let currentItems = config.items || [];
|
|
59
56
|
let activeId = null;
|
|
60
57
|
let itemsContainer = null;
|
|
61
|
-
const initialActive = currentItems.find((item) => item.type !== "divider" && item.type !== "section" && item.active);
|
|
58
|
+
const initialActive = currentItems.find((item) => item.type !== "divider" && item.type !== "section" && item.active && !item.disabled);
|
|
62
59
|
if (initialActive?.id) {
|
|
63
60
|
activeId = initialActive.id;
|
|
64
61
|
}
|
|
@@ -77,7 +74,7 @@ export const withItems = (config) => (component) => {
|
|
|
77
74
|
itemsContainer.appendChild(createSectionElement(item, component.getClass));
|
|
78
75
|
return;
|
|
79
76
|
}
|
|
80
|
-
const itemEl = createItemElement(item, component.getClass);
|
|
77
|
+
const itemEl = createItemElement({ ...item, active: !!activeId && item.id === activeId }, component.getClass);
|
|
81
78
|
itemEl.dataset.navIndex = String(navIndex);
|
|
82
79
|
navIndex++;
|
|
83
80
|
itemEl.addEventListener("click", (e) => {
|
|
@@ -97,39 +94,23 @@ export const withItems = (config) => (component) => {
|
|
|
97
94
|
});
|
|
98
95
|
itemsContainer.appendChild(itemEl);
|
|
99
96
|
});
|
|
100
|
-
if (!activeId) {
|
|
101
|
-
const firstItem = itemsContainer.querySelector(`.${component.getClass("drawer__item")}`);
|
|
102
|
-
if (firstItem) {
|
|
103
|
-
firstItem.setAttribute("tabindex", "0");
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
97
|
};
|
|
107
98
|
const setActive = (id) => {
|
|
108
99
|
if (!itemsContainer)
|
|
109
100
|
return;
|
|
110
101
|
const activeClass = `${component.getClass("drawer__item")}--active`;
|
|
111
|
-
const allItems = itemsContainer.querySelectorAll(`.${component.getClass("drawer__item")}`);
|
|
112
|
-
allItems.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
102
|
+
const allItems = [...itemsContainer.querySelectorAll(`.${component.getClass("drawer__item")}`)];
|
|
103
|
+
const target = allItems.find(element => element.dataset.id === id && !element.hasAttribute("disabled"));
|
|
104
|
+
if (id && !target)
|
|
105
|
+
return;
|
|
106
|
+
allItems.forEach(element => {
|
|
107
|
+
element.classList.toggle(activeClass, element === target);
|
|
108
|
+
if (element === target)
|
|
109
|
+
element.setAttribute("aria-current", "page");
|
|
110
|
+
else
|
|
111
|
+
element.removeAttribute("aria-current");
|
|
116
112
|
});
|
|
117
|
-
|
|
118
|
-
activeId = null;
|
|
119
|
-
const firstItem = itemsContainer.querySelector(`.${component.getClass("drawer__item")}`);
|
|
120
|
-
if (firstItem) {
|
|
121
|
-
firstItem.setAttribute("tabindex", "0");
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
const targetItem = itemsContainer.querySelector(`[data-id="${id}"]`);
|
|
126
|
-
if (targetItem) {
|
|
127
|
-
targetItem.classList.add(activeClass);
|
|
128
|
-
targetItem.setAttribute("aria-selected", "true");
|
|
129
|
-
targetItem.setAttribute("tabindex", "0");
|
|
130
|
-
activeId = id;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
113
|
+
activeId = target ? id : null;
|
|
133
114
|
currentItems = currentItems.map((item) => ({
|
|
134
115
|
...item,
|
|
135
116
|
active: item.id === id,
|
|
@@ -138,7 +119,7 @@ export const withItems = (config) => (component) => {
|
|
|
138
119
|
const getActive = () => activeId;
|
|
139
120
|
const setItems = (items) => {
|
|
140
121
|
currentItems = items;
|
|
141
|
-
const active = items.find((item) => item.type !== "divider" && item.type !== "section" && item.active);
|
|
122
|
+
const active = items.find((item) => item.type !== "divider" && item.type !== "section" && item.active && !item.disabled);
|
|
142
123
|
activeId = active?.id || null;
|
|
143
124
|
renderItems();
|
|
144
125
|
};
|
|
@@ -146,7 +127,7 @@ export const withItems = (config) => (component) => {
|
|
|
146
127
|
const setBadge = (id, badge) => {
|
|
147
128
|
if (!itemsContainer)
|
|
148
129
|
return;
|
|
149
|
-
const itemEl = itemsContainer.
|
|
130
|
+
const itemEl = [...itemsContainer.querySelectorAll("[data-id]")].find(element => element.dataset.id === id);
|
|
150
131
|
if (!itemEl)
|
|
151
132
|
return;
|
|
152
133
|
let badgeEl = itemEl.querySelector(`.${component.getClass("drawer__item-badge")}`);
|
|
@@ -199,15 +180,11 @@ export const withItems = (config) => (component) => {
|
|
|
199
180
|
return;
|
|
200
181
|
}
|
|
201
182
|
if (nextIndex >= 0 && nextIndex < items.length) {
|
|
202
|
-
items.forEach((item) => item.setAttribute("tabindex", "-1"));
|
|
203
|
-
items[nextIndex].setAttribute("tabindex", "0");
|
|
204
183
|
items[nextIndex].focus();
|
|
205
184
|
}
|
|
206
185
|
};
|
|
207
186
|
itemsContainer = document.createElement("div");
|
|
208
187
|
itemsContainer.className = component.getClass("drawer__items");
|
|
209
|
-
itemsContainer.setAttribute("role", "tablist");
|
|
210
|
-
itemsContainer.setAttribute("aria-orientation", "vertical");
|
|
211
188
|
itemsContainer.addEventListener("keydown", handleKeydown);
|
|
212
189
|
renderItems();
|
|
213
190
|
return {
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import { DrawerConfig } from "../types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Component shape expected by withState
|
|
4
|
-
*/
|
|
5
2
|
interface StateBaseComponent {
|
|
6
3
|
element: HTMLElement;
|
|
7
4
|
getClass: (name: string) => string;
|
|
8
5
|
emit: (event: string, data?: unknown) => void;
|
|
9
6
|
[key: string]: unknown;
|
|
10
7
|
}
|
|
11
|
-
/**
|
|
12
|
-
* Adds open/close state management, scrim, and keyboard dismiss to the drawer
|
|
13
|
-
*
|
|
14
|
-
* @param config - Drawer configuration
|
|
15
|
-
* @returns Component enhancer function
|
|
16
|
-
*/
|
|
8
|
+
/** Standard drawers remain in the page; modal drawers own focus and background interaction. */
|
|
17
9
|
export declare const withState: (config: DrawerConfig) => (component: StateBaseComponent) => StateBaseComponent;
|
|
18
10
|
export {};
|
|
@@ -1,95 +1,170 @@
|
|
|
1
1
|
import { DRAWER_EVENTS } from "../constants.js";
|
|
2
|
+
const modals = new WeakMap();
|
|
3
|
+
function updateBackground(doc, state) {
|
|
4
|
+
state.inerted.forEach(element => element.removeAttribute("inert"));
|
|
5
|
+
state.inerted = [];
|
|
6
|
+
let branch = state.roots.at(-1);
|
|
7
|
+
while (branch?.parentElement) {
|
|
8
|
+
for (const sibling of branch.parentElement.children) {
|
|
9
|
+
if (sibling !== branch && !sibling.hasAttribute("inert")) {
|
|
10
|
+
sibling.setAttribute("inert", "");
|
|
11
|
+
state.inerted.push(sibling);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
branch = branch.parentElement;
|
|
15
|
+
if (branch === doc.body)
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function acquireModal(root) {
|
|
20
|
+
const doc = root.ownerDocument;
|
|
21
|
+
let state = modals.get(doc);
|
|
22
|
+
if (!state) {
|
|
23
|
+
state = { roots: [], inerted: [], overflow: doc.body.style.overflow, priority: doc.body.style.getPropertyPriority("overflow") };
|
|
24
|
+
modals.set(doc, state);
|
|
25
|
+
doc.body.style.setProperty("overflow", "hidden");
|
|
26
|
+
}
|
|
27
|
+
if (!state.roots.includes(root))
|
|
28
|
+
state.roots.push(root);
|
|
29
|
+
updateBackground(doc, state);
|
|
30
|
+
}
|
|
31
|
+
function releaseModal(root) {
|
|
32
|
+
const doc = root.ownerDocument;
|
|
33
|
+
const state = modals.get(doc);
|
|
34
|
+
if (!state || !state.roots.includes(root))
|
|
35
|
+
return;
|
|
36
|
+
state.roots = state.roots.filter(element => element !== root);
|
|
37
|
+
updateBackground(doc, state);
|
|
38
|
+
if (!state.roots.length) {
|
|
39
|
+
doc.body.style.setProperty("overflow", state.overflow, state.priority);
|
|
40
|
+
modals.delete(doc);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
2
43
|
export const withState = (config) => (component) => {
|
|
44
|
+
const root = component.element;
|
|
45
|
+
const doc = root.ownerDocument;
|
|
3
46
|
const isModal = config.variant === "modal";
|
|
4
47
|
const dismissible = config.dismissible !== false;
|
|
5
48
|
let isOpen = config.open === true;
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
|
|
49
|
+
let destroyed = false;
|
|
50
|
+
let frame = null;
|
|
51
|
+
let previousFocus = null;
|
|
52
|
+
const scrimElement = isModal ? doc.createElement("div") : null;
|
|
53
|
+
if (scrimElement) {
|
|
9
54
|
scrimElement.className = component.getClass("drawer__scrim");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
});
|
|
14
|
-
}
|
|
55
|
+
scrimElement.setAttribute("aria-hidden", "true");
|
|
56
|
+
if (dismissible)
|
|
57
|
+
scrimElement.addEventListener("click", close);
|
|
15
58
|
}
|
|
16
|
-
const
|
|
17
|
-
if (
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
59
|
+
const cancelFocus = () => {
|
|
60
|
+
if (frame !== null)
|
|
61
|
+
cancelAnimationFrame(frame);
|
|
62
|
+
frame = null;
|
|
21
63
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
64
|
+
const focusable = () => [...root.querySelectorAll('button, a[href], input, select, textarea, [tabindex]')].filter(element => {
|
|
65
|
+
const style = doc.defaultView.getComputedStyle(element);
|
|
66
|
+
return element.tabIndex >= 0 && !element.matches(':disabled, [aria-disabled="true"]') && !element.closest('[inert], [hidden]') && style.display !== 'none' && style.visibility !== 'hidden';
|
|
67
|
+
});
|
|
68
|
+
const focusInside = () => {
|
|
69
|
+
const items = focusable();
|
|
70
|
+
(items.find(element => element.getAttribute("aria-current") === "page") || items[0] || root).focus();
|
|
71
|
+
};
|
|
72
|
+
const isTopModal = () => modals.get(doc)?.roots.at(-1) === root;
|
|
73
|
+
function handleKeydown(event) {
|
|
74
|
+
if (!isOpen || !isTopModal() || event.defaultPrevented)
|
|
27
75
|
return;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
scrimElement.classList.add(`${component.getClass("drawer__scrim")}--visible`);
|
|
32
|
-
document.body.style.overflow = "hidden";
|
|
76
|
+
if (event.key === "Escape" && dismissible) {
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
close();
|
|
33
79
|
}
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
80
|
+
else if (event.key === "Tab") {
|
|
81
|
+
const items = focusable();
|
|
82
|
+
const first = items[0], last = items.at(-1);
|
|
83
|
+
if (!first) {
|
|
84
|
+
event.preventDefault();
|
|
85
|
+
root.focus();
|
|
86
|
+
}
|
|
87
|
+
else if (event.shiftKey && (doc.activeElement === first || doc.activeElement === root || !root.contains(doc.activeElement))) {
|
|
88
|
+
event.preventDefault();
|
|
89
|
+
last.focus();
|
|
38
90
|
}
|
|
39
|
-
else {
|
|
40
|
-
|
|
91
|
+
else if (!event.shiftKey && (doc.activeElement === last || doc.activeElement === root || !root.contains(doc.activeElement))) {
|
|
92
|
+
event.preventDefault();
|
|
93
|
+
first.focus();
|
|
41
94
|
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function handleFocus(event) {
|
|
98
|
+
if (isOpen && isTopModal() && !root.contains(event.target))
|
|
99
|
+
focusInside();
|
|
100
|
+
}
|
|
101
|
+
const synchronize = () => {
|
|
102
|
+
root.classList.toggle(`${component.getClass("drawer")}--open`, isOpen);
|
|
103
|
+
root.toggleAttribute("inert", !isOpen);
|
|
104
|
+
root.setAttribute("aria-hidden", String(!isOpen));
|
|
105
|
+
scrimElement?.classList.toggle(`${component.getClass("drawer__scrim")}--visible`, isOpen);
|
|
106
|
+
};
|
|
107
|
+
const activate = () => {
|
|
108
|
+
if (!isModal)
|
|
109
|
+
return;
|
|
110
|
+
previousFocus = doc.activeElement;
|
|
111
|
+
if (root.isConnected)
|
|
112
|
+
acquireModal(root);
|
|
113
|
+
doc.addEventListener("keydown", handleKeydown);
|
|
114
|
+
doc.addEventListener("focusin", handleFocus);
|
|
115
|
+
frame = requestAnimationFrame(() => {
|
|
116
|
+
frame = null;
|
|
117
|
+
if (destroyed || !isOpen || !root.isConnected)
|
|
118
|
+
return;
|
|
119
|
+
acquireModal(root);
|
|
120
|
+
if (isTopModal())
|
|
121
|
+
focusInside();
|
|
42
122
|
});
|
|
123
|
+
};
|
|
124
|
+
const deactivate = () => {
|
|
125
|
+
cancelFocus();
|
|
126
|
+
doc.removeEventListener("keydown", handleKeydown);
|
|
127
|
+
doc.removeEventListener("focusin", handleFocus);
|
|
128
|
+
const restore = isTopModal();
|
|
129
|
+
releaseModal(root);
|
|
130
|
+
if (restore && previousFocus?.isConnected && !previousFocus.closest('[inert]'))
|
|
131
|
+
previousFocus.focus();
|
|
132
|
+
previousFocus = null;
|
|
133
|
+
};
|
|
134
|
+
function open() {
|
|
135
|
+
if (destroyed || isOpen)
|
|
136
|
+
return;
|
|
137
|
+
isOpen = true;
|
|
138
|
+
synchronize();
|
|
139
|
+
activate();
|
|
43
140
|
component.emit(DRAWER_EVENTS.OPEN);
|
|
44
|
-
|
|
45
|
-
config.onOpen();
|
|
46
|
-
}
|
|
141
|
+
config.onOpen?.();
|
|
47
142
|
}
|
|
48
143
|
function close() {
|
|
49
|
-
if (!isOpen)
|
|
144
|
+
if (destroyed || !isOpen)
|
|
50
145
|
return;
|
|
51
146
|
isOpen = false;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
scrimElement.classList.remove(`${component.getClass("drawer__scrim")}--visible`);
|
|
55
|
-
document.body.style.overflow = "";
|
|
56
|
-
}
|
|
147
|
+
deactivate();
|
|
148
|
+
synchronize();
|
|
57
149
|
component.emit(DRAWER_EVENTS.CLOSE);
|
|
58
|
-
|
|
59
|
-
config.onClose();
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function toggle() {
|
|
63
|
-
if (isOpen) {
|
|
64
|
-
close();
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
open();
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
if (isOpen) {
|
|
71
|
-
component.element.classList.add(`${component.getClass("drawer")}--open`);
|
|
72
|
-
if (isModal && scrimElement) {
|
|
73
|
-
scrimElement.classList.add(`${component.getClass("drawer__scrim")}--visible`);
|
|
74
|
-
}
|
|
150
|
+
config.onClose?.();
|
|
75
151
|
}
|
|
152
|
+
synchronize();
|
|
153
|
+
if (isOpen)
|
|
154
|
+
activate();
|
|
76
155
|
return {
|
|
77
156
|
...component,
|
|
78
157
|
scrimElement,
|
|
79
|
-
drawerState: {
|
|
80
|
-
open,
|
|
81
|
-
close,
|
|
82
|
-
toggle,
|
|
83
|
-
isOpen: () => isOpen,
|
|
84
|
-
},
|
|
158
|
+
drawerState: { open, close, toggle: () => isOpen ? close() : open(), isOpen: () => isOpen },
|
|
85
159
|
_stateCleanup: () => {
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
160
|
+
if (destroyed)
|
|
161
|
+
return;
|
|
162
|
+
destroyed = true;
|
|
163
|
+
isOpen = false;
|
|
164
|
+
deactivate();
|
|
165
|
+
synchronize();
|
|
166
|
+
scrimElement?.removeEventListener("click", close);
|
|
167
|
+
scrimElement?.remove();
|
|
93
168
|
},
|
|
94
169
|
};
|
|
95
170
|
};
|