@lmfaole/basics 0.2.1 → 0.4.0
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/README.md +306 -22
- package/basic-styling/components/basic-accordion.css +65 -0
- package/basic-styling/components/basic-alert.css +27 -0
- package/basic-styling/components/basic-dialog.css +41 -0
- package/basic-styling/components/basic-popover.css +54 -0
- package/basic-styling/components/basic-summary-table.css +76 -0
- package/basic-styling/components/basic-table.css +48 -0
- package/basic-styling/components/basic-tabs.css +45 -0
- package/basic-styling/components/basic-toast.css +102 -0
- package/basic-styling/components/basic-toc.css +30 -0
- package/basic-styling/components.css +9 -0
- package/basic-styling/global.css +61 -0
- package/basic-styling/index.css +2 -0
- package/basic-styling/tokens/base.css +19 -0
- package/basic-styling/tokens/palette.css +117 -0
- package/basic-styling/tokens/palette.tokens.json +1019 -0
- package/components/basic-accordion/index.d.ts +5 -5
- package/components/basic-accordion/index.js +169 -165
- package/components/basic-alert/index.d.ts +53 -0
- package/components/basic-alert/index.js +189 -0
- package/components/basic-alert/register.d.ts +1 -0
- package/components/basic-alert/register.js +3 -0
- package/components/basic-dialog/index.js +21 -1
- package/components/basic-summary-table/index.d.ts +69 -0
- package/components/basic-summary-table/index.js +536 -0
- package/components/basic-summary-table/register.d.ts +1 -0
- package/components/basic-summary-table/register.js +3 -0
- package/components/basic-table/index.d.ts +75 -0
- package/components/basic-table/index.js +612 -0
- package/components/basic-table/register.d.ts +1 -0
- package/components/basic-table/register.js +3 -0
- package/components/basic-tabs/index.d.ts +2 -3
- package/components/basic-tabs/index.js +4 -30
- package/components/basic-toast/index.d.ts +65 -0
- package/components/basic-toast/index.js +429 -0
- package/components/basic-toast/register.d.ts +1 -0
- package/components/basic-toast/register.js +3 -0
- package/index.d.ts +4 -0
- package/index.js +4 -0
- package/package.json +28 -41
- package/readme.mdx +1 -1
|
@@ -8,7 +8,6 @@ const DEFAULT_LABEL = "Faner";
|
|
|
8
8
|
const DEFAULT_ACTIVATION = "automatic";
|
|
9
9
|
const DEFAULT_ORIENTATION = "horizontal";
|
|
10
10
|
const MANUAL_ACTIVATION = "manual";
|
|
11
|
-
const VERTICAL_ORIENTATION = "vertical";
|
|
12
11
|
const TABLIST_SELECTOR = "[data-tabs-list]";
|
|
13
12
|
const TAB_SELECTOR = "[data-tab]";
|
|
14
13
|
const PANEL_SELECTOR = "[data-tab-panel]";
|
|
@@ -16,9 +15,7 @@ const PANEL_SELECTOR = "[data-tab-panel]";
|
|
|
16
15
|
let nextTabsInstanceId = 1;
|
|
17
16
|
|
|
18
17
|
export function normalizeTabsOrientation(value) {
|
|
19
|
-
return
|
|
20
|
-
? VERTICAL_ORIENTATION
|
|
21
|
-
: DEFAULT_ORIENTATION;
|
|
18
|
+
return DEFAULT_ORIENTATION;
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
export function normalizeTabsActivation(value) {
|
|
@@ -98,7 +95,6 @@ export class TabsElement extends HTMLElementBase {
|
|
|
98
95
|
static observedAttributes = [
|
|
99
96
|
"data-activation",
|
|
100
97
|
"data-label",
|
|
101
|
-
"data-orientation",
|
|
102
98
|
"data-selected-index",
|
|
103
99
|
];
|
|
104
100
|
|
|
@@ -168,7 +164,6 @@ export class TabsElement extends HTMLElementBase {
|
|
|
168
164
|
const tabStates = this.#getTabStates();
|
|
169
165
|
const currentIndex = this.#tabs.indexOf(currentTab);
|
|
170
166
|
const activation = this.#getActivation();
|
|
171
|
-
const orientation = this.#getOrientation();
|
|
172
167
|
let nextIndex = -1;
|
|
173
168
|
|
|
174
169
|
if (currentIndex === -1 || currentIndex >= tabStates.length) {
|
|
@@ -177,24 +172,10 @@ export class TabsElement extends HTMLElementBase {
|
|
|
177
172
|
|
|
178
173
|
switch (event.key) {
|
|
179
174
|
case "ArrowRight":
|
|
180
|
-
|
|
181
|
-
nextIndex = findNextEnabledTabIndex(tabStates, currentIndex, 1);
|
|
182
|
-
}
|
|
175
|
+
nextIndex = findNextEnabledTabIndex(tabStates, currentIndex, 1);
|
|
183
176
|
break;
|
|
184
177
|
case "ArrowLeft":
|
|
185
|
-
|
|
186
|
-
nextIndex = findNextEnabledTabIndex(tabStates, currentIndex, -1);
|
|
187
|
-
}
|
|
188
|
-
break;
|
|
189
|
-
case "ArrowDown":
|
|
190
|
-
if (orientation === VERTICAL_ORIENTATION) {
|
|
191
|
-
nextIndex = findNextEnabledTabIndex(tabStates, currentIndex, 1);
|
|
192
|
-
}
|
|
193
|
-
break;
|
|
194
|
-
case "ArrowUp":
|
|
195
|
-
if (orientation === VERTICAL_ORIENTATION) {
|
|
196
|
-
nextIndex = findNextEnabledTabIndex(tabStates, currentIndex, -1);
|
|
197
|
-
}
|
|
178
|
+
nextIndex = findNextEnabledTabIndex(tabStates, currentIndex, -1);
|
|
198
179
|
break;
|
|
199
180
|
case "Home":
|
|
200
181
|
nextIndex = findFirstEnabledTabIndex(tabStates);
|
|
@@ -252,12 +233,6 @@ export class TabsElement extends HTMLElementBase {
|
|
|
252
233
|
return this.getAttribute("data-label")?.trim() || DEFAULT_LABEL;
|
|
253
234
|
}
|
|
254
235
|
|
|
255
|
-
#getOrientation() {
|
|
256
|
-
return normalizeTabsOrientation(
|
|
257
|
-
this.getAttribute("data-orientation") ?? this.#tabList?.getAttribute("aria-orientation"),
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
236
|
#getTabStates(configuredSelectedIndex = null) {
|
|
262
237
|
const pairCount = Math.min(this.#tabs.length, this.#panels.length);
|
|
263
238
|
|
|
@@ -296,7 +271,6 @@ export class TabsElement extends HTMLElementBase {
|
|
|
296
271
|
return;
|
|
297
272
|
}
|
|
298
273
|
|
|
299
|
-
const orientation = this.#getOrientation();
|
|
300
274
|
const pairCount = Math.min(this.#tabs.length, this.#panels.length);
|
|
301
275
|
const baseId = this.id || this.#instanceId;
|
|
302
276
|
|
|
@@ -305,7 +279,7 @@ export class TabsElement extends HTMLElementBase {
|
|
|
305
279
|
}
|
|
306
280
|
|
|
307
281
|
this.#tabList.setAttribute("role", "tablist");
|
|
308
|
-
this.#tabList.setAttribute("aria-orientation",
|
|
282
|
+
this.#tabList.setAttribute("aria-orientation", DEFAULT_ORIENTATION);
|
|
309
283
|
|
|
310
284
|
for (let index = 0; index < this.#tabs.length; index += 1) {
|
|
311
285
|
const tab = this.#tabs[index];
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export const TOAST_TAG_NAME: "basic-toast";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Normalizes unsupported or empty labels back to the default `"Toast"`.
|
|
5
|
+
*/
|
|
6
|
+
export function normalizeToastLabel(
|
|
7
|
+
value?: string | null,
|
|
8
|
+
): string;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Normalizes unsupported live-region values back to `"polite"`.
|
|
12
|
+
*/
|
|
13
|
+
export function normalizeToastLive(
|
|
14
|
+
value?: string | null,
|
|
15
|
+
): "assertive" | "polite";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Maps a toast live setting to the matching ARIA role.
|
|
19
|
+
*/
|
|
20
|
+
export function getToastRoleForLive(
|
|
21
|
+
value?: string | null,
|
|
22
|
+
): "alert" | "status";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Normalizes the optional `data-duration` attribute into milliseconds.
|
|
26
|
+
* A value of `0` disables auto-dismiss.
|
|
27
|
+
*/
|
|
28
|
+
export function normalizeToastDuration(
|
|
29
|
+
value?: string | null,
|
|
30
|
+
): number;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Normalizes the optional `data-open` attribute into a boolean flag.
|
|
34
|
+
*/
|
|
35
|
+
export function normalizeToastOpen(
|
|
36
|
+
value?: string | null,
|
|
37
|
+
): boolean;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Custom element that upgrades trigger-and-panel markup into a toast
|
|
41
|
+
* notification flow with optional auto-dismiss.
|
|
42
|
+
*
|
|
43
|
+
* Attributes:
|
|
44
|
+
* - `data-label`: fallback accessible name when the toast has no title
|
|
45
|
+
* - `data-live`: chooses between `status` and `alert` semantics
|
|
46
|
+
* - `data-duration`: auto-dismiss timeout in milliseconds, `0` disables it
|
|
47
|
+
* - `data-open`: optional initial open state
|
|
48
|
+
*
|
|
49
|
+
* Behavior:
|
|
50
|
+
* - uses the Popover API in manual mode when available so the toast panel can
|
|
51
|
+
* render in the top layer
|
|
52
|
+
*/
|
|
53
|
+
export class ToastElement extends HTMLElement {
|
|
54
|
+
static observedAttributes: string[];
|
|
55
|
+
show(opener?: HTMLElement | null): boolean;
|
|
56
|
+
hide(): boolean;
|
|
57
|
+
toggle(opener?: HTMLElement | null): boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Registers the `basic-toast` custom element if it is not already defined.
|
|
62
|
+
*/
|
|
63
|
+
export function defineToast(
|
|
64
|
+
registry?: CustomElementRegistry,
|
|
65
|
+
): typeof ToastElement;
|
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
const ElementBase = globalThis.Element ?? class {};
|
|
2
|
+
const HTMLElementBase = globalThis.HTMLElement ?? class {};
|
|
3
|
+
const HTMLButtonElementBase = globalThis.HTMLButtonElement ?? class {};
|
|
4
|
+
|
|
5
|
+
export const TOAST_TAG_NAME = "basic-toast";
|
|
6
|
+
|
|
7
|
+
const DEFAULT_DURATION = 5000;
|
|
8
|
+
const DEFAULT_LABEL = "Toast";
|
|
9
|
+
const DEFAULT_LIVE = "polite";
|
|
10
|
+
const PANEL_SELECTOR = "[data-toast-panel]";
|
|
11
|
+
const TITLE_SELECTOR = "[data-toast-title]";
|
|
12
|
+
const OPEN_SELECTOR = "[data-toast-open]";
|
|
13
|
+
const CLOSE_SELECTOR = "[data-toast-close]";
|
|
14
|
+
const MANAGED_LABEL_ATTRIBUTE = "data-basic-toast-managed-label";
|
|
15
|
+
const MANAGED_LABELLEDBY_ATTRIBUTE = "data-basic-toast-managed-labelledby";
|
|
16
|
+
const MANAGED_POPOVER_ATTRIBUTE = "data-basic-toast-managed-popover";
|
|
17
|
+
|
|
18
|
+
let nextToastInstanceId = 1;
|
|
19
|
+
|
|
20
|
+
function collectOwnedElements(root, scope, selector) {
|
|
21
|
+
return Array.from(scope.querySelectorAll(selector)).filter(
|
|
22
|
+
(element) => element instanceof HTMLElementBase && element.closest(TOAST_TAG_NAME) === root,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function supportsToastPopover(panel) {
|
|
27
|
+
return panel instanceof HTMLElementBase
|
|
28
|
+
&& typeof panel.showPopover === "function"
|
|
29
|
+
&& typeof panel.hidePopover === "function";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function isToastPanelOpen(panel) {
|
|
33
|
+
if (!(panel instanceof HTMLElementBase)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
return panel.matches(":popover-open");
|
|
39
|
+
} catch {
|
|
40
|
+
return panel.hasAttribute("data-open") || !panel.hidden;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function normalizeToastLabel(value) {
|
|
45
|
+
return value?.trim() || DEFAULT_LABEL;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function normalizeToastLive(value) {
|
|
49
|
+
const normalized = value?.trim().toLowerCase();
|
|
50
|
+
return normalized === "assertive" ? "assertive" : DEFAULT_LIVE;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function getToastRoleForLive(value) {
|
|
54
|
+
return normalizeToastLive(value) === "assertive" ? "alert" : "status";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function normalizeToastDuration(value) {
|
|
58
|
+
if (value == null || value.trim() === "") {
|
|
59
|
+
return DEFAULT_DURATION;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const parsed = Number.parseInt(value, 10);
|
|
63
|
+
|
|
64
|
+
if (Number.isInteger(parsed) && parsed >= 0) {
|
|
65
|
+
return parsed;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return DEFAULT_DURATION;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function normalizeToastOpen(value) {
|
|
72
|
+
if (value == null) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const normalized = value.trim().toLowerCase();
|
|
77
|
+
return normalized === "" || normalized === "true" || normalized === "1";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export class ToastElement extends HTMLElementBase {
|
|
81
|
+
static observedAttributes = ["data-duration", "data-label", "data-live", "data-open"];
|
|
82
|
+
|
|
83
|
+
#instanceId = `${TOAST_TAG_NAME}-${nextToastInstanceId++}`;
|
|
84
|
+
#panel = null;
|
|
85
|
+
#panelWithEvents = null;
|
|
86
|
+
#title = null;
|
|
87
|
+
#openButtons = [];
|
|
88
|
+
#closeButtons = [];
|
|
89
|
+
#restoreFocusTo = null;
|
|
90
|
+
#dismissTimer = 0;
|
|
91
|
+
#eventsBound = false;
|
|
92
|
+
|
|
93
|
+
connectedCallback() {
|
|
94
|
+
if (!this.#eventsBound) {
|
|
95
|
+
this.addEventListener("click", this.#handleClick);
|
|
96
|
+
this.addEventListener("keydown", this.#handleKeyDown);
|
|
97
|
+
this.#eventsBound = true;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.#sync();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
disconnectedCallback() {
|
|
104
|
+
if (!this.#eventsBound) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.removeEventListener("click", this.#handleClick);
|
|
109
|
+
this.removeEventListener("keydown", this.#handleKeyDown);
|
|
110
|
+
this.#eventsBound = false;
|
|
111
|
+
this.#syncPanelEvents(null);
|
|
112
|
+
this.#clearDismissTimer();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
attributeChangedCallback() {
|
|
116
|
+
this.#sync();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
show(opener = null) {
|
|
120
|
+
this.#sync();
|
|
121
|
+
|
|
122
|
+
if (!(this.#panel instanceof HTMLElementBase)) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const fallbackOpener = opener instanceof HTMLElementBase
|
|
127
|
+
? opener
|
|
128
|
+
: this.ownerDocument?.activeElement instanceof HTMLElementBase
|
|
129
|
+
? this.ownerDocument.activeElement
|
|
130
|
+
: null;
|
|
131
|
+
|
|
132
|
+
this.#restoreFocusTo = fallbackOpener;
|
|
133
|
+
this.toggleAttribute("data-open", true);
|
|
134
|
+
this.#syncOpenState();
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
hide() {
|
|
139
|
+
if (!(this.#panel instanceof HTMLElementBase) || !this.#isOpen()) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const shouldRestoreFocus = this.#panel.contains(this.ownerDocument?.activeElement);
|
|
144
|
+
|
|
145
|
+
this.toggleAttribute("data-open", false);
|
|
146
|
+
this.#syncOpenState();
|
|
147
|
+
|
|
148
|
+
if (
|
|
149
|
+
shouldRestoreFocus
|
|
150
|
+
&& this.#restoreFocusTo instanceof HTMLElementBase
|
|
151
|
+
&& this.#restoreFocusTo.isConnected
|
|
152
|
+
) {
|
|
153
|
+
this.#restoreFocusTo.focus();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
this.#restoreFocusTo = null;
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
toggle(opener = null) {
|
|
161
|
+
if (this.#isOpen()) {
|
|
162
|
+
return this.hide();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return this.show(opener);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
#handleClick = (event) => {
|
|
169
|
+
if (!(event.target instanceof ElementBase)) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const openButton = event.target.closest(OPEN_SELECTOR);
|
|
174
|
+
|
|
175
|
+
if (
|
|
176
|
+
openButton instanceof HTMLElementBase
|
|
177
|
+
&& openButton.closest(TOAST_TAG_NAME) === this
|
|
178
|
+
) {
|
|
179
|
+
event.preventDefault();
|
|
180
|
+
this.toggle(openButton);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const closeButton = event.target.closest(CLOSE_SELECTOR);
|
|
185
|
+
|
|
186
|
+
if (
|
|
187
|
+
closeButton instanceof HTMLElementBase
|
|
188
|
+
&& closeButton.closest(TOAST_TAG_NAME) === this
|
|
189
|
+
) {
|
|
190
|
+
event.preventDefault();
|
|
191
|
+
this.hide();
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
#handleKeyDown = (event) => {
|
|
196
|
+
if (
|
|
197
|
+
event.key !== "Escape"
|
|
198
|
+
|| !(event.target instanceof ElementBase)
|
|
199
|
+
|| event.target.closest(TOAST_TAG_NAME) !== this
|
|
200
|
+
|| !(this.#panel instanceof HTMLElementBase)
|
|
201
|
+
|| !this.#isOpen()
|
|
202
|
+
) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
event.preventDefault();
|
|
207
|
+
this.hide();
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
#handlePanelToggle = () => {
|
|
211
|
+
this.#syncStateFromPanel();
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
#sync() {
|
|
215
|
+
const nextPanel = collectOwnedElements(this, this, PANEL_SELECTOR)[0] ?? null;
|
|
216
|
+
const nextTitle = collectOwnedElements(this, this, TITLE_SELECTOR)[0] ?? null;
|
|
217
|
+
|
|
218
|
+
this.#syncPanelEvents(nextPanel instanceof HTMLElementBase ? nextPanel : null);
|
|
219
|
+
this.#panel = nextPanel instanceof HTMLElementBase ? nextPanel : null;
|
|
220
|
+
this.#title = nextTitle instanceof HTMLElementBase ? nextTitle : null;
|
|
221
|
+
this.#openButtons = collectOwnedElements(this, this, OPEN_SELECTOR);
|
|
222
|
+
this.#closeButtons = collectOwnedElements(this, this, CLOSE_SELECTOR);
|
|
223
|
+
this.#applyState();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
#syncPanelEvents(nextPanel) {
|
|
227
|
+
if (this.#panelWithEvents === nextPanel) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (this.#panelWithEvents instanceof HTMLElementBase) {
|
|
232
|
+
this.#panelWithEvents.removeEventListener("toggle", this.#handlePanelToggle);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (nextPanel instanceof HTMLElementBase) {
|
|
236
|
+
nextPanel.addEventListener("toggle", this.#handlePanelToggle);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
this.#panelWithEvents = nextPanel;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
#shouldBeOpen() {
|
|
243
|
+
return normalizeToastOpen(this.getAttribute("data-open"));
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
#isOpen() {
|
|
247
|
+
if (!(this.#panel instanceof HTMLElementBase)) {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (supportsToastPopover(this.#panel)) {
|
|
252
|
+
return isToastPanelOpen(this.#panel);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return !this.#panel.hidden;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
#applyState() {
|
|
259
|
+
for (const button of [...this.#openButtons, ...this.#closeButtons]) {
|
|
260
|
+
if (button instanceof HTMLButtonElementBase && !button.hasAttribute("type")) {
|
|
261
|
+
button.type = "button";
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (!(this.#panel instanceof HTMLElementBase)) {
|
|
266
|
+
this.#clearDismissTimer();
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const baseId = this.id || this.#instanceId;
|
|
271
|
+
|
|
272
|
+
if (this.#title instanceof HTMLElementBase && !this.#title.id) {
|
|
273
|
+
this.#title.id = `${baseId}-title`;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
this.#panel.setAttribute("role", getToastRoleForLive(this.getAttribute("data-live")));
|
|
277
|
+
this.#panel.setAttribute("aria-live", normalizeToastLive(this.getAttribute("data-live")));
|
|
278
|
+
this.#panel.setAttribute("aria-atomic", "true");
|
|
279
|
+
this.#syncAccessibleLabel();
|
|
280
|
+
this.#syncPopoverState();
|
|
281
|
+
this.#syncOpenState();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
#scheduleDismiss() {
|
|
285
|
+
this.#clearDismissTimer();
|
|
286
|
+
|
|
287
|
+
if (typeof window === "undefined") {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const duration = normalizeToastDuration(this.getAttribute("data-duration"));
|
|
292
|
+
|
|
293
|
+
if (duration === 0) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
this.#dismissTimer = window.setTimeout(() => {
|
|
298
|
+
this.#dismissTimer = 0;
|
|
299
|
+
this.hide();
|
|
300
|
+
}, duration);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
#clearDismissTimer() {
|
|
304
|
+
if (this.#dismissTimer === 0 || typeof window === "undefined") {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
window.clearTimeout(this.#dismissTimer);
|
|
309
|
+
this.#dismissTimer = 0;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
#syncPopoverState() {
|
|
313
|
+
if (!(this.#panel instanceof HTMLElementBase) || !supportsToastPopover(this.#panel)) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (!this.#panel.hasAttribute("popover")) {
|
|
318
|
+
this.#panel.setAttribute("popover", "manual");
|
|
319
|
+
this.#panel.setAttribute(MANAGED_POPOVER_ATTRIBUTE, "");
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
#syncOpenState() {
|
|
324
|
+
if (!(this.#panel instanceof HTMLElementBase)) {
|
|
325
|
+
this.#clearDismissTimer();
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const open = this.#shouldBeOpen();
|
|
330
|
+
|
|
331
|
+
if (supportsToastPopover(this.#panel)) {
|
|
332
|
+
this.#panel.hidden = false;
|
|
333
|
+
|
|
334
|
+
try {
|
|
335
|
+
if (open && !isToastPanelOpen(this.#panel)) {
|
|
336
|
+
this.#panel.showPopover();
|
|
337
|
+
} else if (!open && isToastPanelOpen(this.#panel)) {
|
|
338
|
+
this.#panel.hidePopover();
|
|
339
|
+
}
|
|
340
|
+
} catch {
|
|
341
|
+
this.#panel.hidden = !open;
|
|
342
|
+
}
|
|
343
|
+
} else {
|
|
344
|
+
this.#panel.hidden = !open;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
this.#syncStateFromPanel();
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
#syncStateFromPanel() {
|
|
351
|
+
if (!(this.#panel instanceof HTMLElementBase)) {
|
|
352
|
+
this.#clearDismissTimer();
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const open = supportsToastPopover(this.#panel)
|
|
357
|
+
? isToastPanelOpen(this.#panel)
|
|
358
|
+
: !this.#panel.hidden;
|
|
359
|
+
|
|
360
|
+
this.#panel.hidden = !open;
|
|
361
|
+
this.#panel.toggleAttribute("data-open", open);
|
|
362
|
+
this.toggleAttribute("data-open", open);
|
|
363
|
+
|
|
364
|
+
if (open) {
|
|
365
|
+
this.#scheduleDismiss();
|
|
366
|
+
} else {
|
|
367
|
+
this.#clearDismissTimer();
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
#syncAccessibleLabel() {
|
|
372
|
+
if (!(this.#panel instanceof HTMLElementBase)) {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const nextLabel = normalizeToastLabel(this.getAttribute("data-label"));
|
|
377
|
+
const hasManagedLabelledBy = this.#panel.hasAttribute(MANAGED_LABELLEDBY_ATTRIBUTE);
|
|
378
|
+
|
|
379
|
+
if (
|
|
380
|
+
this.#panel.hasAttribute(MANAGED_LABEL_ATTRIBUTE)
|
|
381
|
+
&& this.#panel.getAttribute("aria-label") !== nextLabel
|
|
382
|
+
) {
|
|
383
|
+
this.#panel.removeAttribute("aria-label");
|
|
384
|
+
this.#panel.removeAttribute(MANAGED_LABEL_ATTRIBUTE);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (this.#title?.id) {
|
|
388
|
+
if (this.#panel.hasAttribute(MANAGED_LABEL_ATTRIBUTE)) {
|
|
389
|
+
this.#panel.removeAttribute("aria-label");
|
|
390
|
+
this.#panel.removeAttribute(MANAGED_LABEL_ATTRIBUTE);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (!this.#panel.hasAttribute("aria-labelledby") || hasManagedLabelledBy) {
|
|
394
|
+
this.#panel.setAttribute("aria-labelledby", this.#title.id);
|
|
395
|
+
this.#panel.setAttribute(MANAGED_LABELLEDBY_ATTRIBUTE, "");
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
if (hasManagedLabelledBy) {
|
|
402
|
+
this.#panel.removeAttribute("aria-labelledby");
|
|
403
|
+
this.#panel.removeAttribute(MANAGED_LABELLEDBY_ATTRIBUTE);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const hasOwnAriaLabel = this.#panel.hasAttribute("aria-label")
|
|
407
|
+
&& !this.#panel.hasAttribute(MANAGED_LABEL_ATTRIBUTE);
|
|
408
|
+
const hasOwnLabelledBy = this.#panel.hasAttribute("aria-labelledby");
|
|
409
|
+
|
|
410
|
+
if (hasOwnAriaLabel || hasOwnLabelledBy) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
this.#panel.setAttribute("aria-label", nextLabel);
|
|
415
|
+
this.#panel.setAttribute(MANAGED_LABEL_ATTRIBUTE, "");
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export function defineToast(registry = globalThis.customElements) {
|
|
420
|
+
if (!registry?.get || !registry?.define) {
|
|
421
|
+
return ToastElement;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if (!registry.get(TOAST_TAG_NAME)) {
|
|
425
|
+
registry.define(TOAST_TAG_NAME, ToastElement);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return ToastElement;
|
|
429
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
export * from "./components/basic-alert";
|
|
1
2
|
export * from "./components/basic-accordion";
|
|
2
3
|
export * from "./components/basic-dialog";
|
|
3
4
|
export * from "./components/basic-popover";
|
|
5
|
+
export * from "./components/basic-summary-table";
|
|
6
|
+
export * from "./components/basic-table";
|
|
4
7
|
export * from "./components/basic-toc";
|
|
5
8
|
export * from "./components/basic-tabs";
|
|
9
|
+
export * from "./components/basic-toast";
|
package/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
export * from "./components/basic-alert/index.js";
|
|
1
2
|
export * from "./components/basic-accordion/index.js";
|
|
2
3
|
export * from "./components/basic-dialog/index.js";
|
|
3
4
|
export * from "./components/basic-popover/index.js";
|
|
5
|
+
export * from "./components/basic-summary-table/index.js";
|
|
6
|
+
export * from "./components/basic-table/index.js";
|
|
4
7
|
export * from "./components/basic-toc/index.js";
|
|
5
8
|
export * from "./components/basic-tabs/index.js";
|
|
9
|
+
export * from "./components/basic-toast/index.js";
|