@expressivecss/expressive 0.7.0 → 0.9.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/CHANGELOG.md +1313 -1
- package/README.md +76 -30
- package/dist/css/expressive.css +4896 -1777
- package/dist/css/expressive.css.map +1 -1
- package/dist/css/expressive.min.css +1 -1
- package/dist/css/expressive.min.css.map +1 -1
- package/dist/fonts/LICENSE-material-symbols +93 -0
- package/dist/fonts/LICENSE-noto-sans +93 -0
- package/dist/fonts/LICENSE-roboto +93 -0
- package/dist/fonts/material-symbols-outlined.woff2 +0 -0
- package/dist/fonts/material-symbols-rounded.woff2 +0 -0
- package/dist/fonts/material-symbols-sharp.woff2 +0 -0
- package/dist/fonts/noto-sans-latin-400.woff2 +0 -0
- package/dist/fonts/noto-sans-latin-500.woff2 +0 -0
- package/dist/fonts/roboto-latin-400.woff2 +0 -0
- package/dist/fonts/roboto-latin-500.woff2 +0 -0
- package/dist/js/expressive.cjs +1673 -1338
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +1673 -1338
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +13 -13
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +1673 -1338
- package/dist/js/expressive.mjs.map +4 -4
- package/dist/types/behaviors/bottomSheets.d.ts +19 -11
- package/dist/types/behaviors/sheetDrag.d.ts +40 -0
- package/dist/types/behaviors/sideSheets.d.ts +2 -9
- package/dist/types/components/appBar.d.ts +26 -0
- package/dist/types/components/autocomplete.d.ts +15 -3
- package/dist/types/components/buttonGroup.d.ts +39 -0
- package/dist/types/components/buttons.d.ts +5 -1
- package/dist/types/components/cards.d.ts +11 -13
- package/dist/types/components/carousel.d.ts +87 -53
- package/dist/types/components/chips.d.ts +21 -1
- package/dist/types/components/expandingCard.d.ts +31 -0
- package/dist/types/components/index.d.ts +23 -20
- package/dist/types/components/lightbox.d.ts +1 -0
- package/dist/types/components/menu.d.ts +11 -1
- package/dist/types/components/{sidenav.d.ts → navigationDrawer.d.ts} +16 -16
- package/dist/types/components/registry.d.ts +18 -8
- package/dist/types/components/slider.d.ts +26 -85
- package/dist/types/components/snackbar.d.ts +20 -5
- package/dist/types/components/tabs.d.ts +12 -0
- package/dist/types/components/timepicker.d.ts +12 -10
- package/dist/types/components/tooltip.d.ts +1 -0
- package/dist/types/core/utils.d.ts +64 -53
- package/dist/types/index.d.ts +8 -9
- package/package.json +39 -3
- package/src/sass/README.md +61 -11
- package/src/sass/abstracts/_breakpoints.scss +17 -19
- package/src/sass/abstracts/_mixins.scss +155 -21
- package/src/sass/abstracts/_variables.scss +69 -5
- package/src/sass/base/_fonts.scss +63 -0
- package/src/sass/base/_global.scss +6 -24
- package/src/sass/base/_grid.scss +15 -12
- package/src/sass/base/_normalize.scss +34 -38
- package/src/sass/base/_typography.scss +4 -18
- package/src/sass/components/_badges.scss +3 -5
- package/src/sass/components/_banners.scss +298 -0
- package/src/sass/components/_bottom-app-bar.scss +180 -0
- package/src/sass/components/_bottom-sheet.scss +12 -4
- package/src/sass/components/_button-groups.scss +358 -0
- package/src/sass/components/_buttons.scss +245 -92
- package/src/sass/components/_cards.scss +514 -78
- package/src/sass/components/_carousel.scss +562 -68
- package/src/sass/components/_chips.scss +64 -5
- package/src/sass/components/_datepicker.scss +24 -24
- package/src/sass/components/_dialog.scss +17 -11
- package/src/sass/components/_drag-handle.scss +130 -0
- package/src/sass/components/_expanding-card.scss +226 -0
- package/src/sass/components/_fab-menu.scss +232 -0
- package/src/sass/components/_floating-sheet.scss +86 -0
- package/src/sass/components/_icon-buttons.scss +172 -0
- package/src/sass/components/_icons-material-design.scss +22 -10
- package/src/sass/components/_index.scss +22 -6
- package/src/sass/components/_list.scss +16 -13
- package/src/sass/components/_loading-indicator.scss +106 -0
- package/src/sass/components/_menu.scss +335 -61
- package/src/sass/components/_navbar.scss +245 -45
- package/src/sass/components/_navigation-bar.scss +22 -11
- package/src/sass/components/{_sidenav.scss → _navigation-drawer.scss} +123 -33
- package/src/sass/components/_navigation-rail.scss +31 -23
- package/src/sass/components/_page-footer.scss +19 -16
- package/src/sass/components/_pagination.scss +24 -6
- package/src/sass/components/_panes.scss +52 -11
- package/src/sass/components/{_preloader.scss → _progress.scss} +11 -3
- package/src/sass/components/_scrim.scss +37 -0
- package/src/sass/components/_search.scss +259 -0
- package/src/sass/components/_segmented-buttons.scss +188 -0
- package/src/sass/components/_side-sheet.scss +2 -2
- package/src/sass/components/_snackbar.scss +20 -15
- package/src/sass/components/_split-button.scss +196 -0
- package/src/sass/components/_tabs.scss +7 -8
- package/src/sass/components/_timepicker.scss +67 -58
- package/src/sass/components/_toolbar.scss +206 -80
- package/src/sass/components/_transitions.scss +8 -1
- package/src/sass/components/forms/_checkboxes.scss +49 -12
- package/src/sass/components/forms/_fieldset.scss +4 -4
- package/src/sass/components/forms/_file-input.scss +8 -1
- package/src/sass/components/forms/_index.scss +1 -1
- package/src/sass/components/forms/_input-fields.scss +50 -44
- package/src/sass/components/forms/_radio-buttons.scss +42 -10
- package/src/sass/components/forms/_select.scss +38 -1
- package/src/sass/components/forms/{_range.scss → _slider.scss} +8 -9
- package/src/sass/components/forms/_switches.scss +6 -7
- package/src/sass/expressive.scss +5 -0
- package/src/sass/tokens/_index.scss +4 -1
- package/src/sass/tokens/_reference.scss +70 -61
- package/src/sass/tokens/_state.scss +24 -0
- package/src/sass/tokens/_theme.scss +6 -3
- package/src/sass/tokens/_vibrant.scss +76 -0
- package/src/sass/utilities/_colors.scss +14 -1
- package/src/sass/utilities/_helpers.scss +5 -5
- package/src/sass/utilities/_visibility.scss +48 -26
- package/dist/types/behaviors/waves.d.ts +0 -15
- package/dist/types/components/parallax.d.ts +0 -16
- package/dist/types/components/range.d.ts +0 -43
- package/dist/types/core/bounding.d.ts +0 -6
- package/dist/types/core/edges.d.ts +0 -6
- package/src/sass/components/_parallax.scss +0 -104
- package/src/sass/components/_pulse.scss +0 -37
- package/src/sass/components/_slider.scss +0 -129
package/dist/js/expressive.cjs
CHANGED
|
@@ -19,78 +19,40 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
// src/ts/index.ts
|
|
20
20
|
var index_exports = {};
|
|
21
21
|
__export(index_exports, {
|
|
22
|
+
AppBar: () => AppBar,
|
|
22
23
|
AutoInit: () => AutoInit,
|
|
23
24
|
Autocomplete: () => Autocomplete,
|
|
24
25
|
BottomSheets: () => BottomSheets,
|
|
26
|
+
ButtonGroup: () => ButtonGroup,
|
|
25
27
|
Cards: () => Cards,
|
|
26
28
|
Carousel: () => Carousel,
|
|
27
29
|
CharacterCounter: () => CharacterCounter,
|
|
28
30
|
Chips: () => Chips,
|
|
29
31
|
Datepicker: () => Datepicker,
|
|
30
32
|
Dialogs: () => Dialogs,
|
|
33
|
+
ExpandingCard: () => ExpandingCard,
|
|
31
34
|
FloatingActionButton: () => FloatingActionButton,
|
|
32
35
|
FormSelect: () => FormSelect,
|
|
33
36
|
Forms: () => Forms,
|
|
34
37
|
Lightbox: () => Lightbox,
|
|
35
38
|
Menu: () => Menu,
|
|
39
|
+
NavigationDrawer: () => NavigationDrawer,
|
|
36
40
|
NavigationRail: () => NavigationRail,
|
|
37
|
-
|
|
38
|
-
Range: () => Range,
|
|
41
|
+
Range: () => Slider,
|
|
39
42
|
ScrollSpy: () => ScrollSpy,
|
|
40
43
|
SideSheets: () => SideSheets,
|
|
41
|
-
Sidenav: () =>
|
|
44
|
+
Sidenav: () => NavigationDrawer,
|
|
42
45
|
Slider: () => Slider,
|
|
43
46
|
Snackbar: () => Snackbar,
|
|
44
47
|
Tabs: () => Tabs,
|
|
45
48
|
Timepicker: () => Timepicker,
|
|
46
49
|
Tooltip: () => Tooltip,
|
|
47
|
-
Waves: () => Waves,
|
|
48
50
|
version: () => version
|
|
49
51
|
});
|
|
50
52
|
module.exports = __toCommonJS(index_exports);
|
|
51
53
|
|
|
52
54
|
// src/ts/core/utils.ts
|
|
53
55
|
var _Utils = class _Utils {
|
|
54
|
-
/**
|
|
55
|
-
* Detects when a key is pressed.
|
|
56
|
-
* @param e Event instance.
|
|
57
|
-
*/
|
|
58
|
-
static docHandleKeydown(e) {
|
|
59
|
-
_Utils.keyDown = true;
|
|
60
|
-
if (_Utils._navigationKeys.has(e.key)) {
|
|
61
|
-
_Utils.tabPressed = true;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Detects when a key is released.
|
|
66
|
-
* @param e Event instance.
|
|
67
|
-
*/
|
|
68
|
-
static docHandleKeyup(e) {
|
|
69
|
-
_Utils.keyDown = false;
|
|
70
|
-
if (_Utils._navigationKeys.has(e.key)) {
|
|
71
|
-
_Utils.tabPressed = false;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Detects when document is focused.
|
|
76
|
-
* @param e Event instance.
|
|
77
|
-
*/
|
|
78
|
-
/* eslint-disabled as of required event type condition check */
|
|
79
|
-
/* eslint-disable-next-line */
|
|
80
|
-
static docHandleFocus(e) {
|
|
81
|
-
if (_Utils.keyDown) {
|
|
82
|
-
document.body.classList.add("keyboard-focused");
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Detects when document is not focused.
|
|
87
|
-
* @param e Event instance.
|
|
88
|
-
*/
|
|
89
|
-
/* eslint-disabled as of required event type condition check */
|
|
90
|
-
/* eslint-disable-next-line */
|
|
91
|
-
static docHandleBlur(e) {
|
|
92
|
-
document.body.classList.remove("keyboard-focused");
|
|
93
|
-
}
|
|
94
56
|
/**
|
|
95
57
|
* Run `callback` once the document is parsed.
|
|
96
58
|
*
|
|
@@ -108,13 +70,46 @@ var _Utils = class _Utils {
|
|
|
108
70
|
}
|
|
109
71
|
}
|
|
110
72
|
/**
|
|
111
|
-
* Generates a unique string identifier.
|
|
73
|
+
* Generates a unique string identifier. Every caller prefixes the result and
|
|
74
|
+
* uses it as an element id, and a UUID is valid in that position.
|
|
75
|
+
*
|
|
76
|
+
* `randomUUID` is exposed only in secure contexts, and a dev server on a
|
|
77
|
+
* plain-HTTP LAN address - the usual way a page is opened on a phone - is
|
|
78
|
+
* not one. Without the fallback every component that stamps an id would
|
|
79
|
+
* throw there. The ids only have to be unique within one document, so the
|
|
80
|
+
* fallback does not need to be cryptographic.
|
|
112
81
|
*/
|
|
113
82
|
static guid() {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
83
|
+
return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Where an element created at runtime has to be appended to stay in the same
|
|
87
|
+
* tree as `el`. A stylesheet adopted into a shadow root cannot match a node
|
|
88
|
+
* in the document, so a portal that lands on `document.body` is unstyled
|
|
89
|
+
* whenever its origin lives in a shadow root (adr/0002).
|
|
90
|
+
*
|
|
91
|
+
* Light-DOM elements still get `document.body`, which is what escapes an
|
|
92
|
+
* ancestor's `overflow: hidden` and stacking context. Inside a shadow root
|
|
93
|
+
* both hazards come back: the host's own ancestors still form the containing
|
|
94
|
+
* block, so a transformed ancestor re-anchors `position: fixed` and a
|
|
95
|
+
* positioned one re-anchors `position: absolute`.
|
|
96
|
+
*/
|
|
97
|
+
static portalRoot(el) {
|
|
98
|
+
const root = el.getRootNode();
|
|
99
|
+
return root.host ? root : document.body;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* `getElementById` against the tree `el` lives in. The mirror of
|
|
103
|
+
* `portalRoot`: an id in a shadow root is invisible to
|
|
104
|
+
* `document.getElementById`, so a trigger and its target inside the same
|
|
105
|
+
* root could not find each other at all.
|
|
106
|
+
*
|
|
107
|
+
* Falls back to the document for a detached `el`, whose root is a plain
|
|
108
|
+
* element with no lookup of its own.
|
|
109
|
+
*/
|
|
110
|
+
static getElementById(el, id) {
|
|
111
|
+
const root = el.getRootNode();
|
|
112
|
+
return root.getElementById ? root.getElementById(id) : document.getElementById(id);
|
|
118
113
|
}
|
|
119
114
|
/**
|
|
120
115
|
* Checks for exceeded edges
|
|
@@ -211,43 +206,50 @@ var _Utils = class _Utils {
|
|
|
211
206
|
* Retrieves document scroll postion from top.
|
|
212
207
|
*/
|
|
213
208
|
static getDocumentScrollTop() {
|
|
214
|
-
return window.scrollY
|
|
209
|
+
return window.scrollY;
|
|
215
210
|
}
|
|
216
211
|
/**
|
|
217
212
|
* Retrieves document scroll postion from left.
|
|
218
213
|
*/
|
|
219
214
|
static getDocumentScrollLeft() {
|
|
220
|
-
return window.scrollX
|
|
215
|
+
return window.scrollX;
|
|
221
216
|
}
|
|
222
217
|
/**
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
218
|
+
* Trailing-edge throttle: run `func` now, then at most once per `wait` ms
|
|
219
|
+
* with the most recent arguments.
|
|
220
|
+
*
|
|
221
|
+
* This used to carry its underscore ancestor's whole configuration - leading
|
|
222
|
+
* and trailing switches, a result passthrough - and both call sites are
|
|
223
|
+
* resize handlers passing nothing but a function and a delay.
|
|
224
|
+
*
|
|
225
|
+
* Assign the return value once. `x = Utils.throttle(fn, 200)` is right;
|
|
226
|
+
* wrapping it in an arrow builds a fresh closure per event and never calls
|
|
227
|
+
* it, which is how resize handling was dead in three components.
|
|
227
228
|
*/
|
|
228
|
-
static throttle(func, wait
|
|
229
|
-
let
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
timeout = null;
|
|
233
|
-
result = func(...lastArgs ?? []);
|
|
234
|
-
lastArgs = null;
|
|
235
|
-
};
|
|
229
|
+
static throttle(func, wait) {
|
|
230
|
+
let timeout = null;
|
|
231
|
+
let lastArgs = null;
|
|
232
|
+
let previous = 0;
|
|
236
233
|
return (...args) => {
|
|
237
234
|
const now = Date.now();
|
|
238
|
-
if (!previous && options?.leading === false) previous = now;
|
|
239
235
|
const remaining = wait - (now - previous);
|
|
240
|
-
lastArgs = args;
|
|
241
236
|
if (remaining <= 0) {
|
|
242
237
|
clearTimeout(timeout);
|
|
243
238
|
timeout = null;
|
|
244
239
|
previous = now;
|
|
245
240
|
lastArgs = null;
|
|
246
|
-
|
|
247
|
-
} else if (!timeout
|
|
248
|
-
|
|
241
|
+
func(...args);
|
|
242
|
+
} else if (!timeout) {
|
|
243
|
+
lastArgs = args;
|
|
244
|
+
timeout = setTimeout(() => {
|
|
245
|
+
previous = Date.now();
|
|
246
|
+
timeout = null;
|
|
247
|
+
func(...lastArgs ?? []);
|
|
248
|
+
lastArgs = null;
|
|
249
|
+
}, remaining);
|
|
250
|
+
} else {
|
|
251
|
+
lastArgs = args;
|
|
249
252
|
}
|
|
250
|
-
return result;
|
|
251
253
|
};
|
|
252
254
|
}
|
|
253
255
|
/**
|
|
@@ -264,7 +266,7 @@ var _Utils = class _Utils {
|
|
|
264
266
|
* Renders a button with optional callback function
|
|
265
267
|
*/
|
|
266
268
|
static createButton(container, text, className = [], visibility = true, callback = null) {
|
|
267
|
-
className = className.concat(["
|
|
269
|
+
className = className.concat(["text"]);
|
|
268
270
|
const button = document.createElement("button");
|
|
269
271
|
button.className = className.join(" ");
|
|
270
272
|
button.style.visibility = visibility ? "visible" : "hidden";
|
|
@@ -274,7 +276,7 @@ var _Utils = class _Utils {
|
|
|
274
276
|
if (typeof callback === "function") {
|
|
275
277
|
button.addEventListener("click", callback);
|
|
276
278
|
button.addEventListener("keypress", (e) => {
|
|
277
|
-
if (_Utils.keys.ENTER
|
|
279
|
+
if (e.key === _Utils.keys.ENTER) callback(e);
|
|
278
280
|
});
|
|
279
281
|
}
|
|
280
282
|
container.append(button);
|
|
@@ -353,36 +355,22 @@ var _Utils = class _Utils {
|
|
|
353
355
|
};
|
|
354
356
|
}
|
|
355
357
|
};
|
|
356
|
-
/** Specifies wether tab is pressed or not. */
|
|
357
|
-
_Utils.tabPressed = false;
|
|
358
|
-
/** Specifies wether there is a key pressed. */
|
|
359
|
-
_Utils.keyDown = false;
|
|
360
358
|
/**
|
|
361
|
-
* Key maps.
|
|
359
|
+
* Key maps. One `KeyboardEvent.key` value each: the second entries these used
|
|
360
|
+
* to carry (`Esc`, `Up`, `Del`, ...) were IE and Edge Legacy spellings, and
|
|
361
|
+
* the support baseline excludes both.
|
|
362
362
|
*/
|
|
363
363
|
_Utils.keys = {
|
|
364
|
-
TAB:
|
|
365
|
-
ENTER:
|
|
366
|
-
ESC:
|
|
367
|
-
BACKSPACE:
|
|
368
|
-
ARROW_UP:
|
|
369
|
-
ARROW_DOWN:
|
|
370
|
-
ARROW_LEFT:
|
|
371
|
-
ARROW_RIGHT:
|
|
372
|
-
DELETE:
|
|
364
|
+
TAB: "Tab",
|
|
365
|
+
ENTER: "Enter",
|
|
366
|
+
ESC: "Escape",
|
|
367
|
+
BACKSPACE: "Backspace",
|
|
368
|
+
ARROW_UP: "ArrowUp",
|
|
369
|
+
ARROW_DOWN: "ArrowDown",
|
|
370
|
+
ARROW_LEFT: "ArrowLeft",
|
|
371
|
+
ARROW_RIGHT: "ArrowRight",
|
|
372
|
+
DELETE: "Delete"
|
|
373
373
|
};
|
|
374
|
-
/**
|
|
375
|
-
* Keys that count as keyboard navigation, precomputed.
|
|
376
|
-
*
|
|
377
|
-
* These handlers run at capture phase on the document for every keystroke on
|
|
378
|
-
* the page, and used to rebuild three arrays and spread them into a fourth
|
|
379
|
-
* on each one.
|
|
380
|
-
*/
|
|
381
|
-
_Utils._navigationKeys = /* @__PURE__ */ new Set([
|
|
382
|
-
..._Utils.keys.TAB,
|
|
383
|
-
..._Utils.keys.ARROW_DOWN,
|
|
384
|
-
..._Utils.keys.ARROW_UP
|
|
385
|
-
]);
|
|
386
374
|
var Utils = _Utils;
|
|
387
375
|
|
|
388
376
|
// src/ts/core/component.ts
|
|
@@ -445,47 +433,63 @@ var _defaults = {
|
|
|
445
433
|
onOpen: null,
|
|
446
434
|
onClose: null
|
|
447
435
|
};
|
|
448
|
-
var CARDS_SELECTOR =
|
|
436
|
+
var CARDS_SELECTOR = 'article:has(> aside[id]:not([id=""])):not(:has(> aside ~ aside)):has(> button.card-reveal-trigger[type="button"], > :not(aside) button.card-reveal-trigger[type="button"])';
|
|
437
|
+
var REVEAL_INITIALIZED_CLASS = "card-reveal-initialized";
|
|
438
|
+
function hasAccessibleName(trigger) {
|
|
439
|
+
const label = trigger.getAttribute("aria-label");
|
|
440
|
+
if (label?.trim()) return true;
|
|
441
|
+
const labelledBy = trigger.getAttribute("aria-labelledby");
|
|
442
|
+
if (labelledBy) {
|
|
443
|
+
const referencedText = labelledBy.trim().split(/\s+/).map((id) => trigger.ownerDocument.getElementById(id)?.textContent ?? "").join(" ").trim();
|
|
444
|
+
if (referencedText) return true;
|
|
445
|
+
}
|
|
446
|
+
const content = trigger.cloneNode(true);
|
|
447
|
+
content.querySelectorAll('[aria-hidden="true"]').forEach((node) => node.remove());
|
|
448
|
+
return Boolean(content.textContent?.trim());
|
|
449
|
+
}
|
|
450
|
+
function isUsableCardTrigger(trigger, card, panel) {
|
|
451
|
+
return trigger.closest("article") === card && !panel.contains(trigger) && !trigger.disabled && trigger.getAttribute("aria-disabled") !== "true" && hasAccessibleName(trigger);
|
|
452
|
+
}
|
|
453
|
+
function isCardReveal(el) {
|
|
454
|
+
if (el.tagName !== "ARTICLE") return false;
|
|
455
|
+
const panels = el.querySelectorAll(":scope > aside");
|
|
456
|
+
if (panels.length !== 1 || !panels[0].id) return false;
|
|
457
|
+
return Array.from(
|
|
458
|
+
el.querySelectorAll('button.card-reveal-trigger[type="button"]')
|
|
459
|
+
).some((trigger) => isUsableCardTrigger(trigger, el, panels[0]));
|
|
460
|
+
}
|
|
449
461
|
var Cards = class _Cards extends Component {
|
|
450
|
-
constructor(el, options) {
|
|
462
|
+
constructor(el, options = {}) {
|
|
451
463
|
super(el, options, _Cards);
|
|
452
464
|
this.isOpen = false;
|
|
465
|
+
this._ownsRevealInitializedClass = false;
|
|
466
|
+
this._initialAriaControls = /* @__PURE__ */ new Map();
|
|
467
|
+
this._lastActivator = null;
|
|
453
468
|
this._setupEventHandlers = () => {
|
|
454
|
-
this._activators.forEach((
|
|
455
|
-
|
|
456
|
-
el.addEventListener("keypress", this._handleKeypressEvent);
|
|
469
|
+
this._activators.forEach((activator) => {
|
|
470
|
+
activator.addEventListener("click", this._handleClickInteraction);
|
|
457
471
|
});
|
|
472
|
+
this.el.addEventListener("keydown", this._handleKeydownEvent);
|
|
458
473
|
};
|
|
459
474
|
this._removeEventHandlers = () => {
|
|
460
|
-
this._activators.forEach((
|
|
461
|
-
|
|
462
|
-
el.removeEventListener("keypress", this._handleKeypressEvent);
|
|
475
|
+
this._activators.forEach((activator) => {
|
|
476
|
+
activator.removeEventListener("click", this._handleClickInteraction);
|
|
463
477
|
});
|
|
478
|
+
this.el.removeEventListener("keydown", this._handleKeydownEvent);
|
|
464
479
|
};
|
|
465
|
-
this._handleClickInteraction = () => {
|
|
480
|
+
this._handleClickInteraction = (event) => {
|
|
481
|
+
this._lastActivator = event.currentTarget;
|
|
466
482
|
this._handleRevealEvent();
|
|
467
483
|
};
|
|
468
|
-
this.
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
484
|
+
this._handleKeydownEvent = (event) => {
|
|
485
|
+
const target = event.target instanceof Element ? event.target.closest("article") : null;
|
|
486
|
+
if (target !== this.el || event.key !== "Escape" || !this.isOpen) return;
|
|
487
|
+
event.preventDefault();
|
|
488
|
+
this.close();
|
|
472
489
|
};
|
|
473
490
|
this._handleRevealEvent = () => {
|
|
474
|
-
this.
|
|
475
|
-
this.open();
|
|
476
|
-
};
|
|
477
|
-
this._setupRevealCloseEventHandlers = () => {
|
|
478
|
-
this.cardRevealClose.addEventListener("click", this.close);
|
|
479
|
-
this.cardRevealClose.addEventListener("keypress", this._handleKeypressCloseEvent);
|
|
480
|
-
};
|
|
481
|
-
this._removeRevealCloseEventHandlers = () => {
|
|
482
|
-
this.cardRevealClose.removeEventListener("click", this.close);
|
|
483
|
-
this.cardRevealClose.removeEventListener("keypress", this._handleKeypressCloseEvent);
|
|
484
|
-
};
|
|
485
|
-
this._handleKeypressCloseEvent = (e) => {
|
|
486
|
-
if (Utils.keys.ENTER.includes(e.key)) {
|
|
487
|
-
this.close();
|
|
488
|
-
}
|
|
491
|
+
if (this.isOpen) this.close();
|
|
492
|
+
else this.open();
|
|
489
493
|
};
|
|
490
494
|
/**
|
|
491
495
|
* Show card reveal.
|
|
@@ -493,44 +497,56 @@ var Cards = class _Cards extends Component {
|
|
|
493
497
|
this.open = () => {
|
|
494
498
|
if (this.isOpen || !this.cardReveal) return;
|
|
495
499
|
this.isOpen = true;
|
|
496
|
-
this.cardReveal.
|
|
497
|
-
|
|
500
|
+
this.cardReveal.classList.add("open");
|
|
501
|
+
this.cardReveal.inert = false;
|
|
502
|
+
this._activators.forEach((activator) => activator.ariaExpanded = "true");
|
|
498
503
|
if (typeof this.options.onOpen === "function") {
|
|
499
|
-
this.options.onOpen.call(this);
|
|
504
|
+
this.options.onOpen.call(this, this.el);
|
|
500
505
|
}
|
|
501
|
-
if (this.cardRevealClose) this._setupRevealCloseEventHandlers();
|
|
502
506
|
};
|
|
503
507
|
/**
|
|
504
508
|
* Hide card reveal.
|
|
505
509
|
*/
|
|
506
510
|
this.close = () => {
|
|
507
511
|
if (!this.isOpen || !this.cardReveal) return;
|
|
512
|
+
const focusWasInside = this.cardReveal.contains(document.activeElement);
|
|
508
513
|
this.isOpen = false;
|
|
509
|
-
this.cardReveal.
|
|
510
|
-
this.
|
|
511
|
-
|
|
514
|
+
this.cardReveal.classList.remove("open");
|
|
515
|
+
this.cardReveal.inert = true;
|
|
516
|
+
this._activators.forEach((activator) => activator.ariaExpanded = "false");
|
|
512
517
|
if (typeof this.options.onClose === "function") {
|
|
513
|
-
this.options.onClose.call(this);
|
|
518
|
+
this.options.onClose.call(this, this.el);
|
|
519
|
+
}
|
|
520
|
+
if (focusWasInside) {
|
|
521
|
+
(this._lastActivator ?? this._activators[0])?.focus();
|
|
514
522
|
}
|
|
515
|
-
if (this.cardRevealClose) this._removeRevealCloseEventHandlers();
|
|
516
523
|
};
|
|
517
524
|
this.el["Expressive_Cards"] = this;
|
|
518
525
|
this.options = {
|
|
519
526
|
..._Cards.defaults,
|
|
520
527
|
...options
|
|
521
528
|
};
|
|
522
|
-
this.
|
|
523
|
-
|
|
529
|
+
const cardReveals = this.el.querySelectorAll(":scope > aside");
|
|
530
|
+
const cardReveal = cardReveals.length === 1 ? cardReveals[0] : null;
|
|
531
|
+
const activators = cardReveal ? Array.from(
|
|
532
|
+
this.el.querySelectorAll(
|
|
533
|
+
'button.card-reveal-trigger[type="button"]'
|
|
534
|
+
)
|
|
535
|
+
).filter(
|
|
536
|
+
(activator) => isUsableCardTrigger(activator, this.el, cardReveal)
|
|
537
|
+
) : [];
|
|
538
|
+
this.cardReveal = cardReveal?.id && activators.length > 0 ? cardReveal : null;
|
|
539
|
+
this._activators = this.cardReveal ? activators : [];
|
|
524
540
|
if (this.cardReveal) {
|
|
525
|
-
this.
|
|
526
|
-
this.
|
|
527
|
-
|
|
541
|
+
this._ownsRevealInitializedClass = !this.el.classList.contains(REVEAL_INITIALIZED_CLASS);
|
|
542
|
+
this.el.classList.add(REVEAL_INITIALIZED_CLASS);
|
|
543
|
+
this._activators.forEach((activator) => {
|
|
544
|
+
this._initialAriaControls.set(activator, activator.getAttribute("aria-controls"));
|
|
545
|
+
activator.ariaExpanded = "false";
|
|
546
|
+
activator.setAttribute("aria-controls", this.cardReveal.id);
|
|
528
547
|
});
|
|
529
|
-
this.
|
|
530
|
-
|
|
531
|
-
);
|
|
532
|
-
if (this.cardRevealClose) this.cardRevealClose.tabIndex = -1;
|
|
533
|
-
this.cardReveal.ariaExpanded = "false";
|
|
548
|
+
this.cardReveal.classList.remove("open");
|
|
549
|
+
this.cardReveal.inert = true;
|
|
534
550
|
this._setupEventHandlers();
|
|
535
551
|
}
|
|
536
552
|
}
|
|
@@ -553,13 +569,28 @@ var Cards = class _Cards extends Component {
|
|
|
553
569
|
*/
|
|
554
570
|
destroy() {
|
|
555
571
|
this._removeEventHandlers();
|
|
556
|
-
if (this.
|
|
572
|
+
if (this.cardReveal) {
|
|
573
|
+
this.cardReveal.classList.remove("open");
|
|
574
|
+
this.cardReveal.inert = false;
|
|
575
|
+
if (this._ownsRevealInitializedClass) this.el.classList.remove(REVEAL_INITIALIZED_CLASS);
|
|
576
|
+
}
|
|
577
|
+
this._activators.forEach((activator) => {
|
|
578
|
+
activator.removeAttribute("aria-expanded");
|
|
579
|
+
const initialAriaControls = this._initialAriaControls.get(activator);
|
|
580
|
+
if (initialAriaControls === null) activator.removeAttribute("aria-controls");
|
|
581
|
+
else if (initialAriaControls !== void 0) {
|
|
582
|
+
activator.setAttribute("aria-controls", initialAriaControls);
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
this.isOpen = false;
|
|
557
586
|
this._activators = [];
|
|
587
|
+
this._initialAriaControls.clear();
|
|
588
|
+
this._lastActivator = null;
|
|
558
589
|
this.el["Expressive_Cards"] = void 0;
|
|
559
590
|
}
|
|
560
591
|
static Init() {
|
|
561
592
|
Utils.onDocumentReady(() => {
|
|
562
|
-
const cards = document.querySelectorAll(CARDS_SELECTOR);
|
|
593
|
+
const cards = Array.from(document.querySelectorAll(CARDS_SELECTOR)).filter(isCardReveal);
|
|
563
594
|
cards.forEach((el) => {
|
|
564
595
|
if (el && el["Expressive_Cards"] == void 0) this.init(el);
|
|
565
596
|
});
|
|
@@ -567,8 +598,173 @@ var Cards = class _Cards extends Component {
|
|
|
567
598
|
}
|
|
568
599
|
};
|
|
569
600
|
|
|
570
|
-
// src/ts/components/
|
|
601
|
+
// src/ts/components/expandingCard.ts
|
|
571
602
|
var _defaults2 = {
|
|
603
|
+
onOpen: null,
|
|
604
|
+
onClose: null
|
|
605
|
+
};
|
|
606
|
+
var EXPANDING_CARD_SELECTOR = "article.expanding-card:has(> dialog.expanding-card-dialog)";
|
|
607
|
+
var ExpandingCard = class _ExpandingCard extends Component {
|
|
608
|
+
constructor(el, options) {
|
|
609
|
+
super(el, options, _ExpandingCard);
|
|
610
|
+
this.isOpen = false;
|
|
611
|
+
this.closeGeneration = 0;
|
|
612
|
+
this._setupEventHandlers = () => {
|
|
613
|
+
this.trigger?.addEventListener("click", this.open);
|
|
614
|
+
this.trigger?.addEventListener("keypress", this._handleTriggerKeypress);
|
|
615
|
+
this.closeButton?.addEventListener("click", this.close);
|
|
616
|
+
this.dialog?.addEventListener("cancel", this._handleCancel);
|
|
617
|
+
this.dialog?.addEventListener("close", this._handleNativeClose);
|
|
618
|
+
};
|
|
619
|
+
this._removeEventHandlers = () => {
|
|
620
|
+
this.trigger?.removeEventListener("click", this.open);
|
|
621
|
+
this.trigger?.removeEventListener("keypress", this._handleTriggerKeypress);
|
|
622
|
+
this.closeButton?.removeEventListener("click", this.close);
|
|
623
|
+
this.dialog?.removeEventListener("cancel", this._handleCancel);
|
|
624
|
+
this.dialog?.removeEventListener("close", this._handleNativeClose);
|
|
625
|
+
};
|
|
626
|
+
this._handleTriggerKeypress = (event) => {
|
|
627
|
+
if (event.key === Utils.keys.ENTER || event.key === " ") {
|
|
628
|
+
event.preventDefault();
|
|
629
|
+
this.open();
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
this._handleCancel = (event) => {
|
|
633
|
+
event.preventDefault();
|
|
634
|
+
this.close();
|
|
635
|
+
};
|
|
636
|
+
this._handleNativeClose = () => {
|
|
637
|
+
if (this.dialog.open) return;
|
|
638
|
+
this.closeGeneration++;
|
|
639
|
+
this.isOpen = false;
|
|
640
|
+
this.trigger.ariaExpanded = "false";
|
|
641
|
+
this.dialog.ariaExpanded = "false";
|
|
642
|
+
this.dialog.classList.remove("expanded");
|
|
643
|
+
};
|
|
644
|
+
this._setTransitionOrigin = () => {
|
|
645
|
+
if (!this.dialog) return;
|
|
646
|
+
const card = this.el.getBoundingClientRect();
|
|
647
|
+
const media = this.el.querySelector(
|
|
648
|
+
":scope > figure, :scope > img"
|
|
649
|
+
);
|
|
650
|
+
const mediaRect = media?.getBoundingClientRect();
|
|
651
|
+
this.dialog.style.setProperty(
|
|
652
|
+
"--md-comp-expanding-card-from-top",
|
|
653
|
+
`${Math.max(0, card.top)}px`
|
|
654
|
+
);
|
|
655
|
+
this.dialog.style.setProperty(
|
|
656
|
+
"--md-comp-expanding-card-from-right",
|
|
657
|
+
`${Math.max(0, window.innerWidth - card.right)}px`
|
|
658
|
+
);
|
|
659
|
+
this.dialog.style.setProperty(
|
|
660
|
+
"--md-comp-expanding-card-from-bottom",
|
|
661
|
+
`${Math.max(0, window.innerHeight - card.bottom)}px`
|
|
662
|
+
);
|
|
663
|
+
this.dialog.style.setProperty(
|
|
664
|
+
"--md-comp-expanding-card-from-left",
|
|
665
|
+
`${Math.max(0, card.left)}px`
|
|
666
|
+
);
|
|
667
|
+
this.dialog.style.setProperty(
|
|
668
|
+
"--md-comp-expanding-card-from-media-height",
|
|
669
|
+
`${Math.max(0, mediaRect?.height ?? 0)}px`
|
|
670
|
+
);
|
|
671
|
+
};
|
|
672
|
+
this.open = () => {
|
|
673
|
+
if (this.isOpen || !this.dialog || !this.trigger) return;
|
|
674
|
+
this.closeGeneration++;
|
|
675
|
+
this._setTransitionOrigin();
|
|
676
|
+
this.isOpen = true;
|
|
677
|
+
this.trigger.ariaExpanded = "true";
|
|
678
|
+
this.dialog.ariaExpanded = "true";
|
|
679
|
+
this.dialog.showModal();
|
|
680
|
+
void this.dialog.offsetWidth;
|
|
681
|
+
this.dialog.classList.add("expanded");
|
|
682
|
+
this.closeButton?.focus();
|
|
683
|
+
if (typeof this.options.onOpen === "function") {
|
|
684
|
+
this.options.onOpen.call(this, this.el);
|
|
685
|
+
}
|
|
686
|
+
};
|
|
687
|
+
this.close = () => {
|
|
688
|
+
if (!this.isOpen || !this.dialog || !this.trigger) return;
|
|
689
|
+
const generation = ++this.closeGeneration;
|
|
690
|
+
this._setTransitionOrigin();
|
|
691
|
+
this.isOpen = false;
|
|
692
|
+
this.trigger.ariaExpanded = "false";
|
|
693
|
+
this.dialog.ariaExpanded = "false";
|
|
694
|
+
this.dialog.classList.remove("expanded");
|
|
695
|
+
if (typeof this.options.onClose === "function") {
|
|
696
|
+
this.options.onClose.call(this, this.el);
|
|
697
|
+
}
|
|
698
|
+
const finish = () => {
|
|
699
|
+
if (generation !== this.closeGeneration || this.isOpen || !this.dialog.open) return;
|
|
700
|
+
this.dialog.close();
|
|
701
|
+
if (this.dialog.isConnected && this.trigger.isConnected) this.trigger.focus();
|
|
702
|
+
};
|
|
703
|
+
const reducedMotion = window.matchMedia(
|
|
704
|
+
"(prefers-reduced-motion: reduce)"
|
|
705
|
+
).matches;
|
|
706
|
+
const transitions = reducedMotion ? [] : (this.dialog.getAnimations?.() ?? []).filter((animation) => animation.transitionProperty === "clip-path");
|
|
707
|
+
if (transitions.length === 0) finish();
|
|
708
|
+
else void Promise.allSettled(transitions.map((animation) => animation.finished)).then(finish);
|
|
709
|
+
};
|
|
710
|
+
this.el["Expressive_ExpandingCard"] = this;
|
|
711
|
+
this.options = {
|
|
712
|
+
..._ExpandingCard.defaults,
|
|
713
|
+
...options
|
|
714
|
+
};
|
|
715
|
+
this.dialog = this.el.querySelector(
|
|
716
|
+
":scope > dialog.expanding-card-dialog"
|
|
717
|
+
);
|
|
718
|
+
this.trigger = this.el.querySelector(
|
|
719
|
+
":scope > .expanding-card-trigger, :scope > figure > .expanding-card-trigger"
|
|
720
|
+
);
|
|
721
|
+
this.closeButton = this.dialog?.querySelector(".expanding-card-close") ?? null;
|
|
722
|
+
if (this.trigger && this.dialog) {
|
|
723
|
+
this.trigger.ariaExpanded = "false";
|
|
724
|
+
if (this.dialog.id)
|
|
725
|
+
this.trigger.setAttribute("aria-controls", this.dialog.id);
|
|
726
|
+
if (!this.trigger.matches("a[href], button, input, select, textarea")) {
|
|
727
|
+
this.trigger.tabIndex = 0;
|
|
728
|
+
this.trigger.setAttribute("role", "button");
|
|
729
|
+
}
|
|
730
|
+
this.dialog.ariaExpanded = "false";
|
|
731
|
+
this._setupEventHandlers();
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
static get defaults() {
|
|
735
|
+
return _defaults2;
|
|
736
|
+
}
|
|
737
|
+
static init(els, options) {
|
|
738
|
+
return super.init(els, options, _ExpandingCard);
|
|
739
|
+
}
|
|
740
|
+
static getInstance(el) {
|
|
741
|
+
return el["Expressive_ExpandingCard"];
|
|
742
|
+
}
|
|
743
|
+
destroy() {
|
|
744
|
+
this._removeEventHandlers();
|
|
745
|
+
this.closeGeneration++;
|
|
746
|
+
this.isOpen = false;
|
|
747
|
+
if (this.trigger) this.trigger.ariaExpanded = "false";
|
|
748
|
+
if (this.dialog) this.dialog.ariaExpanded = "false";
|
|
749
|
+
this.dialog?.classList.remove("expanded");
|
|
750
|
+
if (this.dialog?.open) this.dialog.close();
|
|
751
|
+
this.el["Expressive_ExpandingCard"] = void 0;
|
|
752
|
+
}
|
|
753
|
+
static Init() {
|
|
754
|
+
Utils.onDocumentReady(() => {
|
|
755
|
+
document.querySelectorAll(EXPANDING_CARD_SELECTOR).forEach((el) => {
|
|
756
|
+
if (el && el["Expressive_ExpandingCard"] == void 0) {
|
|
757
|
+
this.init(el);
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
// src/ts/components/menu.ts
|
|
765
|
+
var MIN_SURFACE_WIDTH = 112;
|
|
766
|
+
var MAX_SURFACE_WIDTH = 280;
|
|
767
|
+
var _defaults3 = {
|
|
572
768
|
alignment: "left",
|
|
573
769
|
autoFocus: true,
|
|
574
770
|
constrainWidth: true,
|
|
@@ -584,9 +780,12 @@ var _defaults2 = {
|
|
|
584
780
|
onCloseEnd: null,
|
|
585
781
|
onItemClick: null
|
|
586
782
|
};
|
|
783
|
+
var SPACE = " ";
|
|
587
784
|
var _Menu = class _Menu extends Component {
|
|
588
785
|
constructor(el, options) {
|
|
589
786
|
super(el, options, _Menu);
|
|
787
|
+
this._pendingTimers = /* @__PURE__ */ new Set();
|
|
788
|
+
this._transition = 0;
|
|
590
789
|
this._handleClick = (e) => {
|
|
591
790
|
e.preventDefault();
|
|
592
791
|
if (this.isOpen) {
|
|
@@ -620,7 +819,7 @@ var _Menu = class _Menu extends Component {
|
|
|
620
819
|
if (this.options.closeOnClick && this.menuEl?.contains(target) && !this.isTouchMoving) {
|
|
621
820
|
this.close();
|
|
622
821
|
} else if (!this.menuEl?.contains(target)) {
|
|
623
|
-
|
|
822
|
+
this._schedule(() => {
|
|
624
823
|
if (this.isOpen) {
|
|
625
824
|
this.close();
|
|
626
825
|
}
|
|
@@ -629,8 +828,8 @@ var _Menu = class _Menu extends Component {
|
|
|
629
828
|
this.isTouchMoving = false;
|
|
630
829
|
};
|
|
631
830
|
this._handleTriggerKeydown = (e) => {
|
|
632
|
-
const
|
|
633
|
-
if (
|
|
831
|
+
const opensMenu = e.key === SPACE || e.key === Utils.keys.ENTER || e.key === Utils.keys.ARROW_DOWN || e.key === Utils.keys.ARROW_UP;
|
|
832
|
+
if (opensMenu && !this.isOpen) {
|
|
634
833
|
e.preventDefault();
|
|
635
834
|
this.open();
|
|
636
835
|
}
|
|
@@ -644,13 +843,18 @@ var _Menu = class _Menu extends Component {
|
|
|
644
843
|
this._handleMenuClick = (e) => {
|
|
645
844
|
const target = e.target;
|
|
646
845
|
const li = target.closest("li");
|
|
846
|
+
if (li?.matches('.disabled, [aria-disabled="true"]')) {
|
|
847
|
+
e.preventDefault();
|
|
848
|
+
e.stopPropagation();
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
647
851
|
if (li && this._isSubmenuTriggerClick(target)) {
|
|
648
852
|
e.preventDefault();
|
|
649
853
|
e.stopPropagation();
|
|
650
854
|
this._toggleSubmenu(li);
|
|
651
855
|
return;
|
|
652
856
|
}
|
|
653
|
-
if (typeof this.options.onItemClick === "function") {
|
|
857
|
+
if (li && typeof this.options.onItemClick === "function") {
|
|
654
858
|
this.options.onItemClick.call(this, li);
|
|
655
859
|
}
|
|
656
860
|
};
|
|
@@ -663,11 +867,11 @@ var _Menu = class _Menu extends Component {
|
|
|
663
867
|
}
|
|
664
868
|
};
|
|
665
869
|
this._handleMenuKeydown = (e) => {
|
|
666
|
-
const arrowUpOrDown = Utils.keys.ARROW_DOWN
|
|
667
|
-
if (Utils.keys.TAB
|
|
870
|
+
const arrowUpOrDown = e.key === Utils.keys.ARROW_DOWN || e.key === Utils.keys.ARROW_UP;
|
|
871
|
+
if (e.key === Utils.keys.TAB) {
|
|
668
872
|
e.preventDefault();
|
|
669
873
|
this.close();
|
|
670
|
-
} else if (Utils.keys.ARROW_RIGHT
|
|
874
|
+
} else if (e.key === Utils.keys.ARROW_RIGHT && this.isOpen) {
|
|
671
875
|
const li = this._focusedRow(e);
|
|
672
876
|
if (li?.querySelector(":scope > menu")) {
|
|
673
877
|
e.preventDefault();
|
|
@@ -677,7 +881,7 @@ var _Menu = class _Menu extends Component {
|
|
|
677
881
|
const first = li.querySelector(":scope > menu > li");
|
|
678
882
|
first?.focus();
|
|
679
883
|
}
|
|
680
|
-
} else if (Utils.keys.ARROW_LEFT
|
|
884
|
+
} else if (e.key === Utils.keys.ARROW_LEFT && this.isOpen) {
|
|
681
885
|
const submenu = this._containingSubmenu(e);
|
|
682
886
|
if (submenu) {
|
|
683
887
|
e.preventDefault();
|
|
@@ -688,7 +892,7 @@ var _Menu = class _Menu extends Component {
|
|
|
688
892
|
}
|
|
689
893
|
} else if (arrowUpOrDown && this.isOpen) {
|
|
690
894
|
e.preventDefault();
|
|
691
|
-
const direction = Utils.keys.ARROW_DOWN
|
|
895
|
+
const direction = e.key === Utils.keys.ARROW_DOWN ? 1 : -1;
|
|
692
896
|
const list = this._containingSubmenu(e) ?? this.menuEl;
|
|
693
897
|
let newFocusedIndex = this.focusedIndex;
|
|
694
898
|
let hasFoundNewIndex = false;
|
|
@@ -700,17 +904,17 @@ var _Menu = class _Menu extends Component {
|
|
|
700
904
|
}
|
|
701
905
|
} while (newFocusedIndex < list.children.length && newFocusedIndex >= 0);
|
|
702
906
|
if (hasFoundNewIndex) {
|
|
703
|
-
if (this.focusedIndex >= 0)
|
|
704
|
-
list.children[this.focusedIndex]?.classList.remove("active");
|
|
907
|
+
if (this.focusedIndex >= 0) list.children[this.focusedIndex]?.classList.remove("active");
|
|
705
908
|
this.focusedIndex = newFocusedIndex;
|
|
706
909
|
const item = list.children[this.focusedIndex];
|
|
707
910
|
item.classList.add("active");
|
|
708
911
|
item.focus({ preventScroll: true });
|
|
709
912
|
}
|
|
710
|
-
} else if (Utils.keys.ENTER
|
|
913
|
+
} else if ((e.key === Utils.keys.ENTER || e.key === SPACE) && this.isOpen) {
|
|
711
914
|
const li = this._focusedRow(e);
|
|
915
|
+
e.preventDefault();
|
|
916
|
+
if (li?.matches('.disabled, [aria-disabled="true"]')) return;
|
|
712
917
|
if (li?.querySelector(":scope > menu")) {
|
|
713
|
-
e.preventDefault();
|
|
714
918
|
this._toggleSubmenu(li);
|
|
715
919
|
return;
|
|
716
920
|
}
|
|
@@ -721,7 +925,7 @@ var _Menu = class _Menu extends Component {
|
|
|
721
925
|
} else if (focusedElement instanceof HTMLElement) {
|
|
722
926
|
focusedElement.click();
|
|
723
927
|
}
|
|
724
|
-
} else if (Utils.keys.ESC
|
|
928
|
+
} else if (e.key === Utils.keys.ESC && this.isOpen) {
|
|
725
929
|
e.preventDefault();
|
|
726
930
|
const openSub = this.menuEl.querySelector("li.open");
|
|
727
931
|
if (openSub) {
|
|
@@ -735,11 +939,12 @@ var _Menu = class _Menu extends Component {
|
|
|
735
939
|
const keyText = e.key.toLowerCase();
|
|
736
940
|
const isLetter = /[a-zA-Z0-9-_]/.test(keyText);
|
|
737
941
|
const specialKeys = [
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
942
|
+
Utils.keys.ARROW_DOWN,
|
|
943
|
+
Utils.keys.ARROW_UP,
|
|
944
|
+
Utils.keys.ENTER,
|
|
945
|
+
Utils.keys.ESC,
|
|
946
|
+
Utils.keys.TAB,
|
|
947
|
+
SPACE
|
|
743
948
|
];
|
|
744
949
|
if (isLetter && !specialKeys.includes(e.key)) {
|
|
745
950
|
this.filterQuery.push(keyText);
|
|
@@ -768,16 +973,18 @@ var _Menu = class _Menu extends Component {
|
|
|
768
973
|
* Open menu.
|
|
769
974
|
*/
|
|
770
975
|
this.open = () => {
|
|
771
|
-
if (this.isOpen) return;
|
|
976
|
+
if (this.isOpen || this.el["Expressive_Menu"] !== this) return;
|
|
977
|
+
const transition = this._clearPendingTimers();
|
|
772
978
|
this.isOpen = true;
|
|
773
979
|
if (typeof this.options.onOpenStart === "function") {
|
|
774
980
|
this.options.onOpenStart.call(this, this.el);
|
|
775
981
|
}
|
|
982
|
+
if (transition !== this._transition) return;
|
|
776
983
|
this._resetMenuStyles();
|
|
777
984
|
this.menuEl.style.display = "block";
|
|
778
985
|
this._placeMenu();
|
|
986
|
+
this._schedule(() => this._setupTemporaryEventHandlers(), 0);
|
|
779
987
|
this._animateIn();
|
|
780
|
-
setTimeout(() => this._setupTemporaryEventHandlers(), 0);
|
|
781
988
|
this.el.ariaExpanded = "true";
|
|
782
989
|
};
|
|
783
990
|
/**
|
|
@@ -785,18 +992,20 @@ var _Menu = class _Menu extends Component {
|
|
|
785
992
|
*/
|
|
786
993
|
this.close = () => {
|
|
787
994
|
if (!this.isOpen) return;
|
|
995
|
+
const transition = this._clearPendingTimers();
|
|
788
996
|
this.isOpen = false;
|
|
789
997
|
this.focusedIndex = -1;
|
|
790
998
|
this._closeSubmenus();
|
|
791
999
|
if (typeof this.options.onCloseStart === "function") {
|
|
792
1000
|
this.options.onCloseStart.call(this, this.el);
|
|
793
1001
|
}
|
|
1002
|
+
if (transition !== this._transition) return;
|
|
794
1003
|
this._animateOut();
|
|
795
1004
|
this._removeTemporaryEventHandlers();
|
|
1005
|
+
this.el.ariaExpanded = "false";
|
|
796
1006
|
if (this.options.autoFocus) {
|
|
797
1007
|
this.el.focus();
|
|
798
1008
|
}
|
|
799
|
-
this.el.ariaExpanded = "false";
|
|
800
1009
|
};
|
|
801
1010
|
/**
|
|
802
1011
|
* While menu is open, you can recalculate its dimensions if its contents have changed.
|
|
@@ -810,7 +1019,7 @@ var _Menu = class _Menu extends Component {
|
|
|
810
1019
|
this.el["Expressive_Menu"] = this;
|
|
811
1020
|
_Menu._menus.push(this);
|
|
812
1021
|
this.id = Utils.getIdFromTrigger(el);
|
|
813
|
-
this.menuEl =
|
|
1022
|
+
this.menuEl = Utils.getElementById(el, this.id);
|
|
814
1023
|
this.options = {
|
|
815
1024
|
..._Menu.defaults,
|
|
816
1025
|
...options
|
|
@@ -821,13 +1030,17 @@ var _Menu = class _Menu extends Component {
|
|
|
821
1030
|
this.focusedIndex = -1;
|
|
822
1031
|
this.filterQuery = [];
|
|
823
1032
|
this.el.ariaExpanded = "false";
|
|
1033
|
+
if (!this.el.hasAttribute("aria-haspopup")) this.el.setAttribute("aria-haspopup", "menu");
|
|
1034
|
+
if (this.id && !this.el.hasAttribute("aria-controls"))
|
|
1035
|
+
this.el.setAttribute("aria-controls", this.id);
|
|
824
1036
|
this._moveMenuToElement();
|
|
1037
|
+
this._setupAccessibility();
|
|
825
1038
|
this._makeMenuFocusable();
|
|
826
1039
|
this._setupSubmenus();
|
|
827
1040
|
this._setupEventHandlers();
|
|
828
1041
|
}
|
|
829
1042
|
static get defaults() {
|
|
830
|
-
return
|
|
1043
|
+
return _defaults3;
|
|
831
1044
|
}
|
|
832
1045
|
/**
|
|
833
1046
|
* Initializes instances of Menu.
|
|
@@ -841,6 +1054,9 @@ var _Menu = class _Menu extends Component {
|
|
|
841
1054
|
return el["Expressive_Menu"];
|
|
842
1055
|
}
|
|
843
1056
|
destroy() {
|
|
1057
|
+
this._clearPendingTimers();
|
|
1058
|
+
this.isOpen = false;
|
|
1059
|
+
this.el.ariaExpanded = "false";
|
|
844
1060
|
clearTimeout(this.filterTimeout);
|
|
845
1061
|
this._resetMenuStyles();
|
|
846
1062
|
this._removeEventHandlers();
|
|
@@ -877,7 +1093,9 @@ var _Menu = class _Menu extends Component {
|
|
|
877
1093
|
}
|
|
878
1094
|
_setupTemporaryEventHandlers() {
|
|
879
1095
|
document.body.addEventListener("click", this._handleDocumentClick);
|
|
880
|
-
document.body.addEventListener("touchmove", this._handleDocumentTouchmove, {
|
|
1096
|
+
document.body.addEventListener("touchmove", this._handleDocumentTouchmove, {
|
|
1097
|
+
passive: true
|
|
1098
|
+
});
|
|
881
1099
|
this.menuEl?.addEventListener("keydown", this._handleMenuKeydown);
|
|
882
1100
|
window.addEventListener("resize", this._handleWindowResize);
|
|
883
1101
|
}
|
|
@@ -887,6 +1105,33 @@ var _Menu = class _Menu extends Component {
|
|
|
887
1105
|
this.menuEl?.removeEventListener("keydown", this._handleMenuKeydown);
|
|
888
1106
|
window.removeEventListener("resize", this._handleWindowResize);
|
|
889
1107
|
}
|
|
1108
|
+
_setupAccessibility() {
|
|
1109
|
+
if (!this.menuEl) return;
|
|
1110
|
+
if (!this.menuEl.hasAttribute("role")) this.menuEl.setAttribute("role", "menu");
|
|
1111
|
+
const menus = [this.menuEl, ...this.menuEl.querySelectorAll("menu")];
|
|
1112
|
+
menus.forEach((menu) => {
|
|
1113
|
+
if (!menu.hasAttribute("role")) menu.setAttribute("role", "menu");
|
|
1114
|
+
if (menu.getAttribute("role") !== "menu") return;
|
|
1115
|
+
menu.querySelectorAll(":scope > li").forEach((li) => {
|
|
1116
|
+
if (li.classList.contains("divider")) {
|
|
1117
|
+
if (!li.hasAttribute("role")) li.setAttribute("role", "separator");
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
if (li.classList.contains("gap")) {
|
|
1121
|
+
li.setAttribute("aria-hidden", "true");
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
if (li.classList.contains("label") || li.classList.contains("optgroup")) {
|
|
1125
|
+
if (!li.hasAttribute("role")) li.setAttribute("role", "presentation");
|
|
1126
|
+
return;
|
|
1127
|
+
}
|
|
1128
|
+
if (!li.hasAttribute("role")) li.setAttribute("role", "menuitem");
|
|
1129
|
+
if (li.classList.contains("disabled") && !li.hasAttribute("aria-disabled")) {
|
|
1130
|
+
li.setAttribute("aria-disabled", "true");
|
|
1131
|
+
}
|
|
1132
|
+
});
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
890
1135
|
_isSubmenuTriggerClick(target) {
|
|
891
1136
|
if (!this.menuEl) return false;
|
|
892
1137
|
const li = target.closest("li");
|
|
@@ -973,7 +1218,7 @@ var _Menu = class _Menu extends Component {
|
|
|
973
1218
|
_makeMenuFocusable() {
|
|
974
1219
|
if (!this.menuEl) return;
|
|
975
1220
|
this.menuEl.popover = "";
|
|
976
|
-
this.menuEl.tabIndex =
|
|
1221
|
+
this.menuEl.tabIndex = -1;
|
|
977
1222
|
this.menuEl.querySelectorAll(":scope li, :scope > hr").forEach((el) => {
|
|
978
1223
|
if (el instanceof HTMLHRElement || el.classList.contains("divider") || el.classList.contains("gap") || el.classList.contains("label") || el.classList.contains("optgroup")) {
|
|
979
1224
|
el.setAttribute("tabindex", "-1");
|
|
@@ -982,6 +1227,15 @@ var _Menu = class _Menu extends Component {
|
|
|
982
1227
|
if (!el.getAttribute("tabindex")) el.setAttribute("tabindex", "0");
|
|
983
1228
|
});
|
|
984
1229
|
}
|
|
1230
|
+
_focusInitialItem() {
|
|
1231
|
+
if (!this.menuEl || !this.options.autoFocus) return;
|
|
1232
|
+
const first = Array.from(this.menuEl.children).find(
|
|
1233
|
+
(child) => child instanceof HTMLElement && child.tabIndex !== -1
|
|
1234
|
+
);
|
|
1235
|
+
if (!first) return;
|
|
1236
|
+
this.focusedIndex = Array.from(this.menuEl.children).indexOf(first);
|
|
1237
|
+
first.focus({ preventScroll: true });
|
|
1238
|
+
}
|
|
985
1239
|
_focusFocusedItem() {
|
|
986
1240
|
if (this.focusedIndex >= 0 && this.focusedIndex < this.menuEl.children.length && this.options.autoFocus) {
|
|
987
1241
|
this.menuEl.children[this.focusedIndex].focus({
|
|
@@ -1065,18 +1319,32 @@ var _Menu = class _Menu extends Component {
|
|
|
1065
1319
|
width: idealWidth
|
|
1066
1320
|
};
|
|
1067
1321
|
}
|
|
1322
|
+
_schedule(callback, delay) {
|
|
1323
|
+
const timer = setTimeout(() => {
|
|
1324
|
+
this._pendingTimers.delete(timer);
|
|
1325
|
+
callback();
|
|
1326
|
+
}, delay);
|
|
1327
|
+
this._pendingTimers.add(timer);
|
|
1328
|
+
}
|
|
1329
|
+
_clearPendingTimers() {
|
|
1330
|
+
for (const timer of this._pendingTimers) clearTimeout(timer);
|
|
1331
|
+
this._pendingTimers.clear();
|
|
1332
|
+
return ++this._transition;
|
|
1333
|
+
}
|
|
1068
1334
|
_animateIn() {
|
|
1335
|
+
const transition = this._transition;
|
|
1069
1336
|
const duration = this.options.inDuration;
|
|
1070
1337
|
this.menuEl.style.transition = "none";
|
|
1071
1338
|
this.menuEl.style.opacity = "0";
|
|
1072
1339
|
this.menuEl.style.transform = "scale(0.85)";
|
|
1073
|
-
|
|
1340
|
+
this._schedule(() => {
|
|
1074
1341
|
this.menuEl.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
|
|
1075
1342
|
this.menuEl.style.opacity = "1";
|
|
1076
1343
|
this.menuEl.style.transform = "scale(1)";
|
|
1077
1344
|
}, 1);
|
|
1078
|
-
|
|
1079
|
-
|
|
1345
|
+
this._schedule(() => {
|
|
1346
|
+
this._focusInitialItem();
|
|
1347
|
+
if (transition !== this._transition) return;
|
|
1080
1348
|
if (typeof this.options.onOpenEnd === "function") this.options.onOpenEnd.call(this, this.el);
|
|
1081
1349
|
}, duration);
|
|
1082
1350
|
}
|
|
@@ -1085,7 +1353,7 @@ var _Menu = class _Menu extends Component {
|
|
|
1085
1353
|
this.menuEl.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
|
|
1086
1354
|
this.menuEl.style.opacity = "0";
|
|
1087
1355
|
this.menuEl.style.transform = "scale(0.85)";
|
|
1088
|
-
|
|
1356
|
+
this._schedule(() => {
|
|
1089
1357
|
this._resetMenuStyles();
|
|
1090
1358
|
if (typeof this.options.onCloseEnd === "function")
|
|
1091
1359
|
this.options.onCloseEnd.call(this, this.el);
|
|
@@ -1093,11 +1361,11 @@ var _Menu = class _Menu extends Component {
|
|
|
1093
1361
|
}
|
|
1094
1362
|
_getClosestAncestor(el, condition) {
|
|
1095
1363
|
let ancestor = el.parentNode;
|
|
1096
|
-
while (ancestor !== null && ancestor !== document) {
|
|
1097
|
-
if (condition(ancestor)) {
|
|
1364
|
+
while (ancestor !== null && ancestor !== void 0 && ancestor !== document) {
|
|
1365
|
+
if (ancestor.nodeType === Node.ELEMENT_NODE && condition(ancestor)) {
|
|
1098
1366
|
return ancestor;
|
|
1099
1367
|
}
|
|
1100
|
-
ancestor = ancestor.
|
|
1368
|
+
ancestor = ancestor.parentNode ?? ancestor.host;
|
|
1101
1369
|
}
|
|
1102
1370
|
return null;
|
|
1103
1371
|
}
|
|
@@ -1109,12 +1377,14 @@ var _Menu = class _Menu extends Component {
|
|
|
1109
1377
|
}
|
|
1110
1378
|
);
|
|
1111
1379
|
if (!closestOverflowParent) {
|
|
1112
|
-
|
|
1380
|
+
const parent = !!this.menuEl.offsetParent ? this.menuEl.offsetParent : this.menuEl.parentNode;
|
|
1381
|
+
closestOverflowParent = parent.host ?? parent;
|
|
1113
1382
|
}
|
|
1114
1383
|
if (getComputedStyle(closestOverflowParent).position === "static")
|
|
1115
1384
|
closestOverflowParent.style.position = "relative";
|
|
1116
1385
|
const natural = this.menuEl.getBoundingClientRect().width;
|
|
1117
|
-
const
|
|
1386
|
+
const triggerWidth = this.el.getBoundingClientRect().width;
|
|
1387
|
+
const idealWidth = this.options.constrainWidth && triggerWidth >= MIN_SURFACE_WIDTH ? triggerWidth : Math.min(MAX_SURFACE_WIDTH, Math.max(MIN_SURFACE_WIDTH, natural));
|
|
1118
1388
|
this.menuEl.style.width = idealWidth + "px";
|
|
1119
1389
|
const positionInfo = this._getMenuPosition(closestOverflowParent);
|
|
1120
1390
|
this.menuEl.style.left = positionInfo.x + "px";
|
|
@@ -1128,7 +1398,7 @@ _Menu._menus = [];
|
|
|
1128
1398
|
var Menu = _Menu;
|
|
1129
1399
|
|
|
1130
1400
|
// src/ts/components/autocomplete.ts
|
|
1131
|
-
var
|
|
1401
|
+
var _defaults4 = {
|
|
1132
1402
|
data: [],
|
|
1133
1403
|
// Autocomplete data set
|
|
1134
1404
|
onAutocomplete: null,
|
|
@@ -1158,7 +1428,7 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1158
1428
|
constructor(el, options) {
|
|
1159
1429
|
super(el, options, _Autocomplete);
|
|
1160
1430
|
this._handleInputBlur = () => {
|
|
1161
|
-
if (!this.
|
|
1431
|
+
if (!this._pointerDown) {
|
|
1162
1432
|
this.close();
|
|
1163
1433
|
this._resetAutocomplete();
|
|
1164
1434
|
}
|
|
@@ -1167,9 +1437,9 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1167
1437
|
if (e.type === "keyup") _Autocomplete._keydown = false;
|
|
1168
1438
|
this.count = 0;
|
|
1169
1439
|
const actualValue = this.el.value.toLocaleLowerCase();
|
|
1170
|
-
if (Utils.keys.ENTER
|
|
1440
|
+
if (e.key === Utils.keys.ENTER || e.key === Utils.keys.ARROW_UP || e.key === Utils.keys.ARROW_DOWN)
|
|
1171
1441
|
return;
|
|
1172
|
-
if (this.oldVal !== actualValue &&
|
|
1442
|
+
if (this.oldVal !== actualValue && this.el.matches(":focus-visible")) {
|
|
1173
1443
|
this.open();
|
|
1174
1444
|
}
|
|
1175
1445
|
this._inputChangeDetection(actualValue);
|
|
@@ -1193,7 +1463,7 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1193
1463
|
this._handleInputKeydown = (e) => {
|
|
1194
1464
|
_Autocomplete._keydown = true;
|
|
1195
1465
|
const numItems = this.container.querySelectorAll("li").length;
|
|
1196
|
-
if (Utils.keys.ENTER
|
|
1466
|
+
if (e.key === Utils.keys.ENTER && this.activeIndex >= 0) {
|
|
1197
1467
|
const liElement = this.container.querySelectorAll("li")[this.activeIndex];
|
|
1198
1468
|
if (liElement) {
|
|
1199
1469
|
this.selectOption(liElement.getAttribute("data-id"));
|
|
@@ -1201,15 +1471,14 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1201
1471
|
}
|
|
1202
1472
|
return;
|
|
1203
1473
|
}
|
|
1204
|
-
if (Utils.keys.ARROW_UP
|
|
1474
|
+
if (e.key === Utils.keys.ARROW_UP || e.key === Utils.keys.ARROW_DOWN) {
|
|
1205
1475
|
e.preventDefault();
|
|
1206
|
-
if (Utils.keys.ARROW_UP
|
|
1207
|
-
if (Utils.keys.ARROW_DOWN
|
|
1476
|
+
if (e.key === Utils.keys.ARROW_UP && this.activeIndex > 0) this.activeIndex--;
|
|
1477
|
+
if (e.key === Utils.keys.ARROW_DOWN && this.activeIndex < numItems - 1)
|
|
1208
1478
|
this.activeIndex++;
|
|
1209
|
-
this
|
|
1479
|
+
this._setActive(null);
|
|
1210
1480
|
if (this.activeIndex >= 0) {
|
|
1211
|
-
this
|
|
1212
|
-
this.$active?.classList.add("active");
|
|
1481
|
+
this._setActive(this.container.querySelectorAll("li")[this.activeIndex]);
|
|
1213
1482
|
this.container.children[this.activeIndex].scrollIntoView({
|
|
1214
1483
|
behavior: "smooth",
|
|
1215
1484
|
block: "nearest",
|
|
@@ -1221,11 +1490,17 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1221
1490
|
this._handleInputClick = () => {
|
|
1222
1491
|
this.open();
|
|
1223
1492
|
};
|
|
1224
|
-
|
|
1225
|
-
|
|
1493
|
+
// The flag says "a press is in flight inside the option list", so that a blur
|
|
1494
|
+
// caused by that press does not close the list out from under it. Without the
|
|
1495
|
+
// cancel half, a cancelled gesture left the flag set and the next blur could
|
|
1496
|
+
// not close the list at all.
|
|
1497
|
+
this._handleContainerPointerDown = (e) => {
|
|
1498
|
+
if (!e.isPrimary) return;
|
|
1499
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
1500
|
+
this._pointerDown = true;
|
|
1226
1501
|
};
|
|
1227
|
-
this.
|
|
1228
|
-
this.
|
|
1502
|
+
this._handleContainerPointerUp = () => {
|
|
1503
|
+
this._pointerDown = false;
|
|
1229
1504
|
};
|
|
1230
1505
|
/**
|
|
1231
1506
|
* Show autocomplete.
|
|
@@ -1238,7 +1513,9 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1238
1513
|
this._renderMenu();
|
|
1239
1514
|
}
|
|
1240
1515
|
if (!this.menu.isOpen) {
|
|
1241
|
-
|
|
1516
|
+
if (this._openTimer !== void 0) clearTimeout(this._openTimer);
|
|
1517
|
+
this._openTimer = setTimeout(() => {
|
|
1518
|
+
this._openTimer = void 0;
|
|
1242
1519
|
this.menu.open();
|
|
1243
1520
|
}, 0);
|
|
1244
1521
|
} else this.menu.recalculateDimensions();
|
|
@@ -1261,12 +1538,32 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1261
1538
|
this.selectedValues = this.selectedValues || this.options.selected.map((value) => ({ id: value })) || [];
|
|
1262
1539
|
this.menuItems = this.options.data || [];
|
|
1263
1540
|
this.$active = null;
|
|
1264
|
-
this.
|
|
1541
|
+
this._pointerDown = false;
|
|
1265
1542
|
this._setupMenu();
|
|
1266
1543
|
this._setupEventHandlers();
|
|
1267
1544
|
}
|
|
1545
|
+
/**
|
|
1546
|
+
* The active entry, for both the eye and the screen reader. The class alone
|
|
1547
|
+
* was invisible to assistive technology; aria-activedescendant on the input
|
|
1548
|
+
* is what reports the move.
|
|
1549
|
+
*
|
|
1550
|
+
* Deliberately does not touch aria-selected. Active and selected are two
|
|
1551
|
+
* different things - in a multi-select the checkboxes track real choices,
|
|
1552
|
+
* and folding the highlight into aria-selected would announce a committed
|
|
1553
|
+
* choice as unselected the moment the user arrowed past it.
|
|
1554
|
+
*/
|
|
1555
|
+
_setActive(item) {
|
|
1556
|
+
this.$active?.classList.remove("active");
|
|
1557
|
+
this.$active = item;
|
|
1558
|
+
if (item) {
|
|
1559
|
+
item.classList.add("active");
|
|
1560
|
+
this.el.setAttribute("aria-activedescendant", item.id);
|
|
1561
|
+
} else {
|
|
1562
|
+
this.el.removeAttribute("aria-activedescendant");
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1268
1565
|
static get defaults() {
|
|
1269
|
-
return
|
|
1566
|
+
return _defaults4;
|
|
1270
1567
|
}
|
|
1271
1568
|
/**
|
|
1272
1569
|
* Initializes instances of Autocomplete.
|
|
@@ -1292,6 +1589,10 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1292
1589
|
return _Autocomplete._loadingTemplate.cloneNode(true);
|
|
1293
1590
|
}
|
|
1294
1591
|
destroy() {
|
|
1592
|
+
if (this._openTimer !== void 0) {
|
|
1593
|
+
clearTimeout(this._openTimer);
|
|
1594
|
+
this._openTimer = void 0;
|
|
1595
|
+
}
|
|
1295
1596
|
this._removeEventHandlers();
|
|
1296
1597
|
this._removeMenu();
|
|
1297
1598
|
this.el["Expressive_Autocomplete"] = void 0;
|
|
@@ -1302,12 +1603,9 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1302
1603
|
this.el.addEventListener("focus", this._handleInputFocus);
|
|
1303
1604
|
this.el.addEventListener("keydown", this._handleInputKeydown);
|
|
1304
1605
|
this.el.addEventListener("click", this._handleInputClick);
|
|
1305
|
-
this.container.addEventListener("
|
|
1306
|
-
this.container.addEventListener("
|
|
1307
|
-
|
|
1308
|
-
this.container.addEventListener("touchstart", this._handleContainerMousedownAndTouchstart);
|
|
1309
|
-
this.container.addEventListener("touchend", this._handleContainerMouseupAndTouchend);
|
|
1310
|
-
}
|
|
1606
|
+
this.container.addEventListener("pointerdown", this._handleContainerPointerDown);
|
|
1607
|
+
this.container.addEventListener("pointerup", this._handleContainerPointerUp);
|
|
1608
|
+
this.container.addEventListener("pointercancel", this._handleContainerPointerUp);
|
|
1311
1609
|
}
|
|
1312
1610
|
_removeEventHandlers() {
|
|
1313
1611
|
this.el.removeEventListener("blur", this._handleInputBlur);
|
|
@@ -1315,12 +1613,9 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1315
1613
|
this.el.removeEventListener("focus", this._handleInputFocus);
|
|
1316
1614
|
this.el.removeEventListener("keydown", this._handleInputKeydown);
|
|
1317
1615
|
this.el.removeEventListener("click", this._handleInputClick);
|
|
1318
|
-
this.container.removeEventListener("
|
|
1319
|
-
this.container.removeEventListener("
|
|
1320
|
-
|
|
1321
|
-
this.container.removeEventListener("touchstart", this._handleContainerMousedownAndTouchstart);
|
|
1322
|
-
this.container.removeEventListener("touchend", this._handleContainerMouseupAndTouchend);
|
|
1323
|
-
}
|
|
1616
|
+
this.container.removeEventListener("pointerdown", this._handleContainerPointerDown);
|
|
1617
|
+
this.container.removeEventListener("pointerup", this._handleContainerPointerUp);
|
|
1618
|
+
this.container.removeEventListener("pointercancel", this._handleContainerPointerUp);
|
|
1324
1619
|
}
|
|
1325
1620
|
_setupMenu() {
|
|
1326
1621
|
this.container = document.createElement("menu");
|
|
@@ -1328,6 +1623,10 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1328
1623
|
this.container.id = `autocomplete-options-${Utils.guid()}`;
|
|
1329
1624
|
this.container.classList.add("autocomplete-content");
|
|
1330
1625
|
this.container.ariaExpanded = "true";
|
|
1626
|
+
this.container.setAttribute("role", "listbox");
|
|
1627
|
+
this.el.setAttribute("role", "combobox");
|
|
1628
|
+
this.el.setAttribute("aria-autocomplete", "list");
|
|
1629
|
+
this.el.setAttribute("aria-controls", this.container.id);
|
|
1331
1630
|
this.el.setAttribute("data-target", this.container.id);
|
|
1332
1631
|
this.menuItems.forEach((menuItem) => {
|
|
1333
1632
|
const itemElement = this._createMenuItem(menuItem);
|
|
@@ -1366,14 +1665,14 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1366
1665
|
}
|
|
1367
1666
|
_resetCurrentElementPosition() {
|
|
1368
1667
|
this.activeIndex = -1;
|
|
1369
|
-
this
|
|
1668
|
+
this._setActive(null);
|
|
1370
1669
|
}
|
|
1371
1670
|
_resetAutocomplete() {
|
|
1372
1671
|
this.container.replaceChildren();
|
|
1373
1672
|
this._resetCurrentElementPosition();
|
|
1374
1673
|
this.oldVal = null;
|
|
1375
1674
|
this.isOpen = false;
|
|
1376
|
-
this.
|
|
1675
|
+
this._pointerDown = false;
|
|
1377
1676
|
}
|
|
1378
1677
|
_highlightPartialText(input, label) {
|
|
1379
1678
|
const start = label.toLocaleLowerCase().indexOf("" + input.toLocaleLowerCase());
|
|
@@ -1385,6 +1684,10 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1385
1684
|
}
|
|
1386
1685
|
_createMenuItem(entry) {
|
|
1387
1686
|
const item = document.createElement("li");
|
|
1687
|
+
item.id = `autocomplete-option-${Utils.guid()}`;
|
|
1688
|
+
item.setAttribute("role", "option");
|
|
1689
|
+
const isSelected = this.selectedValues.some((sel) => sel.id === entry.id);
|
|
1690
|
+
item.setAttribute("aria-selected", isSelected ? "true" : "false");
|
|
1388
1691
|
item.setAttribute("data-id", entry.id);
|
|
1389
1692
|
item.setAttribute(
|
|
1390
1693
|
"style",
|
|
@@ -1397,7 +1700,7 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1397
1700
|
selection.style.textAlign = "center";
|
|
1398
1701
|
const checkbox = document.createElement("input");
|
|
1399
1702
|
checkbox.type = "checkbox";
|
|
1400
|
-
checkbox.checked =
|
|
1703
|
+
checkbox.checked = isSelected;
|
|
1401
1704
|
const spacer = document.createElement("span");
|
|
1402
1705
|
spacer.style.paddingLeft = "21px";
|
|
1403
1706
|
selection.append(checkbox, spacer);
|
|
@@ -1543,7 +1846,7 @@ _Autocomplete._loadingTemplate = null;
|
|
|
1543
1846
|
var Autocomplete = _Autocomplete;
|
|
1544
1847
|
|
|
1545
1848
|
// src/ts/components/chips.ts
|
|
1546
|
-
var
|
|
1849
|
+
var _defaults5 = {
|
|
1547
1850
|
data: [],
|
|
1548
1851
|
placeholder: "",
|
|
1549
1852
|
secondaryPlaceholder: "",
|
|
@@ -1552,6 +1855,7 @@ var _defaults4 = {
|
|
|
1552
1855
|
autocompleteOnly: false,
|
|
1553
1856
|
limit: Infinity,
|
|
1554
1857
|
allowUserInput: false,
|
|
1858
|
+
i18n: { remove: "Remove" },
|
|
1555
1859
|
onChipAdd: null,
|
|
1556
1860
|
onChipSelect: null,
|
|
1557
1861
|
onChipDelete: null
|
|
@@ -1561,7 +1865,7 @@ var _Chips = class _Chips extends Component {
|
|
|
1561
1865
|
super(el, options, _Chips);
|
|
1562
1866
|
this._handleChipClick = (e) => {
|
|
1563
1867
|
const _chip = e.target.closest(".chip");
|
|
1564
|
-
const clickedClose = e.target.
|
|
1868
|
+
const clickedClose = !!e.target.closest(".close");
|
|
1565
1869
|
if (_chip) {
|
|
1566
1870
|
const index = this._chips.indexOf(_chip);
|
|
1567
1871
|
if (index < 0) return;
|
|
@@ -1583,7 +1887,7 @@ var _Chips = class _Chips extends Component {
|
|
|
1583
1887
|
};
|
|
1584
1888
|
this._handleInputKeydown = (e) => {
|
|
1585
1889
|
_Chips._keydown = true;
|
|
1586
|
-
if (Utils.keys.ENTER
|
|
1890
|
+
if (e.key === Utils.keys.ENTER) {
|
|
1587
1891
|
if (this.hasAutocomplete && this.autocomplete && this.autocomplete.isOpen) {
|
|
1588
1892
|
return;
|
|
1589
1893
|
}
|
|
@@ -1592,7 +1896,7 @@ var _Chips = class _Chips extends Component {
|
|
|
1592
1896
|
this.addChip({ id: this._input.value });
|
|
1593
1897
|
}
|
|
1594
1898
|
this._input.value = "";
|
|
1595
|
-
} else if ((Utils.keys.BACKSPACE
|
|
1899
|
+
} else if ((e.key === Utils.keys.BACKSPACE || e.key === Utils.keys.ARROW_LEFT) && this._input.value === "" && this.chipsData.length) {
|
|
1596
1900
|
e.preventDefault();
|
|
1597
1901
|
this.selectChip(this.chipsData.length - 1);
|
|
1598
1902
|
}
|
|
@@ -1602,6 +1906,7 @@ var _Chips = class _Chips extends Component {
|
|
|
1602
1906
|
..._Chips.defaults,
|
|
1603
1907
|
...options
|
|
1604
1908
|
};
|
|
1909
|
+
if (options?.i18n) this.options.i18n = { ..._Chips.defaults.i18n, ...options.i18n };
|
|
1605
1910
|
this.el.classList.add("chips");
|
|
1606
1911
|
this.chipsData = [];
|
|
1607
1912
|
this._chips = [];
|
|
@@ -1617,8 +1922,22 @@ var _Chips = class _Chips extends Component {
|
|
|
1617
1922
|
}
|
|
1618
1923
|
this._setupLabel();
|
|
1619
1924
|
}
|
|
1925
|
+
/**
|
|
1926
|
+
* Selection is drawn by a class now, not by `:focus`, so it does not clear
|
|
1927
|
+
* itself when focus moves - every path that changes the selection has to go
|
|
1928
|
+
* through here or the class and the field drift apart.
|
|
1929
|
+
*
|
|
1930
|
+
* Deliberately no `aria-selected`: the chip is not an option in a listbox,
|
|
1931
|
+
* and putting the attribute on an element with no such role is the same
|
|
1932
|
+
* defect the semantics standard exists to remove.
|
|
1933
|
+
*/
|
|
1934
|
+
_setSelected(chip) {
|
|
1935
|
+
this._selectedChip?.classList.remove("selected");
|
|
1936
|
+
this._selectedChip = chip;
|
|
1937
|
+
chip?.classList.add("selected");
|
|
1938
|
+
}
|
|
1620
1939
|
static get defaults() {
|
|
1621
|
-
return
|
|
1940
|
+
return _defaults5;
|
|
1622
1941
|
}
|
|
1623
1942
|
/**
|
|
1624
1943
|
* Initializes instances of Chips.
|
|
@@ -1668,28 +1987,30 @@ var _Chips = class _Chips extends Component {
|
|
|
1668
1987
|
if (tag === "INPUT" || tag === "TEXTAREA" || !chipsKeydown) return;
|
|
1669
1988
|
const currChips = chips["Expressive_Chips"];
|
|
1670
1989
|
if (!currChips) return;
|
|
1671
|
-
if (Utils.keys.BACKSPACE
|
|
1990
|
+
if (e.key === Utils.keys.BACKSPACE || e.key === Utils.keys.DELETE) {
|
|
1672
1991
|
e.preventDefault();
|
|
1673
1992
|
let selectIndex = currChips.chipsData.length;
|
|
1674
1993
|
if (currChips._selectedChip) {
|
|
1675
1994
|
const index = currChips._chips.indexOf(currChips._selectedChip);
|
|
1676
1995
|
currChips.deleteChip(index);
|
|
1677
|
-
currChips.
|
|
1996
|
+
currChips._setSelected(null);
|
|
1678
1997
|
selectIndex = Math.max(index - 1, 0);
|
|
1679
1998
|
}
|
|
1680
1999
|
if (currChips.chipsData.length) currChips.selectChip(selectIndex);
|
|
1681
2000
|
else currChips._input.focus();
|
|
1682
|
-
} else if (Utils.keys.ARROW_LEFT
|
|
2001
|
+
} else if (e.key === Utils.keys.ARROW_LEFT) {
|
|
1683
2002
|
if (currChips._selectedChip) {
|
|
1684
2003
|
const selectIndex = currChips._chips.indexOf(currChips._selectedChip) - 1;
|
|
1685
2004
|
if (selectIndex < 0) return;
|
|
1686
2005
|
currChips.selectChip(selectIndex);
|
|
1687
2006
|
}
|
|
1688
|
-
} else if (Utils.keys.ARROW_RIGHT
|
|
2007
|
+
} else if (e.key === Utils.keys.ARROW_RIGHT) {
|
|
1689
2008
|
if (currChips._selectedChip) {
|
|
1690
2009
|
const selectIndex = currChips._chips.indexOf(currChips._selectedChip) + 1;
|
|
1691
|
-
if (selectIndex >= currChips.chipsData.length)
|
|
1692
|
-
|
|
2010
|
+
if (selectIndex >= currChips.chipsData.length) {
|
|
2011
|
+
currChips._setSelected(null);
|
|
2012
|
+
currChips._input.focus();
|
|
2013
|
+
} else currChips.selectChip(selectIndex);
|
|
1693
2014
|
}
|
|
1694
2015
|
}
|
|
1695
2016
|
}
|
|
@@ -1700,25 +2021,31 @@ var _Chips = class _Chips extends Component {
|
|
|
1700
2021
|
if (!_Chips._keydown && document.hidden) {
|
|
1701
2022
|
const chips = e.target.closest(".chips");
|
|
1702
2023
|
const currChips = chips?.["Expressive_Chips"];
|
|
1703
|
-
if (currChips) currChips.
|
|
2024
|
+
if (currChips) currChips._setSelected(null);
|
|
1704
2025
|
}
|
|
1705
2026
|
}
|
|
1706
2027
|
_renderChip(chip) {
|
|
1707
2028
|
if (!chip.id) return;
|
|
1708
|
-
const
|
|
2029
|
+
const label = chip.text || chip.id;
|
|
2030
|
+
const renderedChip = document.createElement("span");
|
|
1709
2031
|
renderedChip.classList.add("chip");
|
|
1710
|
-
renderedChip.innerText =
|
|
2032
|
+
renderedChip.innerText = label;
|
|
1711
2033
|
if (chip.image) {
|
|
1712
2034
|
const img = document.createElement("img");
|
|
1713
2035
|
img.setAttribute("src", chip.image);
|
|
1714
2036
|
renderedChip.insertBefore(img, renderedChip.firstChild);
|
|
1715
2037
|
}
|
|
1716
2038
|
if (this.options.allowUserInput) {
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
2039
|
+
const closeButton = document.createElement("button");
|
|
2040
|
+
closeButton.type = "button";
|
|
2041
|
+
closeButton.classList.add("close");
|
|
2042
|
+
closeButton.setAttribute("aria-label", `${this.options.i18n.remove} ${label}`);
|
|
2043
|
+
const closeIcon = document.createElement("span");
|
|
2044
|
+
closeIcon.classList.add(this.options.closeIconClass);
|
|
2045
|
+
closeIcon.setAttribute("aria-hidden", "true");
|
|
1720
2046
|
closeIcon.innerText = "close";
|
|
1721
|
-
|
|
2047
|
+
closeButton.appendChild(closeIcon);
|
|
2048
|
+
renderedChip.appendChild(closeButton);
|
|
1722
2049
|
}
|
|
1723
2050
|
return renderedChip;
|
|
1724
2051
|
}
|
|
@@ -1793,6 +2120,7 @@ var _Chips = class _Chips extends Component {
|
|
|
1793
2120
|
deleteChip(chipIndex) {
|
|
1794
2121
|
const chip = this._chips[chipIndex];
|
|
1795
2122
|
if (!chip) return;
|
|
2123
|
+
if (this._selectedChip === chip) this._setSelected(null);
|
|
1796
2124
|
chip.remove();
|
|
1797
2125
|
this._chips.splice(chipIndex, 1);
|
|
1798
2126
|
this.chipsData.splice(chipIndex, 1);
|
|
@@ -1808,8 +2136,8 @@ var _Chips = class _Chips extends Component {
|
|
|
1808
2136
|
selectChip(chipIndex) {
|
|
1809
2137
|
const chip = this._chips[chipIndex];
|
|
1810
2138
|
if (!chip) return;
|
|
1811
|
-
this.
|
|
1812
|
-
chip.focus();
|
|
2139
|
+
this._setSelected(chip);
|
|
2140
|
+
chip.querySelector(".close")?.focus();
|
|
1813
2141
|
if (typeof this.options.onChipSelect === "function") {
|
|
1814
2142
|
this.options.onChipSelect(this.el, chip);
|
|
1815
2143
|
}
|
|
@@ -1820,7 +2148,7 @@ var _Chips = class _Chips extends Component {
|
|
|
1820
2148
|
chips.forEach((el) => {
|
|
1821
2149
|
el.addEventListener("click", (e) => {
|
|
1822
2150
|
if (el["Expressive_Chips"]) return;
|
|
1823
|
-
if (e.target.
|
|
2151
|
+
if (e.target.closest(".close")) {
|
|
1824
2152
|
const chip = e.target.closest(".chip");
|
|
1825
2153
|
if (chip) chip.remove();
|
|
1826
2154
|
}
|
|
@@ -1832,97 +2160,93 @@ var _Chips = class _Chips extends Component {
|
|
|
1832
2160
|
_Chips._keydown = false;
|
|
1833
2161
|
var Chips = _Chips;
|
|
1834
2162
|
|
|
1835
|
-
// src/ts/components/
|
|
1836
|
-
var
|
|
1837
|
-
var
|
|
2163
|
+
// src/ts/components/slider.ts
|
|
2164
|
+
var _defaults6 = {};
|
|
2165
|
+
var Slider = class _Slider extends Component {
|
|
1838
2166
|
constructor(el, options) {
|
|
1839
|
-
super(el, options,
|
|
2167
|
+
super(el, options, _Slider);
|
|
1840
2168
|
this._handleRangeChange = () => {
|
|
1841
2169
|
this._clampDual();
|
|
1842
2170
|
this._sync();
|
|
1843
2171
|
this.thumb.classList.add("active");
|
|
1844
2172
|
};
|
|
1845
|
-
this.
|
|
1846
|
-
|
|
2173
|
+
this._handleRangePointerDown = (e) => {
|
|
2174
|
+
if (!e.isPrimary) return;
|
|
2175
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
2176
|
+
this._pointerDown = true;
|
|
1847
2177
|
this.el.classList.add("active");
|
|
1848
2178
|
this._clampDual();
|
|
1849
2179
|
this._sync();
|
|
1850
|
-
|
|
1851
|
-
this.thumb.classList.add("active");
|
|
1852
|
-
}
|
|
2180
|
+
this.thumb.classList.add("active");
|
|
1853
2181
|
};
|
|
1854
|
-
this.
|
|
1855
|
-
if (this.
|
|
2182
|
+
this._handleRangeInputOrMove = () => {
|
|
2183
|
+
if (this._pointerDown) {
|
|
1856
2184
|
this._clampDual();
|
|
1857
2185
|
this._sync();
|
|
1858
2186
|
this.thumb.classList.add("active");
|
|
1859
2187
|
}
|
|
1860
2188
|
};
|
|
1861
|
-
this.
|
|
1862
|
-
|
|
2189
|
+
this._handleRangePointerUp = (e) => {
|
|
2190
|
+
if (!e.isPrimary) return;
|
|
2191
|
+
this._pointerDown = false;
|
|
1863
2192
|
this.el.classList.remove("active");
|
|
1864
2193
|
};
|
|
1865
|
-
this.
|
|
1866
|
-
if (!this.
|
|
2194
|
+
this._handleRangeRelease = () => {
|
|
2195
|
+
if (!this._pointerDown) {
|
|
1867
2196
|
this.thumb.classList.remove("active");
|
|
1868
2197
|
}
|
|
1869
2198
|
};
|
|
1870
|
-
this.el["
|
|
2199
|
+
this.el["Expressive_Slider"] = this;
|
|
1871
2200
|
this.options = {
|
|
1872
|
-
...
|
|
2201
|
+
..._Slider.defaults,
|
|
1873
2202
|
...options
|
|
1874
2203
|
};
|
|
1875
|
-
this.
|
|
2204
|
+
this._pointerDown = false;
|
|
1876
2205
|
this._setupThumb();
|
|
1877
2206
|
this._sync();
|
|
1878
2207
|
this._setupEventHandlers();
|
|
1879
2208
|
}
|
|
1880
2209
|
static get defaults() {
|
|
1881
|
-
return
|
|
2210
|
+
return _defaults6;
|
|
1882
2211
|
}
|
|
1883
2212
|
/**
|
|
1884
|
-
* Initializes instances of
|
|
2213
|
+
* Initializes instances of Slider.
|
|
1885
2214
|
* @param els HTML elements.
|
|
1886
2215
|
* @param options Component options.
|
|
1887
2216
|
*/
|
|
1888
2217
|
static init(els, options = {}) {
|
|
1889
|
-
return super.init(els, options,
|
|
2218
|
+
return super.init(els, options, _Slider);
|
|
1890
2219
|
}
|
|
1891
2220
|
static getInstance(el) {
|
|
1892
|
-
return el["
|
|
2221
|
+
return el["Expressive_Slider"];
|
|
1893
2222
|
}
|
|
1894
2223
|
destroy() {
|
|
1895
2224
|
this._removeEventHandlers();
|
|
1896
2225
|
this._removeThumb();
|
|
1897
|
-
this.el["
|
|
2226
|
+
this.el["Expressive_Slider"] = void 0;
|
|
1898
2227
|
}
|
|
2228
|
+
// Eleven listeners used to cover four stages, because each one was written
|
|
2229
|
+
// twice - once for mouse, once for touch. One of the touch spellings,
|
|
2230
|
+
// `touchleave`, was never implemented by any browser at all.
|
|
1899
2231
|
_setupEventHandlers() {
|
|
1900
2232
|
this.el.addEventListener("change", this._handleRangeChange);
|
|
1901
|
-
this.el.addEventListener("
|
|
1902
|
-
this.el.addEventListener("
|
|
1903
|
-
this.el.addEventListener("
|
|
1904
|
-
this.el.addEventListener("
|
|
1905
|
-
this.el.addEventListener("
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
this.el.addEventListener("mouseup", this._handleRangeMouseupTouchend);
|
|
1909
|
-
this.el.addEventListener("touchend", this._handleRangeMouseupTouchend);
|
|
1910
|
-
this.el.addEventListener("blur", this._handleRangeBlurMouseoutTouchleave);
|
|
1911
|
-
this.el.addEventListener("mouseout", this._handleRangeBlurMouseoutTouchleave);
|
|
1912
|
-
this.el.addEventListener("touchleave", this._handleRangeBlurMouseoutTouchleave);
|
|
2233
|
+
this.el.addEventListener("pointerdown", this._handleRangePointerDown);
|
|
2234
|
+
this.el.addEventListener("input", this._handleRangeInputOrMove);
|
|
2235
|
+
this.el.addEventListener("pointermove", this._handleRangeInputOrMove, { passive: true });
|
|
2236
|
+
this.el.addEventListener("pointerup", this._handleRangePointerUp);
|
|
2237
|
+
this.el.addEventListener("pointercancel", this._handleRangePointerUp);
|
|
2238
|
+
this.el.addEventListener("blur", this._handleRangeRelease);
|
|
2239
|
+
this.el.addEventListener("mouseout", this._handleRangeRelease);
|
|
1913
2240
|
}
|
|
1914
2241
|
_removeEventHandlers() {
|
|
1915
2242
|
this.el.removeEventListener("change", this._handleRangeChange);
|
|
1916
|
-
this.el.removeEventListener("
|
|
1917
|
-
this.el.removeEventListener("
|
|
1918
|
-
this.el.removeEventListener("
|
|
1919
|
-
this.el.removeEventListener("
|
|
1920
|
-
this.el.removeEventListener("
|
|
1921
|
-
this.el.removeEventListener("
|
|
1922
|
-
this.el.removeEventListener("
|
|
1923
|
-
this.el.removeEventListener("blur", this._handleRangeBlurMouseoutTouchleave);
|
|
1924
|
-
this.el.removeEventListener("mouseout", this._handleRangeBlurMouseoutTouchleave);
|
|
1925
|
-
this.el.removeEventListener("touchleave", this._handleRangeBlurMouseoutTouchleave);
|
|
2243
|
+
this.el.removeEventListener("pointerdown", this._handleRangePointerDown);
|
|
2244
|
+
this.el.removeEventListener("input", this._handleRangeInputOrMove);
|
|
2245
|
+
this.el.removeEventListener("pointermove", this._handleRangeInputOrMove);
|
|
2246
|
+
this.el.removeEventListener("pointerup", this._handleRangePointerUp);
|
|
2247
|
+
this.el.removeEventListener("pointercancel", this._handleRangePointerUp);
|
|
2248
|
+
this.el.removeEventListener("blur", this._handleRangeRelease);
|
|
2249
|
+
this.el.removeEventListener("mouseout", this._handleRangeRelease);
|
|
1926
2250
|
}
|
|
1927
2251
|
_setupThumb() {
|
|
1928
2252
|
this.thumb = document.createElement("span");
|
|
@@ -1939,7 +2263,7 @@ var Range = class _Range extends Component {
|
|
|
1939
2263
|
return !!this.el.closest(".vertical");
|
|
1940
2264
|
}
|
|
1941
2265
|
_host() {
|
|
1942
|
-
return this.el.closest(".range, .range-field, label");
|
|
2266
|
+
return this.el.closest(".slider, .range, .range-field, label");
|
|
1943
2267
|
}
|
|
1944
2268
|
_clampDual() {
|
|
1945
2269
|
const host = this._host();
|
|
@@ -1994,7 +2318,7 @@ var Range = class _Range extends Component {
|
|
|
1994
2318
|
*/
|
|
1995
2319
|
static Init() {
|
|
1996
2320
|
Utils.onDocumentReady(() => {
|
|
1997
|
-
|
|
2321
|
+
_Slider.init(document.querySelectorAll("input[type=range]"), {});
|
|
1998
2322
|
});
|
|
1999
2323
|
}
|
|
2000
2324
|
};
|
|
@@ -2067,169 +2391,144 @@ var _Dialogs = class _Dialogs {
|
|
|
2067
2391
|
_Dialogs._down = null;
|
|
2068
2392
|
var Dialogs = _Dialogs;
|
|
2069
2393
|
|
|
2070
|
-
// src/ts/behaviors/
|
|
2071
|
-
var
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2394
|
+
// src/ts/behaviors/sheetDrag.ts
|
|
2395
|
+
var DISMISS_DISTANCE = 96;
|
|
2396
|
+
var DISMISS_VELOCITY = 0.5;
|
|
2397
|
+
var DRAG_SLOP = 4;
|
|
2398
|
+
function installSheetDrag(config) {
|
|
2399
|
+
const coord = (event) => config.axis === "x" ? event.clientX : event.clientY;
|
|
2400
|
+
let drag = null;
|
|
2401
|
+
const sheetFor = (target) => {
|
|
2402
|
+
if (!(target instanceof Element)) return null;
|
|
2403
|
+
const dialog = target.closest(config.selector);
|
|
2404
|
+
return dialog instanceof HTMLDialogElement ? dialog : null;
|
|
2405
|
+
};
|
|
2406
|
+
const reset = (dialog) => {
|
|
2407
|
+
dialog.style.transition = "";
|
|
2408
|
+
dialog.style.setProperty(config.property, "0px");
|
|
2409
|
+
};
|
|
2410
|
+
const onDown = (event) => {
|
|
2411
|
+
config.onPress?.();
|
|
2081
2412
|
if (!event.isPrimary) return;
|
|
2082
2413
|
if (event.pointerType === "mouse" && event.button !== 0) return;
|
|
2083
|
-
const dialog =
|
|
2414
|
+
const dialog = sheetFor(event.target);
|
|
2084
2415
|
if (!dialog?.open) {
|
|
2085
|
-
|
|
2416
|
+
drag = null;
|
|
2086
2417
|
return;
|
|
2087
2418
|
}
|
|
2088
|
-
if (!
|
|
2089
|
-
|
|
2419
|
+
if (!config.inHandle(event, dialog)) {
|
|
2420
|
+
drag = null;
|
|
2090
2421
|
return;
|
|
2091
2422
|
}
|
|
2092
2423
|
dialog.style.transition = "none";
|
|
2093
|
-
|
|
2424
|
+
drag = {
|
|
2094
2425
|
dialog,
|
|
2095
2426
|
pointerId: event.pointerId,
|
|
2096
|
-
|
|
2097
|
-
|
|
2427
|
+
direction: config.direction(dialog),
|
|
2428
|
+
start: coord(event),
|
|
2429
|
+
last: coord(event),
|
|
2098
2430
|
lastT: Date.now(),
|
|
2099
2431
|
shift: 0
|
|
2100
2432
|
};
|
|
2101
|
-
}
|
|
2102
|
-
|
|
2103
|
-
const drag = _BottomSheets._drag;
|
|
2433
|
+
};
|
|
2434
|
+
const onMove = (event) => {
|
|
2104
2435
|
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
2105
|
-
const
|
|
2106
|
-
drag.shift =
|
|
2107
|
-
drag.
|
|
2436
|
+
const delta = coord(event) - drag.start;
|
|
2437
|
+
drag.shift = drag.direction === 1 ? Math.max(0, delta) : Math.min(0, delta);
|
|
2438
|
+
drag.last = coord(event);
|
|
2108
2439
|
drag.lastT = Date.now();
|
|
2109
|
-
drag.dialog.style.setProperty(
|
|
2110
|
-
}
|
|
2111
|
-
|
|
2112
|
-
const
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
const
|
|
2118
|
-
|
|
2119
|
-
const dismiss =
|
|
2120
|
-
if (dismiss && dialog.open)
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2440
|
+
drag.dialog.style.setProperty(config.property, `${drag.shift}px`);
|
|
2441
|
+
};
|
|
2442
|
+
const onUp = (event) => {
|
|
2443
|
+
const held = drag;
|
|
2444
|
+
if (!held || held.pointerId !== event.pointerId) return;
|
|
2445
|
+
drag = null;
|
|
2446
|
+
held.dialog.style.transition = "";
|
|
2447
|
+
const dt = Math.max(1, Date.now() - held.lastT);
|
|
2448
|
+
const velocity = (coord(event) - held.last) / dt;
|
|
2449
|
+
config.onRelease?.(Math.abs(held.shift) > DRAG_SLOP);
|
|
2450
|
+
const dismiss = held.direction === 1 ? held.shift > DISMISS_DISTANCE || velocity > DISMISS_VELOCITY : held.shift < -DISMISS_DISTANCE || velocity < -DISMISS_VELOCITY;
|
|
2451
|
+
if (dismiss && held.dialog.open) held.dialog.close();
|
|
2452
|
+
held.dialog.style.setProperty(config.property, "0px");
|
|
2453
|
+
};
|
|
2454
|
+
const onCancel = () => {
|
|
2455
|
+
config.onRelease?.(false);
|
|
2456
|
+
const held = drag;
|
|
2457
|
+
drag = null;
|
|
2458
|
+
if (held) reset(held.dialog);
|
|
2459
|
+
};
|
|
2460
|
+
Utils.onDocumentReady(() => {
|
|
2461
|
+
document.addEventListener("pointerdown", onDown, { passive: true });
|
|
2462
|
+
document.addEventListener("pointermove", onMove, { passive: true });
|
|
2463
|
+
document.addEventListener("pointerup", onUp, { passive: true });
|
|
2464
|
+
document.addEventListener("pointercancel", onCancel, { passive: true });
|
|
2465
|
+
});
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
// src/ts/behaviors/bottomSheets.ts
|
|
2469
|
+
var SHEET_SELECTOR = "dialog.bottom-sheet, dialog.bottom";
|
|
2470
|
+
var _BottomSheets = class _BottomSheets {
|
|
2471
|
+
static Init() {
|
|
2472
|
+
installSheetDrag({
|
|
2473
|
+
selector: SHEET_SELECTOR,
|
|
2474
|
+
axis: "y",
|
|
2475
|
+
property: "--md-comp-bottom-sheet-shift",
|
|
2476
|
+
direction: () => 1,
|
|
2477
|
+
inHandle: (event, dialog) => {
|
|
2478
|
+
const target = event.target;
|
|
2479
|
+
if (target instanceof Element && target.closest(".handle")) return true;
|
|
2480
|
+
const rect = dialog.getBoundingClientRect();
|
|
2481
|
+
return event.clientY >= rect.top && event.clientY <= rect.top + 48;
|
|
2482
|
+
},
|
|
2483
|
+
onPress: () => {
|
|
2484
|
+
_BottomSheets._dragged = false;
|
|
2485
|
+
},
|
|
2486
|
+
onRelease: (dragged) => {
|
|
2487
|
+
_BottomSheets._dragged = dragged;
|
|
2488
|
+
}
|
|
2489
|
+
});
|
|
2490
|
+
Utils.onDocumentReady(() => {
|
|
2491
|
+
document.addEventListener("click", _BottomSheets._onClick);
|
|
2492
|
+
});
|
|
2136
2493
|
}
|
|
2137
|
-
static
|
|
2494
|
+
static _onClick(event) {
|
|
2138
2495
|
const target = event.target;
|
|
2139
|
-
if (target instanceof Element
|
|
2140
|
-
const
|
|
2141
|
-
|
|
2496
|
+
if (!(target instanceof Element)) return;
|
|
2497
|
+
const handle = target.closest(".handle, .drag-handle");
|
|
2498
|
+
if (!(handle instanceof HTMLButtonElement)) return;
|
|
2499
|
+
if (event.detail !== 0 && _BottomSheets._dragged) return;
|
|
2500
|
+
const dialog = handle.closest(SHEET_SELECTOR);
|
|
2501
|
+
if (dialog instanceof HTMLDialogElement && dialog.open) dialog.close();
|
|
2142
2502
|
}
|
|
2143
2503
|
};
|
|
2144
|
-
|
|
2504
|
+
/**
|
|
2505
|
+
* Whether the last pointer sequence moved. A drag ends with a `click` on the
|
|
2506
|
+
* element it started on, so without this the tail of a drag that snapped back
|
|
2507
|
+
* would dismiss the sheet the drag had just declined to dismiss.
|
|
2508
|
+
*/
|
|
2509
|
+
_BottomSheets._dragged = false;
|
|
2145
2510
|
var BottomSheets = _BottomSheets;
|
|
2146
2511
|
|
|
2147
2512
|
// src/ts/behaviors/sideSheets.ts
|
|
2148
|
-
var
|
|
2513
|
+
var startDocked = (dialog) => dialog.classList.contains("left") || dialog.classList.contains("left-sheet") || dialog.classList.contains("start");
|
|
2514
|
+
var SideSheets = class {
|
|
2149
2515
|
static Init() {
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2516
|
+
installSheetDrag({
|
|
2517
|
+
selector: "dialog.side-sheet, dialog.right, dialog.right-sheet, dialog.left, dialog.left-sheet",
|
|
2518
|
+
axis: "x",
|
|
2519
|
+
property: "--md-comp-side-sheet-shift",
|
|
2520
|
+
// A start-docked sheet leaves toward the start edge, so its dismissal
|
|
2521
|
+
// direction is the negative one.
|
|
2522
|
+
direction: (dialog) => startDocked(dialog) ? -1 : 1,
|
|
2523
|
+
inHandle: (event, dialog) => {
|
|
2524
|
+
const target = event.target;
|
|
2525
|
+
if (target instanceof Element && target.closest("header")) return true;
|
|
2526
|
+
const rect = dialog.getBoundingClientRect();
|
|
2527
|
+
return startDocked(dialog) ? event.clientX >= rect.right - 24 && event.clientX <= rect.right : event.clientX >= rect.left && event.clientX <= rect.left + 24;
|
|
2528
|
+
}
|
|
2155
2529
|
});
|
|
2156
2530
|
}
|
|
2157
|
-
static _onDown(event) {
|
|
2158
|
-
if (!event.isPrimary) return;
|
|
2159
|
-
if (event.pointerType === "mouse" && event.button !== 0) return;
|
|
2160
|
-
const dialog = _SideSheets._sheet(event.target);
|
|
2161
|
-
if (!dialog?.open) {
|
|
2162
|
-
_SideSheets._drag = null;
|
|
2163
|
-
return;
|
|
2164
|
-
}
|
|
2165
|
-
if (!_SideSheets._inHandle(event, dialog)) {
|
|
2166
|
-
_SideSheets._drag = null;
|
|
2167
|
-
return;
|
|
2168
|
-
}
|
|
2169
|
-
dialog.style.transition = "none";
|
|
2170
|
-
_SideSheets._drag = {
|
|
2171
|
-
dialog,
|
|
2172
|
-
pointerId: event.pointerId,
|
|
2173
|
-
startX: event.clientX,
|
|
2174
|
-
lastX: event.clientX,
|
|
2175
|
-
lastT: Date.now(),
|
|
2176
|
-
shift: 0,
|
|
2177
|
-
startDocked: _SideSheets._startDocked(dialog)
|
|
2178
|
-
};
|
|
2179
|
-
}
|
|
2180
|
-
static _onMove(event) {
|
|
2181
|
-
const drag = _SideSheets._drag;
|
|
2182
|
-
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
2183
|
-
const delta = event.clientX - drag.startX;
|
|
2184
|
-
const shift = drag.startDocked ? Math.min(0, delta) : Math.max(0, delta);
|
|
2185
|
-
drag.shift = shift;
|
|
2186
|
-
drag.lastX = event.clientX;
|
|
2187
|
-
drag.lastT = Date.now();
|
|
2188
|
-
drag.dialog.style.setProperty("--md-comp-side-sheet-shift", `${shift}px`);
|
|
2189
|
-
}
|
|
2190
|
-
static _onUp(event) {
|
|
2191
|
-
const drag = _SideSheets._drag;
|
|
2192
|
-
_SideSheets._drag = null;
|
|
2193
|
-
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
2194
|
-
const dialog = drag.dialog;
|
|
2195
|
-
dialog.style.transition = "";
|
|
2196
|
-
const dt = Math.max(1, Date.now() - drag.lastT);
|
|
2197
|
-
const velocity = (event.clientX - drag.lastX) / dt;
|
|
2198
|
-
const dismiss = drag.startDocked ? drag.shift < -96 || velocity < -0.5 : drag.shift > 96 || velocity > 0.5;
|
|
2199
|
-
if (dismiss && dialog.open) {
|
|
2200
|
-
dialog.close();
|
|
2201
|
-
}
|
|
2202
|
-
dialog.style.setProperty("--md-comp-side-sheet-shift", "0px");
|
|
2203
|
-
}
|
|
2204
|
-
static _onCancel() {
|
|
2205
|
-
const drag = _SideSheets._drag;
|
|
2206
|
-
_SideSheets._drag = null;
|
|
2207
|
-
if (!drag) return;
|
|
2208
|
-
drag.dialog.style.transition = "";
|
|
2209
|
-
drag.dialog.style.setProperty("--md-comp-side-sheet-shift", "0px");
|
|
2210
|
-
}
|
|
2211
|
-
static _sheet(target) {
|
|
2212
|
-
if (!(target instanceof Element)) return null;
|
|
2213
|
-
const dialog = target.closest(
|
|
2214
|
-
"dialog.side-sheet, dialog.right, dialog.right-sheet, dialog.left, dialog.left-sheet"
|
|
2215
|
-
);
|
|
2216
|
-
return dialog instanceof HTMLDialogElement ? dialog : null;
|
|
2217
|
-
}
|
|
2218
|
-
static _startDocked(dialog) {
|
|
2219
|
-
return dialog.classList.contains("left") || dialog.classList.contains("left-sheet") || dialog.classList.contains("start");
|
|
2220
|
-
}
|
|
2221
|
-
static _inHandle(event, dialog) {
|
|
2222
|
-
const target = event.target;
|
|
2223
|
-
if (target instanceof Element && target.closest("header")) return true;
|
|
2224
|
-
const rect = dialog.getBoundingClientRect();
|
|
2225
|
-
if (_SideSheets._startDocked(dialog)) {
|
|
2226
|
-
return event.clientX >= rect.right - 24 && event.clientX <= rect.right;
|
|
2227
|
-
}
|
|
2228
|
-
return event.clientX >= rect.left && event.clientX <= rect.left + 24;
|
|
2229
|
-
}
|
|
2230
2531
|
};
|
|
2231
|
-
_SideSheets._drag = null;
|
|
2232
|
-
var SideSheets = _SideSheets;
|
|
2233
2532
|
|
|
2234
2533
|
// src/ts/behaviors/forms.ts
|
|
2235
2534
|
var Forms = class _Forms {
|
|
@@ -2285,7 +2584,7 @@ var Forms = class _Forms {
|
|
|
2285
2584
|
document.addEventListener("keyup", (e) => {
|
|
2286
2585
|
const target = e.target;
|
|
2287
2586
|
if (target instanceof HTMLInputElement && ["radio", "checkbox"].includes(target.type)) {
|
|
2288
|
-
if (Utils.keys.TAB
|
|
2587
|
+
if (e.key === Utils.keys.TAB) {
|
|
2289
2588
|
target.classList.add("tabbed");
|
|
2290
2589
|
target.addEventListener("blur", () => target.classList.remove("tabbed"), {
|
|
2291
2590
|
once: true
|
|
@@ -2323,61 +2622,89 @@ var Forms = class _Forms {
|
|
|
2323
2622
|
}
|
|
2324
2623
|
};
|
|
2325
2624
|
|
|
2326
|
-
// src/ts/
|
|
2327
|
-
var
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
if (
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
const waveColor = `rgba(${color?.r || 0}, ${color?.g || 0}, ${color?.b || 0}, ${0.3 * (1 - easing)})`;
|
|
2350
|
-
const stop = 90 * easing + "%";
|
|
2351
|
-
targetElement.style.backgroundImage = "radial-gradient(" + circle + ", " + waveColor + " " + stop + ", transparent " + stop + ")";
|
|
2352
|
-
animationFrame = window.requestAnimationFrame(animationStep);
|
|
2353
|
-
} else {
|
|
2354
|
-
targetElement.style.backgroundImage = "none";
|
|
2355
|
-
window.cancelAnimationFrame(animationFrame);
|
|
2625
|
+
// src/ts/components/appBar.ts
|
|
2626
|
+
var _defaults7 = {};
|
|
2627
|
+
var AppBar = class _AppBar extends Component {
|
|
2628
|
+
constructor(el, options) {
|
|
2629
|
+
super(el, options, _AppBar);
|
|
2630
|
+
this._observer = null;
|
|
2631
|
+
this._sentinel = null;
|
|
2632
|
+
this._input = null;
|
|
2633
|
+
this._view = null;
|
|
2634
|
+
this._suppressSearchOpen = false;
|
|
2635
|
+
this._onIntersect = (entries) => {
|
|
2636
|
+
const entry = entries[0];
|
|
2637
|
+
if (!entry) return;
|
|
2638
|
+
this.el.classList.toggle("collapsed", !entry.isIntersecting);
|
|
2639
|
+
};
|
|
2640
|
+
this._onSearchViewClose = () => {
|
|
2641
|
+
this._suppressSearchOpen = true;
|
|
2642
|
+
};
|
|
2643
|
+
this._onSearchFocus = () => {
|
|
2644
|
+
if (!this._view) return;
|
|
2645
|
+
if (this._suppressSearchOpen) {
|
|
2646
|
+
this._suppressSearchOpen = false;
|
|
2647
|
+
return;
|
|
2356
2648
|
}
|
|
2649
|
+
if (this._view instanceof HTMLDialogElement) {
|
|
2650
|
+
if (!this._view.open) this._view.showModal();
|
|
2651
|
+
return;
|
|
2652
|
+
}
|
|
2653
|
+
this._view.hidden = false;
|
|
2654
|
+
this._input?.setAttribute("aria-expanded", "true");
|
|
2357
2655
|
};
|
|
2358
|
-
|
|
2656
|
+
this.el["Expressive_AppBar"] = this;
|
|
2657
|
+
this.options = { ..._AppBar.defaults, ...options };
|
|
2658
|
+
this._setupCollapse();
|
|
2659
|
+
this._setupSearch();
|
|
2359
2660
|
}
|
|
2360
|
-
static
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2661
|
+
static get defaults() {
|
|
2662
|
+
return _defaults7;
|
|
2663
|
+
}
|
|
2664
|
+
static init(els, options = {}) {
|
|
2665
|
+
return super.init(els, options, _AppBar);
|
|
2666
|
+
}
|
|
2667
|
+
static getInstance(el) {
|
|
2668
|
+
return el["Expressive_AppBar"];
|
|
2669
|
+
}
|
|
2670
|
+
destroy() {
|
|
2671
|
+
this._observer?.disconnect();
|
|
2672
|
+
this._observer = null;
|
|
2673
|
+
this._sentinel?.remove();
|
|
2674
|
+
this._sentinel = null;
|
|
2675
|
+
this._input?.removeEventListener("focus", this._onSearchFocus);
|
|
2676
|
+
this._view?.removeEventListener("close", this._onSearchViewClose);
|
|
2677
|
+
this.el.classList.remove("collapsed");
|
|
2678
|
+
this.el["Expressive_AppBar"] = void 0;
|
|
2679
|
+
}
|
|
2680
|
+
_setupCollapse() {
|
|
2681
|
+
if (!this.el.classList.contains("medium") && !this.el.classList.contains("large")) {
|
|
2682
|
+
return;
|
|
2683
|
+
}
|
|
2684
|
+
if (typeof IntersectionObserver === "undefined") return;
|
|
2685
|
+
this._sentinel = document.createElement("span");
|
|
2686
|
+
this._sentinel.setAttribute("aria-hidden", "true");
|
|
2687
|
+
this._sentinel.style.cssText = "display:block;width:100%;height:1px;margin-top:-1px;pointer-events:none;visibility:hidden";
|
|
2688
|
+
this.el.insertAdjacentElement("beforebegin", this._sentinel);
|
|
2689
|
+
this._observer = new IntersectionObserver(this._onIntersect);
|
|
2690
|
+
this._observer.observe(this._sentinel);
|
|
2691
|
+
}
|
|
2692
|
+
_setupSearch() {
|
|
2693
|
+
this._input = this.el.querySelector('input[type="search"]');
|
|
2694
|
+
if (!this._input) return;
|
|
2695
|
+
const id = this._input.getAttribute("aria-controls");
|
|
2696
|
+
if (id) this._view = document.getElementById(id);
|
|
2697
|
+
if (!this._view) this._view = this.el.querySelector(".search-view");
|
|
2698
|
+
if (!this._view) return;
|
|
2699
|
+
this._input.addEventListener("focus", this._onSearchFocus);
|
|
2700
|
+
if (this._view instanceof HTMLDialogElement) {
|
|
2701
|
+
this._view.addEventListener("close", this._onSearchViewClose);
|
|
2702
|
+
}
|
|
2376
2703
|
}
|
|
2377
2704
|
};
|
|
2378
2705
|
|
|
2379
2706
|
// src/ts/components/buttons.ts
|
|
2380
|
-
var
|
|
2707
|
+
var _defaults8 = {
|
|
2381
2708
|
direction: "top",
|
|
2382
2709
|
hoverEnabled: true,
|
|
2383
2710
|
toolbarEnabled: false
|
|
@@ -2412,13 +2739,13 @@ var FloatingActionButton = class _FloatingActionButton extends Component {
|
|
|
2412
2739
|
this._toggle();
|
|
2413
2740
|
};
|
|
2414
2741
|
this._handleAnchorKeydown = (e) => {
|
|
2415
|
-
if (Utils.keys.ENTER
|
|
2742
|
+
if (e.key === Utils.keys.ENTER || e.key === " ") {
|
|
2416
2743
|
e.preventDefault();
|
|
2417
2744
|
this._toggle();
|
|
2418
2745
|
}
|
|
2419
2746
|
};
|
|
2420
2747
|
this._handleDocumentKeydown = (e) => {
|
|
2421
|
-
if (Utils.keys.ESC
|
|
2748
|
+
if (e.key === Utils.keys.ESC) this.close();
|
|
2422
2749
|
};
|
|
2423
2750
|
this._handleDocumentClick = (e) => {
|
|
2424
2751
|
const target = e.target;
|
|
@@ -2438,22 +2765,19 @@ var FloatingActionButton = class _FloatingActionButton extends Component {
|
|
|
2438
2765
|
};
|
|
2439
2766
|
this.isOpen = false;
|
|
2440
2767
|
this._anchor = this.el.querySelector(":scope > a, :scope > button");
|
|
2441
|
-
this._menu = this.el.querySelector("ul, menu");
|
|
2442
2768
|
this.el.classList.add(`direction-${this.options.direction}`);
|
|
2443
2769
|
if (clickToToggle) this.el.classList.add("click-to-toggle");
|
|
2444
2770
|
if (toolbar) this.el.classList.add("toolbar");
|
|
2445
2771
|
if (this._anchor) {
|
|
2446
|
-
this._anchor.setAttribute("aria-haspopup", "menu");
|
|
2447
2772
|
this._anchor.setAttribute("aria-expanded", "false");
|
|
2448
2773
|
if (this._anchor instanceof HTMLAnchorElement && !this._anchor.hasAttribute("href") && this._anchor.tabIndex < 0) {
|
|
2449
2774
|
this._anchor.tabIndex = 0;
|
|
2450
2775
|
}
|
|
2451
2776
|
}
|
|
2452
|
-
if (this._menu) this._menu.setAttribute("role", "menu");
|
|
2453
2777
|
this._setupEventHandlers();
|
|
2454
2778
|
}
|
|
2455
2779
|
static get defaults() {
|
|
2456
|
-
return
|
|
2780
|
+
return _defaults8;
|
|
2457
2781
|
}
|
|
2458
2782
|
static init(els, options = {}) {
|
|
2459
2783
|
return super.init(els, options, _FloatingActionButton);
|
|
@@ -2490,17 +2814,240 @@ var FloatingActionButton = class _FloatingActionButton extends Component {
|
|
|
2490
2814
|
}
|
|
2491
2815
|
};
|
|
2492
2816
|
|
|
2817
|
+
// src/ts/components/buttonGroup.ts
|
|
2818
|
+
var _defaults9 = {};
|
|
2819
|
+
var VALID_SELECTION_MODES = /* @__PURE__ */ new Set(["single", "multiple"]);
|
|
2820
|
+
var PRESSED_CLASS = "button-group-pressed";
|
|
2821
|
+
var MAX_ICON_COMPRESSION = 0.15;
|
|
2822
|
+
var ButtonGroup = class _ButtonGroup extends Component {
|
|
2823
|
+
constructor(el, options = {}) {
|
|
2824
|
+
super(el, options, _ButtonGroup);
|
|
2825
|
+
this._pressedStyles = /* @__PURE__ */ new Map();
|
|
2826
|
+
this._releaseStyles = /* @__PURE__ */ new Map();
|
|
2827
|
+
this._releaseTimer = null;
|
|
2828
|
+
this._originalPressed = /* @__PURE__ */ new Map();
|
|
2829
|
+
this._activeItem = null;
|
|
2830
|
+
this._handleClick = (event) => {
|
|
2831
|
+
if (!this._selectionMode) return;
|
|
2832
|
+
const item = this._itemFromEvent(event);
|
|
2833
|
+
if (!(item instanceof HTMLButtonElement) || this._isDisabled(item)) return;
|
|
2834
|
+
this._rememberPressed(item);
|
|
2835
|
+
const willSelect = item.getAttribute("aria-pressed") !== "true";
|
|
2836
|
+
const selectedCount = this._toggleItems.filter(
|
|
2837
|
+
(button) => button.getAttribute("aria-pressed") === "true"
|
|
2838
|
+
).length;
|
|
2839
|
+
if (!willSelect && this.el.hasAttribute("data-selection-required") && selectedCount === 1) {
|
|
2840
|
+
return;
|
|
2841
|
+
}
|
|
2842
|
+
if (this._selectionMode === "single" && willSelect) {
|
|
2843
|
+
this._toggleItems.forEach((button) => {
|
|
2844
|
+
this._rememberPressed(button);
|
|
2845
|
+
button.setAttribute("aria-pressed", "false");
|
|
2846
|
+
});
|
|
2847
|
+
}
|
|
2848
|
+
item.setAttribute("aria-pressed", willSelect ? "true" : "false");
|
|
2849
|
+
};
|
|
2850
|
+
this._handlePointerDown = (event) => {
|
|
2851
|
+
if (event.button !== 0) return;
|
|
2852
|
+
const item = this._itemFromEvent(event);
|
|
2853
|
+
if (item && !this._isDisabled(item)) this._startPress(item);
|
|
2854
|
+
};
|
|
2855
|
+
this._handleKeyDown = (event) => {
|
|
2856
|
+
if (event.repeat || event.key !== " " && event.key !== "Enter") return;
|
|
2857
|
+
const item = this._itemFromEvent(event);
|
|
2858
|
+
if (item && !this._isDisabled(item)) this._startPress(item);
|
|
2859
|
+
};
|
|
2860
|
+
this._handleKeyUp = (event) => {
|
|
2861
|
+
if (event.key === " " || event.key === "Enter") this._resetPress();
|
|
2862
|
+
};
|
|
2863
|
+
this._handleFocusOut = (event) => {
|
|
2864
|
+
if (event.target === this._activeItem) this._resetPress();
|
|
2865
|
+
};
|
|
2866
|
+
this._resetPress = () => {
|
|
2867
|
+
this._activeItem?.classList.remove(PRESSED_CLASS);
|
|
2868
|
+
this._activeItem = null;
|
|
2869
|
+
if (!this._pressedStyles.size) return;
|
|
2870
|
+
this._finishRelease();
|
|
2871
|
+
this._releaseStyles = new Map(this._pressedStyles);
|
|
2872
|
+
for (const [item, style] of this._releaseStyles) {
|
|
2873
|
+
item.style.width = `${style.baseWidth}px`;
|
|
2874
|
+
}
|
|
2875
|
+
this._pressedStyles.clear();
|
|
2876
|
+
this._releaseTimer = window.setTimeout(this._finishRelease, 200);
|
|
2877
|
+
};
|
|
2878
|
+
this._finishRelease = () => {
|
|
2879
|
+
if (this._releaseTimer !== null) window.clearTimeout(this._releaseTimer);
|
|
2880
|
+
this._releaseTimer = null;
|
|
2881
|
+
for (const [item, style] of this._releaseStyles) item.style.width = style.width;
|
|
2882
|
+
this._releaseStyles.clear();
|
|
2883
|
+
};
|
|
2884
|
+
this.el["Expressive_ButtonGroup"] = this;
|
|
2885
|
+
this.options = { ..._ButtonGroup.defaults, ...options };
|
|
2886
|
+
if (this._selectionMode) {
|
|
2887
|
+
this._normalizeSelection();
|
|
2888
|
+
this.el.addEventListener("click", this._handleClick, true);
|
|
2889
|
+
}
|
|
2890
|
+
this.el.addEventListener("pointerdown", this._handlePointerDown);
|
|
2891
|
+
this.el.addEventListener("keydown", this._handleKeyDown);
|
|
2892
|
+
this.el.addEventListener("focusout", this._handleFocusOut);
|
|
2893
|
+
document.addEventListener("pointerup", this._resetPress);
|
|
2894
|
+
document.addEventListener("pointercancel", this._resetPress);
|
|
2895
|
+
document.addEventListener("keyup", this._handleKeyUp);
|
|
2896
|
+
window.addEventListener("blur", this._resetPress);
|
|
2897
|
+
}
|
|
2898
|
+
static get defaults() {
|
|
2899
|
+
return _defaults9;
|
|
2900
|
+
}
|
|
2901
|
+
static init(els, options = {}) {
|
|
2902
|
+
return super.init(els, options, _ButtonGroup);
|
|
2903
|
+
}
|
|
2904
|
+
static getInstance(el) {
|
|
2905
|
+
return el["Expressive_ButtonGroup"];
|
|
2906
|
+
}
|
|
2907
|
+
destroy() {
|
|
2908
|
+
this._resetPress();
|
|
2909
|
+
this._finishRelease();
|
|
2910
|
+
this.el.removeEventListener("click", this._handleClick, true);
|
|
2911
|
+
this.el.removeEventListener("pointerdown", this._handlePointerDown);
|
|
2912
|
+
this.el.removeEventListener("keydown", this._handleKeyDown);
|
|
2913
|
+
this.el.removeEventListener("focusout", this._handleFocusOut);
|
|
2914
|
+
document.removeEventListener("pointerup", this._resetPress);
|
|
2915
|
+
document.removeEventListener("pointercancel", this._resetPress);
|
|
2916
|
+
document.removeEventListener("keyup", this._handleKeyUp);
|
|
2917
|
+
window.removeEventListener("blur", this._resetPress);
|
|
2918
|
+
for (const [item, value] of this._originalPressed) {
|
|
2919
|
+
if (value === null) item.removeAttribute("aria-pressed");
|
|
2920
|
+
else item.setAttribute("aria-pressed", value);
|
|
2921
|
+
}
|
|
2922
|
+
this._originalPressed.clear();
|
|
2923
|
+
this.el["Expressive_ButtonGroup"] = void 0;
|
|
2924
|
+
}
|
|
2925
|
+
get _selectionMode() {
|
|
2926
|
+
const mode = this.el.dataset.selection;
|
|
2927
|
+
return VALID_SELECTION_MODES.has(mode) ? mode : null;
|
|
2928
|
+
}
|
|
2929
|
+
get _items() {
|
|
2930
|
+
return Array.from(this.el.children).filter(
|
|
2931
|
+
(child) => child instanceof HTMLButtonElement || child instanceof HTMLAnchorElement && child.classList.contains("button")
|
|
2932
|
+
);
|
|
2933
|
+
}
|
|
2934
|
+
get _toggleItems() {
|
|
2935
|
+
return this._items.filter(
|
|
2936
|
+
(item) => item instanceof HTMLButtonElement
|
|
2937
|
+
);
|
|
2938
|
+
}
|
|
2939
|
+
_normalizeSelection() {
|
|
2940
|
+
const items = this._toggleItems;
|
|
2941
|
+
items.forEach((item) => {
|
|
2942
|
+
this._rememberPressed(item);
|
|
2943
|
+
if (!["true", "false"].includes(item.getAttribute("aria-pressed") || "")) {
|
|
2944
|
+
item.setAttribute("aria-pressed", "false");
|
|
2945
|
+
}
|
|
2946
|
+
});
|
|
2947
|
+
if (this._selectionMode === "single") {
|
|
2948
|
+
const selected = items.filter((item) => item.getAttribute("aria-pressed") === "true");
|
|
2949
|
+
selected.slice(1).forEach((item) => item.setAttribute("aria-pressed", "false"));
|
|
2950
|
+
}
|
|
2951
|
+
if (this.el.hasAttribute("data-selection-required") && !items.some((item) => item.getAttribute("aria-pressed") === "true")) {
|
|
2952
|
+
items.find((item) => !this._isDisabled(item))?.setAttribute("aria-pressed", "true");
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
_itemFromEvent(event) {
|
|
2956
|
+
if (!(event.target instanceof Element)) return null;
|
|
2957
|
+
const item = event.target.closest("button, a.button");
|
|
2958
|
+
return item instanceof HTMLElement && item.parentElement === this.el ? item : null;
|
|
2959
|
+
}
|
|
2960
|
+
_isDisabled(item) {
|
|
2961
|
+
return item instanceof HTMLButtonElement && item.disabled || item.getAttribute("aria-disabled") === "true" || item.classList.contains("disabled");
|
|
2962
|
+
}
|
|
2963
|
+
_rememberPressed(item) {
|
|
2964
|
+
if (!this._originalPressed.has(item)) {
|
|
2965
|
+
this._originalPressed.set(item, item.getAttribute("aria-pressed"));
|
|
2966
|
+
}
|
|
2967
|
+
}
|
|
2968
|
+
_startPress(item) {
|
|
2969
|
+
if (this._activeItem) return;
|
|
2970
|
+
this._finishRelease();
|
|
2971
|
+
const items = this._items;
|
|
2972
|
+
const activeIndex = items.indexOf(item);
|
|
2973
|
+
if (activeIndex < 0) return;
|
|
2974
|
+
this._activeItem = item;
|
|
2975
|
+
item.classList.add(PRESSED_CLASS);
|
|
2976
|
+
if (this.el.classList.contains("connected") || items.length < 2) return;
|
|
2977
|
+
const rects = items.map((candidate) => candidate.getBoundingClientRect());
|
|
2978
|
+
const activeWidth = rects[activeIndex].width;
|
|
2979
|
+
if (activeWidth <= 0) return;
|
|
2980
|
+
const parsedMultiplier = Number.parseFloat(
|
|
2981
|
+
getComputedStyle(this.el).getPropertyValue(
|
|
2982
|
+
"--md-comp-button-group-pressed-item-width-multiplier"
|
|
2983
|
+
)
|
|
2984
|
+
);
|
|
2985
|
+
const multiplier = Number.isFinite(parsedMultiplier) ? parsedMultiplier : 0.15;
|
|
2986
|
+
const desiredGrowth = activeWidth * multiplier;
|
|
2987
|
+
const neighborIndexes = [activeIndex - 1, activeIndex + 1].filter(
|
|
2988
|
+
(index) => index >= 0 && index < items.length
|
|
2989
|
+
);
|
|
2990
|
+
const compression = /* @__PURE__ */ new Map();
|
|
2991
|
+
if (neighborIndexes.length === 1) {
|
|
2992
|
+
const index = neighborIndexes[0];
|
|
2993
|
+
compression.set(
|
|
2994
|
+
index,
|
|
2995
|
+
Math.min(desiredGrowth, this._compressionCapacity(items[index], rects[index]))
|
|
2996
|
+
);
|
|
2997
|
+
} else {
|
|
2998
|
+
const half = desiredGrowth / 2;
|
|
2999
|
+
for (const index of neighborIndexes) {
|
|
3000
|
+
compression.set(
|
|
3001
|
+
index,
|
|
3002
|
+
Math.min(half, this._compressionCapacity(items[index], rects[index]))
|
|
3003
|
+
);
|
|
3004
|
+
}
|
|
3005
|
+
let remaining = desiredGrowth - [...compression.values()].reduce((sum, value) => sum + value, 0);
|
|
3006
|
+
for (const index of neighborIndexes) {
|
|
3007
|
+
if (remaining <= 0) break;
|
|
3008
|
+
const capacity = this._compressionCapacity(items[index], rects[index]) - compression.get(index);
|
|
3009
|
+
const extra = Math.min(remaining, capacity);
|
|
3010
|
+
compression.set(index, compression.get(index) + extra);
|
|
3011
|
+
remaining -= extra;
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
const actualGrowth = [...compression.values()].reduce((sum, value) => sum + value, 0);
|
|
3015
|
+
if (actualGrowth <= 0) return;
|
|
3016
|
+
items.forEach((candidate, index) => {
|
|
3017
|
+
this._pressedStyles.set(candidate, {
|
|
3018
|
+
width: candidate.style.width,
|
|
3019
|
+
baseWidth: rects[index].width
|
|
3020
|
+
});
|
|
3021
|
+
candidate.style.width = `${rects[index].width}px`;
|
|
3022
|
+
});
|
|
3023
|
+
void this.el.offsetWidth;
|
|
3024
|
+
items.forEach((candidate, index) => {
|
|
3025
|
+
const adjustment = index === activeIndex ? actualGrowth : -(compression.get(index) || 0);
|
|
3026
|
+
candidate.style.width = `${rects[index].width + adjustment}px`;
|
|
3027
|
+
});
|
|
3028
|
+
}
|
|
3029
|
+
_compressionCapacity(item, rect) {
|
|
3030
|
+
const minimumWidth = item.classList.contains("icon-button") ? rect.width * (1 - MAX_ICON_COMPRESSION) : rect.height;
|
|
3031
|
+
return Math.max(0, rect.width - minimumWidth);
|
|
3032
|
+
}
|
|
3033
|
+
};
|
|
3034
|
+
|
|
2493
3035
|
// src/ts/components/carousel.ts
|
|
2494
|
-
var
|
|
3036
|
+
var _defaults10 = {
|
|
2495
3037
|
duration: 200,
|
|
2496
|
-
dist: -100,
|
|
2497
|
-
shift: 0,
|
|
2498
|
-
padding: 0,
|
|
2499
|
-
numVisible: 5,
|
|
2500
3038
|
fullWidth: false,
|
|
2501
3039
|
indicators: false,
|
|
2502
3040
|
noWrap: false,
|
|
2503
|
-
|
|
3041
|
+
interval: 0,
|
|
3042
|
+
height: null,
|
|
3043
|
+
onCycleTo: null,
|
|
3044
|
+
i18n: {
|
|
3045
|
+
carousel: "Carousel",
|
|
3046
|
+
item: "Item",
|
|
3047
|
+
of: "of",
|
|
3048
|
+
indicators: "Slides",
|
|
3049
|
+
slide: "Slide"
|
|
3050
|
+
}
|
|
2504
3051
|
};
|
|
2505
3052
|
var _Carousel = class _Carousel extends Component {
|
|
2506
3053
|
constructor(el, options) {
|
|
@@ -2511,101 +3058,112 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2511
3058
|
this._ignoreScroll = false;
|
|
2512
3059
|
this._trackRaf = null;
|
|
2513
3060
|
this._started = false;
|
|
3061
|
+
this._vertical = false;
|
|
3062
|
+
this._resizeObserver = null;
|
|
3063
|
+
this._usesWindowResize = false;
|
|
3064
|
+
this._dragPointerId = null;
|
|
3065
|
+
this._dragStartX = 0;
|
|
3066
|
+
this._dragStartY = 0;
|
|
3067
|
+
this._dragStartScroll = 0;
|
|
3068
|
+
this._suppressClick = false;
|
|
3069
|
+
this._suppressClickTimeout = null;
|
|
3070
|
+
this._generatedContainerRole = false;
|
|
3071
|
+
this._generatedContainerLabel = false;
|
|
3072
|
+
this._generatedContainerDescription = false;
|
|
3073
|
+
this._generatedWideLayout = false;
|
|
3074
|
+
this._generatedFixedHeight = false;
|
|
3075
|
+
this._authoredInlineHeight = null;
|
|
3076
|
+
this._autoAdvanceTimer = null;
|
|
3077
|
+
this._autoAdvances = false;
|
|
3078
|
+
this._autoPaused = false;
|
|
3079
|
+
this._hovered = false;
|
|
3080
|
+
this._focused = false;
|
|
3081
|
+
this._generatedItemTabIndexes = /* @__PURE__ */ new Set();
|
|
3082
|
+
this._generatedItemLabels = /* @__PURE__ */ new Set();
|
|
3083
|
+
this._generatedItemDescriptions = /* @__PURE__ */ new Set();
|
|
3084
|
+
this._generatedItemSizes = /* @__PURE__ */ new Set();
|
|
3085
|
+
this._authoredItemSizes = /* @__PURE__ */ new Set();
|
|
3086
|
+
this._itemA11yOriginal = /* @__PURE__ */ new Map();
|
|
2514
3087
|
this._handleThrottledResize = Utils.throttle(() => this._handleResize(), 200);
|
|
2515
|
-
this.
|
|
2516
|
-
if (e.
|
|
2517
|
-
if (e.
|
|
2518
|
-
|
|
3088
|
+
this._handleAutoAdvanceState = (e) => {
|
|
3089
|
+
if (e.type === "mouseenter") this._hovered = true;
|
|
3090
|
+
else if (e.type === "mouseleave") this._hovered = false;
|
|
3091
|
+
else if (e.type === "focusin") this._focused = true;
|
|
3092
|
+
else if (e.type === "focusout") this._focused = false;
|
|
3093
|
+
this._syncAutoAdvance();
|
|
3094
|
+
};
|
|
3095
|
+
this._tick = () => {
|
|
3096
|
+
this._autoAdvanceTimer = null;
|
|
3097
|
+
this._advance();
|
|
3098
|
+
this._syncAutoAdvance();
|
|
3099
|
+
};
|
|
3100
|
+
this._advance = () => {
|
|
3101
|
+
const next = this.center + 1;
|
|
3102
|
+
if (next < this.count) {
|
|
3103
|
+
this.set(next);
|
|
3104
|
+
return;
|
|
3105
|
+
}
|
|
3106
|
+
if (this.options.noWrap) {
|
|
3107
|
+
this._autoAdvances = false;
|
|
3108
|
+
this._syncAutoAdvance();
|
|
3109
|
+
return;
|
|
2519
3110
|
}
|
|
3111
|
+
this.set(0);
|
|
3112
|
+
};
|
|
3113
|
+
this._handleTrackPointerDown = (e) => {
|
|
3114
|
+
if (e.pointerType !== "mouse" || e.button !== 0) return;
|
|
2520
3115
|
this.pressed = true;
|
|
2521
3116
|
this.dragged = false;
|
|
2522
|
-
this.
|
|
2523
|
-
this.
|
|
2524
|
-
this.
|
|
2525
|
-
this.
|
|
2526
|
-
this.
|
|
2527
|
-
this.timestamp = Date.now();
|
|
3117
|
+
this._suppressClick = false;
|
|
3118
|
+
this._dragPointerId = e.pointerId;
|
|
3119
|
+
this._dragStartX = e.clientX;
|
|
3120
|
+
this._dragStartY = e.clientY;
|
|
3121
|
+
this._dragStartScroll = this._vertical ? this._scroller.scrollTop : this._scroller.scrollLeft;
|
|
2528
3122
|
try {
|
|
2529
|
-
this.
|
|
3123
|
+
this._scroller.setPointerCapture(e.pointerId);
|
|
2530
3124
|
} catch {
|
|
2531
3125
|
}
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
this.
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
const deltaY = Math.abs(this.referenceY - e.clientY);
|
|
2544
|
-
if (deltaY < 30 && !this.verticalDragged) {
|
|
2545
|
-
if (delta > 2 || delta < -2) {
|
|
2546
|
-
this.dragged = true;
|
|
2547
|
-
this.reference = e.clientX;
|
|
2548
|
-
this._scroll(this.offset + delta);
|
|
2549
|
-
}
|
|
2550
|
-
} else if (this.dragged) {
|
|
2551
|
-
e.preventDefault();
|
|
2552
|
-
} else {
|
|
2553
|
-
this.verticalDragged = true;
|
|
3126
|
+
};
|
|
3127
|
+
this._handleTrackPointerMove = (e) => {
|
|
3128
|
+
if (!this.pressed || e.pointerId !== this._dragPointerId) return;
|
|
3129
|
+
const deltaX = e.clientX - this._dragStartX;
|
|
3130
|
+
const deltaY = e.clientY - this._dragStartY;
|
|
3131
|
+
const primaryDelta = this._vertical ? deltaY : deltaX;
|
|
3132
|
+
const crossDelta = this._vertical ? deltaX : deltaY;
|
|
3133
|
+
if (!this.dragged) {
|
|
3134
|
+
if (Math.abs(primaryDelta) < 6 || Math.abs(primaryDelta) <= Math.abs(crossDelta)) return;
|
|
3135
|
+
this.dragged = true;
|
|
3136
|
+
this.el.classList.add("dragging");
|
|
2554
3137
|
}
|
|
2555
|
-
if (this.
|
|
3138
|
+
if (this._vertical) this._scroller.scrollTop = this._dragStartScroll - deltaY;
|
|
3139
|
+
else this._scroller.scrollLeft = this._dragStartScroll - deltaX;
|
|
3140
|
+
e.preventDefault();
|
|
2556
3141
|
};
|
|
2557
|
-
this.
|
|
2558
|
-
if (!this.pressed) return;
|
|
3142
|
+
this._handleTrackPointerUp = (e) => {
|
|
3143
|
+
if (!this.pressed || e.pointerId !== this._dragPointerId) return;
|
|
2559
3144
|
this.pressed = false;
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
this._trackRaf = null;
|
|
2563
|
-
}
|
|
3145
|
+
this._dragPointerId = null;
|
|
3146
|
+
this.el.classList.remove("dragging");
|
|
2564
3147
|
try {
|
|
2565
|
-
this.
|
|
3148
|
+
this._scroller.releasePointerCapture(e.pointerId);
|
|
2566
3149
|
} catch {
|
|
2567
3150
|
}
|
|
2568
|
-
this.
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
this.amplitude = this.target - this.offset;
|
|
2582
|
-
this.timestamp = Date.now();
|
|
2583
|
-
requestAnimationFrame(this._autoScroll);
|
|
2584
|
-
if (this.dragged) e.preventDefault();
|
|
3151
|
+
if (!this.dragged) return;
|
|
3152
|
+
this._suppressClick = true;
|
|
3153
|
+
window.clearTimeout(this._suppressClickTimeout);
|
|
3154
|
+
this._suppressClickTimeout = setTimeout(() => {
|
|
3155
|
+
this._suppressClick = false;
|
|
3156
|
+
}, 0);
|
|
3157
|
+
this._syncActive(this._nearestIndex(), true);
|
|
3158
|
+
};
|
|
3159
|
+
this._handleTrackClick = (e) => {
|
|
3160
|
+
if (!this._suppressClick) return;
|
|
3161
|
+
this._suppressClick = false;
|
|
3162
|
+
e.preventDefault();
|
|
3163
|
+
e.stopImmediatePropagation();
|
|
2585
3164
|
};
|
|
2586
|
-
this.
|
|
2587
|
-
if (
|
|
2588
|
-
e.preventDefault();
|
|
2589
|
-
e.stopPropagation();
|
|
2590
|
-
return;
|
|
2591
|
-
}
|
|
2592
|
-
const clickedElem = e.target.closest(".carousel-item");
|
|
2593
|
-
if (!clickedElem || !this.el.contains(clickedElem)) return;
|
|
2594
|
-
const clickedIndex = this.images.indexOf(clickedElem);
|
|
2595
|
-
const diff = this._wrap(this.center) - clickedIndex;
|
|
2596
|
-
if (diff !== 0) {
|
|
2597
|
-
e.preventDefault();
|
|
2598
|
-
e.stopPropagation();
|
|
2599
|
-
}
|
|
2600
|
-
if (clickedIndex < 0) {
|
|
2601
|
-
if (e.clientX - e.target.getBoundingClientRect().left > this.el.clientWidth / 2) {
|
|
2602
|
-
this.next();
|
|
2603
|
-
} else {
|
|
2604
|
-
this.prev();
|
|
2605
|
-
}
|
|
2606
|
-
} else {
|
|
2607
|
-
this._cycleTo(clickedIndex);
|
|
2608
|
-
}
|
|
3165
|
+
this._handleTrackDragStart = (e) => {
|
|
3166
|
+
if (e.target.closest("img, picture, video")) e.preventDefault();
|
|
2609
3167
|
};
|
|
2610
3168
|
this._handleIndicatorClick = (e) => {
|
|
2611
3169
|
e.stopPropagation();
|
|
@@ -2618,112 +3176,107 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2618
3176
|
this._handleKeydown = (e) => {
|
|
2619
3177
|
const target = e.target;
|
|
2620
3178
|
if (target.closest('input, textarea, select, [contenteditable="true"]')) return;
|
|
2621
|
-
|
|
3179
|
+
const forward = this._vertical ? e.key === "ArrowDown" : e.key === Utils.keys.ARROW_RIGHT;
|
|
3180
|
+
const backward = this._vertical ? e.key === "ArrowUp" : e.key === Utils.keys.ARROW_LEFT;
|
|
3181
|
+
if (e.key === "Home") {
|
|
3182
|
+
e.preventDefault();
|
|
3183
|
+
this.set(0);
|
|
3184
|
+
this._focusItem(0);
|
|
3185
|
+
} else if (e.key === "End") {
|
|
3186
|
+
e.preventDefault();
|
|
3187
|
+
this.set(this.count - 1);
|
|
3188
|
+
this._focusItem(this.count - 1);
|
|
3189
|
+
} else if (forward) {
|
|
2622
3190
|
e.preventDefault();
|
|
2623
3191
|
this.next();
|
|
2624
|
-
|
|
3192
|
+
this._focusItem(this.center);
|
|
3193
|
+
} else if (backward) {
|
|
2625
3194
|
e.preventDefault();
|
|
2626
3195
|
this.prev();
|
|
3196
|
+
this._focusItem(this.center);
|
|
2627
3197
|
}
|
|
2628
3198
|
};
|
|
2629
|
-
this.
|
|
2630
|
-
if (this.
|
|
2631
|
-
|
|
2632
|
-
|
|
3199
|
+
this._handleTrackScroll = () => {
|
|
3200
|
+
if (!this.el.classList.contains("scrolling")) this.el.classList.add("scrolling");
|
|
3201
|
+
window.clearTimeout(this.scrollingTimeout);
|
|
3202
|
+
this.scrollingTimeout = setTimeout(() => this.el.classList.remove("scrolling"), 120);
|
|
3203
|
+
if (this._trackRaf !== null) return;
|
|
3204
|
+
this._trackRaf = requestAnimationFrame(() => {
|
|
3205
|
+
this._trackRaf = null;
|
|
3206
|
+
this._updateParallax();
|
|
3207
|
+
if (this._ignoreScroll) return;
|
|
3208
|
+
const index = this._nearestIndex();
|
|
3209
|
+
if (index !== this.center) this._syncActive(index, this.dragged);
|
|
3210
|
+
});
|
|
2633
3211
|
};
|
|
2634
3212
|
this._handleResize = () => {
|
|
2635
3213
|
if (!this.images.length) return;
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
if (this.options.fullWidth) {
|
|
2641
|
-
const firstItem = this.images[0];
|
|
2642
|
-
if (!firstItem) return;
|
|
2643
|
-
this.itemWidth = firstItem.clientWidth;
|
|
2644
|
-
this.dim = this.itemWidth * 2 + this.options.padding;
|
|
2645
|
-
this.offset = this.center * 2 * this.itemWidth;
|
|
2646
|
-
this.target = this.offset;
|
|
2647
|
-
} else {
|
|
2648
|
-
this._scroll();
|
|
2649
|
-
}
|
|
2650
|
-
};
|
|
2651
|
-
this._track = () => {
|
|
2652
|
-
const now = Date.now();
|
|
2653
|
-
const elapsed = now - this.timestamp;
|
|
2654
|
-
const delta = this.offset - this.frame;
|
|
2655
|
-
const v = 1e3 * delta / (1 + elapsed);
|
|
2656
|
-
this.timestamp = now;
|
|
2657
|
-
this.frame = this.offset;
|
|
2658
|
-
this.velocity = 0.8 * v + 0.2 * this.velocity;
|
|
2659
|
-
};
|
|
2660
|
-
this._autoScroll = () => {
|
|
2661
|
-
if (!this.amplitude) return;
|
|
2662
|
-
const elapsed = Date.now() - this.timestamp;
|
|
2663
|
-
const delta = this.amplitude * Math.exp(-elapsed / this.options.duration);
|
|
2664
|
-
if (delta > 2 || delta < -2) {
|
|
2665
|
-
this._scroll(this.target - delta);
|
|
2666
|
-
requestAnimationFrame(this._autoScroll);
|
|
2667
|
-
} else {
|
|
2668
|
-
this._scroll(this.target);
|
|
2669
|
-
}
|
|
3214
|
+
this._syncAdaptiveMode();
|
|
3215
|
+
this._syncLayoutRoles(this.center);
|
|
3216
|
+
this._scrollToIndex(this.center, false);
|
|
3217
|
+
this._updateParallax();
|
|
2670
3218
|
};
|
|
2671
3219
|
this.el["Expressive_Carousel"] = this;
|
|
2672
3220
|
this.options = {
|
|
2673
3221
|
..._Carousel.defaults,
|
|
2674
3222
|
...options
|
|
2675
3223
|
};
|
|
2676
|
-
|
|
2677
|
-
|
|
3224
|
+
if (options?.i18n) {
|
|
3225
|
+
this.options.i18n = { ..._Carousel.defaults.i18n, ...options.i18n };
|
|
3226
|
+
}
|
|
3227
|
+
if (this.options.fullWidth || this.el.classList.contains("flat")) {
|
|
2678
3228
|
this.el.classList.add("flat");
|
|
2679
3229
|
this.options.fullWidth = true;
|
|
2680
|
-
this.options.dist = 0;
|
|
2681
|
-
}
|
|
2682
|
-
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
2683
|
-
this.options.duration = 1;
|
|
2684
|
-
if (!this._flat) this.options.dist = 0;
|
|
2685
3230
|
}
|
|
3231
|
+
this._vertical = this.el.classList.contains("full-screen");
|
|
3232
|
+
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
3233
|
+
if (reducedMotion) this.options.duration = 1;
|
|
2686
3234
|
this.pressed = false;
|
|
2687
3235
|
this.dragged = false;
|
|
2688
|
-
this.offset = this.target = 0;
|
|
2689
3236
|
this.images = this._collectItems();
|
|
2690
3237
|
if (!this.images.length) {
|
|
2691
3238
|
console.error("Carousel: no .carousel-item elements to show");
|
|
2692
3239
|
return;
|
|
2693
3240
|
}
|
|
3241
|
+
this.images.forEach((item) => {
|
|
3242
|
+
this._itemA11yOriginal.set(item, {
|
|
3243
|
+
ariaHidden: item.getAttribute("aria-hidden"),
|
|
3244
|
+
tabIndex: item.getAttribute("tabindex")
|
|
3245
|
+
});
|
|
3246
|
+
if (item.hasAttribute("data-carousel-size")) this._authoredItemSizes.add(item);
|
|
3247
|
+
});
|
|
2694
3248
|
this.hasMultipleSlides = this.images.length > 1;
|
|
2695
3249
|
this.showIndicators = this.options.indicators && this.hasMultipleSlides;
|
|
2696
|
-
this.noWrap = this.options.noWrap || !this.hasMultipleSlides || this._flat;
|
|
2697
3250
|
this.count = this.images.length;
|
|
2698
|
-
this.
|
|
3251
|
+
this._autoAdvances = this.options.interval > 0 && this.hasMultipleSlides && !reducedMotion;
|
|
2699
3252
|
this.images.forEach((item) => item.classList.add("carousel-item"));
|
|
2700
|
-
if (this.
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
3253
|
+
if (this.options.height !== null) {
|
|
3254
|
+
this._generatedFixedHeight = !this.el.classList.contains("fixed-height");
|
|
3255
|
+
this._authoredInlineHeight = this.el.style.getPropertyValue("--carousel-height") || null;
|
|
3256
|
+
this.el.classList.add("fixed-height");
|
|
3257
|
+
this.el.style.setProperty("--carousel-height", `${this.options.height}px`);
|
|
3258
|
+
}
|
|
3259
|
+
this._wrapTrack();
|
|
3260
|
+
this._syncAdaptiveMode();
|
|
2705
3261
|
if (this.showIndicators) this._setupIndicators();
|
|
2706
|
-
this.
|
|
2707
|
-
this.el.setAttribute("aria-roledescription", "carousel");
|
|
3262
|
+
this._setupAccessibility();
|
|
2708
3263
|
this._setupEventHandlers();
|
|
2709
3264
|
this._started = true;
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
this._scroll(this.offset);
|
|
2720
|
-
}
|
|
3265
|
+
const start = Math.max(
|
|
3266
|
+
0,
|
|
3267
|
+
this.images.findIndex((el2) => el2.classList.contains("active"))
|
|
3268
|
+
);
|
|
3269
|
+
this.center = start;
|
|
3270
|
+
this._syncActive(start, false);
|
|
3271
|
+
this._updateParallax();
|
|
3272
|
+
this._scrollToIndex(start, false);
|
|
3273
|
+
this._syncAutoAdvance();
|
|
2721
3274
|
}
|
|
2722
3275
|
get _scroller() {
|
|
2723
3276
|
return this._trackEl ?? this.el;
|
|
2724
3277
|
}
|
|
2725
3278
|
static get defaults() {
|
|
2726
|
-
return
|
|
3279
|
+
return _defaults10;
|
|
2727
3280
|
}
|
|
2728
3281
|
static init(els, options = {}) {
|
|
2729
3282
|
return super.init(els, options, _Carousel);
|
|
@@ -2748,6 +3301,39 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2748
3301
|
return el.tagName !== "NAV";
|
|
2749
3302
|
});
|
|
2750
3303
|
}
|
|
3304
|
+
_setupAccessibility() {
|
|
3305
|
+
if (!this.el.hasAttribute("role")) {
|
|
3306
|
+
this.el.setAttribute("role", "region");
|
|
3307
|
+
this._generatedContainerRole = true;
|
|
3308
|
+
}
|
|
3309
|
+
if (!this.el.hasAttribute("aria-label") && !this.el.hasAttribute("aria-labelledby")) {
|
|
3310
|
+
this.el.setAttribute("aria-label", this.options.i18n.carousel);
|
|
3311
|
+
this._generatedContainerLabel = true;
|
|
3312
|
+
}
|
|
3313
|
+
if (!this.el.hasAttribute("aria-roledescription")) {
|
|
3314
|
+
this.el.setAttribute("aria-roledescription", "carousel");
|
|
3315
|
+
this._generatedContainerDescription = true;
|
|
3316
|
+
}
|
|
3317
|
+
const naturallyFocusable = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
3318
|
+
this.images.forEach((item, index) => {
|
|
3319
|
+
if (!item.hasAttribute("aria-roledescription")) {
|
|
3320
|
+
item.setAttribute("aria-roledescription", "slide");
|
|
3321
|
+
this._generatedItemDescriptions.add(item);
|
|
3322
|
+
}
|
|
3323
|
+
if (!item.hasAttribute("aria-label") && !item.hasAttribute("aria-labelledby")) {
|
|
3324
|
+
const mediaName = item.querySelector("img[alt]")?.getAttribute("alt")?.trim();
|
|
3325
|
+
const textName = item.textContent?.replace(/\s+/g, " ").trim();
|
|
3326
|
+
const name = mediaName || textName;
|
|
3327
|
+
const position = `${this.options.i18n.item} ${index + 1} ${this.options.i18n.of} ${this.count}`;
|
|
3328
|
+
item.setAttribute("aria-label", name ? `${name}, ${position}` : position);
|
|
3329
|
+
this._generatedItemLabels.add(item);
|
|
3330
|
+
}
|
|
3331
|
+
if (!item.matches(naturallyFocusable) && !item.querySelector(naturallyFocusable)) {
|
|
3332
|
+
item.tabIndex = 0;
|
|
3333
|
+
this._generatedItemTabIndexes.add(item);
|
|
3334
|
+
}
|
|
3335
|
+
});
|
|
3336
|
+
}
|
|
2751
3337
|
_setupIndicators() {
|
|
2752
3338
|
const existing = Array.from(this.el.children).find(
|
|
2753
3339
|
(el) => el instanceof HTMLElement && el.classList.contains("indicators")
|
|
@@ -2755,7 +3341,7 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2755
3341
|
this._indicators = existing ?? document.createElement("nav");
|
|
2756
3342
|
this._ownIndicators = !existing;
|
|
2757
3343
|
this._indicators.classList.add("indicators");
|
|
2758
|
-
this._indicators.setAttribute("aria-label",
|
|
3344
|
+
this._indicators.setAttribute("aria-label", this.options.i18n.indicators);
|
|
2759
3345
|
this._indicators.replaceChildren();
|
|
2760
3346
|
this.images.forEach((_, i) => {
|
|
2761
3347
|
const button = document.createElement("button");
|
|
@@ -2765,158 +3351,124 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2765
3351
|
button.classList.add("active");
|
|
2766
3352
|
button.setAttribute("aria-current", "true");
|
|
2767
3353
|
}
|
|
2768
|
-
button.setAttribute("aria-label",
|
|
3354
|
+
button.setAttribute("aria-label", `${this.options.i18n.slide} ${i + 1}`);
|
|
2769
3355
|
this._indicators.appendChild(button);
|
|
2770
3356
|
});
|
|
2771
3357
|
if (this._ownIndicators) this.el.appendChild(this._indicators);
|
|
2772
|
-
|
|
2773
|
-
this.el.querySelector(".carousel-fixed-item")?.classList.add("with-indicators");
|
|
2774
|
-
}
|
|
3358
|
+
this.el.querySelector(".carousel-fixed-item")?.classList.add("with-indicators");
|
|
2775
3359
|
}
|
|
2776
3360
|
_setupEventHandlers() {
|
|
2777
3361
|
this.el.addEventListener("keydown", this._handleKeydown);
|
|
3362
|
+
if (this._autoAdvances) {
|
|
3363
|
+
this.el.addEventListener("mouseenter", this._handleAutoAdvanceState);
|
|
3364
|
+
this.el.addEventListener("mouseleave", this._handleAutoAdvanceState);
|
|
3365
|
+
this.el.addEventListener("focusin", this._handleAutoAdvanceState);
|
|
3366
|
+
this.el.addEventListener("focusout", this._handleAutoAdvanceState);
|
|
3367
|
+
document.addEventListener("visibilitychange", this._handleAutoAdvanceState);
|
|
3368
|
+
}
|
|
2778
3369
|
if (this.showIndicators && this._indicators) {
|
|
2779
3370
|
this._indicators.addEventListener("click", this._handleIndicatorClick);
|
|
2780
3371
|
}
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
_Carousel._resizeListening = true;
|
|
3372
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
3373
|
+
this._resizeObserver = new ResizeObserver(() => this._handleThrottledResize());
|
|
3374
|
+
this._resizeObserver.observe(this.el);
|
|
2785
3375
|
}
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
3376
|
+
this._usesWindowResize = !this._resizeObserver || this.el.classList.contains("full-screen");
|
|
3377
|
+
if (this._usesWindowResize) {
|
|
3378
|
+
_Carousel._live.add(this);
|
|
3379
|
+
if (!_Carousel._resizeListening) {
|
|
3380
|
+
window.addEventListener("resize", _Carousel._onResize, {
|
|
3381
|
+
passive: true
|
|
3382
|
+
});
|
|
3383
|
+
_Carousel._resizeListening = true;
|
|
3384
|
+
}
|
|
2789
3385
|
}
|
|
2790
|
-
this.
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
this.
|
|
2794
|
-
this.
|
|
3386
|
+
this._scroller.addEventListener("scroll", this._handleTrackScroll, {
|
|
3387
|
+
passive: true
|
|
3388
|
+
});
|
|
3389
|
+
this._scroller.addEventListener("pointerdown", this._handleTrackPointerDown);
|
|
3390
|
+
this._scroller.addEventListener("pointermove", this._handleTrackPointerMove);
|
|
3391
|
+
this._scroller.addEventListener("pointerup", this._handleTrackPointerUp);
|
|
3392
|
+
this._scroller.addEventListener("pointercancel", this._handleTrackPointerUp);
|
|
3393
|
+
this._scroller.addEventListener("click", this._handleTrackClick, true);
|
|
3394
|
+
this._scroller.addEventListener("dragstart", this._handleTrackDragStart);
|
|
2795
3395
|
}
|
|
2796
3396
|
_removeEventHandlers() {
|
|
2797
3397
|
this.el.removeEventListener("keydown", this._handleKeydown);
|
|
3398
|
+
this.el.removeEventListener("mouseenter", this._handleAutoAdvanceState);
|
|
3399
|
+
this.el.removeEventListener("mouseleave", this._handleAutoAdvanceState);
|
|
3400
|
+
this.el.removeEventListener("focusin", this._handleAutoAdvanceState);
|
|
3401
|
+
this.el.removeEventListener("focusout", this._handleAutoAdvanceState);
|
|
3402
|
+
document.removeEventListener("visibilitychange", this._handleAutoAdvanceState);
|
|
2798
3403
|
if (this._indicators) {
|
|
2799
3404
|
this._indicators.removeEventListener("click", this._handleIndicatorClick);
|
|
2800
3405
|
}
|
|
2801
|
-
this._scroller.removeEventListener("scroll", this.
|
|
2802
|
-
this.
|
|
2803
|
-
this.
|
|
2804
|
-
this.
|
|
2805
|
-
this.
|
|
2806
|
-
this.
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
3406
|
+
this._scroller.removeEventListener("scroll", this._handleTrackScroll);
|
|
3407
|
+
this._scroller.removeEventListener("pointerdown", this._handleTrackPointerDown);
|
|
3408
|
+
this._scroller.removeEventListener("pointermove", this._handleTrackPointerMove);
|
|
3409
|
+
this._scroller.removeEventListener("pointerup", this._handleTrackPointerUp);
|
|
3410
|
+
this._scroller.removeEventListener("pointercancel", this._handleTrackPointerUp);
|
|
3411
|
+
this._scroller.removeEventListener("click", this._handleTrackClick, true);
|
|
3412
|
+
this._scroller.removeEventListener("dragstart", this._handleTrackDragStart);
|
|
3413
|
+
this._resizeObserver?.disconnect();
|
|
3414
|
+
this._resizeObserver = null;
|
|
3415
|
+
if (this._usesWindowResize) {
|
|
3416
|
+
_Carousel._live.delete(this);
|
|
3417
|
+
if (_Carousel._live.size === 0 && _Carousel._resizeListening) {
|
|
3418
|
+
window.removeEventListener("resize", _Carousel._onResize);
|
|
3419
|
+
_Carousel._resizeListening = false;
|
|
3420
|
+
}
|
|
2811
3421
|
}
|
|
2812
3422
|
}
|
|
2813
3423
|
_teardown() {
|
|
2814
3424
|
this._removeEventHandlers();
|
|
3425
|
+
this._autoAdvances = false;
|
|
3426
|
+
this._syncAutoAdvance();
|
|
2815
3427
|
if (this._trackRaf !== null) cancelAnimationFrame(this._trackRaf);
|
|
2816
3428
|
window.clearTimeout(this.scrollingTimeout);
|
|
3429
|
+
window.clearTimeout(this._suppressClickTimeout);
|
|
2817
3430
|
if (this._ownIndicators) this._indicators?.remove();
|
|
2818
3431
|
this._unwrapTrack();
|
|
2819
3432
|
this.images.forEach((el) => {
|
|
2820
|
-
el.style.
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
3433
|
+
el.style.removeProperty("--md-comp-carousel-item-parallax");
|
|
3434
|
+
if (this._generatedItemLabels.has(el)) el.removeAttribute("aria-label");
|
|
3435
|
+
if (this._generatedItemDescriptions.has(el)) el.removeAttribute("aria-roledescription");
|
|
3436
|
+
if (this._generatedItemSizes.has(el)) el.removeAttribute("data-carousel-size");
|
|
3437
|
+
const original = this._itemA11yOriginal.get(el);
|
|
3438
|
+
if (original?.ariaHidden === null) el.removeAttribute("aria-hidden");
|
|
3439
|
+
else if (original) el.setAttribute("aria-hidden", original.ariaHidden);
|
|
3440
|
+
if (original?.tabIndex === null) el.removeAttribute("tabindex");
|
|
3441
|
+
else if (original) el.setAttribute("tabindex", original.tabIndex);
|
|
2824
3442
|
});
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
if ("
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
}
|
|
2841
|
-
window.clearTimeout(this.scrollingTimeout);
|
|
2842
|
-
this.scrollingTimeout = setTimeout(() => {
|
|
2843
|
-
this.el.classList.remove("scrolling");
|
|
2844
|
-
}, this.options.duration);
|
|
2845
|
-
this.offset = typeof x === "number" ? x : this.offset;
|
|
2846
|
-
this.center = Math.floor((this.offset + this.dim / 2) / this.dim);
|
|
2847
|
-
const half = this.count >> 1;
|
|
2848
|
-
const delta = this.offset - this.center * this.dim;
|
|
2849
|
-
const dir = delta < 0 ? 1 : -1;
|
|
2850
|
-
const tween = -dir * delta * 2 / this.dim;
|
|
2851
|
-
const lastCenter = this.center;
|
|
2852
|
-
const numVisibleOffset = 1 / this.options.numVisible;
|
|
2853
|
-
let alignment;
|
|
2854
|
-
let centerTweenedOpacity;
|
|
2855
|
-
if (this.options.fullWidth) {
|
|
2856
|
-
alignment = "translateX(0)";
|
|
2857
|
-
centerTweenedOpacity = 1;
|
|
2858
|
-
} else {
|
|
2859
|
-
alignment = "translateX(" + (this.el.clientWidth - this.itemWidth) / 2 + "px) ";
|
|
2860
|
-
alignment += "translateY(" + (this.el.clientHeight - this.itemHeight) / 2 + "px)";
|
|
2861
|
-
centerTweenedOpacity = 1 - numVisibleOffset * tween;
|
|
2862
|
-
}
|
|
2863
|
-
this._paintIndicators(this.center);
|
|
2864
|
-
if (!this.noWrap || this.center >= 0 && this.center < this.count) {
|
|
2865
|
-
const el = this.images[this._wrap(this.center)];
|
|
2866
|
-
if (el && !el.classList.contains("active")) {
|
|
2867
|
-
this.el.querySelector(".carousel-item.active")?.classList.remove("active");
|
|
2868
|
-
el.classList.add("active");
|
|
2869
|
-
}
|
|
2870
|
-
}
|
|
2871
|
-
for (let i = 1; i <= half; ++i) {
|
|
2872
|
-
let zTranslation;
|
|
2873
|
-
let tweenedOpacity;
|
|
2874
|
-
if (this.options.fullWidth) {
|
|
2875
|
-
zTranslation = this.options.dist;
|
|
2876
|
-
tweenedOpacity = i === half && delta < 0 ? 1 - tween : 1;
|
|
2877
|
-
} else {
|
|
2878
|
-
zTranslation = this.options.dist * (i * 2 + tween * dir);
|
|
2879
|
-
tweenedOpacity = 1 - numVisibleOffset * (i * 2 + tween * dir);
|
|
2880
|
-
}
|
|
2881
|
-
if (!this.noWrap || this.center + i < this.count) {
|
|
2882
|
-
const el = this.images[this._wrap(this.center + i)];
|
|
2883
|
-
const transformString = `${alignment} translateX(${this.options.shift + (this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
2884
|
-
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
2885
|
-
}
|
|
2886
|
-
if (this.options.fullWidth) {
|
|
2887
|
-
zTranslation = this.options.dist;
|
|
2888
|
-
tweenedOpacity = i === half && delta > 0 ? 1 - tween : 1;
|
|
2889
|
-
} else {
|
|
2890
|
-
zTranslation = this.options.dist * (i * 2 - tween * dir);
|
|
2891
|
-
tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
|
|
2892
|
-
}
|
|
2893
|
-
if (!this.noWrap || this.center - i >= 0) {
|
|
2894
|
-
const el = this.images[this._wrap(this.center - i)];
|
|
2895
|
-
const transformString = `${alignment} translateX(${-this.options.shift + (-this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
2896
|
-
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
2897
|
-
}
|
|
2898
|
-
}
|
|
2899
|
-
if (!this.noWrap || this.center >= 0 && this.center < this.count) {
|
|
2900
|
-
const el = this.images[this._wrap(this.center)];
|
|
2901
|
-
const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir * this.options.shift * tween}px) translateZ(${this.options.dist * tween}px)`;
|
|
2902
|
-
this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
|
|
2903
|
-
}
|
|
2904
|
-
const currItem = this.images[this._wrap(this.center)];
|
|
2905
|
-
this._syncA11y(this._wrap(this.center));
|
|
2906
|
-
if (lastCenter !== this.center && typeof this.options.onCycleTo === "function") {
|
|
2907
|
-
this.options.onCycleTo.call(this, currItem, this.dragged);
|
|
2908
|
-
}
|
|
2909
|
-
if (typeof this.oneTimeCallback === "function") {
|
|
2910
|
-
this.oneTimeCallback.call(this, currItem, this.dragged);
|
|
2911
|
-
this.oneTimeCallback = null;
|
|
3443
|
+
if (this._generatedContainerRole) this.el.removeAttribute("role");
|
|
3444
|
+
if (this._generatedContainerLabel) this.el.removeAttribute("aria-label");
|
|
3445
|
+
if (this._generatedContainerDescription) this.el.removeAttribute("aria-roledescription");
|
|
3446
|
+
if (this._generatedFixedHeight) this.el.classList.remove("fixed-height");
|
|
3447
|
+
if (this.options.height !== null) {
|
|
3448
|
+
if (this._authoredInlineHeight === null) this.el.style.removeProperty("--carousel-height");
|
|
3449
|
+
else this.el.style.setProperty("--carousel-height", this._authoredInlineHeight);
|
|
3450
|
+
}
|
|
3451
|
+
if (this._generatedWideLayout) {
|
|
3452
|
+
this.el.classList.remove(
|
|
3453
|
+
"multi-wide",
|
|
3454
|
+
"multi-large",
|
|
3455
|
+
"multi-extra-large",
|
|
3456
|
+
"full-screen-horizontal"
|
|
3457
|
+
);
|
|
2912
3458
|
}
|
|
2913
3459
|
}
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
3460
|
+
/** Start or stop the timer to match the current pause state. */
|
|
3461
|
+
_syncAutoAdvance() {
|
|
3462
|
+
const run = this._autoAdvances && !this._autoPaused && !this._hovered && !this._focused && !document.hidden;
|
|
3463
|
+
if (run && this._autoAdvanceTimer === null) {
|
|
3464
|
+
this._autoAdvanceTimer = setTimeout(
|
|
3465
|
+
this._tick,
|
|
3466
|
+
this.options.duration + this.options.interval
|
|
3467
|
+
);
|
|
3468
|
+
} else if (!run && this._autoAdvanceTimer !== null) {
|
|
3469
|
+
clearTimeout(this._autoAdvanceTimer);
|
|
3470
|
+
this._autoAdvanceTimer = null;
|
|
3471
|
+
}
|
|
2920
3472
|
}
|
|
2921
3473
|
_paintIndicators(center) {
|
|
2922
3474
|
if (!this.showIndicators || !this._indicators) return;
|
|
@@ -2928,18 +3480,12 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2928
3480
|
else el.removeAttribute("aria-current");
|
|
2929
3481
|
});
|
|
2930
3482
|
}
|
|
2931
|
-
_syncA11y(index) {
|
|
2932
|
-
this.images.forEach((el, i) => {
|
|
2933
|
-
if (i === index) el.removeAttribute("aria-hidden");
|
|
2934
|
-
else el.setAttribute("aria-hidden", "true");
|
|
2935
|
-
});
|
|
2936
|
-
}
|
|
2937
3483
|
_syncActive(index, dragged) {
|
|
2938
3484
|
const prev = this.center;
|
|
2939
3485
|
this.center = index;
|
|
2940
3486
|
this.images.forEach((el, i) => el.classList.toggle("active", i === index));
|
|
2941
3487
|
this._paintIndicators(index);
|
|
2942
|
-
this.
|
|
3488
|
+
this._syncLayoutRoles(index);
|
|
2943
3489
|
const curr = this.images[index];
|
|
2944
3490
|
if (prev !== index && typeof this.options.onCycleTo === "function") {
|
|
2945
3491
|
this.options.onCycleTo.call(this, curr, dragged);
|
|
@@ -2949,6 +3495,81 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2949
3495
|
this.oneTimeCallback = null;
|
|
2950
3496
|
}
|
|
2951
3497
|
}
|
|
3498
|
+
_syncLayoutRoles(index) {
|
|
3499
|
+
const setSize = (item, size) => {
|
|
3500
|
+
if (this._authoredItemSizes.has(item)) return;
|
|
3501
|
+
item.setAttribute("data-carousel-size", size);
|
|
3502
|
+
this._generatedItemSizes.add(item);
|
|
3503
|
+
};
|
|
3504
|
+
this.images.forEach((item) => setSize(item, "large"));
|
|
3505
|
+
if (this.el.classList.contains("flat") || this.el.classList.contains("uncontained") || this.el.classList.contains("full-screen") && this._vertical) {
|
|
3506
|
+
return;
|
|
3507
|
+
}
|
|
3508
|
+
if (this.el.classList.contains("hero") || this.el.classList.contains("full-screen-horizontal")) {
|
|
3509
|
+
const next = this.images[index + 1];
|
|
3510
|
+
if (next) setSize(next, "small");
|
|
3511
|
+
if (this.el.classList.contains("center-aligned")) {
|
|
3512
|
+
const previous = this.images[index - 1];
|
|
3513
|
+
if (previous) setSize(previous, "small");
|
|
3514
|
+
}
|
|
3515
|
+
return;
|
|
3516
|
+
}
|
|
3517
|
+
const width = this.el.clientWidth;
|
|
3518
|
+
const desiredLargeCount = width >= 1600 ? 4 : width >= 1200 ? 3 : width >= 600 ? 2 : 1;
|
|
3519
|
+
const largeCount = Math.min(desiredLargeCount, Math.max(1, this.count - 2));
|
|
3520
|
+
this.el.classList.remove("multi-wide", "multi-large", "multi-extra-large");
|
|
3521
|
+
if (largeCount === 2) this.el.classList.add("multi-wide");
|
|
3522
|
+
else if (largeCount === 3) this.el.classList.add("multi-large");
|
|
3523
|
+
else if (largeCount >= 4) this.el.classList.add("multi-extra-large");
|
|
3524
|
+
this._generatedWideLayout = this._generatedWideLayout || largeCount > 1;
|
|
3525
|
+
for (let offset = 1; offset < largeCount; offset += 1) {
|
|
3526
|
+
const item = this.images[index + offset];
|
|
3527
|
+
if (item) setSize(item, "large");
|
|
3528
|
+
}
|
|
3529
|
+
const medium = this.images[index + largeCount];
|
|
3530
|
+
const small = this.images[index + largeCount + 1];
|
|
3531
|
+
if (medium) setSize(medium, "medium");
|
|
3532
|
+
if (small) setSize(small, "small");
|
|
3533
|
+
}
|
|
3534
|
+
_syncAdaptiveMode() {
|
|
3535
|
+
if (!this.el.classList.contains("full-screen")) return;
|
|
3536
|
+
const landscape = window.matchMedia("(orientation: landscape)").matches;
|
|
3537
|
+
const horizontal = this.el.clientWidth >= 840 || landscape;
|
|
3538
|
+
const wasVertical = this._vertical;
|
|
3539
|
+
this._vertical = !horizontal;
|
|
3540
|
+
this.el.classList.toggle("full-screen-horizontal", horizontal);
|
|
3541
|
+
this._generatedWideLayout = this._generatedWideLayout || horizontal;
|
|
3542
|
+
if (this._started && wasVertical !== this._vertical) {
|
|
3543
|
+
this._scroller.scrollTo({ left: 0, top: 0, behavior: "auto" });
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
_focusItem(index) {
|
|
3547
|
+
const item = this.images[index];
|
|
3548
|
+
if (!item) return;
|
|
3549
|
+
const focusable = item.matches(
|
|
3550
|
+
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
3551
|
+
) ? item : item.querySelector(
|
|
3552
|
+
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
3553
|
+
);
|
|
3554
|
+
(focusable ?? item).focus({ preventScroll: true });
|
|
3555
|
+
}
|
|
3556
|
+
_updateParallax() {
|
|
3557
|
+
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
3558
|
+
this.images.forEach(
|
|
3559
|
+
(item) => item.style.setProperty("--md-comp-carousel-item-parallax", "0px")
|
|
3560
|
+
);
|
|
3561
|
+
return;
|
|
3562
|
+
}
|
|
3563
|
+
const scrollerRect = this._scroller.getBoundingClientRect();
|
|
3564
|
+
const viewportCenter = this._vertical ? scrollerRect.top + scrollerRect.height / 2 : scrollerRect.left + scrollerRect.width / 2;
|
|
3565
|
+
const viewportSize = Math.max(1, this._vertical ? scrollerRect.height : scrollerRect.width);
|
|
3566
|
+
this.images.forEach((item) => {
|
|
3567
|
+
const rect = item.getBoundingClientRect();
|
|
3568
|
+
const itemCenter = this._vertical ? rect.top + rect.height / 2 : rect.left + rect.width / 2;
|
|
3569
|
+
const progress = Math.max(-1, Math.min(1, (itemCenter - viewportCenter) / viewportSize));
|
|
3570
|
+
item.style.setProperty("--md-comp-carousel-item-parallax", `${progress * -24}px`);
|
|
3571
|
+
});
|
|
3572
|
+
}
|
|
2952
3573
|
_wrapTrack() {
|
|
2953
3574
|
const track = document.createElement("div");
|
|
2954
3575
|
track.className = "carousel-track";
|
|
@@ -2963,11 +3584,16 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2963
3584
|
this._trackEl = null;
|
|
2964
3585
|
}
|
|
2965
3586
|
_nearestIndex() {
|
|
2966
|
-
const
|
|
3587
|
+
const centered = this.el.classList.contains("center-aligned");
|
|
3588
|
+
const position = this._vertical ? this._scroller.scrollTop : this._scroller.scrollLeft;
|
|
3589
|
+
const viewportCenter = position + (this._vertical ? this._scroller.clientHeight : this._scroller.clientWidth) / 2;
|
|
2967
3590
|
let best = 0;
|
|
2968
3591
|
let bestDist = Infinity;
|
|
2969
3592
|
this.images.forEach((el, i) => {
|
|
2970
|
-
const
|
|
3593
|
+
const start = this._vertical ? el.offsetTop : el.offsetLeft;
|
|
3594
|
+
const size = this._vertical ? el.offsetHeight : el.offsetWidth;
|
|
3595
|
+
const target = centered ? start + size / 2 : start;
|
|
3596
|
+
const dist = Math.abs(target - (centered ? viewportCenter : position));
|
|
2971
3597
|
if (dist < bestDist) {
|
|
2972
3598
|
bestDist = dist;
|
|
2973
3599
|
best = i;
|
|
@@ -2978,13 +3604,24 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2978
3604
|
_scrollToIndex(n, smooth = true) {
|
|
2979
3605
|
const el = this.images[n];
|
|
2980
3606
|
if (!el) return;
|
|
2981
|
-
const
|
|
2982
|
-
|
|
3607
|
+
const centered = this.el.classList.contains("center-aligned");
|
|
3608
|
+
const style = getComputedStyle(this._scroller);
|
|
3609
|
+
const inlinePadding = Number.parseFloat(style.paddingInlineStart) || 0;
|
|
3610
|
+
const blockPadding = Number.parseFloat(style.paddingBlockStart) || 0;
|
|
3611
|
+
const left = centered ? el.offsetLeft - (this._scroller.clientWidth - el.offsetWidth) / 2 : el.offsetLeft - inlinePadding;
|
|
3612
|
+
const top = el.offsetTop - blockPadding;
|
|
3613
|
+
const current = this._vertical ? this._scroller.scrollTop : this._scroller.scrollLeft;
|
|
3614
|
+
const target = this._vertical ? top : left;
|
|
3615
|
+
if (Math.abs(current - target) < 1) {
|
|
2983
3616
|
this._syncActive(n, false);
|
|
2984
3617
|
return;
|
|
2985
3618
|
}
|
|
2986
3619
|
this._ignoreScroll = true;
|
|
2987
|
-
this._scroller.scrollTo({
|
|
3620
|
+
this._scroller.scrollTo({
|
|
3621
|
+
left: this._vertical ? 0 : left,
|
|
3622
|
+
top: this._vertical ? top : 0,
|
|
3623
|
+
behavior: smooth ? "smooth" : "auto"
|
|
3624
|
+
});
|
|
2988
3625
|
const done = () => {
|
|
2989
3626
|
this._ignoreScroll = false;
|
|
2990
3627
|
};
|
|
@@ -2992,63 +3629,38 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2992
3629
|
window.setTimeout(done, this.options.duration + 350);
|
|
2993
3630
|
}
|
|
2994
3631
|
_cycleTo(n, callback = null) {
|
|
2995
|
-
if (this.
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
}
|
|
3012
|
-
}
|
|
3013
|
-
this.target = this.dim * Math.round(this.offset / this.dim);
|
|
3014
|
-
if (diff < 0) {
|
|
3015
|
-
this.target += this.dim * Math.abs(diff);
|
|
3016
|
-
} else if (diff > 0) {
|
|
3017
|
-
this.target -= this.dim * diff;
|
|
3018
|
-
}
|
|
3019
|
-
if (typeof callback === "function") {
|
|
3020
|
-
this.oneTimeCallback = callback;
|
|
3021
|
-
}
|
|
3022
|
-
if (this.offset !== this.target) {
|
|
3023
|
-
this.amplitude = this.target - this.offset;
|
|
3024
|
-
this.timestamp = Date.now();
|
|
3025
|
-
requestAnimationFrame(this._autoScroll);
|
|
3026
|
-
}
|
|
3632
|
+
if (typeof callback === "function") this.oneTimeCallback = callback;
|
|
3633
|
+
this._syncActive(n, false);
|
|
3634
|
+
this._scrollToIndex(n);
|
|
3635
|
+
}
|
|
3636
|
+
/**
|
|
3637
|
+
* Stop auto-advance until start() is called. Without an `interval` there is
|
|
3638
|
+
* nothing to stop and this does nothing.
|
|
3639
|
+
*/
|
|
3640
|
+
pause() {
|
|
3641
|
+
this._autoPaused = true;
|
|
3642
|
+
this._syncAutoAdvance();
|
|
3643
|
+
}
|
|
3644
|
+
/** Resume auto-advance after pause(). */
|
|
3645
|
+
start() {
|
|
3646
|
+
this._autoPaused = false;
|
|
3647
|
+
this._syncAutoAdvance();
|
|
3027
3648
|
}
|
|
3028
3649
|
next(n = 1) {
|
|
3029
3650
|
if (n === void 0 || isNaN(n)) n = 1;
|
|
3030
|
-
|
|
3031
|
-
if (index >= this.count || index < 0)
|
|
3032
|
-
if (this.noWrap) return;
|
|
3033
|
-
index = this._wrap(index);
|
|
3034
|
-
}
|
|
3651
|
+
const index = this.center + n;
|
|
3652
|
+
if (index >= this.count || index < 0) return;
|
|
3035
3653
|
this._cycleTo(index);
|
|
3036
3654
|
}
|
|
3037
3655
|
prev(n = 1) {
|
|
3038
3656
|
if (n === void 0 || isNaN(n)) n = 1;
|
|
3039
|
-
|
|
3040
|
-
if (index >= this.count || index < 0)
|
|
3041
|
-
if (this.noWrap) return;
|
|
3042
|
-
index = this._wrap(index);
|
|
3043
|
-
}
|
|
3657
|
+
const index = this.center - n;
|
|
3658
|
+
if (index >= this.count || index < 0) return;
|
|
3044
3659
|
this._cycleTo(index);
|
|
3045
3660
|
}
|
|
3046
3661
|
set(n, callback) {
|
|
3047
3662
|
if (n === void 0 || isNaN(n)) n = 0;
|
|
3048
|
-
if (n
|
|
3049
|
-
if (this.noWrap) return;
|
|
3050
|
-
n = this._wrap(n);
|
|
3051
|
-
}
|
|
3663
|
+
if (n >= this.count || n < 0) return;
|
|
3052
3664
|
this._cycleTo(n, callback);
|
|
3053
3665
|
}
|
|
3054
3666
|
};
|
|
@@ -3060,7 +3672,7 @@ _Carousel._onResize = Utils.throttle(() => {
|
|
|
3060
3672
|
var Carousel = _Carousel;
|
|
3061
3673
|
|
|
3062
3674
|
// src/ts/components/characterCounter.ts
|
|
3063
|
-
var
|
|
3675
|
+
var _defaults11 = Object.freeze({});
|
|
3064
3676
|
var CharacterCounter = class _CharacterCounter extends Component {
|
|
3065
3677
|
constructor(el, options) {
|
|
3066
3678
|
super(el, {}, _CharacterCounter);
|
|
@@ -3085,7 +3697,7 @@ var CharacterCounter = class _CharacterCounter extends Component {
|
|
|
3085
3697
|
this._setupEventHandlers();
|
|
3086
3698
|
}
|
|
3087
3699
|
static get defaults() {
|
|
3088
|
-
return
|
|
3700
|
+
return _defaults11;
|
|
3089
3701
|
}
|
|
3090
3702
|
/**
|
|
3091
3703
|
* Initializes instances of CharacterCounter.
|
|
@@ -3114,6 +3726,8 @@ var CharacterCounter = class _CharacterCounter extends Component {
|
|
|
3114
3726
|
_setupCounter() {
|
|
3115
3727
|
this.counterEl = document.createElement("span");
|
|
3116
3728
|
this.counterEl.classList.add("character-counter");
|
|
3729
|
+
this.counterEl.setAttribute("aria-live", "polite");
|
|
3730
|
+
this.counterEl.setAttribute("aria-atomic", "true");
|
|
3117
3731
|
this.counterEl.style.float = "right";
|
|
3118
3732
|
this.counterEl.style.fontSize = "12px";
|
|
3119
3733
|
this.counterEl.style.height = "1";
|
|
@@ -3135,7 +3749,7 @@ var CharacterCounter = class _CharacterCounter extends Component {
|
|
|
3135
3749
|
};
|
|
3136
3750
|
|
|
3137
3751
|
// src/ts/components/select.ts
|
|
3138
|
-
var
|
|
3752
|
+
var _defaults12 = {
|
|
3139
3753
|
classes: "",
|
|
3140
3754
|
menuOptions: {}
|
|
3141
3755
|
};
|
|
@@ -3184,7 +3798,7 @@ var FormSelect = class _FormSelect extends Component {
|
|
|
3184
3798
|
this._setupEventHandlers();
|
|
3185
3799
|
}
|
|
3186
3800
|
static get defaults() {
|
|
3187
|
-
return
|
|
3801
|
+
return _defaults12;
|
|
3188
3802
|
}
|
|
3189
3803
|
/**
|
|
3190
3804
|
* Initializes instances of FormSelect.
|
|
@@ -3315,7 +3929,7 @@ var FormSelect = class _FormSelect extends Component {
|
|
|
3315
3929
|
_buildInput() {
|
|
3316
3930
|
this.input = document.createElement("input");
|
|
3317
3931
|
this.input.id = "select-input-" + Utils.guid();
|
|
3318
|
-
this.input.classList.add("menu-trigger");
|
|
3932
|
+
this.input.classList.add("menu-trigger", "no-autoinit");
|
|
3319
3933
|
this.input.type = "text";
|
|
3320
3934
|
this.input.readOnly = true;
|
|
3321
3935
|
this.input.setAttribute("data-target", this.menuEl.id);
|
|
@@ -3355,10 +3969,8 @@ var FormSelect = class _FormSelect extends Component {
|
|
|
3355
3969
|
menuOptions.onOpenEnd = () => {
|
|
3356
3970
|
const selectedOption = this.menuEl.querySelector(".selected");
|
|
3357
3971
|
if (selectedOption) {
|
|
3358
|
-
Utils.keyDown = true;
|
|
3359
3972
|
this.menu.focusedIndex = [...selectedOption.parentNode.children].indexOf(selectedOption);
|
|
3360
3973
|
this.menu._focusFocusedItem();
|
|
3361
|
-
Utils.keyDown = false;
|
|
3362
3974
|
if (this.menu.isScrollable) {
|
|
3363
3975
|
let scrollOffset = selectedOption.getBoundingClientRect().top - this.menuEl.getBoundingClientRect().top;
|
|
3364
3976
|
scrollOffset -= this.menuEl.clientHeight / 2;
|
|
@@ -3558,7 +4170,7 @@ var FormSelect = class _FormSelect extends Component {
|
|
|
3558
4170
|
};
|
|
3559
4171
|
|
|
3560
4172
|
// src/ts/plugins/dockedDisplayPlugin.ts
|
|
3561
|
-
var
|
|
4173
|
+
var _defaults13 = {
|
|
3562
4174
|
margin: 5,
|
|
3563
4175
|
transition: 10,
|
|
3564
4176
|
duration: 250,
|
|
@@ -3607,7 +4219,7 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
|
|
|
3607
4219
|
};
|
|
3608
4220
|
this.el = el;
|
|
3609
4221
|
this.options = {
|
|
3610
|
-
...
|
|
4222
|
+
..._defaults13,
|
|
3611
4223
|
...options
|
|
3612
4224
|
};
|
|
3613
4225
|
this.container = document.createElement("div");
|
|
@@ -3628,7 +4240,7 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
|
|
|
3628
4240
|
};
|
|
3629
4241
|
|
|
3630
4242
|
// src/ts/components/datepicker.ts
|
|
3631
|
-
var
|
|
4243
|
+
var _defaults14 = {
|
|
3632
4244
|
// the default output format for the input field value
|
|
3633
4245
|
format: "mmm dd, yyyy",
|
|
3634
4246
|
// Used to create date object from current input string
|
|
@@ -3753,7 +4365,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
3753
4365
|
if (this.options.onInputInteraction) this.options.onInputInteraction.call(this);
|
|
3754
4366
|
};
|
|
3755
4367
|
this._handleInputKeydown = (e) => {
|
|
3756
|
-
if (Utils.keys.ENTER
|
|
4368
|
+
if (e.key === Utils.keys.ENTER) {
|
|
3757
4369
|
e.preventDefault();
|
|
3758
4370
|
this._batchDraws(() => {
|
|
3759
4371
|
this.setDateFromInput(e.target);
|
|
@@ -3893,7 +4505,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
3893
4505
|
}
|
|
3894
4506
|
}
|
|
3895
4507
|
static get defaults() {
|
|
3896
|
-
return
|
|
4508
|
+
return _defaults14;
|
|
3897
4509
|
}
|
|
3898
4510
|
/**
|
|
3899
4511
|
* Initializes instances of Datepicker.
|
|
@@ -4476,11 +5088,11 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
4476
5088
|
const monthSelect = this.calendarEl.querySelector(".orig-select-month");
|
|
4477
5089
|
FormSelect.init(yearSelect, {
|
|
4478
5090
|
classes: "select-year",
|
|
4479
|
-
menuOptions: { container:
|
|
5091
|
+
menuOptions: { container: Utils.portalRoot(this.el), constrainWidth: false }
|
|
4480
5092
|
});
|
|
4481
5093
|
FormSelect.init(monthSelect, {
|
|
4482
5094
|
classes: "select-month",
|
|
4483
|
-
menuOptions: { container:
|
|
5095
|
+
menuOptions: { container: Utils.portalRoot(this.el), constrainWidth: false }
|
|
4484
5096
|
});
|
|
4485
5097
|
yearSelect.addEventListener("change", this._handleYearChange);
|
|
4486
5098
|
monthSelect.addEventListener("change", this._handleMonthChange);
|
|
@@ -4611,7 +5223,7 @@ _Datepicker._template = `
|
|
|
4611
5223
|
var Datepicker = _Datepicker;
|
|
4612
5224
|
|
|
4613
5225
|
// src/ts/components/lightbox.ts
|
|
4614
|
-
var
|
|
5226
|
+
var _defaults15 = {
|
|
4615
5227
|
inDuration: 275,
|
|
4616
5228
|
outDuration: 200,
|
|
4617
5229
|
onOpenStart: null,
|
|
@@ -4626,7 +5238,7 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4626
5238
|
this._handleLightboxToggle();
|
|
4627
5239
|
};
|
|
4628
5240
|
this._handleLightboxKeypress = (e) => {
|
|
4629
|
-
if (Utils.keys.ENTER
|
|
5241
|
+
if (e.key === Utils.keys.ENTER) {
|
|
4630
5242
|
this._handleLightboxToggle();
|
|
4631
5243
|
}
|
|
4632
5244
|
};
|
|
@@ -4641,7 +5253,7 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4641
5253
|
if (this.overlayActive) this.close();
|
|
4642
5254
|
};
|
|
4643
5255
|
this._handleWindowEscape = (e) => {
|
|
4644
|
-
if (Utils.keys.ESC
|
|
5256
|
+
if (e.key === Utils.keys.ESC && this.doneAnimating && this.overlayActive) this.close();
|
|
4645
5257
|
};
|
|
4646
5258
|
/**
|
|
4647
5259
|
* Open lightbox.
|
|
@@ -4730,7 +5342,7 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4730
5342
|
this._setupEventHandlers();
|
|
4731
5343
|
}
|
|
4732
5344
|
static get defaults() {
|
|
4733
|
-
return
|
|
5345
|
+
return _defaults15;
|
|
4734
5346
|
}
|
|
4735
5347
|
/**
|
|
4736
5348
|
* Initializes instances of Lightbox.
|
|
@@ -4760,13 +5372,13 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4760
5372
|
_makeAncestorsOverflowVisible() {
|
|
4761
5373
|
this._changedAncestorList = [];
|
|
4762
5374
|
let ancestor = this.placeholder.parentNode;
|
|
4763
|
-
while (ancestor !== null && ancestor !== document) {
|
|
5375
|
+
while (ancestor !== null && ancestor !== void 0 && ancestor !== document) {
|
|
4764
5376
|
const curr = ancestor;
|
|
4765
|
-
if (curr.style.overflow !== "visible") {
|
|
5377
|
+
if (curr.style && curr.style.overflow !== "visible") {
|
|
5378
|
+
this._changedAncestorList.push([curr, curr.style.overflow]);
|
|
4766
5379
|
curr.style.overflow = "visible";
|
|
4767
|
-
this._changedAncestorList.push(curr);
|
|
4768
5380
|
}
|
|
4769
|
-
ancestor = ancestor.parentNode;
|
|
5381
|
+
ancestor = ancestor.parentNode ?? ancestor.host;
|
|
4770
5382
|
}
|
|
4771
5383
|
}
|
|
4772
5384
|
_offset(el) {
|
|
@@ -4830,7 +5442,7 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4830
5442
|
if (this.originInlineStyles) this.el.setAttribute("style", this.originInlineStyles);
|
|
4831
5443
|
this.el.classList.remove("active");
|
|
4832
5444
|
this.doneAnimating = true;
|
|
4833
|
-
this._changedAncestorList.forEach((
|
|
5445
|
+
this._changedAncestorList.forEach(([ancestor, overflow]) => ancestor.style.overflow = overflow);
|
|
4834
5446
|
if (typeof this.options.onCloseEnd === "function")
|
|
4835
5447
|
this.options.onCloseEnd.call(this, this.el);
|
|
4836
5448
|
}, duration);
|
|
@@ -4840,7 +5452,7 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4840
5452
|
this._photoCaption = document.createElement("div");
|
|
4841
5453
|
this._photoCaption.classList.add("lightbox-caption");
|
|
4842
5454
|
this._photoCaption.innerText = this.caption;
|
|
4843
|
-
|
|
5455
|
+
Utils.portalRoot(this.el).append(this._photoCaption);
|
|
4844
5456
|
this._photoCaption.style.display = "inline";
|
|
4845
5457
|
this._photoCaption.style.transition = "none";
|
|
4846
5458
|
this._photoCaption.style.opacity = "0";
|
|
@@ -4894,37 +5506,9 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4894
5506
|
}
|
|
4895
5507
|
};
|
|
4896
5508
|
|
|
4897
|
-
// src/ts/components/parallax.ts
|
|
4898
|
-
var _defaults13 = {};
|
|
4899
|
-
var Parallax = class _Parallax extends Component {
|
|
4900
|
-
constructor(el, options) {
|
|
4901
|
-
super(el, options, _Parallax);
|
|
4902
|
-
this.el["Expressive_Parallax"] = this;
|
|
4903
|
-
this.options = {
|
|
4904
|
-
..._Parallax.defaults,
|
|
4905
|
-
...options
|
|
4906
|
-
};
|
|
4907
|
-
if (!this.el.querySelector("img, video")) {
|
|
4908
|
-
console.error("Parallax: no <img> or <video> to move inside the .parallax element");
|
|
4909
|
-
}
|
|
4910
|
-
}
|
|
4911
|
-
static get defaults() {
|
|
4912
|
-
return _defaults13;
|
|
4913
|
-
}
|
|
4914
|
-
static init(els, options = {}) {
|
|
4915
|
-
return super.init(els, options, _Parallax);
|
|
4916
|
-
}
|
|
4917
|
-
static getInstance(el) {
|
|
4918
|
-
return el["Expressive_Parallax"];
|
|
4919
|
-
}
|
|
4920
|
-
destroy() {
|
|
4921
|
-
this.el["Expressive_Parallax"] = void 0;
|
|
4922
|
-
}
|
|
4923
|
-
};
|
|
4924
|
-
|
|
4925
5509
|
// src/ts/components/scrollspy.ts
|
|
4926
5510
|
var _defaultGetActiveElement = (id) => `a[href="#${id}"]`;
|
|
4927
|
-
var
|
|
5511
|
+
var _defaults16 = {
|
|
4928
5512
|
scrollOffset: 200,
|
|
4929
5513
|
activeClass: "active",
|
|
4930
5514
|
getActiveElement: _defaultGetActiveElement,
|
|
@@ -4947,7 +5531,7 @@ var _ScrollSpy = class _ScrollSpy extends Component {
|
|
|
4947
5531
|
_ScrollSpy._observer?.observe(this.el);
|
|
4948
5532
|
}
|
|
4949
5533
|
static get defaults() {
|
|
4950
|
-
return
|
|
5534
|
+
return _defaults16;
|
|
4951
5535
|
}
|
|
4952
5536
|
static init(els, options = {}) {
|
|
4953
5537
|
return super.init(els, options, _ScrollSpy);
|
|
@@ -5068,8 +5652,8 @@ _ScrollSpy._onIntersect = (entries) => {
|
|
|
5068
5652
|
};
|
|
5069
5653
|
var ScrollSpy = _ScrollSpy;
|
|
5070
5654
|
|
|
5071
|
-
// src/ts/components/
|
|
5072
|
-
var
|
|
5655
|
+
// src/ts/components/navigationDrawer.ts
|
|
5656
|
+
var _defaults17 = {
|
|
5073
5657
|
edge: "left",
|
|
5074
5658
|
draggable: true,
|
|
5075
5659
|
dragTargetWidth: "10px",
|
|
@@ -5078,17 +5662,17 @@ var _defaults15 = {
|
|
|
5078
5662
|
onCloseStart: null,
|
|
5079
5663
|
onCloseEnd: null
|
|
5080
5664
|
};
|
|
5081
|
-
var
|
|
5082
|
-
var
|
|
5665
|
+
var EXPANDED_UP = "(width >= 840px)";
|
|
5666
|
+
var _NavigationDrawer = class _NavigationDrawer extends Component {
|
|
5083
5667
|
constructor(el, options) {
|
|
5084
|
-
super(el, options,
|
|
5668
|
+
super(el, options, _NavigationDrawer);
|
|
5085
5669
|
/**
|
|
5086
5670
|
* Opens the overlay drawer. No-op while the sidenav is docked
|
|
5087
|
-
* (
|
|
5671
|
+
* (navigation-drawer-fixed at the Expanded breakpoint).
|
|
5088
5672
|
*/
|
|
5089
5673
|
this.open = () => {
|
|
5090
5674
|
if (this._isCurrentlyFixed() || this.isOpen || !this._dialog) return;
|
|
5091
|
-
|
|
5675
|
+
_NavigationDrawer._sidenavs.forEach((other) => {
|
|
5092
5676
|
if (other !== this && other.isOpen) other.close();
|
|
5093
5677
|
});
|
|
5094
5678
|
if (typeof this.options.onOpenStart === "function") {
|
|
@@ -5140,7 +5724,7 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5140
5724
|
this._handleCloseTriggerClick = (e) => {
|
|
5141
5725
|
const target = e.target;
|
|
5142
5726
|
if (!(target instanceof Element)) return;
|
|
5143
|
-
const closeTrigger = target.closest(".sidenav-close");
|
|
5727
|
+
const closeTrigger = target.closest(".sidenav-close, .navigation-drawer-close");
|
|
5144
5728
|
if (closeTrigger && !this._isCurrentlyFixed()) {
|
|
5145
5729
|
this.close();
|
|
5146
5730
|
}
|
|
@@ -5184,14 +5768,14 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5184
5768
|
this.isDragged = false;
|
|
5185
5769
|
this._verticallyScrolling = false;
|
|
5186
5770
|
};
|
|
5187
|
-
this.el["
|
|
5771
|
+
this.el["Expressive_NavigationDrawer"] = this;
|
|
5188
5772
|
this.options = {
|
|
5189
|
-
...
|
|
5773
|
+
..._NavigationDrawer.defaults,
|
|
5190
5774
|
...options
|
|
5191
5775
|
};
|
|
5192
5776
|
this.id = this.el.id;
|
|
5193
5777
|
this.isOpen = false;
|
|
5194
|
-
this.isFixed = this.el.classList.contains("sidenav-fixed");
|
|
5778
|
+
this.isFixed = this.el.classList.contains("navigation-drawer-fixed") || this.el.classList.contains("sidenav-fixed");
|
|
5195
5779
|
this.isDragged = false;
|
|
5196
5780
|
this.dragTarget = null;
|
|
5197
5781
|
this._dialog = null;
|
|
@@ -5203,27 +5787,27 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5203
5787
|
this._width = 0;
|
|
5204
5788
|
this._initialScrollTop = 0;
|
|
5205
5789
|
this._verticallyScrolling = false;
|
|
5206
|
-
this._mql = window.matchMedia(
|
|
5790
|
+
this._mql = window.matchMedia(EXPANDED_UP);
|
|
5207
5791
|
this._setupDialog();
|
|
5208
5792
|
this._createDragTarget();
|
|
5209
5793
|
this._setupClasses();
|
|
5210
5794
|
this._setupEventHandlers();
|
|
5211
5795
|
this._syncTriggers();
|
|
5212
|
-
|
|
5796
|
+
_NavigationDrawer._sidenavs.push(this);
|
|
5213
5797
|
}
|
|
5214
5798
|
static get defaults() {
|
|
5215
|
-
return
|
|
5799
|
+
return _defaults17;
|
|
5216
5800
|
}
|
|
5217
5801
|
/**
|
|
5218
|
-
* Initializes instances of
|
|
5802
|
+
* Initializes instances of NavigationDrawer.
|
|
5219
5803
|
* @param els HTML elements.
|
|
5220
5804
|
* @param options Component options.
|
|
5221
5805
|
*/
|
|
5222
5806
|
static init(els, options = {}) {
|
|
5223
|
-
return super.init(els, options,
|
|
5807
|
+
return super.init(els, options, _NavigationDrawer);
|
|
5224
5808
|
}
|
|
5225
5809
|
static getInstance(el) {
|
|
5226
|
-
return el["
|
|
5810
|
+
return el["Expressive_NavigationDrawer"];
|
|
5227
5811
|
}
|
|
5228
5812
|
destroy() {
|
|
5229
5813
|
this._removeEventHandlers();
|
|
@@ -5236,10 +5820,10 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5236
5820
|
this._clearShift();
|
|
5237
5821
|
this._unwrapDialog();
|
|
5238
5822
|
this._removeDragTarget();
|
|
5239
|
-
this.el["
|
|
5240
|
-
const index =
|
|
5823
|
+
this.el["Expressive_NavigationDrawer"] = void 0;
|
|
5824
|
+
const index = _NavigationDrawer._sidenavs.indexOf(this);
|
|
5241
5825
|
if (index >= 0) {
|
|
5242
|
-
|
|
5826
|
+
_NavigationDrawer._sidenavs.splice(index, 1);
|
|
5243
5827
|
}
|
|
5244
5828
|
}
|
|
5245
5829
|
_beginClose() {
|
|
@@ -5270,6 +5854,11 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5270
5854
|
}
|
|
5271
5855
|
const dialog = document.createElement("dialog");
|
|
5272
5856
|
dialog.classList.add("sidenav-overlay");
|
|
5857
|
+
const named = this.el.closest("[aria-label], [aria-labelledby]") ?? this.el;
|
|
5858
|
+
const label = named.getAttribute("aria-label");
|
|
5859
|
+
const labelledBy = named.getAttribute("aria-labelledby");
|
|
5860
|
+
if (label) dialog.setAttribute("aria-label", label);
|
|
5861
|
+
else if (labelledBy) dialog.setAttribute("aria-labelledby", labelledBy);
|
|
5273
5862
|
this.el.replaceWith(dialog);
|
|
5274
5863
|
dialog.appendChild(this.el);
|
|
5275
5864
|
this._dialog = dialog;
|
|
@@ -5287,7 +5876,7 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5287
5876
|
dragTarget.classList.add("drag-target");
|
|
5288
5877
|
dragTarget.style.width = this.options.dragTargetWidth;
|
|
5289
5878
|
if (this.isFixed) dragTarget.dataset.fixed = "";
|
|
5290
|
-
|
|
5879
|
+
Utils.portalRoot(this.el).appendChild(dragTarget);
|
|
5291
5880
|
this.dragTarget = dragTarget;
|
|
5292
5881
|
}
|
|
5293
5882
|
_removeDragTarget() {
|
|
@@ -5302,8 +5891,8 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5302
5891
|
}
|
|
5303
5892
|
}
|
|
5304
5893
|
_setupEventHandlers() {
|
|
5305
|
-
if (
|
|
5306
|
-
document.body.addEventListener("click",
|
|
5894
|
+
if (_NavigationDrawer._sidenavs.length === 0) {
|
|
5895
|
+
document.body.addEventListener("click", _NavigationDrawer._handleTriggerClick);
|
|
5307
5896
|
}
|
|
5308
5897
|
const passive = { passive: true };
|
|
5309
5898
|
this.dragTarget?.addEventListener("touchmove", this._handleDragTargetDrag, passive);
|
|
@@ -5315,8 +5904,8 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5315
5904
|
this._mql.addEventListener("change", this._onBreakpointChange);
|
|
5316
5905
|
}
|
|
5317
5906
|
_removeEventHandlers() {
|
|
5318
|
-
if (
|
|
5319
|
-
document.body.removeEventListener("click",
|
|
5907
|
+
if (_NavigationDrawer._sidenavs.length === 1) {
|
|
5908
|
+
document.body.removeEventListener("click", _NavigationDrawer._handleTriggerClick);
|
|
5320
5909
|
}
|
|
5321
5910
|
this.dragTarget?.removeEventListener("touchmove", this._handleDragTargetDrag);
|
|
5322
5911
|
this.dragTarget?.removeEventListener("touchend", this._handleDragTargetRelease);
|
|
@@ -5329,10 +5918,10 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5329
5918
|
static _handleTriggerClick(e) {
|
|
5330
5919
|
const target = e.target;
|
|
5331
5920
|
if (!(target instanceof Element)) return;
|
|
5332
|
-
const trigger = target.closest(".sidenav-trigger");
|
|
5921
|
+
const trigger = target.closest(".sidenav-trigger, .navigation-drawer-trigger");
|
|
5333
5922
|
if (!trigger || !(trigger instanceof HTMLElement)) return;
|
|
5334
5923
|
const sidenavId = Utils.getIdFromTrigger(trigger);
|
|
5335
|
-
const sidenavInstance =
|
|
5924
|
+
const sidenavInstance = Utils.getElementById(trigger, sidenavId)?.["Expressive_NavigationDrawer"];
|
|
5336
5925
|
if (sidenavInstance) {
|
|
5337
5926
|
sidenavInstance.open();
|
|
5338
5927
|
e.preventDefault();
|
|
@@ -5386,7 +5975,7 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5386
5975
|
}
|
|
5387
5976
|
_syncTriggers() {
|
|
5388
5977
|
if (!this.id) return;
|
|
5389
|
-
document.querySelectorAll(".sidenav-trigger").forEach((trigger) => {
|
|
5978
|
+
document.querySelectorAll(".sidenav-trigger, .navigation-drawer-trigger").forEach((trigger) => {
|
|
5390
5979
|
if (!(trigger instanceof HTMLElement)) return;
|
|
5391
5980
|
if (Utils.getIdFromTrigger(trigger) !== this.id) return;
|
|
5392
5981
|
trigger.setAttribute("aria-expanded", this.isOpen ? "true" : "false");
|
|
@@ -5394,17 +5983,17 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5394
5983
|
});
|
|
5395
5984
|
}
|
|
5396
5985
|
};
|
|
5397
|
-
|
|
5398
|
-
var
|
|
5986
|
+
_NavigationDrawer._sidenavs = [];
|
|
5987
|
+
var NavigationDrawer = _NavigationDrawer;
|
|
5399
5988
|
|
|
5400
5989
|
// src/ts/components/navigationRail.ts
|
|
5401
|
-
var
|
|
5990
|
+
var _defaults18 = {
|
|
5402
5991
|
onOpenStart: null,
|
|
5403
5992
|
onOpenEnd: null,
|
|
5404
5993
|
onCloseStart: null,
|
|
5405
5994
|
onCloseEnd: null
|
|
5406
5995
|
};
|
|
5407
|
-
var COMPACT = "(width <
|
|
5996
|
+
var COMPACT = "(width < 600px)";
|
|
5408
5997
|
var NavigationRail = class _NavigationRail extends Component {
|
|
5409
5998
|
constructor(el, options) {
|
|
5410
5999
|
super(el, options, _NavigationRail);
|
|
@@ -5474,7 +6063,7 @@ var NavigationRail = class _NavigationRail extends Component {
|
|
|
5474
6063
|
document.addEventListener("keydown", this._onKeyDown);
|
|
5475
6064
|
}
|
|
5476
6065
|
static get defaults() {
|
|
5477
|
-
return
|
|
6066
|
+
return _defaults18;
|
|
5478
6067
|
}
|
|
5479
6068
|
static init(els, options = {}) {
|
|
5480
6069
|
return super.init(els, options, _NavigationRail);
|
|
@@ -5503,309 +6092,8 @@ var NavigationRail = class _NavigationRail extends Component {
|
|
|
5503
6092
|
}
|
|
5504
6093
|
};
|
|
5505
6094
|
|
|
5506
|
-
// src/ts/components/slider.ts
|
|
5507
|
-
var _defaults17 = {
|
|
5508
|
-
indicators: true,
|
|
5509
|
-
height: 400,
|
|
5510
|
-
duration: 500,
|
|
5511
|
-
interval: 6e3,
|
|
5512
|
-
pauseOnFocus: true,
|
|
5513
|
-
pauseOnHover: true,
|
|
5514
|
-
indicatorLabelFunc: null
|
|
5515
|
-
// Function which will generate a label for the indicators (ARIA)
|
|
5516
|
-
};
|
|
5517
|
-
var Slider = class _Slider extends Component {
|
|
5518
|
-
constructor(el, options) {
|
|
5519
|
-
super(el, options, _Slider);
|
|
5520
|
-
// Nobody is watching a backgrounded tab. Browsers clamp the timer rather
|
|
5521
|
-
// than stopping it, so without this the slider keeps cycling slides - and
|
|
5522
|
-
// running their transitions - out of sight.
|
|
5523
|
-
this._handleVisibilityChange = () => {
|
|
5524
|
-
if (document.hidden) {
|
|
5525
|
-
if (this.interval != null) this._pause(true);
|
|
5526
|
-
} else if (this.eventPause && !(this.options.pauseOnHover && this._hovered) && !(this.options.pauseOnFocus && this._focused)) {
|
|
5527
|
-
this.start();
|
|
5528
|
-
}
|
|
5529
|
-
};
|
|
5530
|
-
this._handleIndicatorClick = (e) => {
|
|
5531
|
-
const el = e.target.parentElement;
|
|
5532
|
-
const currIndex = [...el.parentNode.children].indexOf(el);
|
|
5533
|
-
this._focusCurrent = true;
|
|
5534
|
-
this.set(currIndex);
|
|
5535
|
-
};
|
|
5536
|
-
this._handleAutoPauseHover = () => {
|
|
5537
|
-
this._hovered = true;
|
|
5538
|
-
if (this.interval != null) {
|
|
5539
|
-
this._pause(true);
|
|
5540
|
-
}
|
|
5541
|
-
};
|
|
5542
|
-
this._handleAutoPauseFocus = () => {
|
|
5543
|
-
this._focused = true;
|
|
5544
|
-
if (this.interval != null) {
|
|
5545
|
-
this._pause(true);
|
|
5546
|
-
}
|
|
5547
|
-
};
|
|
5548
|
-
this._handleAutoStartHover = () => {
|
|
5549
|
-
this._hovered = false;
|
|
5550
|
-
if (!(this.options.pauseOnFocus && this._focused) && this.eventPause) {
|
|
5551
|
-
this.start();
|
|
5552
|
-
}
|
|
5553
|
-
};
|
|
5554
|
-
this._handleAutoStartFocus = () => {
|
|
5555
|
-
this._focused = false;
|
|
5556
|
-
if (!(this.options.pauseOnHover && this._hovered) && this.eventPause) {
|
|
5557
|
-
this.start();
|
|
5558
|
-
}
|
|
5559
|
-
};
|
|
5560
|
-
this._handleInterval = () => {
|
|
5561
|
-
const activeElem = this._slider.querySelector(".active");
|
|
5562
|
-
let newActiveIndex = [...activeElem.parentNode.children].indexOf(activeElem);
|
|
5563
|
-
if (this._slides.length === newActiveIndex + 1)
|
|
5564
|
-
newActiveIndex = 0;
|
|
5565
|
-
else newActiveIndex += 1;
|
|
5566
|
-
this.set(newActiveIndex);
|
|
5567
|
-
};
|
|
5568
|
-
/**
|
|
5569
|
-
* Pause slider autoslide.
|
|
5570
|
-
*/
|
|
5571
|
-
this.pause = () => {
|
|
5572
|
-
this._pause(false);
|
|
5573
|
-
};
|
|
5574
|
-
/**
|
|
5575
|
-
* Start slider autoslide.
|
|
5576
|
-
*/
|
|
5577
|
-
this.start = () => {
|
|
5578
|
-
clearInterval(this.interval);
|
|
5579
|
-
this.interval = setInterval(
|
|
5580
|
-
this._handleInterval,
|
|
5581
|
-
this.options.duration + this.options.interval
|
|
5582
|
-
);
|
|
5583
|
-
this.eventPause = false;
|
|
5584
|
-
};
|
|
5585
|
-
/**
|
|
5586
|
-
* Move to next slider.
|
|
5587
|
-
*/
|
|
5588
|
-
this.next = () => {
|
|
5589
|
-
let newIndex = this.activeIndex + 1;
|
|
5590
|
-
if (newIndex >= this._slides.length) newIndex = 0;
|
|
5591
|
-
else if (newIndex < 0) newIndex = this._slides.length - 1;
|
|
5592
|
-
this.set(newIndex);
|
|
5593
|
-
};
|
|
5594
|
-
/**
|
|
5595
|
-
* Move to prev slider.
|
|
5596
|
-
*/
|
|
5597
|
-
this.prev = () => {
|
|
5598
|
-
let newIndex = this.activeIndex - 1;
|
|
5599
|
-
if (newIndex >= this._slides.length) newIndex = 0;
|
|
5600
|
-
else if (newIndex < 0) newIndex = this._slides.length - 1;
|
|
5601
|
-
this.set(newIndex);
|
|
5602
|
-
};
|
|
5603
|
-
this.el["Expressive_Slider"] = this;
|
|
5604
|
-
this.options = {
|
|
5605
|
-
..._Slider.defaults,
|
|
5606
|
-
...options
|
|
5607
|
-
};
|
|
5608
|
-
this.interval = null;
|
|
5609
|
-
this.eventPause = false;
|
|
5610
|
-
this._hovered = false;
|
|
5611
|
-
this._focused = false;
|
|
5612
|
-
this._focusCurrent = false;
|
|
5613
|
-
this._slider = this.el.querySelector(".slides");
|
|
5614
|
-
this._slides = Array.from(this._slider.querySelectorAll("li"));
|
|
5615
|
-
this.activeIndex = this._slides.findIndex((li) => li.classList.contains("active"));
|
|
5616
|
-
if (this.activeIndex !== -1) {
|
|
5617
|
-
this._activeSlide = this._slides[this.activeIndex];
|
|
5618
|
-
}
|
|
5619
|
-
this._setSliderHeight();
|
|
5620
|
-
if (this._slider.hasAttribute("id")) this._sliderId = this._slider.getAttribute("id");
|
|
5621
|
-
else {
|
|
5622
|
-
this._sliderId = "slider-" + Utils.guid();
|
|
5623
|
-
this._slider.setAttribute("id", this._sliderId);
|
|
5624
|
-
}
|
|
5625
|
-
const placeholderBase64 = "data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
|
|
5626
|
-
this._slides.forEach((slide) => {
|
|
5627
|
-
const img = slide.querySelector("img");
|
|
5628
|
-
if (img) {
|
|
5629
|
-
if (img.src !== placeholderBase64) {
|
|
5630
|
-
img.style.backgroundImage = "url(" + img.src + ")";
|
|
5631
|
-
img.src = placeholderBase64;
|
|
5632
|
-
}
|
|
5633
|
-
}
|
|
5634
|
-
if (!slide.hasAttribute("tabindex")) slide.setAttribute("tabindex", "-1");
|
|
5635
|
-
slide.style.visibility = "hidden";
|
|
5636
|
-
});
|
|
5637
|
-
this._setupIndicators();
|
|
5638
|
-
if (this._activeSlide) {
|
|
5639
|
-
this._activeSlide.style.display = "block";
|
|
5640
|
-
this._activeSlide.style.visibility = "visible";
|
|
5641
|
-
} else {
|
|
5642
|
-
this.activeIndex = 0;
|
|
5643
|
-
this._slides[0].classList.add("active");
|
|
5644
|
-
this._slides[0].style.visibility = "visible";
|
|
5645
|
-
this._activeSlide = this._slides[0];
|
|
5646
|
-
this._animateSlide(this._slides[0], true);
|
|
5647
|
-
if (this.options.indicators) {
|
|
5648
|
-
this._indicators[this.activeIndex].children[0].classList.add("active");
|
|
5649
|
-
}
|
|
5650
|
-
}
|
|
5651
|
-
this._setupEventHandlers();
|
|
5652
|
-
this.start();
|
|
5653
|
-
}
|
|
5654
|
-
static get defaults() {
|
|
5655
|
-
return _defaults17;
|
|
5656
|
-
}
|
|
5657
|
-
/**
|
|
5658
|
-
* Initializes instances of Slider.
|
|
5659
|
-
* @param els HTML elements.
|
|
5660
|
-
* @param options Component options.
|
|
5661
|
-
*/
|
|
5662
|
-
static init(els, options = {}) {
|
|
5663
|
-
return super.init(els, options, _Slider);
|
|
5664
|
-
}
|
|
5665
|
-
static getInstance(el) {
|
|
5666
|
-
return el["Expressive_Slider"];
|
|
5667
|
-
}
|
|
5668
|
-
destroy() {
|
|
5669
|
-
this.pause();
|
|
5670
|
-
this._removeIndicators();
|
|
5671
|
-
this._removeEventHandlers();
|
|
5672
|
-
this.el["Expressive_Slider"] = void 0;
|
|
5673
|
-
}
|
|
5674
|
-
_setupEventHandlers() {
|
|
5675
|
-
if (this.options.pauseOnFocus) {
|
|
5676
|
-
this.el.addEventListener("focusin", this._handleAutoPauseFocus);
|
|
5677
|
-
this.el.addEventListener("focusout", this._handleAutoStartFocus);
|
|
5678
|
-
}
|
|
5679
|
-
if (this.options.pauseOnHover) {
|
|
5680
|
-
this.el.addEventListener("mouseenter", this._handleAutoPauseHover);
|
|
5681
|
-
this.el.addEventListener("mouseleave", this._handleAutoStartHover);
|
|
5682
|
-
}
|
|
5683
|
-
if (this.options.indicators) {
|
|
5684
|
-
this._indicators.forEach((el) => {
|
|
5685
|
-
el.addEventListener("click", this._handleIndicatorClick);
|
|
5686
|
-
});
|
|
5687
|
-
}
|
|
5688
|
-
document.addEventListener("visibilitychange", this._handleVisibilityChange);
|
|
5689
|
-
}
|
|
5690
|
-
_removeEventHandlers() {
|
|
5691
|
-
if (this.options.pauseOnFocus) {
|
|
5692
|
-
this.el.removeEventListener("focusin", this._handleAutoPauseFocus);
|
|
5693
|
-
this.el.removeEventListener("focusout", this._handleAutoStartFocus);
|
|
5694
|
-
}
|
|
5695
|
-
if (this.options.pauseOnHover) {
|
|
5696
|
-
this.el.removeEventListener("mouseenter", this._handleAutoPauseHover);
|
|
5697
|
-
this.el.removeEventListener("mouseleave", this._handleAutoStartHover);
|
|
5698
|
-
}
|
|
5699
|
-
if (this.options.indicators) {
|
|
5700
|
-
this._indicators.forEach((el) => {
|
|
5701
|
-
el.removeEventListener("click", this._handleIndicatorClick);
|
|
5702
|
-
});
|
|
5703
|
-
}
|
|
5704
|
-
document.removeEventListener("visibilitychange", this._handleVisibilityChange);
|
|
5705
|
-
}
|
|
5706
|
-
_animateSlide(slide, isDirectionIn) {
|
|
5707
|
-
let dx = 0, dy = 0;
|
|
5708
|
-
slide.style.opacity = isDirectionIn ? "0" : "1";
|
|
5709
|
-
setTimeout(() => {
|
|
5710
|
-
slide.style.transition = `opacity ${this.options.duration}ms ease`;
|
|
5711
|
-
slide.style.opacity = isDirectionIn ? "1" : "0";
|
|
5712
|
-
}, 1);
|
|
5713
|
-
const caption = slide.querySelector(".caption");
|
|
5714
|
-
if (!caption) return;
|
|
5715
|
-
if (caption.classList.contains("center-align")) dy = -100;
|
|
5716
|
-
else if (caption.classList.contains("right-align")) dx = 100;
|
|
5717
|
-
else if (caption.classList.contains("left-align")) dx = -100;
|
|
5718
|
-
caption.style.opacity = isDirectionIn ? "0" : "1";
|
|
5719
|
-
caption.style.transform = isDirectionIn ? `translate(${dx}px, ${dy}px)` : `translate(0, 0)`;
|
|
5720
|
-
setTimeout(() => {
|
|
5721
|
-
caption.style.transition = `opacity ${this.options.duration}ms ease, transform ${this.options.duration}ms ease`;
|
|
5722
|
-
caption.style.opacity = isDirectionIn ? "1" : "0";
|
|
5723
|
-
caption.style.transform = isDirectionIn ? `translate(0, 0)` : `translate(${dx}px, ${dy}px)`;
|
|
5724
|
-
}, this.options.duration);
|
|
5725
|
-
}
|
|
5726
|
-
_setSliderHeight() {
|
|
5727
|
-
if (!this.el.classList.contains("fullscreen")) {
|
|
5728
|
-
if (this.options.indicators) {
|
|
5729
|
-
this.el.style.height = this.options.height + 40 + "px";
|
|
5730
|
-
} else {
|
|
5731
|
-
this.el.style.height = this.options.height + "px";
|
|
5732
|
-
}
|
|
5733
|
-
this._slider.style.height = this.options.height + "px";
|
|
5734
|
-
}
|
|
5735
|
-
}
|
|
5736
|
-
_setupIndicators() {
|
|
5737
|
-
if (this.options.indicators) {
|
|
5738
|
-
const ul = document.createElement("ul");
|
|
5739
|
-
ul.classList.add("indicators");
|
|
5740
|
-
const arrLi = [];
|
|
5741
|
-
this._slides.forEach((el, i) => {
|
|
5742
|
-
const label = this.options.indicatorLabelFunc ? this.options.indicatorLabelFunc.call(this, i + 1, i === 0) : `${i + 1}`;
|
|
5743
|
-
const li = document.createElement("li");
|
|
5744
|
-
li.classList.add("indicator-item");
|
|
5745
|
-
const button = document.createElement("button");
|
|
5746
|
-
button.type = "button";
|
|
5747
|
-
button.classList.add("indicator-item-btn");
|
|
5748
|
-
button.setAttribute("aria-label", label);
|
|
5749
|
-
button.setAttribute("aria-controls", this._sliderId);
|
|
5750
|
-
li.appendChild(button);
|
|
5751
|
-
arrLi.push(li);
|
|
5752
|
-
ul.append(li);
|
|
5753
|
-
});
|
|
5754
|
-
this.el.append(ul);
|
|
5755
|
-
this._indicators = arrLi;
|
|
5756
|
-
}
|
|
5757
|
-
}
|
|
5758
|
-
_removeIndicators() {
|
|
5759
|
-
this.el.querySelector("ul.indicators").remove();
|
|
5760
|
-
}
|
|
5761
|
-
set(index) {
|
|
5762
|
-
if (index >= this._slides.length) index = 0;
|
|
5763
|
-
else if (index < 0) index = this._slides.length - 1;
|
|
5764
|
-
if (this.activeIndex === index) return;
|
|
5765
|
-
this._activeSlide = this._slides[this.activeIndex];
|
|
5766
|
-
const _caption = this._activeSlide.querySelector(".caption");
|
|
5767
|
-
this._activeSlide.classList.remove("active");
|
|
5768
|
-
this._slides.forEach((slide) => slide.style.visibility = "visible");
|
|
5769
|
-
this._activeSlide.style.opacity = "0";
|
|
5770
|
-
setTimeout(() => {
|
|
5771
|
-
this._slides.forEach((slide) => {
|
|
5772
|
-
if (slide.classList.contains("active")) return;
|
|
5773
|
-
slide.style.opacity = "0";
|
|
5774
|
-
slide.style.transform = "translate(0, 0)";
|
|
5775
|
-
slide.style.visibility = "hidden";
|
|
5776
|
-
});
|
|
5777
|
-
}, this.options.duration);
|
|
5778
|
-
if (_caption) _caption.style.opacity = "0";
|
|
5779
|
-
if (this.options.indicators) {
|
|
5780
|
-
const activeIndicator = this._indicators[this.activeIndex].children[0];
|
|
5781
|
-
const nextIndicator = this._indicators[index].children[0];
|
|
5782
|
-
activeIndicator.classList.remove("active");
|
|
5783
|
-
nextIndicator.classList.add("active");
|
|
5784
|
-
if (typeof this.options.indicatorLabelFunc === "function") {
|
|
5785
|
-
activeIndicator.ariaLabel = this.options.indicatorLabelFunc.call(
|
|
5786
|
-
this,
|
|
5787
|
-
this.activeIndex,
|
|
5788
|
-
false
|
|
5789
|
-
);
|
|
5790
|
-
nextIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, index, true);
|
|
5791
|
-
}
|
|
5792
|
-
}
|
|
5793
|
-
this._animateSlide(this._slides[index], true);
|
|
5794
|
-
this._slides[index].classList.add("active");
|
|
5795
|
-
this.activeIndex = index;
|
|
5796
|
-
if (this.interval != null) {
|
|
5797
|
-
this.start();
|
|
5798
|
-
}
|
|
5799
|
-
}
|
|
5800
|
-
_pause(fromEvent) {
|
|
5801
|
-
clearInterval(this.interval);
|
|
5802
|
-
this.eventPause = fromEvent;
|
|
5803
|
-
this.interval = null;
|
|
5804
|
-
}
|
|
5805
|
-
};
|
|
5806
|
-
|
|
5807
6095
|
// src/ts/components/tabs.ts
|
|
5808
|
-
var
|
|
6096
|
+
var _defaults19 = {
|
|
5809
6097
|
duration: 300,
|
|
5810
6098
|
onShow: null,
|
|
5811
6099
|
swipeable: false,
|
|
@@ -5834,12 +6122,10 @@ var Tabs = class _Tabs extends Component {
|
|
|
5834
6122
|
return;
|
|
5835
6123
|
}
|
|
5836
6124
|
if (tabLink.hasAttribute("target")) return;
|
|
5837
|
-
this._activeTabLink.classList.remove("active");
|
|
5838
6125
|
const _oldContent = this._content;
|
|
5839
|
-
this._activeTabLink = tabLink;
|
|
5840
6126
|
if (tabLink.hash) this._content = document.querySelector(tabLink.hash);
|
|
5841
6127
|
this._tabLinks = this._queryTabLinks();
|
|
5842
|
-
this.
|
|
6128
|
+
this._setActiveTabLink(tabLink);
|
|
5843
6129
|
const prevIndex = this._index;
|
|
5844
6130
|
this._index = Math.max(Array.from(this._tabLinks).indexOf(tabLink), 0);
|
|
5845
6131
|
if (this.options.swipeable) {
|
|
@@ -5883,7 +6169,7 @@ var Tabs = class _Tabs extends Component {
|
|
|
5883
6169
|
this._setupEventHandlers();
|
|
5884
6170
|
}
|
|
5885
6171
|
static get defaults() {
|
|
5886
|
-
return
|
|
6172
|
+
return _defaults19;
|
|
5887
6173
|
}
|
|
5888
6174
|
/**
|
|
5889
6175
|
* Initializes instances of Tabs.
|
|
@@ -5934,6 +6220,26 @@ var Tabs = class _Tabs extends Component {
|
|
|
5934
6220
|
this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + "px";
|
|
5935
6221
|
this._indicator.style.right = this._calcRightPos(this._activeTabLink) + "px";
|
|
5936
6222
|
}
|
|
6223
|
+
/**
|
|
6224
|
+
* Which tab is current, for the eye and for assistive technology.
|
|
6225
|
+
*
|
|
6226
|
+
* The class alone is a colour. `aria-current` is the part a screen reader
|
|
6227
|
+
* reads, and because tabs are navigation rather than a tablist (rule 2 -
|
|
6228
|
+
* there is no keyboard model here to back a tablist), "current" is exactly
|
|
6229
|
+
* the right word for it. Its *value* changes as the user clicks, which makes
|
|
6230
|
+
* maintaining it the component's job, not the author's - see CONTEXT.md on
|
|
6231
|
+
* static semantics versus dynamic state. Writing it once in the markup and
|
|
6232
|
+
* never moving it left the old tab announcing itself as current.
|
|
6233
|
+
*/
|
|
6234
|
+
_setActiveTabLink(tabLink) {
|
|
6235
|
+
Array.from(this._tabLinks).forEach((a) => {
|
|
6236
|
+
a.classList.remove("active");
|
|
6237
|
+
a.removeAttribute("aria-current");
|
|
6238
|
+
});
|
|
6239
|
+
this._activeTabLink = tabLink;
|
|
6240
|
+
tabLink.classList.add("active");
|
|
6241
|
+
tabLink.setAttribute("aria-current", "page");
|
|
6242
|
+
}
|
|
5937
6243
|
_setupActiveTabLink() {
|
|
5938
6244
|
this._activeTabLink = Array.from(this._tabLinks).find(
|
|
5939
6245
|
(a) => a.getAttribute("href") === location.hash
|
|
@@ -5945,8 +6251,7 @@ var Tabs = class _Tabs extends Component {
|
|
|
5945
6251
|
}
|
|
5946
6252
|
this._activeTabLink = activeTabLink;
|
|
5947
6253
|
}
|
|
5948
|
-
|
|
5949
|
-
this._activeTabLink.classList.add("active");
|
|
6254
|
+
this._setActiveTabLink(this._activeTabLink);
|
|
5950
6255
|
this._index = Math.max(Array.from(this._tabLinks).indexOf(this._activeTabLink), 0);
|
|
5951
6256
|
if (this._activeTabLink && this._activeTabLink.hash) {
|
|
5952
6257
|
this._content = document.querySelector(this._activeTabLink.hash);
|
|
@@ -6051,7 +6356,7 @@ var Tabs = class _Tabs extends Component {
|
|
|
6051
6356
|
};
|
|
6052
6357
|
|
|
6053
6358
|
// src/ts/components/timepicker.ts
|
|
6054
|
-
var
|
|
6359
|
+
var _defaults20 = {
|
|
6055
6360
|
dialRadius: 135,
|
|
6056
6361
|
outerRadius: 105,
|
|
6057
6362
|
innerRadius: 70,
|
|
@@ -6085,6 +6390,8 @@ var _defaults19 = {
|
|
|
6085
6390
|
var _Timepicker = class _Timepicker extends Component {
|
|
6086
6391
|
constructor(el, options) {
|
|
6087
6392
|
super(el, options, _Timepicker);
|
|
6393
|
+
/** Which pointer is dragging the clock hand; a second finger is ignored. */
|
|
6394
|
+
this._dragPointerId = null;
|
|
6088
6395
|
/** Whether the dial (ticks + SVG + AM/PM buttons) has been built yet. */
|
|
6089
6396
|
this._clockBuilt = false;
|
|
6090
6397
|
this._handleInputClick = () => {
|
|
@@ -6094,7 +6401,7 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6094
6401
|
if (this.displayPlugin) this.displayPlugin.show();
|
|
6095
6402
|
};
|
|
6096
6403
|
this._handleInputKeydown = (e) => {
|
|
6097
|
-
if (Utils.keys.ENTER
|
|
6404
|
+
if (e.key === Utils.keys.ENTER) {
|
|
6098
6405
|
e.preventDefault();
|
|
6099
6406
|
this._ensureClockBuilt();
|
|
6100
6407
|
this.inputHours.focus();
|
|
@@ -6102,13 +6409,9 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6102
6409
|
if (this.displayPlugin) this.displayPlugin.show();
|
|
6103
6410
|
}
|
|
6104
6411
|
};
|
|
6105
|
-
this._handleTimeInputEnterKey = (e) => {
|
|
6106
|
-
if (Utils.keys.ENTER.includes(e.key)) {
|
|
6107
|
-
e.preventDefault();
|
|
6108
|
-
this._inputFromTextField();
|
|
6109
|
-
}
|
|
6110
|
-
};
|
|
6111
6412
|
this._handleClockClickStart = (e) => {
|
|
6413
|
+
if (!e.isPrimary) return;
|
|
6414
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
6112
6415
|
e.preventDefault();
|
|
6113
6416
|
this._ensureClockBuilt();
|
|
6114
6417
|
const clockPlateBR = this.plate.getBoundingClientRect();
|
|
@@ -6116,30 +6419,30 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6116
6419
|
this.x0 = offset.x + this.options.dialRadius;
|
|
6117
6420
|
this.y0 = offset.y + this.options.dialRadius;
|
|
6118
6421
|
this.moved = false;
|
|
6119
|
-
|
|
6120
|
-
this.dx =
|
|
6121
|
-
this.dy =
|
|
6422
|
+
this._dragPointerId = e.pointerId;
|
|
6423
|
+
this.dx = e.clientX - this.x0;
|
|
6424
|
+
this.dy = e.clientY - this.y0;
|
|
6122
6425
|
this.setHand(this.dx, this.dy, false);
|
|
6123
|
-
document.addEventListener("
|
|
6124
|
-
document.addEventListener("
|
|
6125
|
-
document.addEventListener("
|
|
6126
|
-
document.addEventListener("touchend", this._handleDocumentClickEnd);
|
|
6426
|
+
document.addEventListener("pointermove", this._handleDocumentClickMove);
|
|
6427
|
+
document.addEventListener("pointerup", this._handleDocumentClickEnd);
|
|
6428
|
+
document.addEventListener("pointercancel", this._handleDocumentClickCancel);
|
|
6127
6429
|
};
|
|
6128
6430
|
this._handleDocumentClickMove = (e) => {
|
|
6431
|
+
if (e.pointerId !== this._dragPointerId) return;
|
|
6129
6432
|
e.preventDefault();
|
|
6130
|
-
const
|
|
6131
|
-
const
|
|
6132
|
-
const y = clickPos.y - this.y0;
|
|
6433
|
+
const x = e.clientX - this.x0;
|
|
6434
|
+
const y = e.clientY - this.y0;
|
|
6133
6435
|
this.moved = true;
|
|
6134
6436
|
this.setHand(x, y, false);
|
|
6135
6437
|
};
|
|
6136
6438
|
this._handleDocumentClickEnd = (e) => {
|
|
6439
|
+
if (e.pointerId !== this._dragPointerId) return;
|
|
6440
|
+
this._dragPointerId = null;
|
|
6137
6441
|
e.preventDefault();
|
|
6138
|
-
document.removeEventListener("
|
|
6139
|
-
document.removeEventListener("
|
|
6140
|
-
const
|
|
6141
|
-
const
|
|
6142
|
-
const y = clickPos.y - this.y0;
|
|
6442
|
+
document.removeEventListener("pointerup", this._handleDocumentClickEnd);
|
|
6443
|
+
document.removeEventListener("pointercancel", this._handleDocumentClickCancel);
|
|
6444
|
+
const x = e.clientX - this.x0;
|
|
6445
|
+
const y = e.clientY - this.y0;
|
|
6143
6446
|
if (this.moved && x === this.dx && y === this.dy) {
|
|
6144
6447
|
this.setHand(x, y);
|
|
6145
6448
|
}
|
|
@@ -6154,14 +6457,27 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6154
6457
|
if (typeof this.options.onSelect === "function") {
|
|
6155
6458
|
this.options.onSelect.call(this, this.hours, this.minutes);
|
|
6156
6459
|
}
|
|
6157
|
-
document.removeEventListener("
|
|
6158
|
-
|
|
6460
|
+
document.removeEventListener("pointermove", this._handleDocumentClickMove);
|
|
6461
|
+
};
|
|
6462
|
+
/**
|
|
6463
|
+
* A cancelled pointer is not a completed selection. The browser or the OS
|
|
6464
|
+
* took the gesture over, so this only lets go of the drag - it must not run
|
|
6465
|
+
* the pointer-up path, which advances hours to minutes, fires `onSelect`,
|
|
6466
|
+
* and under `autoSubmit` closes the picker on a time the user never chose.
|
|
6467
|
+
*/
|
|
6468
|
+
this._handleDocumentClickCancel = (e) => {
|
|
6469
|
+
if (e.pointerId !== this._dragPointerId) return;
|
|
6470
|
+
this._dragPointerId = null;
|
|
6471
|
+
this.moved = false;
|
|
6472
|
+
document.removeEventListener("pointermove", this._handleDocumentClickMove);
|
|
6473
|
+
document.removeEventListener("pointerup", this._handleDocumentClickEnd);
|
|
6474
|
+
document.removeEventListener("pointercancel", this._handleDocumentClickCancel);
|
|
6159
6475
|
};
|
|
6160
6476
|
this._handleAmPmClick = (e) => {
|
|
6161
6477
|
this._handleAmPmInteraction(e.target);
|
|
6162
6478
|
};
|
|
6163
6479
|
this._handleAmPmKeypress = (e) => {
|
|
6164
|
-
if (Utils.keys.ENTER
|
|
6480
|
+
if (e.key === Utils.keys.ENTER) {
|
|
6165
6481
|
this._handleAmPmInteraction(e.target);
|
|
6166
6482
|
}
|
|
6167
6483
|
};
|
|
@@ -6176,8 +6492,6 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6176
6492
|
*/
|
|
6177
6493
|
this.showView = (view, delay = null) => {
|
|
6178
6494
|
this._ensureClockBuilt();
|
|
6179
|
-
if (view === "minutes" && getComputedStyle(this.hoursView).visibility === "visible") {
|
|
6180
|
-
}
|
|
6181
6495
|
const isHours = view === "hours", nextView = isHours ? this.hoursView : this.minutesView, hideView = isHours ? this.minutesView : this.hoursView;
|
|
6182
6496
|
this.currentView = view;
|
|
6183
6497
|
hideView.classList.add("timepicker-dial-out");
|
|
@@ -6249,7 +6563,7 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6249
6563
|
}
|
|
6250
6564
|
}
|
|
6251
6565
|
static get defaults() {
|
|
6252
|
-
return
|
|
6566
|
+
return _defaults20;
|
|
6253
6567
|
}
|
|
6254
6568
|
/**
|
|
6255
6569
|
* Initializes instances of Timepicker.
|
|
@@ -6266,15 +6580,6 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6266
6580
|
const svgNS = "http://www.w3.org/2000/svg";
|
|
6267
6581
|
return document.createElementNS(svgNS, name);
|
|
6268
6582
|
}
|
|
6269
|
-
static _Pos(e) {
|
|
6270
|
-
if (e.type.startsWith("touch") && e.targetTouches.length >= 1) {
|
|
6271
|
-
return {
|
|
6272
|
-
x: e.targetTouches[0].clientX,
|
|
6273
|
-
y: e.targetTouches[0].clientY
|
|
6274
|
-
};
|
|
6275
|
-
}
|
|
6276
|
-
return { x: e.clientX, y: e.clientY };
|
|
6277
|
-
}
|
|
6278
6583
|
static getInstance(el) {
|
|
6279
6584
|
return el["Expressive_Timepicker"];
|
|
6280
6585
|
}
|
|
@@ -6287,8 +6592,7 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6287
6592
|
_setupEventHandlers() {
|
|
6288
6593
|
this.el.addEventListener("click", this._handleInputClick);
|
|
6289
6594
|
this.el.addEventListener("keydown", this._handleInputKeydown);
|
|
6290
|
-
this.plate.addEventListener("
|
|
6291
|
-
this.plate.addEventListener("touchstart", this._handleClockClickStart);
|
|
6595
|
+
this.plate.addEventListener("pointerdown", this._handleClockClickStart);
|
|
6292
6596
|
this.digitalClock.addEventListener("keyup", this._inputFromTextField);
|
|
6293
6597
|
this.inputHours.addEventListener("focus", () => this.showView("hours"));
|
|
6294
6598
|
this.inputHours.addEventListener("focusout", () => this.formatHours());
|
|
@@ -6298,10 +6602,9 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6298
6602
|
_removeEventHandlers() {
|
|
6299
6603
|
this.el.removeEventListener("click", this._handleInputClick);
|
|
6300
6604
|
this.el.removeEventListener("keydown", this._handleInputKeydown);
|
|
6301
|
-
document.removeEventListener("
|
|
6302
|
-
document.removeEventListener("
|
|
6303
|
-
document.removeEventListener("
|
|
6304
|
-
document.removeEventListener("touchend", this._handleDocumentClickEnd);
|
|
6605
|
+
document.removeEventListener("pointermove", this._handleDocumentClickMove);
|
|
6606
|
+
document.removeEventListener("pointerup", this._handleDocumentClickEnd);
|
|
6607
|
+
document.removeEventListener("pointercancel", this._handleDocumentClickCancel);
|
|
6305
6608
|
}
|
|
6306
6609
|
_insertHTMLIntoDOM() {
|
|
6307
6610
|
const template = document.createElement("template");
|
|
@@ -6330,15 +6633,6 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6330
6633
|
this.footer = this.containerEl.querySelector(".timepicker-footer");
|
|
6331
6634
|
this.amOrPm = "PM";
|
|
6332
6635
|
}
|
|
6333
|
-
/*private _createButton(text: string, visibility: string): HTMLButtonElement {
|
|
6334
|
-
const button = document.createElement('button');
|
|
6335
|
-
button.classList.add('waves-effect', 'text');
|
|
6336
|
-
button.style.visibility = visibility;
|
|
6337
|
-
button.type = 'button';
|
|
6338
|
-
button.tabIndex = -1;
|
|
6339
|
-
button.innerText = text;
|
|
6340
|
-
return button;
|
|
6341
|
-
}*/
|
|
6342
6636
|
_pickerSetup() {
|
|
6343
6637
|
Utils.createButton(
|
|
6344
6638
|
this.footer,
|
|
@@ -6619,7 +6913,7 @@ _Timepicker._template = `<div class="timepicker-container">
|
|
|
6619
6913
|
var Timepicker = _Timepicker;
|
|
6620
6914
|
|
|
6621
6915
|
// src/ts/components/snackbar.ts
|
|
6622
|
-
var
|
|
6916
|
+
var _defaults21 = {
|
|
6623
6917
|
text: "",
|
|
6624
6918
|
action: "",
|
|
6625
6919
|
onAction: null,
|
|
@@ -6629,7 +6923,8 @@ var _defaults20 = {
|
|
|
6629
6923
|
outDuration: 375,
|
|
6630
6924
|
classes: "",
|
|
6631
6925
|
completeCallback: null,
|
|
6632
|
-
activationPercent: 0.8
|
|
6926
|
+
activationPercent: 0.8,
|
|
6927
|
+
root: null
|
|
6633
6928
|
};
|
|
6634
6929
|
var _Snackbar = class _Snackbar {
|
|
6635
6930
|
constructor(options = {}) {
|
|
@@ -6652,8 +6947,10 @@ var _Snackbar = class _Snackbar {
|
|
|
6652
6947
|
}
|
|
6653
6948
|
_Snackbar._snackbars.length = 0;
|
|
6654
6949
|
}
|
|
6655
|
-
|
|
6656
|
-
|
|
6950
|
+
const root = Utils.portalRoot(this.options.root ?? document.body);
|
|
6951
|
+
if (!_Snackbar._container || !_Snackbar._container.isConnected || _Snackbar._container.parentNode !== root) {
|
|
6952
|
+
if (_Snackbar._container) _Snackbar._removeContainer();
|
|
6953
|
+
_Snackbar._createContainer(root);
|
|
6657
6954
|
}
|
|
6658
6955
|
_Snackbar._snackbars.push(this);
|
|
6659
6956
|
const snackbarElement = this._createSnackbar();
|
|
@@ -6663,30 +6960,31 @@ var _Snackbar = class _Snackbar {
|
|
|
6663
6960
|
this._setTimer();
|
|
6664
6961
|
}
|
|
6665
6962
|
static get defaults() {
|
|
6666
|
-
return
|
|
6963
|
+
return _defaults21;
|
|
6667
6964
|
}
|
|
6668
6965
|
static getInstance(el) {
|
|
6669
6966
|
return el["Expressive_Snackbar"];
|
|
6670
6967
|
}
|
|
6671
|
-
static _createContainer() {
|
|
6968
|
+
static _createContainer(root = document.body) {
|
|
6672
6969
|
const container = document.createElement("div");
|
|
6673
6970
|
container.setAttribute("id", "snackbar-container");
|
|
6674
|
-
container.addEventListener("
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
document.addEventListener("mouseup", _Snackbar._onDragEnd);
|
|
6680
|
-
document.body.appendChild(container);
|
|
6971
|
+
container.addEventListener("pointerdown", _Snackbar._onDragStart);
|
|
6972
|
+
document.addEventListener("pointermove", _Snackbar._onDragMove);
|
|
6973
|
+
document.addEventListener("pointerup", _Snackbar._onDragEnd);
|
|
6974
|
+
document.addEventListener("pointercancel", _Snackbar._onDragCancel);
|
|
6975
|
+
root.appendChild(container);
|
|
6681
6976
|
_Snackbar._container = container;
|
|
6682
6977
|
}
|
|
6683
6978
|
static _removeContainer() {
|
|
6684
|
-
document.removeEventListener("
|
|
6685
|
-
document.removeEventListener("
|
|
6979
|
+
document.removeEventListener("pointermove", _Snackbar._onDragMove);
|
|
6980
|
+
document.removeEventListener("pointerup", _Snackbar._onDragEnd);
|
|
6981
|
+
document.removeEventListener("pointercancel", _Snackbar._onDragCancel);
|
|
6686
6982
|
_Snackbar._container.remove();
|
|
6687
6983
|
_Snackbar._container = null;
|
|
6688
6984
|
}
|
|
6689
6985
|
static _onDragStart(e) {
|
|
6986
|
+
if (!e.isPrimary) return;
|
|
6987
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
6690
6988
|
const target = e.target;
|
|
6691
6989
|
if (target && !target.closest("button, a") && target.closest(".snackbar")) {
|
|
6692
6990
|
const snackbarElem = target.closest(".snackbar");
|
|
@@ -6697,17 +6995,19 @@ var _Snackbar = class _Snackbar {
|
|
|
6697
6995
|
_Snackbar._draggedSnackbar = snackbar;
|
|
6698
6996
|
snackbar.el.classList.add("panning");
|
|
6699
6997
|
snackbar.el.style.transition = "";
|
|
6700
|
-
|
|
6998
|
+
_Snackbar._dragPointerId = e.pointerId;
|
|
6999
|
+
snackbar.startingXPos = e.clientX;
|
|
6701
7000
|
snackbar.time = Date.now();
|
|
6702
|
-
snackbar.xPos =
|
|
7001
|
+
snackbar.xPos = e.clientX;
|
|
6703
7002
|
}
|
|
6704
7003
|
}
|
|
6705
7004
|
static _onDragMove(e) {
|
|
7005
|
+
if (_Snackbar._dragPointerId !== e.pointerId) return;
|
|
6706
7006
|
if (!!_Snackbar._draggedSnackbar) {
|
|
6707
7007
|
e.preventDefault();
|
|
6708
7008
|
const snackbar = _Snackbar._draggedSnackbar;
|
|
6709
|
-
snackbar.deltaX = Math.abs(snackbar.xPos -
|
|
6710
|
-
snackbar.xPos =
|
|
7009
|
+
snackbar.deltaX = Math.abs(snackbar.xPos - e.clientX);
|
|
7010
|
+
snackbar.xPos = e.clientX;
|
|
6711
7011
|
snackbar.velocityX = snackbar.deltaX / (Date.now() - snackbar.time);
|
|
6712
7012
|
snackbar.time = Date.now();
|
|
6713
7013
|
const totalDeltaX = snackbar.xPos - snackbar.startingXPos;
|
|
@@ -6716,7 +7016,9 @@ var _Snackbar = class _Snackbar {
|
|
|
6716
7016
|
snackbar.el.style.opacity = (1 - Math.abs(totalDeltaX / activationDistance)).toString();
|
|
6717
7017
|
}
|
|
6718
7018
|
}
|
|
6719
|
-
static _onDragEnd() {
|
|
7019
|
+
static _onDragEnd(e) {
|
|
7020
|
+
if (_Snackbar._dragPointerId !== e.pointerId) return;
|
|
7021
|
+
_Snackbar._dragPointerId = null;
|
|
6720
7022
|
if (!!_Snackbar._draggedSnackbar) {
|
|
6721
7023
|
const snackbar = _Snackbar._draggedSnackbar;
|
|
6722
7024
|
snackbar.panning = false;
|
|
@@ -6736,11 +7038,23 @@ var _Snackbar = class _Snackbar {
|
|
|
6736
7038
|
_Snackbar._draggedSnackbar = null;
|
|
6737
7039
|
}
|
|
6738
7040
|
}
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
7041
|
+
/**
|
|
7042
|
+
* A cancelled pointer is not a short swipe. Snap back and resume the timer
|
|
7043
|
+
* without consulting the distance travelled - the browser took the gesture
|
|
7044
|
+
* over, so the movement so far says nothing about what the user wanted.
|
|
7045
|
+
*/
|
|
7046
|
+
static _onDragCancel(e) {
|
|
7047
|
+
if (_Snackbar._dragPointerId !== e.pointerId) return;
|
|
7048
|
+
_Snackbar._dragPointerId = null;
|
|
7049
|
+
const snackbar = _Snackbar._draggedSnackbar;
|
|
7050
|
+
if (!snackbar) return;
|
|
7051
|
+
snackbar.panning = false;
|
|
7052
|
+
snackbar.el.classList.remove("panning");
|
|
7053
|
+
snackbar.el.style.transition = "transform .2s, opacity .2s";
|
|
7054
|
+
snackbar.el.style.transform = "";
|
|
7055
|
+
snackbar.el.style.opacity = "";
|
|
7056
|
+
snackbar._resumeTimer();
|
|
7057
|
+
_Snackbar._draggedSnackbar = null;
|
|
6744
7058
|
}
|
|
6745
7059
|
/**
|
|
6746
7060
|
* dismiss all snackbars.
|
|
@@ -6751,7 +7065,7 @@ var _Snackbar = class _Snackbar {
|
|
|
6751
7065
|
}
|
|
6752
7066
|
}
|
|
6753
7067
|
_createSnackbar() {
|
|
6754
|
-
let snackbar = this.options.snackbarId ?
|
|
7068
|
+
let snackbar = this.options.snackbarId ? Utils.getElementById(this.options.root ?? document.body, this.options.snackbarId) : document.createElement("div");
|
|
6755
7069
|
if (snackbar instanceof HTMLTemplateElement) {
|
|
6756
7070
|
const node = snackbar.content.cloneNode(true);
|
|
6757
7071
|
snackbar = node.firstElementChild;
|
|
@@ -6873,13 +7187,15 @@ var _Snackbar = class _Snackbar {
|
|
|
6873
7187
|
}, this.options.outDuration);
|
|
6874
7188
|
}
|
|
6875
7189
|
};
|
|
7190
|
+
/** Which pointer owns the drag in flight; a second finger is ignored. */
|
|
7191
|
+
_Snackbar._dragPointerId = null;
|
|
6876
7192
|
_Snackbar._snackbars = [];
|
|
6877
7193
|
_Snackbar._container = null;
|
|
6878
7194
|
_Snackbar._draggedSnackbar = null;
|
|
6879
7195
|
var Snackbar = _Snackbar;
|
|
6880
7196
|
|
|
6881
7197
|
// src/ts/components/tooltip.ts
|
|
6882
|
-
var
|
|
7198
|
+
var _defaults22 = {
|
|
6883
7199
|
exitDelay: 200,
|
|
6884
7200
|
enterDelay: 0,
|
|
6885
7201
|
text: "",
|
|
@@ -6924,8 +7240,10 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
6924
7240
|
this.isFocused = false;
|
|
6925
7241
|
this.close();
|
|
6926
7242
|
};
|
|
7243
|
+
// Focus opens the tooltip only when it arrived by keyboard: a pointer press
|
|
7244
|
+
// on the trigger also focuses it, and _handleMouseEnter already covers that.
|
|
6927
7245
|
this._handleFocus = () => {
|
|
6928
|
-
if (
|
|
7246
|
+
if (this.el.matches(":focus-visible")) {
|
|
6929
7247
|
this.isFocused = true;
|
|
6930
7248
|
this.open(false);
|
|
6931
7249
|
}
|
|
@@ -6947,7 +7265,7 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
6947
7265
|
this._setupEventHandlers();
|
|
6948
7266
|
}
|
|
6949
7267
|
static get defaults() {
|
|
6950
|
-
return
|
|
7268
|
+
return _defaults22;
|
|
6951
7269
|
}
|
|
6952
7270
|
/**
|
|
6953
7271
|
* Initializes instances of Tooltip.
|
|
@@ -6961,6 +7279,12 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
6961
7279
|
return el["Expressive_Tooltip"];
|
|
6962
7280
|
}
|
|
6963
7281
|
destroy() {
|
|
7282
|
+
clearTimeout(this._enterDelayTimeout);
|
|
7283
|
+
clearTimeout(this._exitDelayTimeout);
|
|
7284
|
+
clearTimeout(this._animationTimeout);
|
|
7285
|
+
this.isOpen = false;
|
|
7286
|
+
this.isHovered = false;
|
|
7287
|
+
this.isFocused = false;
|
|
6964
7288
|
if (this.el.getAttribute("aria-describedby") === this.tooltipEl.id) {
|
|
6965
7289
|
this.el.removeAttribute("aria-describedby");
|
|
6966
7290
|
}
|
|
@@ -6974,7 +7298,7 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
6974
7298
|
this.tooltipEl.id = `tooltip-${Utils.guid()}`;
|
|
6975
7299
|
this.tooltipEl.setAttribute("role", "tooltip");
|
|
6976
7300
|
this.el.setAttribute("aria-describedby", this.tooltipEl.id);
|
|
6977
|
-
const tooltipContentEl = this.options.tooltipId ?
|
|
7301
|
+
const tooltipContentEl = this.options.tooltipId ? Utils.getElementById(this.el, this.options.tooltipId) : document.createElement("div");
|
|
6978
7302
|
if (this.options.tooltipId) {
|
|
6979
7303
|
this.tooltipEl.classList.add("rich");
|
|
6980
7304
|
}
|
|
@@ -6982,7 +7306,7 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
6982
7306
|
tooltipContentEl.classList.add("tooltip-content");
|
|
6983
7307
|
this._setTooltipContent(tooltipContentEl);
|
|
6984
7308
|
this.tooltipEl.appendChild(tooltipContentEl);
|
|
6985
|
-
|
|
7309
|
+
Utils.portalRoot(this.el).appendChild(this.tooltipEl);
|
|
6986
7310
|
}
|
|
6987
7311
|
_setTooltipContent(tooltipContentEl) {
|
|
6988
7312
|
if (this.options.tooltipId) return;
|
|
@@ -7052,32 +7376,15 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
7052
7376
|
tooltip.style.left = newCoordinates.x + "px";
|
|
7053
7377
|
}
|
|
7054
7378
|
_repositionWithinScreen(x, y, width, height) {
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
let newY = y - scrollTop;
|
|
7059
|
-
const bounding = {
|
|
7060
|
-
left: newX,
|
|
7061
|
-
top: newY,
|
|
7379
|
+
return Utils._repositionWithinScreen(
|
|
7380
|
+
x,
|
|
7381
|
+
y,
|
|
7062
7382
|
width,
|
|
7063
|
-
height
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
newX = offset;
|
|
7069
|
-
} else if (edges.right) {
|
|
7070
|
-
newX -= newX + width - window.innerWidth;
|
|
7071
|
-
}
|
|
7072
|
-
if (edges.top) {
|
|
7073
|
-
newY = offset;
|
|
7074
|
-
} else if (edges.bottom) {
|
|
7075
|
-
newY -= newY + height - window.innerHeight;
|
|
7076
|
-
}
|
|
7077
|
-
return {
|
|
7078
|
-
x: newX + scrollLeft,
|
|
7079
|
-
y: newY + scrollTop
|
|
7080
|
-
};
|
|
7383
|
+
height,
|
|
7384
|
+
this.options.margin,
|
|
7385
|
+
this.options.transitionMovement,
|
|
7386
|
+
"center"
|
|
7387
|
+
);
|
|
7081
7388
|
}
|
|
7082
7389
|
_animateIn() {
|
|
7083
7390
|
this._positionTooltip();
|
|
@@ -7086,7 +7393,8 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
7086
7393
|
this.tooltipEl.style.transition = `
|
|
7087
7394
|
transform ${duration}ms ease-out,
|
|
7088
7395
|
opacity ${duration}ms ease-out`;
|
|
7089
|
-
|
|
7396
|
+
clearTimeout(this._animationTimeout);
|
|
7397
|
+
this._animationTimeout = setTimeout(() => {
|
|
7090
7398
|
this.tooltipEl.style.transform = `translateX(${this.xMovement}px) translateY(${this.yMovement}px)`;
|
|
7091
7399
|
this.tooltipEl.style.opacity = (this.options.opacity || 1).toString();
|
|
7092
7400
|
}, 1);
|
|
@@ -7096,7 +7404,8 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
7096
7404
|
this.tooltipEl.style.transition = `
|
|
7097
7405
|
transform ${duration}ms ease-out,
|
|
7098
7406
|
opacity ${duration}ms ease-out`;
|
|
7099
|
-
|
|
7407
|
+
clearTimeout(this._animationTimeout);
|
|
7408
|
+
this._animationTimeout = setTimeout(() => {
|
|
7100
7409
|
this.tooltipEl.style.transform = `translateX(0px) translateY(0px)`;
|
|
7101
7410
|
this.tooltipEl.style.opacity = "0";
|
|
7102
7411
|
}, 1);
|
|
@@ -7121,49 +7430,75 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
7121
7430
|
|
|
7122
7431
|
// src/ts/components/registry.ts
|
|
7123
7432
|
var AUTO_INIT_COMPONENTS = {
|
|
7124
|
-
|
|
7433
|
+
AppBar: {
|
|
7434
|
+
component: AppBar,
|
|
7435
|
+
selector: "header.medium, header.large, header:has(> :is(nav:not(.tabs, .navigation-bar, .navigation-rail), .bar) > :is(.search-bar, .searchbar))"
|
|
7436
|
+
},
|
|
7437
|
+
Autocomplete: {
|
|
7438
|
+
component: Autocomplete,
|
|
7439
|
+
selector: ".autocomplete"
|
|
7440
|
+
},
|
|
7441
|
+
ButtonGroup: {
|
|
7442
|
+
component: ButtonGroup,
|
|
7443
|
+
selector: ".button-group"
|
|
7444
|
+
},
|
|
7125
7445
|
// Shared with Cards.Init() - see CARDS_SELECTOR. This entry used to read
|
|
7126
7446
|
// '.cards', which no card markup uses.
|
|
7127
|
-
Cards: { component: Cards, selector: CARDS_SELECTOR },
|
|
7447
|
+
Cards: { component: Cards, selector: CARDS_SELECTOR, filter: isCardReveal },
|
|
7448
|
+
ExpandingCard: {
|
|
7449
|
+
component: ExpandingCard,
|
|
7450
|
+
selector: EXPANDING_CARD_SELECTOR
|
|
7451
|
+
},
|
|
7128
7452
|
Carousel: { component: Carousel, selector: ".carousel" },
|
|
7129
7453
|
Chips: { component: Chips, selector: ".chips" },
|
|
7130
|
-
Datepicker: {
|
|
7454
|
+
Datepicker: {
|
|
7455
|
+
component: Datepicker,
|
|
7456
|
+
selector: ".datepicker, .date-picker"
|
|
7457
|
+
},
|
|
7131
7458
|
Menu: { component: Menu, selector: ".menu-trigger" },
|
|
7132
7459
|
Lightbox: { component: Lightbox, selector: ".lightboxed" },
|
|
7133
|
-
Parallax: { component: Parallax, selector: ".parallax" },
|
|
7134
7460
|
ScrollSpy: { component: ScrollSpy, selector: ".scrollspy" },
|
|
7135
7461
|
FormSelect: { component: FormSelect, selector: "select" },
|
|
7136
|
-
|
|
7137
|
-
|
|
7462
|
+
NavigationDrawer: {
|
|
7463
|
+
component: NavigationDrawer,
|
|
7464
|
+
selector: ".sidenav, .navigation-drawer"
|
|
7465
|
+
},
|
|
7466
|
+
NavigationRail: {
|
|
7467
|
+
component: NavigationRail,
|
|
7468
|
+
selector: ".navigation-rail"
|
|
7469
|
+
},
|
|
7138
7470
|
Tabs: { component: Tabs, selector: ".tabs" },
|
|
7139
|
-
Timepicker: {
|
|
7471
|
+
Timepicker: {
|
|
7472
|
+
component: Timepicker,
|
|
7473
|
+
selector: ".timepicker, .time-picker"
|
|
7474
|
+
},
|
|
7140
7475
|
Tooltip: { component: Tooltip, selector: ".tooltipped" },
|
|
7141
7476
|
FloatingActionButton: {
|
|
7142
7477
|
component: FloatingActionButton,
|
|
7143
|
-
selector: ".fixed-action-btn"
|
|
7478
|
+
selector: ".fab, .fixed-action-btn, .fab-menu"
|
|
7144
7479
|
}
|
|
7145
7480
|
};
|
|
7146
7481
|
function AutoInit(context = document.body, options) {
|
|
7147
7482
|
for (const name of Object.keys(AUTO_INIT_COMPONENTS)) {
|
|
7148
|
-
const { component, selector } = AUTO_INIT_COMPONENTS[name];
|
|
7483
|
+
const { component, selector, filter } = AUTO_INIT_COMPONENTS[name];
|
|
7149
7484
|
const els = context.querySelectorAll(`:is(${selector}):not(.no-autoinit)`);
|
|
7150
|
-
|
|
7485
|
+
if (filter) {
|
|
7486
|
+
els.forEach((el) => {
|
|
7487
|
+
if (filter(el)) component.init(el, options?.[name] ?? {});
|
|
7488
|
+
});
|
|
7489
|
+
} else {
|
|
7490
|
+
component.init(els, options?.[name] ?? {});
|
|
7491
|
+
}
|
|
7151
7492
|
}
|
|
7152
7493
|
}
|
|
7153
7494
|
|
|
7154
7495
|
// src/ts/index.ts
|
|
7155
|
-
var version = "0.
|
|
7156
|
-
if (typeof document !== "undefined") {
|
|
7157
|
-
document.addEventListener("keydown", Utils.docHandleKeydown, true);
|
|
7158
|
-
document.addEventListener("keyup", Utils.docHandleKeyup, true);
|
|
7159
|
-
document.addEventListener("focus", Utils.docHandleFocus, true);
|
|
7160
|
-
document.addEventListener("blur", Utils.docHandleBlur, true);
|
|
7161
|
-
}
|
|
7496
|
+
var version = "0.9.0";
|
|
7162
7497
|
Forms.Init();
|
|
7163
7498
|
Chips.Init();
|
|
7164
|
-
|
|
7165
|
-
Range.Init();
|
|
7499
|
+
Slider.Init();
|
|
7166
7500
|
Cards.Init();
|
|
7501
|
+
ExpandingCard.Init();
|
|
7167
7502
|
Dialogs.Init();
|
|
7168
7503
|
BottomSheets.Init();
|
|
7169
7504
|
SideSheets.Init();
|