@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.mjs
CHANGED
|
@@ -1,45 +1,5 @@
|
|
|
1
1
|
// src/ts/core/utils.ts
|
|
2
2
|
var _Utils = class _Utils {
|
|
3
|
-
/**
|
|
4
|
-
* Detects when a key is pressed.
|
|
5
|
-
* @param e Event instance.
|
|
6
|
-
*/
|
|
7
|
-
static docHandleKeydown(e) {
|
|
8
|
-
_Utils.keyDown = true;
|
|
9
|
-
if (_Utils._navigationKeys.has(e.key)) {
|
|
10
|
-
_Utils.tabPressed = true;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Detects when a key is released.
|
|
15
|
-
* @param e Event instance.
|
|
16
|
-
*/
|
|
17
|
-
static docHandleKeyup(e) {
|
|
18
|
-
_Utils.keyDown = false;
|
|
19
|
-
if (_Utils._navigationKeys.has(e.key)) {
|
|
20
|
-
_Utils.tabPressed = false;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Detects when document is focused.
|
|
25
|
-
* @param e Event instance.
|
|
26
|
-
*/
|
|
27
|
-
/* eslint-disabled as of required event type condition check */
|
|
28
|
-
/* eslint-disable-next-line */
|
|
29
|
-
static docHandleFocus(e) {
|
|
30
|
-
if (_Utils.keyDown) {
|
|
31
|
-
document.body.classList.add("keyboard-focused");
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Detects when document is not focused.
|
|
36
|
-
* @param e Event instance.
|
|
37
|
-
*/
|
|
38
|
-
/* eslint-disabled as of required event type condition check */
|
|
39
|
-
/* eslint-disable-next-line */
|
|
40
|
-
static docHandleBlur(e) {
|
|
41
|
-
document.body.classList.remove("keyboard-focused");
|
|
42
|
-
}
|
|
43
3
|
/**
|
|
44
4
|
* Run `callback` once the document is parsed.
|
|
45
5
|
*
|
|
@@ -57,13 +17,46 @@ var _Utils = class _Utils {
|
|
|
57
17
|
}
|
|
58
18
|
}
|
|
59
19
|
/**
|
|
60
|
-
* Generates a unique string identifier.
|
|
20
|
+
* Generates a unique string identifier. Every caller prefixes the result and
|
|
21
|
+
* uses it as an element id, and a UUID is valid in that position.
|
|
22
|
+
*
|
|
23
|
+
* `randomUUID` is exposed only in secure contexts, and a dev server on a
|
|
24
|
+
* plain-HTTP LAN address - the usual way a page is opened on a phone - is
|
|
25
|
+
* not one. Without the fallback every component that stamps an id would
|
|
26
|
+
* throw there. The ids only have to be unique within one document, so the
|
|
27
|
+
* fallback does not need to be cryptographic.
|
|
61
28
|
*/
|
|
62
29
|
static guid() {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
30
|
+
return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Where an element created at runtime has to be appended to stay in the same
|
|
34
|
+
* tree as `el`. A stylesheet adopted into a shadow root cannot match a node
|
|
35
|
+
* in the document, so a portal that lands on `document.body` is unstyled
|
|
36
|
+
* whenever its origin lives in a shadow root (adr/0002).
|
|
37
|
+
*
|
|
38
|
+
* Light-DOM elements still get `document.body`, which is what escapes an
|
|
39
|
+
* ancestor's `overflow: hidden` and stacking context. Inside a shadow root
|
|
40
|
+
* both hazards come back: the host's own ancestors still form the containing
|
|
41
|
+
* block, so a transformed ancestor re-anchors `position: fixed` and a
|
|
42
|
+
* positioned one re-anchors `position: absolute`.
|
|
43
|
+
*/
|
|
44
|
+
static portalRoot(el) {
|
|
45
|
+
const root = el.getRootNode();
|
|
46
|
+
return root.host ? root : document.body;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* `getElementById` against the tree `el` lives in. The mirror of
|
|
50
|
+
* `portalRoot`: an id in a shadow root is invisible to
|
|
51
|
+
* `document.getElementById`, so a trigger and its target inside the same
|
|
52
|
+
* root could not find each other at all.
|
|
53
|
+
*
|
|
54
|
+
* Falls back to the document for a detached `el`, whose root is a plain
|
|
55
|
+
* element with no lookup of its own.
|
|
56
|
+
*/
|
|
57
|
+
static getElementById(el, id) {
|
|
58
|
+
const root = el.getRootNode();
|
|
59
|
+
return root.getElementById ? root.getElementById(id) : document.getElementById(id);
|
|
67
60
|
}
|
|
68
61
|
/**
|
|
69
62
|
* Checks for exceeded edges
|
|
@@ -160,43 +153,50 @@ var _Utils = class _Utils {
|
|
|
160
153
|
* Retrieves document scroll postion from top.
|
|
161
154
|
*/
|
|
162
155
|
static getDocumentScrollTop() {
|
|
163
|
-
return window.scrollY
|
|
156
|
+
return window.scrollY;
|
|
164
157
|
}
|
|
165
158
|
/**
|
|
166
159
|
* Retrieves document scroll postion from left.
|
|
167
160
|
*/
|
|
168
161
|
static getDocumentScrollLeft() {
|
|
169
|
-
return window.scrollX
|
|
162
|
+
return window.scrollX;
|
|
170
163
|
}
|
|
171
164
|
/**
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
165
|
+
* Trailing-edge throttle: run `func` now, then at most once per `wait` ms
|
|
166
|
+
* with the most recent arguments.
|
|
167
|
+
*
|
|
168
|
+
* This used to carry its underscore ancestor's whole configuration - leading
|
|
169
|
+
* and trailing switches, a result passthrough - and both call sites are
|
|
170
|
+
* resize handlers passing nothing but a function and a delay.
|
|
171
|
+
*
|
|
172
|
+
* Assign the return value once. `x = Utils.throttle(fn, 200)` is right;
|
|
173
|
+
* wrapping it in an arrow builds a fresh closure per event and never calls
|
|
174
|
+
* it, which is how resize handling was dead in three components.
|
|
176
175
|
*/
|
|
177
|
-
static throttle(func, wait
|
|
178
|
-
let
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
timeout = null;
|
|
182
|
-
result = func(...lastArgs ?? []);
|
|
183
|
-
lastArgs = null;
|
|
184
|
-
};
|
|
176
|
+
static throttle(func, wait) {
|
|
177
|
+
let timeout = null;
|
|
178
|
+
let lastArgs = null;
|
|
179
|
+
let previous = 0;
|
|
185
180
|
return (...args) => {
|
|
186
181
|
const now = Date.now();
|
|
187
|
-
if (!previous && options?.leading === false) previous = now;
|
|
188
182
|
const remaining = wait - (now - previous);
|
|
189
|
-
lastArgs = args;
|
|
190
183
|
if (remaining <= 0) {
|
|
191
184
|
clearTimeout(timeout);
|
|
192
185
|
timeout = null;
|
|
193
186
|
previous = now;
|
|
194
187
|
lastArgs = null;
|
|
195
|
-
|
|
196
|
-
} else if (!timeout
|
|
197
|
-
|
|
188
|
+
func(...args);
|
|
189
|
+
} else if (!timeout) {
|
|
190
|
+
lastArgs = args;
|
|
191
|
+
timeout = setTimeout(() => {
|
|
192
|
+
previous = Date.now();
|
|
193
|
+
timeout = null;
|
|
194
|
+
func(...lastArgs ?? []);
|
|
195
|
+
lastArgs = null;
|
|
196
|
+
}, remaining);
|
|
197
|
+
} else {
|
|
198
|
+
lastArgs = args;
|
|
198
199
|
}
|
|
199
|
-
return result;
|
|
200
200
|
};
|
|
201
201
|
}
|
|
202
202
|
/**
|
|
@@ -213,7 +213,7 @@ var _Utils = class _Utils {
|
|
|
213
213
|
* Renders a button with optional callback function
|
|
214
214
|
*/
|
|
215
215
|
static createButton(container, text, className = [], visibility = true, callback = null) {
|
|
216
|
-
className = className.concat(["
|
|
216
|
+
className = className.concat(["text"]);
|
|
217
217
|
const button = document.createElement("button");
|
|
218
218
|
button.className = className.join(" ");
|
|
219
219
|
button.style.visibility = visibility ? "visible" : "hidden";
|
|
@@ -223,7 +223,7 @@ var _Utils = class _Utils {
|
|
|
223
223
|
if (typeof callback === "function") {
|
|
224
224
|
button.addEventListener("click", callback);
|
|
225
225
|
button.addEventListener("keypress", (e) => {
|
|
226
|
-
if (_Utils.keys.ENTER
|
|
226
|
+
if (e.key === _Utils.keys.ENTER) callback(e);
|
|
227
227
|
});
|
|
228
228
|
}
|
|
229
229
|
container.append(button);
|
|
@@ -302,36 +302,22 @@ var _Utils = class _Utils {
|
|
|
302
302
|
};
|
|
303
303
|
}
|
|
304
304
|
};
|
|
305
|
-
/** Specifies wether tab is pressed or not. */
|
|
306
|
-
_Utils.tabPressed = false;
|
|
307
|
-
/** Specifies wether there is a key pressed. */
|
|
308
|
-
_Utils.keyDown = false;
|
|
309
305
|
/**
|
|
310
|
-
* Key maps.
|
|
306
|
+
* Key maps. One `KeyboardEvent.key` value each: the second entries these used
|
|
307
|
+
* to carry (`Esc`, `Up`, `Del`, ...) were IE and Edge Legacy spellings, and
|
|
308
|
+
* the support baseline excludes both.
|
|
311
309
|
*/
|
|
312
310
|
_Utils.keys = {
|
|
313
|
-
TAB:
|
|
314
|
-
ENTER:
|
|
315
|
-
ESC:
|
|
316
|
-
BACKSPACE:
|
|
317
|
-
ARROW_UP:
|
|
318
|
-
ARROW_DOWN:
|
|
319
|
-
ARROW_LEFT:
|
|
320
|
-
ARROW_RIGHT:
|
|
321
|
-
DELETE:
|
|
311
|
+
TAB: "Tab",
|
|
312
|
+
ENTER: "Enter",
|
|
313
|
+
ESC: "Escape",
|
|
314
|
+
BACKSPACE: "Backspace",
|
|
315
|
+
ARROW_UP: "ArrowUp",
|
|
316
|
+
ARROW_DOWN: "ArrowDown",
|
|
317
|
+
ARROW_LEFT: "ArrowLeft",
|
|
318
|
+
ARROW_RIGHT: "ArrowRight",
|
|
319
|
+
DELETE: "Delete"
|
|
322
320
|
};
|
|
323
|
-
/**
|
|
324
|
-
* Keys that count as keyboard navigation, precomputed.
|
|
325
|
-
*
|
|
326
|
-
* These handlers run at capture phase on the document for every keystroke on
|
|
327
|
-
* the page, and used to rebuild three arrays and spread them into a fourth
|
|
328
|
-
* on each one.
|
|
329
|
-
*/
|
|
330
|
-
_Utils._navigationKeys = /* @__PURE__ */ new Set([
|
|
331
|
-
..._Utils.keys.TAB,
|
|
332
|
-
..._Utils.keys.ARROW_DOWN,
|
|
333
|
-
..._Utils.keys.ARROW_UP
|
|
334
|
-
]);
|
|
335
321
|
var Utils = _Utils;
|
|
336
322
|
|
|
337
323
|
// src/ts/core/component.ts
|
|
@@ -394,47 +380,63 @@ var _defaults = {
|
|
|
394
380
|
onOpen: null,
|
|
395
381
|
onClose: null
|
|
396
382
|
};
|
|
397
|
-
var CARDS_SELECTOR =
|
|
383
|
+
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"])';
|
|
384
|
+
var REVEAL_INITIALIZED_CLASS = "card-reveal-initialized";
|
|
385
|
+
function hasAccessibleName(trigger) {
|
|
386
|
+
const label = trigger.getAttribute("aria-label");
|
|
387
|
+
if (label?.trim()) return true;
|
|
388
|
+
const labelledBy = trigger.getAttribute("aria-labelledby");
|
|
389
|
+
if (labelledBy) {
|
|
390
|
+
const referencedText = labelledBy.trim().split(/\s+/).map((id) => trigger.ownerDocument.getElementById(id)?.textContent ?? "").join(" ").trim();
|
|
391
|
+
if (referencedText) return true;
|
|
392
|
+
}
|
|
393
|
+
const content = trigger.cloneNode(true);
|
|
394
|
+
content.querySelectorAll('[aria-hidden="true"]').forEach((node) => node.remove());
|
|
395
|
+
return Boolean(content.textContent?.trim());
|
|
396
|
+
}
|
|
397
|
+
function isUsableCardTrigger(trigger, card, panel) {
|
|
398
|
+
return trigger.closest("article") === card && !panel.contains(trigger) && !trigger.disabled && trigger.getAttribute("aria-disabled") !== "true" && hasAccessibleName(trigger);
|
|
399
|
+
}
|
|
400
|
+
function isCardReveal(el) {
|
|
401
|
+
if (el.tagName !== "ARTICLE") return false;
|
|
402
|
+
const panels = el.querySelectorAll(":scope > aside");
|
|
403
|
+
if (panels.length !== 1 || !panels[0].id) return false;
|
|
404
|
+
return Array.from(
|
|
405
|
+
el.querySelectorAll('button.card-reveal-trigger[type="button"]')
|
|
406
|
+
).some((trigger) => isUsableCardTrigger(trigger, el, panels[0]));
|
|
407
|
+
}
|
|
398
408
|
var Cards = class _Cards extends Component {
|
|
399
|
-
constructor(el, options) {
|
|
409
|
+
constructor(el, options = {}) {
|
|
400
410
|
super(el, options, _Cards);
|
|
401
411
|
this.isOpen = false;
|
|
412
|
+
this._ownsRevealInitializedClass = false;
|
|
413
|
+
this._initialAriaControls = /* @__PURE__ */ new Map();
|
|
414
|
+
this._lastActivator = null;
|
|
402
415
|
this._setupEventHandlers = () => {
|
|
403
|
-
this._activators.forEach((
|
|
404
|
-
|
|
405
|
-
el.addEventListener("keypress", this._handleKeypressEvent);
|
|
416
|
+
this._activators.forEach((activator) => {
|
|
417
|
+
activator.addEventListener("click", this._handleClickInteraction);
|
|
406
418
|
});
|
|
419
|
+
this.el.addEventListener("keydown", this._handleKeydownEvent);
|
|
407
420
|
};
|
|
408
421
|
this._removeEventHandlers = () => {
|
|
409
|
-
this._activators.forEach((
|
|
410
|
-
|
|
411
|
-
el.removeEventListener("keypress", this._handleKeypressEvent);
|
|
422
|
+
this._activators.forEach((activator) => {
|
|
423
|
+
activator.removeEventListener("click", this._handleClickInteraction);
|
|
412
424
|
});
|
|
425
|
+
this.el.removeEventListener("keydown", this._handleKeydownEvent);
|
|
413
426
|
};
|
|
414
|
-
this._handleClickInteraction = () => {
|
|
427
|
+
this._handleClickInteraction = (event) => {
|
|
428
|
+
this._lastActivator = event.currentTarget;
|
|
415
429
|
this._handleRevealEvent();
|
|
416
430
|
};
|
|
417
|
-
this.
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
431
|
+
this._handleKeydownEvent = (event) => {
|
|
432
|
+
const target = event.target instanceof Element ? event.target.closest("article") : null;
|
|
433
|
+
if (target !== this.el || event.key !== "Escape" || !this.isOpen) return;
|
|
434
|
+
event.preventDefault();
|
|
435
|
+
this.close();
|
|
421
436
|
};
|
|
422
437
|
this._handleRevealEvent = () => {
|
|
423
|
-
this.
|
|
424
|
-
this.open();
|
|
425
|
-
};
|
|
426
|
-
this._setupRevealCloseEventHandlers = () => {
|
|
427
|
-
this.cardRevealClose.addEventListener("click", this.close);
|
|
428
|
-
this.cardRevealClose.addEventListener("keypress", this._handleKeypressCloseEvent);
|
|
429
|
-
};
|
|
430
|
-
this._removeRevealCloseEventHandlers = () => {
|
|
431
|
-
this.cardRevealClose.removeEventListener("click", this.close);
|
|
432
|
-
this.cardRevealClose.removeEventListener("keypress", this._handleKeypressCloseEvent);
|
|
433
|
-
};
|
|
434
|
-
this._handleKeypressCloseEvent = (e) => {
|
|
435
|
-
if (Utils.keys.ENTER.includes(e.key)) {
|
|
436
|
-
this.close();
|
|
437
|
-
}
|
|
438
|
+
if (this.isOpen) this.close();
|
|
439
|
+
else this.open();
|
|
438
440
|
};
|
|
439
441
|
/**
|
|
440
442
|
* Show card reveal.
|
|
@@ -442,44 +444,56 @@ var Cards = class _Cards extends Component {
|
|
|
442
444
|
this.open = () => {
|
|
443
445
|
if (this.isOpen || !this.cardReveal) return;
|
|
444
446
|
this.isOpen = true;
|
|
445
|
-
this.cardReveal.
|
|
446
|
-
|
|
447
|
+
this.cardReveal.classList.add("open");
|
|
448
|
+
this.cardReveal.inert = false;
|
|
449
|
+
this._activators.forEach((activator) => activator.ariaExpanded = "true");
|
|
447
450
|
if (typeof this.options.onOpen === "function") {
|
|
448
|
-
this.options.onOpen.call(this);
|
|
451
|
+
this.options.onOpen.call(this, this.el);
|
|
449
452
|
}
|
|
450
|
-
if (this.cardRevealClose) this._setupRevealCloseEventHandlers();
|
|
451
453
|
};
|
|
452
454
|
/**
|
|
453
455
|
* Hide card reveal.
|
|
454
456
|
*/
|
|
455
457
|
this.close = () => {
|
|
456
458
|
if (!this.isOpen || !this.cardReveal) return;
|
|
459
|
+
const focusWasInside = this.cardReveal.contains(document.activeElement);
|
|
457
460
|
this.isOpen = false;
|
|
458
|
-
this.cardReveal.
|
|
459
|
-
this.
|
|
460
|
-
|
|
461
|
+
this.cardReveal.classList.remove("open");
|
|
462
|
+
this.cardReveal.inert = true;
|
|
463
|
+
this._activators.forEach((activator) => activator.ariaExpanded = "false");
|
|
461
464
|
if (typeof this.options.onClose === "function") {
|
|
462
|
-
this.options.onClose.call(this);
|
|
465
|
+
this.options.onClose.call(this, this.el);
|
|
466
|
+
}
|
|
467
|
+
if (focusWasInside) {
|
|
468
|
+
(this._lastActivator ?? this._activators[0])?.focus();
|
|
463
469
|
}
|
|
464
|
-
if (this.cardRevealClose) this._removeRevealCloseEventHandlers();
|
|
465
470
|
};
|
|
466
471
|
this.el["Expressive_Cards"] = this;
|
|
467
472
|
this.options = {
|
|
468
473
|
..._Cards.defaults,
|
|
469
474
|
...options
|
|
470
475
|
};
|
|
471
|
-
this.
|
|
472
|
-
|
|
476
|
+
const cardReveals = this.el.querySelectorAll(":scope > aside");
|
|
477
|
+
const cardReveal = cardReveals.length === 1 ? cardReveals[0] : null;
|
|
478
|
+
const activators = cardReveal ? Array.from(
|
|
479
|
+
this.el.querySelectorAll(
|
|
480
|
+
'button.card-reveal-trigger[type="button"]'
|
|
481
|
+
)
|
|
482
|
+
).filter(
|
|
483
|
+
(activator) => isUsableCardTrigger(activator, this.el, cardReveal)
|
|
484
|
+
) : [];
|
|
485
|
+
this.cardReveal = cardReveal?.id && activators.length > 0 ? cardReveal : null;
|
|
486
|
+
this._activators = this.cardReveal ? activators : [];
|
|
473
487
|
if (this.cardReveal) {
|
|
474
|
-
this.
|
|
475
|
-
this.
|
|
476
|
-
|
|
488
|
+
this._ownsRevealInitializedClass = !this.el.classList.contains(REVEAL_INITIALIZED_CLASS);
|
|
489
|
+
this.el.classList.add(REVEAL_INITIALIZED_CLASS);
|
|
490
|
+
this._activators.forEach((activator) => {
|
|
491
|
+
this._initialAriaControls.set(activator, activator.getAttribute("aria-controls"));
|
|
492
|
+
activator.ariaExpanded = "false";
|
|
493
|
+
activator.setAttribute("aria-controls", this.cardReveal.id);
|
|
477
494
|
});
|
|
478
|
-
this.
|
|
479
|
-
|
|
480
|
-
);
|
|
481
|
-
if (this.cardRevealClose) this.cardRevealClose.tabIndex = -1;
|
|
482
|
-
this.cardReveal.ariaExpanded = "false";
|
|
495
|
+
this.cardReveal.classList.remove("open");
|
|
496
|
+
this.cardReveal.inert = true;
|
|
483
497
|
this._setupEventHandlers();
|
|
484
498
|
}
|
|
485
499
|
}
|
|
@@ -502,13 +516,28 @@ var Cards = class _Cards extends Component {
|
|
|
502
516
|
*/
|
|
503
517
|
destroy() {
|
|
504
518
|
this._removeEventHandlers();
|
|
505
|
-
if (this.
|
|
519
|
+
if (this.cardReveal) {
|
|
520
|
+
this.cardReveal.classList.remove("open");
|
|
521
|
+
this.cardReveal.inert = false;
|
|
522
|
+
if (this._ownsRevealInitializedClass) this.el.classList.remove(REVEAL_INITIALIZED_CLASS);
|
|
523
|
+
}
|
|
524
|
+
this._activators.forEach((activator) => {
|
|
525
|
+
activator.removeAttribute("aria-expanded");
|
|
526
|
+
const initialAriaControls = this._initialAriaControls.get(activator);
|
|
527
|
+
if (initialAriaControls === null) activator.removeAttribute("aria-controls");
|
|
528
|
+
else if (initialAriaControls !== void 0) {
|
|
529
|
+
activator.setAttribute("aria-controls", initialAriaControls);
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
this.isOpen = false;
|
|
506
533
|
this._activators = [];
|
|
534
|
+
this._initialAriaControls.clear();
|
|
535
|
+
this._lastActivator = null;
|
|
507
536
|
this.el["Expressive_Cards"] = void 0;
|
|
508
537
|
}
|
|
509
538
|
static Init() {
|
|
510
539
|
Utils.onDocumentReady(() => {
|
|
511
|
-
const cards = document.querySelectorAll(CARDS_SELECTOR);
|
|
540
|
+
const cards = Array.from(document.querySelectorAll(CARDS_SELECTOR)).filter(isCardReveal);
|
|
512
541
|
cards.forEach((el) => {
|
|
513
542
|
if (el && el["Expressive_Cards"] == void 0) this.init(el);
|
|
514
543
|
});
|
|
@@ -516,8 +545,173 @@ var Cards = class _Cards extends Component {
|
|
|
516
545
|
}
|
|
517
546
|
};
|
|
518
547
|
|
|
519
|
-
// src/ts/components/
|
|
548
|
+
// src/ts/components/expandingCard.ts
|
|
520
549
|
var _defaults2 = {
|
|
550
|
+
onOpen: null,
|
|
551
|
+
onClose: null
|
|
552
|
+
};
|
|
553
|
+
var EXPANDING_CARD_SELECTOR = "article.expanding-card:has(> dialog.expanding-card-dialog)";
|
|
554
|
+
var ExpandingCard = class _ExpandingCard extends Component {
|
|
555
|
+
constructor(el, options) {
|
|
556
|
+
super(el, options, _ExpandingCard);
|
|
557
|
+
this.isOpen = false;
|
|
558
|
+
this.closeGeneration = 0;
|
|
559
|
+
this._setupEventHandlers = () => {
|
|
560
|
+
this.trigger?.addEventListener("click", this.open);
|
|
561
|
+
this.trigger?.addEventListener("keypress", this._handleTriggerKeypress);
|
|
562
|
+
this.closeButton?.addEventListener("click", this.close);
|
|
563
|
+
this.dialog?.addEventListener("cancel", this._handleCancel);
|
|
564
|
+
this.dialog?.addEventListener("close", this._handleNativeClose);
|
|
565
|
+
};
|
|
566
|
+
this._removeEventHandlers = () => {
|
|
567
|
+
this.trigger?.removeEventListener("click", this.open);
|
|
568
|
+
this.trigger?.removeEventListener("keypress", this._handleTriggerKeypress);
|
|
569
|
+
this.closeButton?.removeEventListener("click", this.close);
|
|
570
|
+
this.dialog?.removeEventListener("cancel", this._handleCancel);
|
|
571
|
+
this.dialog?.removeEventListener("close", this._handleNativeClose);
|
|
572
|
+
};
|
|
573
|
+
this._handleTriggerKeypress = (event) => {
|
|
574
|
+
if (event.key === Utils.keys.ENTER || event.key === " ") {
|
|
575
|
+
event.preventDefault();
|
|
576
|
+
this.open();
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
this._handleCancel = (event) => {
|
|
580
|
+
event.preventDefault();
|
|
581
|
+
this.close();
|
|
582
|
+
};
|
|
583
|
+
this._handleNativeClose = () => {
|
|
584
|
+
if (this.dialog.open) return;
|
|
585
|
+
this.closeGeneration++;
|
|
586
|
+
this.isOpen = false;
|
|
587
|
+
this.trigger.ariaExpanded = "false";
|
|
588
|
+
this.dialog.ariaExpanded = "false";
|
|
589
|
+
this.dialog.classList.remove("expanded");
|
|
590
|
+
};
|
|
591
|
+
this._setTransitionOrigin = () => {
|
|
592
|
+
if (!this.dialog) return;
|
|
593
|
+
const card = this.el.getBoundingClientRect();
|
|
594
|
+
const media = this.el.querySelector(
|
|
595
|
+
":scope > figure, :scope > img"
|
|
596
|
+
);
|
|
597
|
+
const mediaRect = media?.getBoundingClientRect();
|
|
598
|
+
this.dialog.style.setProperty(
|
|
599
|
+
"--md-comp-expanding-card-from-top",
|
|
600
|
+
`${Math.max(0, card.top)}px`
|
|
601
|
+
);
|
|
602
|
+
this.dialog.style.setProperty(
|
|
603
|
+
"--md-comp-expanding-card-from-right",
|
|
604
|
+
`${Math.max(0, window.innerWidth - card.right)}px`
|
|
605
|
+
);
|
|
606
|
+
this.dialog.style.setProperty(
|
|
607
|
+
"--md-comp-expanding-card-from-bottom",
|
|
608
|
+
`${Math.max(0, window.innerHeight - card.bottom)}px`
|
|
609
|
+
);
|
|
610
|
+
this.dialog.style.setProperty(
|
|
611
|
+
"--md-comp-expanding-card-from-left",
|
|
612
|
+
`${Math.max(0, card.left)}px`
|
|
613
|
+
);
|
|
614
|
+
this.dialog.style.setProperty(
|
|
615
|
+
"--md-comp-expanding-card-from-media-height",
|
|
616
|
+
`${Math.max(0, mediaRect?.height ?? 0)}px`
|
|
617
|
+
);
|
|
618
|
+
};
|
|
619
|
+
this.open = () => {
|
|
620
|
+
if (this.isOpen || !this.dialog || !this.trigger) return;
|
|
621
|
+
this.closeGeneration++;
|
|
622
|
+
this._setTransitionOrigin();
|
|
623
|
+
this.isOpen = true;
|
|
624
|
+
this.trigger.ariaExpanded = "true";
|
|
625
|
+
this.dialog.ariaExpanded = "true";
|
|
626
|
+
this.dialog.showModal();
|
|
627
|
+
void this.dialog.offsetWidth;
|
|
628
|
+
this.dialog.classList.add("expanded");
|
|
629
|
+
this.closeButton?.focus();
|
|
630
|
+
if (typeof this.options.onOpen === "function") {
|
|
631
|
+
this.options.onOpen.call(this, this.el);
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
this.close = () => {
|
|
635
|
+
if (!this.isOpen || !this.dialog || !this.trigger) return;
|
|
636
|
+
const generation = ++this.closeGeneration;
|
|
637
|
+
this._setTransitionOrigin();
|
|
638
|
+
this.isOpen = false;
|
|
639
|
+
this.trigger.ariaExpanded = "false";
|
|
640
|
+
this.dialog.ariaExpanded = "false";
|
|
641
|
+
this.dialog.classList.remove("expanded");
|
|
642
|
+
if (typeof this.options.onClose === "function") {
|
|
643
|
+
this.options.onClose.call(this, this.el);
|
|
644
|
+
}
|
|
645
|
+
const finish = () => {
|
|
646
|
+
if (generation !== this.closeGeneration || this.isOpen || !this.dialog.open) return;
|
|
647
|
+
this.dialog.close();
|
|
648
|
+
if (this.dialog.isConnected && this.trigger.isConnected) this.trigger.focus();
|
|
649
|
+
};
|
|
650
|
+
const reducedMotion = window.matchMedia(
|
|
651
|
+
"(prefers-reduced-motion: reduce)"
|
|
652
|
+
).matches;
|
|
653
|
+
const transitions = reducedMotion ? [] : (this.dialog.getAnimations?.() ?? []).filter((animation) => animation.transitionProperty === "clip-path");
|
|
654
|
+
if (transitions.length === 0) finish();
|
|
655
|
+
else void Promise.allSettled(transitions.map((animation) => animation.finished)).then(finish);
|
|
656
|
+
};
|
|
657
|
+
this.el["Expressive_ExpandingCard"] = this;
|
|
658
|
+
this.options = {
|
|
659
|
+
..._ExpandingCard.defaults,
|
|
660
|
+
...options
|
|
661
|
+
};
|
|
662
|
+
this.dialog = this.el.querySelector(
|
|
663
|
+
":scope > dialog.expanding-card-dialog"
|
|
664
|
+
);
|
|
665
|
+
this.trigger = this.el.querySelector(
|
|
666
|
+
":scope > .expanding-card-trigger, :scope > figure > .expanding-card-trigger"
|
|
667
|
+
);
|
|
668
|
+
this.closeButton = this.dialog?.querySelector(".expanding-card-close") ?? null;
|
|
669
|
+
if (this.trigger && this.dialog) {
|
|
670
|
+
this.trigger.ariaExpanded = "false";
|
|
671
|
+
if (this.dialog.id)
|
|
672
|
+
this.trigger.setAttribute("aria-controls", this.dialog.id);
|
|
673
|
+
if (!this.trigger.matches("a[href], button, input, select, textarea")) {
|
|
674
|
+
this.trigger.tabIndex = 0;
|
|
675
|
+
this.trigger.setAttribute("role", "button");
|
|
676
|
+
}
|
|
677
|
+
this.dialog.ariaExpanded = "false";
|
|
678
|
+
this._setupEventHandlers();
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
static get defaults() {
|
|
682
|
+
return _defaults2;
|
|
683
|
+
}
|
|
684
|
+
static init(els, options) {
|
|
685
|
+
return super.init(els, options, _ExpandingCard);
|
|
686
|
+
}
|
|
687
|
+
static getInstance(el) {
|
|
688
|
+
return el["Expressive_ExpandingCard"];
|
|
689
|
+
}
|
|
690
|
+
destroy() {
|
|
691
|
+
this._removeEventHandlers();
|
|
692
|
+
this.closeGeneration++;
|
|
693
|
+
this.isOpen = false;
|
|
694
|
+
if (this.trigger) this.trigger.ariaExpanded = "false";
|
|
695
|
+
if (this.dialog) this.dialog.ariaExpanded = "false";
|
|
696
|
+
this.dialog?.classList.remove("expanded");
|
|
697
|
+
if (this.dialog?.open) this.dialog.close();
|
|
698
|
+
this.el["Expressive_ExpandingCard"] = void 0;
|
|
699
|
+
}
|
|
700
|
+
static Init() {
|
|
701
|
+
Utils.onDocumentReady(() => {
|
|
702
|
+
document.querySelectorAll(EXPANDING_CARD_SELECTOR).forEach((el) => {
|
|
703
|
+
if (el && el["Expressive_ExpandingCard"] == void 0) {
|
|
704
|
+
this.init(el);
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
// src/ts/components/menu.ts
|
|
712
|
+
var MIN_SURFACE_WIDTH = 112;
|
|
713
|
+
var MAX_SURFACE_WIDTH = 280;
|
|
714
|
+
var _defaults3 = {
|
|
521
715
|
alignment: "left",
|
|
522
716
|
autoFocus: true,
|
|
523
717
|
constrainWidth: true,
|
|
@@ -533,9 +727,12 @@ var _defaults2 = {
|
|
|
533
727
|
onCloseEnd: null,
|
|
534
728
|
onItemClick: null
|
|
535
729
|
};
|
|
730
|
+
var SPACE = " ";
|
|
536
731
|
var _Menu = class _Menu extends Component {
|
|
537
732
|
constructor(el, options) {
|
|
538
733
|
super(el, options, _Menu);
|
|
734
|
+
this._pendingTimers = /* @__PURE__ */ new Set();
|
|
735
|
+
this._transition = 0;
|
|
539
736
|
this._handleClick = (e) => {
|
|
540
737
|
e.preventDefault();
|
|
541
738
|
if (this.isOpen) {
|
|
@@ -569,7 +766,7 @@ var _Menu = class _Menu extends Component {
|
|
|
569
766
|
if (this.options.closeOnClick && this.menuEl?.contains(target) && !this.isTouchMoving) {
|
|
570
767
|
this.close();
|
|
571
768
|
} else if (!this.menuEl?.contains(target)) {
|
|
572
|
-
|
|
769
|
+
this._schedule(() => {
|
|
573
770
|
if (this.isOpen) {
|
|
574
771
|
this.close();
|
|
575
772
|
}
|
|
@@ -578,8 +775,8 @@ var _Menu = class _Menu extends Component {
|
|
|
578
775
|
this.isTouchMoving = false;
|
|
579
776
|
};
|
|
580
777
|
this._handleTriggerKeydown = (e) => {
|
|
581
|
-
const
|
|
582
|
-
if (
|
|
778
|
+
const opensMenu = e.key === SPACE || e.key === Utils.keys.ENTER || e.key === Utils.keys.ARROW_DOWN || e.key === Utils.keys.ARROW_UP;
|
|
779
|
+
if (opensMenu && !this.isOpen) {
|
|
583
780
|
e.preventDefault();
|
|
584
781
|
this.open();
|
|
585
782
|
}
|
|
@@ -593,13 +790,18 @@ var _Menu = class _Menu extends Component {
|
|
|
593
790
|
this._handleMenuClick = (e) => {
|
|
594
791
|
const target = e.target;
|
|
595
792
|
const li = target.closest("li");
|
|
793
|
+
if (li?.matches('.disabled, [aria-disabled="true"]')) {
|
|
794
|
+
e.preventDefault();
|
|
795
|
+
e.stopPropagation();
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
596
798
|
if (li && this._isSubmenuTriggerClick(target)) {
|
|
597
799
|
e.preventDefault();
|
|
598
800
|
e.stopPropagation();
|
|
599
801
|
this._toggleSubmenu(li);
|
|
600
802
|
return;
|
|
601
803
|
}
|
|
602
|
-
if (typeof this.options.onItemClick === "function") {
|
|
804
|
+
if (li && typeof this.options.onItemClick === "function") {
|
|
603
805
|
this.options.onItemClick.call(this, li);
|
|
604
806
|
}
|
|
605
807
|
};
|
|
@@ -612,11 +814,11 @@ var _Menu = class _Menu extends Component {
|
|
|
612
814
|
}
|
|
613
815
|
};
|
|
614
816
|
this._handleMenuKeydown = (e) => {
|
|
615
|
-
const arrowUpOrDown = Utils.keys.ARROW_DOWN
|
|
616
|
-
if (Utils.keys.TAB
|
|
817
|
+
const arrowUpOrDown = e.key === Utils.keys.ARROW_DOWN || e.key === Utils.keys.ARROW_UP;
|
|
818
|
+
if (e.key === Utils.keys.TAB) {
|
|
617
819
|
e.preventDefault();
|
|
618
820
|
this.close();
|
|
619
|
-
} else if (Utils.keys.ARROW_RIGHT
|
|
821
|
+
} else if (e.key === Utils.keys.ARROW_RIGHT && this.isOpen) {
|
|
620
822
|
const li = this._focusedRow(e);
|
|
621
823
|
if (li?.querySelector(":scope > menu")) {
|
|
622
824
|
e.preventDefault();
|
|
@@ -626,7 +828,7 @@ var _Menu = class _Menu extends Component {
|
|
|
626
828
|
const first = li.querySelector(":scope > menu > li");
|
|
627
829
|
first?.focus();
|
|
628
830
|
}
|
|
629
|
-
} else if (Utils.keys.ARROW_LEFT
|
|
831
|
+
} else if (e.key === Utils.keys.ARROW_LEFT && this.isOpen) {
|
|
630
832
|
const submenu = this._containingSubmenu(e);
|
|
631
833
|
if (submenu) {
|
|
632
834
|
e.preventDefault();
|
|
@@ -637,7 +839,7 @@ var _Menu = class _Menu extends Component {
|
|
|
637
839
|
}
|
|
638
840
|
} else if (arrowUpOrDown && this.isOpen) {
|
|
639
841
|
e.preventDefault();
|
|
640
|
-
const direction = Utils.keys.ARROW_DOWN
|
|
842
|
+
const direction = e.key === Utils.keys.ARROW_DOWN ? 1 : -1;
|
|
641
843
|
const list = this._containingSubmenu(e) ?? this.menuEl;
|
|
642
844
|
let newFocusedIndex = this.focusedIndex;
|
|
643
845
|
let hasFoundNewIndex = false;
|
|
@@ -649,17 +851,17 @@ var _Menu = class _Menu extends Component {
|
|
|
649
851
|
}
|
|
650
852
|
} while (newFocusedIndex < list.children.length && newFocusedIndex >= 0);
|
|
651
853
|
if (hasFoundNewIndex) {
|
|
652
|
-
if (this.focusedIndex >= 0)
|
|
653
|
-
list.children[this.focusedIndex]?.classList.remove("active");
|
|
854
|
+
if (this.focusedIndex >= 0) list.children[this.focusedIndex]?.classList.remove("active");
|
|
654
855
|
this.focusedIndex = newFocusedIndex;
|
|
655
856
|
const item = list.children[this.focusedIndex];
|
|
656
857
|
item.classList.add("active");
|
|
657
858
|
item.focus({ preventScroll: true });
|
|
658
859
|
}
|
|
659
|
-
} else if (Utils.keys.ENTER
|
|
860
|
+
} else if ((e.key === Utils.keys.ENTER || e.key === SPACE) && this.isOpen) {
|
|
660
861
|
const li = this._focusedRow(e);
|
|
862
|
+
e.preventDefault();
|
|
863
|
+
if (li?.matches('.disabled, [aria-disabled="true"]')) return;
|
|
661
864
|
if (li?.querySelector(":scope > menu")) {
|
|
662
|
-
e.preventDefault();
|
|
663
865
|
this._toggleSubmenu(li);
|
|
664
866
|
return;
|
|
665
867
|
}
|
|
@@ -670,7 +872,7 @@ var _Menu = class _Menu extends Component {
|
|
|
670
872
|
} else if (focusedElement instanceof HTMLElement) {
|
|
671
873
|
focusedElement.click();
|
|
672
874
|
}
|
|
673
|
-
} else if (Utils.keys.ESC
|
|
875
|
+
} else if (e.key === Utils.keys.ESC && this.isOpen) {
|
|
674
876
|
e.preventDefault();
|
|
675
877
|
const openSub = this.menuEl.querySelector("li.open");
|
|
676
878
|
if (openSub) {
|
|
@@ -684,11 +886,12 @@ var _Menu = class _Menu extends Component {
|
|
|
684
886
|
const keyText = e.key.toLowerCase();
|
|
685
887
|
const isLetter = /[a-zA-Z0-9-_]/.test(keyText);
|
|
686
888
|
const specialKeys = [
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
889
|
+
Utils.keys.ARROW_DOWN,
|
|
890
|
+
Utils.keys.ARROW_UP,
|
|
891
|
+
Utils.keys.ENTER,
|
|
892
|
+
Utils.keys.ESC,
|
|
893
|
+
Utils.keys.TAB,
|
|
894
|
+
SPACE
|
|
692
895
|
];
|
|
693
896
|
if (isLetter && !specialKeys.includes(e.key)) {
|
|
694
897
|
this.filterQuery.push(keyText);
|
|
@@ -717,16 +920,18 @@ var _Menu = class _Menu extends Component {
|
|
|
717
920
|
* Open menu.
|
|
718
921
|
*/
|
|
719
922
|
this.open = () => {
|
|
720
|
-
if (this.isOpen) return;
|
|
923
|
+
if (this.isOpen || this.el["Expressive_Menu"] !== this) return;
|
|
924
|
+
const transition = this._clearPendingTimers();
|
|
721
925
|
this.isOpen = true;
|
|
722
926
|
if (typeof this.options.onOpenStart === "function") {
|
|
723
927
|
this.options.onOpenStart.call(this, this.el);
|
|
724
928
|
}
|
|
929
|
+
if (transition !== this._transition) return;
|
|
725
930
|
this._resetMenuStyles();
|
|
726
931
|
this.menuEl.style.display = "block";
|
|
727
932
|
this._placeMenu();
|
|
933
|
+
this._schedule(() => this._setupTemporaryEventHandlers(), 0);
|
|
728
934
|
this._animateIn();
|
|
729
|
-
setTimeout(() => this._setupTemporaryEventHandlers(), 0);
|
|
730
935
|
this.el.ariaExpanded = "true";
|
|
731
936
|
};
|
|
732
937
|
/**
|
|
@@ -734,18 +939,20 @@ var _Menu = class _Menu extends Component {
|
|
|
734
939
|
*/
|
|
735
940
|
this.close = () => {
|
|
736
941
|
if (!this.isOpen) return;
|
|
942
|
+
const transition = this._clearPendingTimers();
|
|
737
943
|
this.isOpen = false;
|
|
738
944
|
this.focusedIndex = -1;
|
|
739
945
|
this._closeSubmenus();
|
|
740
946
|
if (typeof this.options.onCloseStart === "function") {
|
|
741
947
|
this.options.onCloseStart.call(this, this.el);
|
|
742
948
|
}
|
|
949
|
+
if (transition !== this._transition) return;
|
|
743
950
|
this._animateOut();
|
|
744
951
|
this._removeTemporaryEventHandlers();
|
|
952
|
+
this.el.ariaExpanded = "false";
|
|
745
953
|
if (this.options.autoFocus) {
|
|
746
954
|
this.el.focus();
|
|
747
955
|
}
|
|
748
|
-
this.el.ariaExpanded = "false";
|
|
749
956
|
};
|
|
750
957
|
/**
|
|
751
958
|
* While menu is open, you can recalculate its dimensions if its contents have changed.
|
|
@@ -759,7 +966,7 @@ var _Menu = class _Menu extends Component {
|
|
|
759
966
|
this.el["Expressive_Menu"] = this;
|
|
760
967
|
_Menu._menus.push(this);
|
|
761
968
|
this.id = Utils.getIdFromTrigger(el);
|
|
762
|
-
this.menuEl =
|
|
969
|
+
this.menuEl = Utils.getElementById(el, this.id);
|
|
763
970
|
this.options = {
|
|
764
971
|
..._Menu.defaults,
|
|
765
972
|
...options
|
|
@@ -770,13 +977,17 @@ var _Menu = class _Menu extends Component {
|
|
|
770
977
|
this.focusedIndex = -1;
|
|
771
978
|
this.filterQuery = [];
|
|
772
979
|
this.el.ariaExpanded = "false";
|
|
980
|
+
if (!this.el.hasAttribute("aria-haspopup")) this.el.setAttribute("aria-haspopup", "menu");
|
|
981
|
+
if (this.id && !this.el.hasAttribute("aria-controls"))
|
|
982
|
+
this.el.setAttribute("aria-controls", this.id);
|
|
773
983
|
this._moveMenuToElement();
|
|
984
|
+
this._setupAccessibility();
|
|
774
985
|
this._makeMenuFocusable();
|
|
775
986
|
this._setupSubmenus();
|
|
776
987
|
this._setupEventHandlers();
|
|
777
988
|
}
|
|
778
989
|
static get defaults() {
|
|
779
|
-
return
|
|
990
|
+
return _defaults3;
|
|
780
991
|
}
|
|
781
992
|
/**
|
|
782
993
|
* Initializes instances of Menu.
|
|
@@ -790,6 +1001,9 @@ var _Menu = class _Menu extends Component {
|
|
|
790
1001
|
return el["Expressive_Menu"];
|
|
791
1002
|
}
|
|
792
1003
|
destroy() {
|
|
1004
|
+
this._clearPendingTimers();
|
|
1005
|
+
this.isOpen = false;
|
|
1006
|
+
this.el.ariaExpanded = "false";
|
|
793
1007
|
clearTimeout(this.filterTimeout);
|
|
794
1008
|
this._resetMenuStyles();
|
|
795
1009
|
this._removeEventHandlers();
|
|
@@ -826,7 +1040,9 @@ var _Menu = class _Menu extends Component {
|
|
|
826
1040
|
}
|
|
827
1041
|
_setupTemporaryEventHandlers() {
|
|
828
1042
|
document.body.addEventListener("click", this._handleDocumentClick);
|
|
829
|
-
document.body.addEventListener("touchmove", this._handleDocumentTouchmove, {
|
|
1043
|
+
document.body.addEventListener("touchmove", this._handleDocumentTouchmove, {
|
|
1044
|
+
passive: true
|
|
1045
|
+
});
|
|
830
1046
|
this.menuEl?.addEventListener("keydown", this._handleMenuKeydown);
|
|
831
1047
|
window.addEventListener("resize", this._handleWindowResize);
|
|
832
1048
|
}
|
|
@@ -836,6 +1052,33 @@ var _Menu = class _Menu extends Component {
|
|
|
836
1052
|
this.menuEl?.removeEventListener("keydown", this._handleMenuKeydown);
|
|
837
1053
|
window.removeEventListener("resize", this._handleWindowResize);
|
|
838
1054
|
}
|
|
1055
|
+
_setupAccessibility() {
|
|
1056
|
+
if (!this.menuEl) return;
|
|
1057
|
+
if (!this.menuEl.hasAttribute("role")) this.menuEl.setAttribute("role", "menu");
|
|
1058
|
+
const menus = [this.menuEl, ...this.menuEl.querySelectorAll("menu")];
|
|
1059
|
+
menus.forEach((menu) => {
|
|
1060
|
+
if (!menu.hasAttribute("role")) menu.setAttribute("role", "menu");
|
|
1061
|
+
if (menu.getAttribute("role") !== "menu") return;
|
|
1062
|
+
menu.querySelectorAll(":scope > li").forEach((li) => {
|
|
1063
|
+
if (li.classList.contains("divider")) {
|
|
1064
|
+
if (!li.hasAttribute("role")) li.setAttribute("role", "separator");
|
|
1065
|
+
return;
|
|
1066
|
+
}
|
|
1067
|
+
if (li.classList.contains("gap")) {
|
|
1068
|
+
li.setAttribute("aria-hidden", "true");
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
if (li.classList.contains("label") || li.classList.contains("optgroup")) {
|
|
1072
|
+
if (!li.hasAttribute("role")) li.setAttribute("role", "presentation");
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1075
|
+
if (!li.hasAttribute("role")) li.setAttribute("role", "menuitem");
|
|
1076
|
+
if (li.classList.contains("disabled") && !li.hasAttribute("aria-disabled")) {
|
|
1077
|
+
li.setAttribute("aria-disabled", "true");
|
|
1078
|
+
}
|
|
1079
|
+
});
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
839
1082
|
_isSubmenuTriggerClick(target) {
|
|
840
1083
|
if (!this.menuEl) return false;
|
|
841
1084
|
const li = target.closest("li");
|
|
@@ -922,7 +1165,7 @@ var _Menu = class _Menu extends Component {
|
|
|
922
1165
|
_makeMenuFocusable() {
|
|
923
1166
|
if (!this.menuEl) return;
|
|
924
1167
|
this.menuEl.popover = "";
|
|
925
|
-
this.menuEl.tabIndex =
|
|
1168
|
+
this.menuEl.tabIndex = -1;
|
|
926
1169
|
this.menuEl.querySelectorAll(":scope li, :scope > hr").forEach((el) => {
|
|
927
1170
|
if (el instanceof HTMLHRElement || el.classList.contains("divider") || el.classList.contains("gap") || el.classList.contains("label") || el.classList.contains("optgroup")) {
|
|
928
1171
|
el.setAttribute("tabindex", "-1");
|
|
@@ -931,6 +1174,15 @@ var _Menu = class _Menu extends Component {
|
|
|
931
1174
|
if (!el.getAttribute("tabindex")) el.setAttribute("tabindex", "0");
|
|
932
1175
|
});
|
|
933
1176
|
}
|
|
1177
|
+
_focusInitialItem() {
|
|
1178
|
+
if (!this.menuEl || !this.options.autoFocus) return;
|
|
1179
|
+
const first = Array.from(this.menuEl.children).find(
|
|
1180
|
+
(child) => child instanceof HTMLElement && child.tabIndex !== -1
|
|
1181
|
+
);
|
|
1182
|
+
if (!first) return;
|
|
1183
|
+
this.focusedIndex = Array.from(this.menuEl.children).indexOf(first);
|
|
1184
|
+
first.focus({ preventScroll: true });
|
|
1185
|
+
}
|
|
934
1186
|
_focusFocusedItem() {
|
|
935
1187
|
if (this.focusedIndex >= 0 && this.focusedIndex < this.menuEl.children.length && this.options.autoFocus) {
|
|
936
1188
|
this.menuEl.children[this.focusedIndex].focus({
|
|
@@ -1014,18 +1266,32 @@ var _Menu = class _Menu extends Component {
|
|
|
1014
1266
|
width: idealWidth
|
|
1015
1267
|
};
|
|
1016
1268
|
}
|
|
1269
|
+
_schedule(callback, delay) {
|
|
1270
|
+
const timer = setTimeout(() => {
|
|
1271
|
+
this._pendingTimers.delete(timer);
|
|
1272
|
+
callback();
|
|
1273
|
+
}, delay);
|
|
1274
|
+
this._pendingTimers.add(timer);
|
|
1275
|
+
}
|
|
1276
|
+
_clearPendingTimers() {
|
|
1277
|
+
for (const timer of this._pendingTimers) clearTimeout(timer);
|
|
1278
|
+
this._pendingTimers.clear();
|
|
1279
|
+
return ++this._transition;
|
|
1280
|
+
}
|
|
1017
1281
|
_animateIn() {
|
|
1282
|
+
const transition = this._transition;
|
|
1018
1283
|
const duration = this.options.inDuration;
|
|
1019
1284
|
this.menuEl.style.transition = "none";
|
|
1020
1285
|
this.menuEl.style.opacity = "0";
|
|
1021
1286
|
this.menuEl.style.transform = "scale(0.85)";
|
|
1022
|
-
|
|
1287
|
+
this._schedule(() => {
|
|
1023
1288
|
this.menuEl.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
|
|
1024
1289
|
this.menuEl.style.opacity = "1";
|
|
1025
1290
|
this.menuEl.style.transform = "scale(1)";
|
|
1026
1291
|
}, 1);
|
|
1027
|
-
|
|
1028
|
-
|
|
1292
|
+
this._schedule(() => {
|
|
1293
|
+
this._focusInitialItem();
|
|
1294
|
+
if (transition !== this._transition) return;
|
|
1029
1295
|
if (typeof this.options.onOpenEnd === "function") this.options.onOpenEnd.call(this, this.el);
|
|
1030
1296
|
}, duration);
|
|
1031
1297
|
}
|
|
@@ -1034,7 +1300,7 @@ var _Menu = class _Menu extends Component {
|
|
|
1034
1300
|
this.menuEl.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
|
|
1035
1301
|
this.menuEl.style.opacity = "0";
|
|
1036
1302
|
this.menuEl.style.transform = "scale(0.85)";
|
|
1037
|
-
|
|
1303
|
+
this._schedule(() => {
|
|
1038
1304
|
this._resetMenuStyles();
|
|
1039
1305
|
if (typeof this.options.onCloseEnd === "function")
|
|
1040
1306
|
this.options.onCloseEnd.call(this, this.el);
|
|
@@ -1042,11 +1308,11 @@ var _Menu = class _Menu extends Component {
|
|
|
1042
1308
|
}
|
|
1043
1309
|
_getClosestAncestor(el, condition) {
|
|
1044
1310
|
let ancestor = el.parentNode;
|
|
1045
|
-
while (ancestor !== null && ancestor !== document) {
|
|
1046
|
-
if (condition(ancestor)) {
|
|
1311
|
+
while (ancestor !== null && ancestor !== void 0 && ancestor !== document) {
|
|
1312
|
+
if (ancestor.nodeType === Node.ELEMENT_NODE && condition(ancestor)) {
|
|
1047
1313
|
return ancestor;
|
|
1048
1314
|
}
|
|
1049
|
-
ancestor = ancestor.
|
|
1315
|
+
ancestor = ancestor.parentNode ?? ancestor.host;
|
|
1050
1316
|
}
|
|
1051
1317
|
return null;
|
|
1052
1318
|
}
|
|
@@ -1058,12 +1324,14 @@ var _Menu = class _Menu extends Component {
|
|
|
1058
1324
|
}
|
|
1059
1325
|
);
|
|
1060
1326
|
if (!closestOverflowParent) {
|
|
1061
|
-
|
|
1327
|
+
const parent = !!this.menuEl.offsetParent ? this.menuEl.offsetParent : this.menuEl.parentNode;
|
|
1328
|
+
closestOverflowParent = parent.host ?? parent;
|
|
1062
1329
|
}
|
|
1063
1330
|
if (getComputedStyle(closestOverflowParent).position === "static")
|
|
1064
1331
|
closestOverflowParent.style.position = "relative";
|
|
1065
1332
|
const natural = this.menuEl.getBoundingClientRect().width;
|
|
1066
|
-
const
|
|
1333
|
+
const triggerWidth = this.el.getBoundingClientRect().width;
|
|
1334
|
+
const idealWidth = this.options.constrainWidth && triggerWidth >= MIN_SURFACE_WIDTH ? triggerWidth : Math.min(MAX_SURFACE_WIDTH, Math.max(MIN_SURFACE_WIDTH, natural));
|
|
1067
1335
|
this.menuEl.style.width = idealWidth + "px";
|
|
1068
1336
|
const positionInfo = this._getMenuPosition(closestOverflowParent);
|
|
1069
1337
|
this.menuEl.style.left = positionInfo.x + "px";
|
|
@@ -1077,7 +1345,7 @@ _Menu._menus = [];
|
|
|
1077
1345
|
var Menu = _Menu;
|
|
1078
1346
|
|
|
1079
1347
|
// src/ts/components/autocomplete.ts
|
|
1080
|
-
var
|
|
1348
|
+
var _defaults4 = {
|
|
1081
1349
|
data: [],
|
|
1082
1350
|
// Autocomplete data set
|
|
1083
1351
|
onAutocomplete: null,
|
|
@@ -1107,7 +1375,7 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1107
1375
|
constructor(el, options) {
|
|
1108
1376
|
super(el, options, _Autocomplete);
|
|
1109
1377
|
this._handleInputBlur = () => {
|
|
1110
|
-
if (!this.
|
|
1378
|
+
if (!this._pointerDown) {
|
|
1111
1379
|
this.close();
|
|
1112
1380
|
this._resetAutocomplete();
|
|
1113
1381
|
}
|
|
@@ -1116,9 +1384,9 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1116
1384
|
if (e.type === "keyup") _Autocomplete._keydown = false;
|
|
1117
1385
|
this.count = 0;
|
|
1118
1386
|
const actualValue = this.el.value.toLocaleLowerCase();
|
|
1119
|
-
if (Utils.keys.ENTER
|
|
1387
|
+
if (e.key === Utils.keys.ENTER || e.key === Utils.keys.ARROW_UP || e.key === Utils.keys.ARROW_DOWN)
|
|
1120
1388
|
return;
|
|
1121
|
-
if (this.oldVal !== actualValue &&
|
|
1389
|
+
if (this.oldVal !== actualValue && this.el.matches(":focus-visible")) {
|
|
1122
1390
|
this.open();
|
|
1123
1391
|
}
|
|
1124
1392
|
this._inputChangeDetection(actualValue);
|
|
@@ -1142,7 +1410,7 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1142
1410
|
this._handleInputKeydown = (e) => {
|
|
1143
1411
|
_Autocomplete._keydown = true;
|
|
1144
1412
|
const numItems = this.container.querySelectorAll("li").length;
|
|
1145
|
-
if (Utils.keys.ENTER
|
|
1413
|
+
if (e.key === Utils.keys.ENTER && this.activeIndex >= 0) {
|
|
1146
1414
|
const liElement = this.container.querySelectorAll("li")[this.activeIndex];
|
|
1147
1415
|
if (liElement) {
|
|
1148
1416
|
this.selectOption(liElement.getAttribute("data-id"));
|
|
@@ -1150,15 +1418,14 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1150
1418
|
}
|
|
1151
1419
|
return;
|
|
1152
1420
|
}
|
|
1153
|
-
if (Utils.keys.ARROW_UP
|
|
1421
|
+
if (e.key === Utils.keys.ARROW_UP || e.key === Utils.keys.ARROW_DOWN) {
|
|
1154
1422
|
e.preventDefault();
|
|
1155
|
-
if (Utils.keys.ARROW_UP
|
|
1156
|
-
if (Utils.keys.ARROW_DOWN
|
|
1423
|
+
if (e.key === Utils.keys.ARROW_UP && this.activeIndex > 0) this.activeIndex--;
|
|
1424
|
+
if (e.key === Utils.keys.ARROW_DOWN && this.activeIndex < numItems - 1)
|
|
1157
1425
|
this.activeIndex++;
|
|
1158
|
-
this
|
|
1426
|
+
this._setActive(null);
|
|
1159
1427
|
if (this.activeIndex >= 0) {
|
|
1160
|
-
this
|
|
1161
|
-
this.$active?.classList.add("active");
|
|
1428
|
+
this._setActive(this.container.querySelectorAll("li")[this.activeIndex]);
|
|
1162
1429
|
this.container.children[this.activeIndex].scrollIntoView({
|
|
1163
1430
|
behavior: "smooth",
|
|
1164
1431
|
block: "nearest",
|
|
@@ -1170,11 +1437,17 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1170
1437
|
this._handleInputClick = () => {
|
|
1171
1438
|
this.open();
|
|
1172
1439
|
};
|
|
1173
|
-
|
|
1174
|
-
|
|
1440
|
+
// The flag says "a press is in flight inside the option list", so that a blur
|
|
1441
|
+
// caused by that press does not close the list out from under it. Without the
|
|
1442
|
+
// cancel half, a cancelled gesture left the flag set and the next blur could
|
|
1443
|
+
// not close the list at all.
|
|
1444
|
+
this._handleContainerPointerDown = (e) => {
|
|
1445
|
+
if (!e.isPrimary) return;
|
|
1446
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
1447
|
+
this._pointerDown = true;
|
|
1175
1448
|
};
|
|
1176
|
-
this.
|
|
1177
|
-
this.
|
|
1449
|
+
this._handleContainerPointerUp = () => {
|
|
1450
|
+
this._pointerDown = false;
|
|
1178
1451
|
};
|
|
1179
1452
|
/**
|
|
1180
1453
|
* Show autocomplete.
|
|
@@ -1187,7 +1460,9 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1187
1460
|
this._renderMenu();
|
|
1188
1461
|
}
|
|
1189
1462
|
if (!this.menu.isOpen) {
|
|
1190
|
-
|
|
1463
|
+
if (this._openTimer !== void 0) clearTimeout(this._openTimer);
|
|
1464
|
+
this._openTimer = setTimeout(() => {
|
|
1465
|
+
this._openTimer = void 0;
|
|
1191
1466
|
this.menu.open();
|
|
1192
1467
|
}, 0);
|
|
1193
1468
|
} else this.menu.recalculateDimensions();
|
|
@@ -1210,12 +1485,32 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1210
1485
|
this.selectedValues = this.selectedValues || this.options.selected.map((value) => ({ id: value })) || [];
|
|
1211
1486
|
this.menuItems = this.options.data || [];
|
|
1212
1487
|
this.$active = null;
|
|
1213
|
-
this.
|
|
1488
|
+
this._pointerDown = false;
|
|
1214
1489
|
this._setupMenu();
|
|
1215
1490
|
this._setupEventHandlers();
|
|
1216
1491
|
}
|
|
1492
|
+
/**
|
|
1493
|
+
* The active entry, for both the eye and the screen reader. The class alone
|
|
1494
|
+
* was invisible to assistive technology; aria-activedescendant on the input
|
|
1495
|
+
* is what reports the move.
|
|
1496
|
+
*
|
|
1497
|
+
* Deliberately does not touch aria-selected. Active and selected are two
|
|
1498
|
+
* different things - in a multi-select the checkboxes track real choices,
|
|
1499
|
+
* and folding the highlight into aria-selected would announce a committed
|
|
1500
|
+
* choice as unselected the moment the user arrowed past it.
|
|
1501
|
+
*/
|
|
1502
|
+
_setActive(item) {
|
|
1503
|
+
this.$active?.classList.remove("active");
|
|
1504
|
+
this.$active = item;
|
|
1505
|
+
if (item) {
|
|
1506
|
+
item.classList.add("active");
|
|
1507
|
+
this.el.setAttribute("aria-activedescendant", item.id);
|
|
1508
|
+
} else {
|
|
1509
|
+
this.el.removeAttribute("aria-activedescendant");
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1217
1512
|
static get defaults() {
|
|
1218
|
-
return
|
|
1513
|
+
return _defaults4;
|
|
1219
1514
|
}
|
|
1220
1515
|
/**
|
|
1221
1516
|
* Initializes instances of Autocomplete.
|
|
@@ -1241,6 +1536,10 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1241
1536
|
return _Autocomplete._loadingTemplate.cloneNode(true);
|
|
1242
1537
|
}
|
|
1243
1538
|
destroy() {
|
|
1539
|
+
if (this._openTimer !== void 0) {
|
|
1540
|
+
clearTimeout(this._openTimer);
|
|
1541
|
+
this._openTimer = void 0;
|
|
1542
|
+
}
|
|
1244
1543
|
this._removeEventHandlers();
|
|
1245
1544
|
this._removeMenu();
|
|
1246
1545
|
this.el["Expressive_Autocomplete"] = void 0;
|
|
@@ -1251,12 +1550,9 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1251
1550
|
this.el.addEventListener("focus", this._handleInputFocus);
|
|
1252
1551
|
this.el.addEventListener("keydown", this._handleInputKeydown);
|
|
1253
1552
|
this.el.addEventListener("click", this._handleInputClick);
|
|
1254
|
-
this.container.addEventListener("
|
|
1255
|
-
this.container.addEventListener("
|
|
1256
|
-
|
|
1257
|
-
this.container.addEventListener("touchstart", this._handleContainerMousedownAndTouchstart);
|
|
1258
|
-
this.container.addEventListener("touchend", this._handleContainerMouseupAndTouchend);
|
|
1259
|
-
}
|
|
1553
|
+
this.container.addEventListener("pointerdown", this._handleContainerPointerDown);
|
|
1554
|
+
this.container.addEventListener("pointerup", this._handleContainerPointerUp);
|
|
1555
|
+
this.container.addEventListener("pointercancel", this._handleContainerPointerUp);
|
|
1260
1556
|
}
|
|
1261
1557
|
_removeEventHandlers() {
|
|
1262
1558
|
this.el.removeEventListener("blur", this._handleInputBlur);
|
|
@@ -1264,12 +1560,9 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1264
1560
|
this.el.removeEventListener("focus", this._handleInputFocus);
|
|
1265
1561
|
this.el.removeEventListener("keydown", this._handleInputKeydown);
|
|
1266
1562
|
this.el.removeEventListener("click", this._handleInputClick);
|
|
1267
|
-
this.container.removeEventListener("
|
|
1268
|
-
this.container.removeEventListener("
|
|
1269
|
-
|
|
1270
|
-
this.container.removeEventListener("touchstart", this._handleContainerMousedownAndTouchstart);
|
|
1271
|
-
this.container.removeEventListener("touchend", this._handleContainerMouseupAndTouchend);
|
|
1272
|
-
}
|
|
1563
|
+
this.container.removeEventListener("pointerdown", this._handleContainerPointerDown);
|
|
1564
|
+
this.container.removeEventListener("pointerup", this._handleContainerPointerUp);
|
|
1565
|
+
this.container.removeEventListener("pointercancel", this._handleContainerPointerUp);
|
|
1273
1566
|
}
|
|
1274
1567
|
_setupMenu() {
|
|
1275
1568
|
this.container = document.createElement("menu");
|
|
@@ -1277,6 +1570,10 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1277
1570
|
this.container.id = `autocomplete-options-${Utils.guid()}`;
|
|
1278
1571
|
this.container.classList.add("autocomplete-content");
|
|
1279
1572
|
this.container.ariaExpanded = "true";
|
|
1573
|
+
this.container.setAttribute("role", "listbox");
|
|
1574
|
+
this.el.setAttribute("role", "combobox");
|
|
1575
|
+
this.el.setAttribute("aria-autocomplete", "list");
|
|
1576
|
+
this.el.setAttribute("aria-controls", this.container.id);
|
|
1280
1577
|
this.el.setAttribute("data-target", this.container.id);
|
|
1281
1578
|
this.menuItems.forEach((menuItem) => {
|
|
1282
1579
|
const itemElement = this._createMenuItem(menuItem);
|
|
@@ -1315,14 +1612,14 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1315
1612
|
}
|
|
1316
1613
|
_resetCurrentElementPosition() {
|
|
1317
1614
|
this.activeIndex = -1;
|
|
1318
|
-
this
|
|
1615
|
+
this._setActive(null);
|
|
1319
1616
|
}
|
|
1320
1617
|
_resetAutocomplete() {
|
|
1321
1618
|
this.container.replaceChildren();
|
|
1322
1619
|
this._resetCurrentElementPosition();
|
|
1323
1620
|
this.oldVal = null;
|
|
1324
1621
|
this.isOpen = false;
|
|
1325
|
-
this.
|
|
1622
|
+
this._pointerDown = false;
|
|
1326
1623
|
}
|
|
1327
1624
|
_highlightPartialText(input, label) {
|
|
1328
1625
|
const start = label.toLocaleLowerCase().indexOf("" + input.toLocaleLowerCase());
|
|
@@ -1334,6 +1631,10 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1334
1631
|
}
|
|
1335
1632
|
_createMenuItem(entry) {
|
|
1336
1633
|
const item = document.createElement("li");
|
|
1634
|
+
item.id = `autocomplete-option-${Utils.guid()}`;
|
|
1635
|
+
item.setAttribute("role", "option");
|
|
1636
|
+
const isSelected = this.selectedValues.some((sel) => sel.id === entry.id);
|
|
1637
|
+
item.setAttribute("aria-selected", isSelected ? "true" : "false");
|
|
1337
1638
|
item.setAttribute("data-id", entry.id);
|
|
1338
1639
|
item.setAttribute(
|
|
1339
1640
|
"style",
|
|
@@ -1346,7 +1647,7 @@ var _Autocomplete = class _Autocomplete extends Component {
|
|
|
1346
1647
|
selection.style.textAlign = "center";
|
|
1347
1648
|
const checkbox = document.createElement("input");
|
|
1348
1649
|
checkbox.type = "checkbox";
|
|
1349
|
-
checkbox.checked =
|
|
1650
|
+
checkbox.checked = isSelected;
|
|
1350
1651
|
const spacer = document.createElement("span");
|
|
1351
1652
|
spacer.style.paddingLeft = "21px";
|
|
1352
1653
|
selection.append(checkbox, spacer);
|
|
@@ -1492,7 +1793,7 @@ _Autocomplete._loadingTemplate = null;
|
|
|
1492
1793
|
var Autocomplete = _Autocomplete;
|
|
1493
1794
|
|
|
1494
1795
|
// src/ts/components/chips.ts
|
|
1495
|
-
var
|
|
1796
|
+
var _defaults5 = {
|
|
1496
1797
|
data: [],
|
|
1497
1798
|
placeholder: "",
|
|
1498
1799
|
secondaryPlaceholder: "",
|
|
@@ -1501,6 +1802,7 @@ var _defaults4 = {
|
|
|
1501
1802
|
autocompleteOnly: false,
|
|
1502
1803
|
limit: Infinity,
|
|
1503
1804
|
allowUserInput: false,
|
|
1805
|
+
i18n: { remove: "Remove" },
|
|
1504
1806
|
onChipAdd: null,
|
|
1505
1807
|
onChipSelect: null,
|
|
1506
1808
|
onChipDelete: null
|
|
@@ -1510,7 +1812,7 @@ var _Chips = class _Chips extends Component {
|
|
|
1510
1812
|
super(el, options, _Chips);
|
|
1511
1813
|
this._handleChipClick = (e) => {
|
|
1512
1814
|
const _chip = e.target.closest(".chip");
|
|
1513
|
-
const clickedClose = e.target.
|
|
1815
|
+
const clickedClose = !!e.target.closest(".close");
|
|
1514
1816
|
if (_chip) {
|
|
1515
1817
|
const index = this._chips.indexOf(_chip);
|
|
1516
1818
|
if (index < 0) return;
|
|
@@ -1532,7 +1834,7 @@ var _Chips = class _Chips extends Component {
|
|
|
1532
1834
|
};
|
|
1533
1835
|
this._handleInputKeydown = (e) => {
|
|
1534
1836
|
_Chips._keydown = true;
|
|
1535
|
-
if (Utils.keys.ENTER
|
|
1837
|
+
if (e.key === Utils.keys.ENTER) {
|
|
1536
1838
|
if (this.hasAutocomplete && this.autocomplete && this.autocomplete.isOpen) {
|
|
1537
1839
|
return;
|
|
1538
1840
|
}
|
|
@@ -1541,7 +1843,7 @@ var _Chips = class _Chips extends Component {
|
|
|
1541
1843
|
this.addChip({ id: this._input.value });
|
|
1542
1844
|
}
|
|
1543
1845
|
this._input.value = "";
|
|
1544
|
-
} else if ((Utils.keys.BACKSPACE
|
|
1846
|
+
} else if ((e.key === Utils.keys.BACKSPACE || e.key === Utils.keys.ARROW_LEFT) && this._input.value === "" && this.chipsData.length) {
|
|
1545
1847
|
e.preventDefault();
|
|
1546
1848
|
this.selectChip(this.chipsData.length - 1);
|
|
1547
1849
|
}
|
|
@@ -1551,6 +1853,7 @@ var _Chips = class _Chips extends Component {
|
|
|
1551
1853
|
..._Chips.defaults,
|
|
1552
1854
|
...options
|
|
1553
1855
|
};
|
|
1856
|
+
if (options?.i18n) this.options.i18n = { ..._Chips.defaults.i18n, ...options.i18n };
|
|
1554
1857
|
this.el.classList.add("chips");
|
|
1555
1858
|
this.chipsData = [];
|
|
1556
1859
|
this._chips = [];
|
|
@@ -1566,8 +1869,22 @@ var _Chips = class _Chips extends Component {
|
|
|
1566
1869
|
}
|
|
1567
1870
|
this._setupLabel();
|
|
1568
1871
|
}
|
|
1872
|
+
/**
|
|
1873
|
+
* Selection is drawn by a class now, not by `:focus`, so it does not clear
|
|
1874
|
+
* itself when focus moves - every path that changes the selection has to go
|
|
1875
|
+
* through here or the class and the field drift apart.
|
|
1876
|
+
*
|
|
1877
|
+
* Deliberately no `aria-selected`: the chip is not an option in a listbox,
|
|
1878
|
+
* and putting the attribute on an element with no such role is the same
|
|
1879
|
+
* defect the semantics standard exists to remove.
|
|
1880
|
+
*/
|
|
1881
|
+
_setSelected(chip) {
|
|
1882
|
+
this._selectedChip?.classList.remove("selected");
|
|
1883
|
+
this._selectedChip = chip;
|
|
1884
|
+
chip?.classList.add("selected");
|
|
1885
|
+
}
|
|
1569
1886
|
static get defaults() {
|
|
1570
|
-
return
|
|
1887
|
+
return _defaults5;
|
|
1571
1888
|
}
|
|
1572
1889
|
/**
|
|
1573
1890
|
* Initializes instances of Chips.
|
|
@@ -1617,28 +1934,30 @@ var _Chips = class _Chips extends Component {
|
|
|
1617
1934
|
if (tag === "INPUT" || tag === "TEXTAREA" || !chipsKeydown) return;
|
|
1618
1935
|
const currChips = chips["Expressive_Chips"];
|
|
1619
1936
|
if (!currChips) return;
|
|
1620
|
-
if (Utils.keys.BACKSPACE
|
|
1937
|
+
if (e.key === Utils.keys.BACKSPACE || e.key === Utils.keys.DELETE) {
|
|
1621
1938
|
e.preventDefault();
|
|
1622
1939
|
let selectIndex = currChips.chipsData.length;
|
|
1623
1940
|
if (currChips._selectedChip) {
|
|
1624
1941
|
const index = currChips._chips.indexOf(currChips._selectedChip);
|
|
1625
1942
|
currChips.deleteChip(index);
|
|
1626
|
-
currChips.
|
|
1943
|
+
currChips._setSelected(null);
|
|
1627
1944
|
selectIndex = Math.max(index - 1, 0);
|
|
1628
1945
|
}
|
|
1629
1946
|
if (currChips.chipsData.length) currChips.selectChip(selectIndex);
|
|
1630
1947
|
else currChips._input.focus();
|
|
1631
|
-
} else if (Utils.keys.ARROW_LEFT
|
|
1948
|
+
} else if (e.key === Utils.keys.ARROW_LEFT) {
|
|
1632
1949
|
if (currChips._selectedChip) {
|
|
1633
1950
|
const selectIndex = currChips._chips.indexOf(currChips._selectedChip) - 1;
|
|
1634
1951
|
if (selectIndex < 0) return;
|
|
1635
1952
|
currChips.selectChip(selectIndex);
|
|
1636
1953
|
}
|
|
1637
|
-
} else if (Utils.keys.ARROW_RIGHT
|
|
1954
|
+
} else if (e.key === Utils.keys.ARROW_RIGHT) {
|
|
1638
1955
|
if (currChips._selectedChip) {
|
|
1639
1956
|
const selectIndex = currChips._chips.indexOf(currChips._selectedChip) + 1;
|
|
1640
|
-
if (selectIndex >= currChips.chipsData.length)
|
|
1641
|
-
|
|
1957
|
+
if (selectIndex >= currChips.chipsData.length) {
|
|
1958
|
+
currChips._setSelected(null);
|
|
1959
|
+
currChips._input.focus();
|
|
1960
|
+
} else currChips.selectChip(selectIndex);
|
|
1642
1961
|
}
|
|
1643
1962
|
}
|
|
1644
1963
|
}
|
|
@@ -1649,25 +1968,31 @@ var _Chips = class _Chips extends Component {
|
|
|
1649
1968
|
if (!_Chips._keydown && document.hidden) {
|
|
1650
1969
|
const chips = e.target.closest(".chips");
|
|
1651
1970
|
const currChips = chips?.["Expressive_Chips"];
|
|
1652
|
-
if (currChips) currChips.
|
|
1971
|
+
if (currChips) currChips._setSelected(null);
|
|
1653
1972
|
}
|
|
1654
1973
|
}
|
|
1655
1974
|
_renderChip(chip) {
|
|
1656
1975
|
if (!chip.id) return;
|
|
1657
|
-
const
|
|
1976
|
+
const label = chip.text || chip.id;
|
|
1977
|
+
const renderedChip = document.createElement("span");
|
|
1658
1978
|
renderedChip.classList.add("chip");
|
|
1659
|
-
renderedChip.innerText =
|
|
1979
|
+
renderedChip.innerText = label;
|
|
1660
1980
|
if (chip.image) {
|
|
1661
1981
|
const img = document.createElement("img");
|
|
1662
1982
|
img.setAttribute("src", chip.image);
|
|
1663
1983
|
renderedChip.insertBefore(img, renderedChip.firstChild);
|
|
1664
1984
|
}
|
|
1665
1985
|
if (this.options.allowUserInput) {
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1986
|
+
const closeButton = document.createElement("button");
|
|
1987
|
+
closeButton.type = "button";
|
|
1988
|
+
closeButton.classList.add("close");
|
|
1989
|
+
closeButton.setAttribute("aria-label", `${this.options.i18n.remove} ${label}`);
|
|
1990
|
+
const closeIcon = document.createElement("span");
|
|
1991
|
+
closeIcon.classList.add(this.options.closeIconClass);
|
|
1992
|
+
closeIcon.setAttribute("aria-hidden", "true");
|
|
1669
1993
|
closeIcon.innerText = "close";
|
|
1670
|
-
|
|
1994
|
+
closeButton.appendChild(closeIcon);
|
|
1995
|
+
renderedChip.appendChild(closeButton);
|
|
1671
1996
|
}
|
|
1672
1997
|
return renderedChip;
|
|
1673
1998
|
}
|
|
@@ -1742,6 +2067,7 @@ var _Chips = class _Chips extends Component {
|
|
|
1742
2067
|
deleteChip(chipIndex) {
|
|
1743
2068
|
const chip = this._chips[chipIndex];
|
|
1744
2069
|
if (!chip) return;
|
|
2070
|
+
if (this._selectedChip === chip) this._setSelected(null);
|
|
1745
2071
|
chip.remove();
|
|
1746
2072
|
this._chips.splice(chipIndex, 1);
|
|
1747
2073
|
this.chipsData.splice(chipIndex, 1);
|
|
@@ -1757,8 +2083,8 @@ var _Chips = class _Chips extends Component {
|
|
|
1757
2083
|
selectChip(chipIndex) {
|
|
1758
2084
|
const chip = this._chips[chipIndex];
|
|
1759
2085
|
if (!chip) return;
|
|
1760
|
-
this.
|
|
1761
|
-
chip.focus();
|
|
2086
|
+
this._setSelected(chip);
|
|
2087
|
+
chip.querySelector(".close")?.focus();
|
|
1762
2088
|
if (typeof this.options.onChipSelect === "function") {
|
|
1763
2089
|
this.options.onChipSelect(this.el, chip);
|
|
1764
2090
|
}
|
|
@@ -1769,7 +2095,7 @@ var _Chips = class _Chips extends Component {
|
|
|
1769
2095
|
chips.forEach((el) => {
|
|
1770
2096
|
el.addEventListener("click", (e) => {
|
|
1771
2097
|
if (el["Expressive_Chips"]) return;
|
|
1772
|
-
if (e.target.
|
|
2098
|
+
if (e.target.closest(".close")) {
|
|
1773
2099
|
const chip = e.target.closest(".chip");
|
|
1774
2100
|
if (chip) chip.remove();
|
|
1775
2101
|
}
|
|
@@ -1781,97 +2107,93 @@ var _Chips = class _Chips extends Component {
|
|
|
1781
2107
|
_Chips._keydown = false;
|
|
1782
2108
|
var Chips = _Chips;
|
|
1783
2109
|
|
|
1784
|
-
// src/ts/components/
|
|
1785
|
-
var
|
|
1786
|
-
var
|
|
2110
|
+
// src/ts/components/slider.ts
|
|
2111
|
+
var _defaults6 = {};
|
|
2112
|
+
var Slider = class _Slider extends Component {
|
|
1787
2113
|
constructor(el, options) {
|
|
1788
|
-
super(el, options,
|
|
2114
|
+
super(el, options, _Slider);
|
|
1789
2115
|
this._handleRangeChange = () => {
|
|
1790
2116
|
this._clampDual();
|
|
1791
2117
|
this._sync();
|
|
1792
2118
|
this.thumb.classList.add("active");
|
|
1793
2119
|
};
|
|
1794
|
-
this.
|
|
1795
|
-
|
|
2120
|
+
this._handleRangePointerDown = (e) => {
|
|
2121
|
+
if (!e.isPrimary) return;
|
|
2122
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
2123
|
+
this._pointerDown = true;
|
|
1796
2124
|
this.el.classList.add("active");
|
|
1797
2125
|
this._clampDual();
|
|
1798
2126
|
this._sync();
|
|
1799
|
-
|
|
1800
|
-
this.thumb.classList.add("active");
|
|
1801
|
-
}
|
|
2127
|
+
this.thumb.classList.add("active");
|
|
1802
2128
|
};
|
|
1803
|
-
this.
|
|
1804
|
-
if (this.
|
|
2129
|
+
this._handleRangeInputOrMove = () => {
|
|
2130
|
+
if (this._pointerDown) {
|
|
1805
2131
|
this._clampDual();
|
|
1806
2132
|
this._sync();
|
|
1807
2133
|
this.thumb.classList.add("active");
|
|
1808
2134
|
}
|
|
1809
2135
|
};
|
|
1810
|
-
this.
|
|
1811
|
-
|
|
2136
|
+
this._handleRangePointerUp = (e) => {
|
|
2137
|
+
if (!e.isPrimary) return;
|
|
2138
|
+
this._pointerDown = false;
|
|
1812
2139
|
this.el.classList.remove("active");
|
|
1813
2140
|
};
|
|
1814
|
-
this.
|
|
1815
|
-
if (!this.
|
|
2141
|
+
this._handleRangeRelease = () => {
|
|
2142
|
+
if (!this._pointerDown) {
|
|
1816
2143
|
this.thumb.classList.remove("active");
|
|
1817
2144
|
}
|
|
1818
2145
|
};
|
|
1819
|
-
this.el["
|
|
2146
|
+
this.el["Expressive_Slider"] = this;
|
|
1820
2147
|
this.options = {
|
|
1821
|
-
...
|
|
2148
|
+
..._Slider.defaults,
|
|
1822
2149
|
...options
|
|
1823
2150
|
};
|
|
1824
|
-
this.
|
|
2151
|
+
this._pointerDown = false;
|
|
1825
2152
|
this._setupThumb();
|
|
1826
2153
|
this._sync();
|
|
1827
2154
|
this._setupEventHandlers();
|
|
1828
2155
|
}
|
|
1829
2156
|
static get defaults() {
|
|
1830
|
-
return
|
|
2157
|
+
return _defaults6;
|
|
1831
2158
|
}
|
|
1832
2159
|
/**
|
|
1833
|
-
* Initializes instances of
|
|
2160
|
+
* Initializes instances of Slider.
|
|
1834
2161
|
* @param els HTML elements.
|
|
1835
2162
|
* @param options Component options.
|
|
1836
2163
|
*/
|
|
1837
2164
|
static init(els, options = {}) {
|
|
1838
|
-
return super.init(els, options,
|
|
2165
|
+
return super.init(els, options, _Slider);
|
|
1839
2166
|
}
|
|
1840
2167
|
static getInstance(el) {
|
|
1841
|
-
return el["
|
|
2168
|
+
return el["Expressive_Slider"];
|
|
1842
2169
|
}
|
|
1843
2170
|
destroy() {
|
|
1844
2171
|
this._removeEventHandlers();
|
|
1845
2172
|
this._removeThumb();
|
|
1846
|
-
this.el["
|
|
2173
|
+
this.el["Expressive_Slider"] = void 0;
|
|
1847
2174
|
}
|
|
2175
|
+
// Eleven listeners used to cover four stages, because each one was written
|
|
2176
|
+
// twice - once for mouse, once for touch. One of the touch spellings,
|
|
2177
|
+
// `touchleave`, was never implemented by any browser at all.
|
|
1848
2178
|
_setupEventHandlers() {
|
|
1849
2179
|
this.el.addEventListener("change", this._handleRangeChange);
|
|
1850
|
-
this.el.addEventListener("
|
|
1851
|
-
this.el.addEventListener("
|
|
1852
|
-
this.el.addEventListener("
|
|
1853
|
-
this.el.addEventListener("
|
|
1854
|
-
this.el.addEventListener("
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
this.el.addEventListener("mouseup", this._handleRangeMouseupTouchend);
|
|
1858
|
-
this.el.addEventListener("touchend", this._handleRangeMouseupTouchend);
|
|
1859
|
-
this.el.addEventListener("blur", this._handleRangeBlurMouseoutTouchleave);
|
|
1860
|
-
this.el.addEventListener("mouseout", this._handleRangeBlurMouseoutTouchleave);
|
|
1861
|
-
this.el.addEventListener("touchleave", this._handleRangeBlurMouseoutTouchleave);
|
|
2180
|
+
this.el.addEventListener("pointerdown", this._handleRangePointerDown);
|
|
2181
|
+
this.el.addEventListener("input", this._handleRangeInputOrMove);
|
|
2182
|
+
this.el.addEventListener("pointermove", this._handleRangeInputOrMove, { passive: true });
|
|
2183
|
+
this.el.addEventListener("pointerup", this._handleRangePointerUp);
|
|
2184
|
+
this.el.addEventListener("pointercancel", this._handleRangePointerUp);
|
|
2185
|
+
this.el.addEventListener("blur", this._handleRangeRelease);
|
|
2186
|
+
this.el.addEventListener("mouseout", this._handleRangeRelease);
|
|
1862
2187
|
}
|
|
1863
2188
|
_removeEventHandlers() {
|
|
1864
2189
|
this.el.removeEventListener("change", this._handleRangeChange);
|
|
1865
|
-
this.el.removeEventListener("
|
|
1866
|
-
this.el.removeEventListener("
|
|
1867
|
-
this.el.removeEventListener("
|
|
1868
|
-
this.el.removeEventListener("
|
|
1869
|
-
this.el.removeEventListener("
|
|
1870
|
-
this.el.removeEventListener("
|
|
1871
|
-
this.el.removeEventListener("
|
|
1872
|
-
this.el.removeEventListener("blur", this._handleRangeBlurMouseoutTouchleave);
|
|
1873
|
-
this.el.removeEventListener("mouseout", this._handleRangeBlurMouseoutTouchleave);
|
|
1874
|
-
this.el.removeEventListener("touchleave", this._handleRangeBlurMouseoutTouchleave);
|
|
2190
|
+
this.el.removeEventListener("pointerdown", this._handleRangePointerDown);
|
|
2191
|
+
this.el.removeEventListener("input", this._handleRangeInputOrMove);
|
|
2192
|
+
this.el.removeEventListener("pointermove", this._handleRangeInputOrMove);
|
|
2193
|
+
this.el.removeEventListener("pointerup", this._handleRangePointerUp);
|
|
2194
|
+
this.el.removeEventListener("pointercancel", this._handleRangePointerUp);
|
|
2195
|
+
this.el.removeEventListener("blur", this._handleRangeRelease);
|
|
2196
|
+
this.el.removeEventListener("mouseout", this._handleRangeRelease);
|
|
1875
2197
|
}
|
|
1876
2198
|
_setupThumb() {
|
|
1877
2199
|
this.thumb = document.createElement("span");
|
|
@@ -1888,7 +2210,7 @@ var Range = class _Range extends Component {
|
|
|
1888
2210
|
return !!this.el.closest(".vertical");
|
|
1889
2211
|
}
|
|
1890
2212
|
_host() {
|
|
1891
|
-
return this.el.closest(".range, .range-field, label");
|
|
2213
|
+
return this.el.closest(".slider, .range, .range-field, label");
|
|
1892
2214
|
}
|
|
1893
2215
|
_clampDual() {
|
|
1894
2216
|
const host = this._host();
|
|
@@ -1943,7 +2265,7 @@ var Range = class _Range extends Component {
|
|
|
1943
2265
|
*/
|
|
1944
2266
|
static Init() {
|
|
1945
2267
|
Utils.onDocumentReady(() => {
|
|
1946
|
-
|
|
2268
|
+
_Slider.init(document.querySelectorAll("input[type=range]"), {});
|
|
1947
2269
|
});
|
|
1948
2270
|
}
|
|
1949
2271
|
};
|
|
@@ -2016,169 +2338,144 @@ var _Dialogs = class _Dialogs {
|
|
|
2016
2338
|
_Dialogs._down = null;
|
|
2017
2339
|
var Dialogs = _Dialogs;
|
|
2018
2340
|
|
|
2019
|
-
// src/ts/behaviors/
|
|
2020
|
-
var
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2341
|
+
// src/ts/behaviors/sheetDrag.ts
|
|
2342
|
+
var DISMISS_DISTANCE = 96;
|
|
2343
|
+
var DISMISS_VELOCITY = 0.5;
|
|
2344
|
+
var DRAG_SLOP = 4;
|
|
2345
|
+
function installSheetDrag(config) {
|
|
2346
|
+
const coord = (event) => config.axis === "x" ? event.clientX : event.clientY;
|
|
2347
|
+
let drag = null;
|
|
2348
|
+
const sheetFor = (target) => {
|
|
2349
|
+
if (!(target instanceof Element)) return null;
|
|
2350
|
+
const dialog = target.closest(config.selector);
|
|
2351
|
+
return dialog instanceof HTMLDialogElement ? dialog : null;
|
|
2352
|
+
};
|
|
2353
|
+
const reset = (dialog) => {
|
|
2354
|
+
dialog.style.transition = "";
|
|
2355
|
+
dialog.style.setProperty(config.property, "0px");
|
|
2356
|
+
};
|
|
2357
|
+
const onDown = (event) => {
|
|
2358
|
+
config.onPress?.();
|
|
2030
2359
|
if (!event.isPrimary) return;
|
|
2031
2360
|
if (event.pointerType === "mouse" && event.button !== 0) return;
|
|
2032
|
-
const dialog =
|
|
2361
|
+
const dialog = sheetFor(event.target);
|
|
2033
2362
|
if (!dialog?.open) {
|
|
2034
|
-
|
|
2363
|
+
drag = null;
|
|
2035
2364
|
return;
|
|
2036
2365
|
}
|
|
2037
|
-
if (!
|
|
2038
|
-
|
|
2366
|
+
if (!config.inHandle(event, dialog)) {
|
|
2367
|
+
drag = null;
|
|
2039
2368
|
return;
|
|
2040
2369
|
}
|
|
2041
2370
|
dialog.style.transition = "none";
|
|
2042
|
-
|
|
2371
|
+
drag = {
|
|
2043
2372
|
dialog,
|
|
2044
2373
|
pointerId: event.pointerId,
|
|
2045
|
-
|
|
2046
|
-
|
|
2374
|
+
direction: config.direction(dialog),
|
|
2375
|
+
start: coord(event),
|
|
2376
|
+
last: coord(event),
|
|
2047
2377
|
lastT: Date.now(),
|
|
2048
2378
|
shift: 0
|
|
2049
2379
|
};
|
|
2050
|
-
}
|
|
2051
|
-
|
|
2052
|
-
const drag = _BottomSheets._drag;
|
|
2380
|
+
};
|
|
2381
|
+
const onMove = (event) => {
|
|
2053
2382
|
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
2054
|
-
const
|
|
2055
|
-
drag.shift =
|
|
2056
|
-
drag.
|
|
2383
|
+
const delta = coord(event) - drag.start;
|
|
2384
|
+
drag.shift = drag.direction === 1 ? Math.max(0, delta) : Math.min(0, delta);
|
|
2385
|
+
drag.last = coord(event);
|
|
2057
2386
|
drag.lastT = Date.now();
|
|
2058
|
-
drag.dialog.style.setProperty(
|
|
2059
|
-
}
|
|
2060
|
-
|
|
2061
|
-
const
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
const
|
|
2067
|
-
|
|
2068
|
-
const dismiss =
|
|
2069
|
-
if (dismiss && dialog.open)
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2387
|
+
drag.dialog.style.setProperty(config.property, `${drag.shift}px`);
|
|
2388
|
+
};
|
|
2389
|
+
const onUp = (event) => {
|
|
2390
|
+
const held = drag;
|
|
2391
|
+
if (!held || held.pointerId !== event.pointerId) return;
|
|
2392
|
+
drag = null;
|
|
2393
|
+
held.dialog.style.transition = "";
|
|
2394
|
+
const dt = Math.max(1, Date.now() - held.lastT);
|
|
2395
|
+
const velocity = (coord(event) - held.last) / dt;
|
|
2396
|
+
config.onRelease?.(Math.abs(held.shift) > DRAG_SLOP);
|
|
2397
|
+
const dismiss = held.direction === 1 ? held.shift > DISMISS_DISTANCE || velocity > DISMISS_VELOCITY : held.shift < -DISMISS_DISTANCE || velocity < -DISMISS_VELOCITY;
|
|
2398
|
+
if (dismiss && held.dialog.open) held.dialog.close();
|
|
2399
|
+
held.dialog.style.setProperty(config.property, "0px");
|
|
2400
|
+
};
|
|
2401
|
+
const onCancel = () => {
|
|
2402
|
+
config.onRelease?.(false);
|
|
2403
|
+
const held = drag;
|
|
2404
|
+
drag = null;
|
|
2405
|
+
if (held) reset(held.dialog);
|
|
2406
|
+
};
|
|
2407
|
+
Utils.onDocumentReady(() => {
|
|
2408
|
+
document.addEventListener("pointerdown", onDown, { passive: true });
|
|
2409
|
+
document.addEventListener("pointermove", onMove, { passive: true });
|
|
2410
|
+
document.addEventListener("pointerup", onUp, { passive: true });
|
|
2411
|
+
document.addEventListener("pointercancel", onCancel, { passive: true });
|
|
2412
|
+
});
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
// src/ts/behaviors/bottomSheets.ts
|
|
2416
|
+
var SHEET_SELECTOR = "dialog.bottom-sheet, dialog.bottom";
|
|
2417
|
+
var _BottomSheets = class _BottomSheets {
|
|
2418
|
+
static Init() {
|
|
2419
|
+
installSheetDrag({
|
|
2420
|
+
selector: SHEET_SELECTOR,
|
|
2421
|
+
axis: "y",
|
|
2422
|
+
property: "--md-comp-bottom-sheet-shift",
|
|
2423
|
+
direction: () => 1,
|
|
2424
|
+
inHandle: (event, dialog) => {
|
|
2425
|
+
const target = event.target;
|
|
2426
|
+
if (target instanceof Element && target.closest(".handle")) return true;
|
|
2427
|
+
const rect = dialog.getBoundingClientRect();
|
|
2428
|
+
return event.clientY >= rect.top && event.clientY <= rect.top + 48;
|
|
2429
|
+
},
|
|
2430
|
+
onPress: () => {
|
|
2431
|
+
_BottomSheets._dragged = false;
|
|
2432
|
+
},
|
|
2433
|
+
onRelease: (dragged) => {
|
|
2434
|
+
_BottomSheets._dragged = dragged;
|
|
2435
|
+
}
|
|
2436
|
+
});
|
|
2437
|
+
Utils.onDocumentReady(() => {
|
|
2438
|
+
document.addEventListener("click", _BottomSheets._onClick);
|
|
2439
|
+
});
|
|
2085
2440
|
}
|
|
2086
|
-
static
|
|
2441
|
+
static _onClick(event) {
|
|
2087
2442
|
const target = event.target;
|
|
2088
|
-
if (target instanceof Element
|
|
2089
|
-
const
|
|
2090
|
-
|
|
2443
|
+
if (!(target instanceof Element)) return;
|
|
2444
|
+
const handle = target.closest(".handle, .drag-handle");
|
|
2445
|
+
if (!(handle instanceof HTMLButtonElement)) return;
|
|
2446
|
+
if (event.detail !== 0 && _BottomSheets._dragged) return;
|
|
2447
|
+
const dialog = handle.closest(SHEET_SELECTOR);
|
|
2448
|
+
if (dialog instanceof HTMLDialogElement && dialog.open) dialog.close();
|
|
2091
2449
|
}
|
|
2092
2450
|
};
|
|
2093
|
-
|
|
2451
|
+
/**
|
|
2452
|
+
* Whether the last pointer sequence moved. A drag ends with a `click` on the
|
|
2453
|
+
* element it started on, so without this the tail of a drag that snapped back
|
|
2454
|
+
* would dismiss the sheet the drag had just declined to dismiss.
|
|
2455
|
+
*/
|
|
2456
|
+
_BottomSheets._dragged = false;
|
|
2094
2457
|
var BottomSheets = _BottomSheets;
|
|
2095
2458
|
|
|
2096
2459
|
// src/ts/behaviors/sideSheets.ts
|
|
2097
|
-
var
|
|
2460
|
+
var startDocked = (dialog) => dialog.classList.contains("left") || dialog.classList.contains("left-sheet") || dialog.classList.contains("start");
|
|
2461
|
+
var SideSheets = class {
|
|
2098
2462
|
static Init() {
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2463
|
+
installSheetDrag({
|
|
2464
|
+
selector: "dialog.side-sheet, dialog.right, dialog.right-sheet, dialog.left, dialog.left-sheet",
|
|
2465
|
+
axis: "x",
|
|
2466
|
+
property: "--md-comp-side-sheet-shift",
|
|
2467
|
+
// A start-docked sheet leaves toward the start edge, so its dismissal
|
|
2468
|
+
// direction is the negative one.
|
|
2469
|
+
direction: (dialog) => startDocked(dialog) ? -1 : 1,
|
|
2470
|
+
inHandle: (event, dialog) => {
|
|
2471
|
+
const target = event.target;
|
|
2472
|
+
if (target instanceof Element && target.closest("header")) return true;
|
|
2473
|
+
const rect = dialog.getBoundingClientRect();
|
|
2474
|
+
return startDocked(dialog) ? event.clientX >= rect.right - 24 && event.clientX <= rect.right : event.clientX >= rect.left && event.clientX <= rect.left + 24;
|
|
2475
|
+
}
|
|
2104
2476
|
});
|
|
2105
2477
|
}
|
|
2106
|
-
static _onDown(event) {
|
|
2107
|
-
if (!event.isPrimary) return;
|
|
2108
|
-
if (event.pointerType === "mouse" && event.button !== 0) return;
|
|
2109
|
-
const dialog = _SideSheets._sheet(event.target);
|
|
2110
|
-
if (!dialog?.open) {
|
|
2111
|
-
_SideSheets._drag = null;
|
|
2112
|
-
return;
|
|
2113
|
-
}
|
|
2114
|
-
if (!_SideSheets._inHandle(event, dialog)) {
|
|
2115
|
-
_SideSheets._drag = null;
|
|
2116
|
-
return;
|
|
2117
|
-
}
|
|
2118
|
-
dialog.style.transition = "none";
|
|
2119
|
-
_SideSheets._drag = {
|
|
2120
|
-
dialog,
|
|
2121
|
-
pointerId: event.pointerId,
|
|
2122
|
-
startX: event.clientX,
|
|
2123
|
-
lastX: event.clientX,
|
|
2124
|
-
lastT: Date.now(),
|
|
2125
|
-
shift: 0,
|
|
2126
|
-
startDocked: _SideSheets._startDocked(dialog)
|
|
2127
|
-
};
|
|
2128
|
-
}
|
|
2129
|
-
static _onMove(event) {
|
|
2130
|
-
const drag = _SideSheets._drag;
|
|
2131
|
-
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
2132
|
-
const delta = event.clientX - drag.startX;
|
|
2133
|
-
const shift = drag.startDocked ? Math.min(0, delta) : Math.max(0, delta);
|
|
2134
|
-
drag.shift = shift;
|
|
2135
|
-
drag.lastX = event.clientX;
|
|
2136
|
-
drag.lastT = Date.now();
|
|
2137
|
-
drag.dialog.style.setProperty("--md-comp-side-sheet-shift", `${shift}px`);
|
|
2138
|
-
}
|
|
2139
|
-
static _onUp(event) {
|
|
2140
|
-
const drag = _SideSheets._drag;
|
|
2141
|
-
_SideSheets._drag = null;
|
|
2142
|
-
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
2143
|
-
const dialog = drag.dialog;
|
|
2144
|
-
dialog.style.transition = "";
|
|
2145
|
-
const dt = Math.max(1, Date.now() - drag.lastT);
|
|
2146
|
-
const velocity = (event.clientX - drag.lastX) / dt;
|
|
2147
|
-
const dismiss = drag.startDocked ? drag.shift < -96 || velocity < -0.5 : drag.shift > 96 || velocity > 0.5;
|
|
2148
|
-
if (dismiss && dialog.open) {
|
|
2149
|
-
dialog.close();
|
|
2150
|
-
}
|
|
2151
|
-
dialog.style.setProperty("--md-comp-side-sheet-shift", "0px");
|
|
2152
|
-
}
|
|
2153
|
-
static _onCancel() {
|
|
2154
|
-
const drag = _SideSheets._drag;
|
|
2155
|
-
_SideSheets._drag = null;
|
|
2156
|
-
if (!drag) return;
|
|
2157
|
-
drag.dialog.style.transition = "";
|
|
2158
|
-
drag.dialog.style.setProperty("--md-comp-side-sheet-shift", "0px");
|
|
2159
|
-
}
|
|
2160
|
-
static _sheet(target) {
|
|
2161
|
-
if (!(target instanceof Element)) return null;
|
|
2162
|
-
const dialog = target.closest(
|
|
2163
|
-
"dialog.side-sheet, dialog.right, dialog.right-sheet, dialog.left, dialog.left-sheet"
|
|
2164
|
-
);
|
|
2165
|
-
return dialog instanceof HTMLDialogElement ? dialog : null;
|
|
2166
|
-
}
|
|
2167
|
-
static _startDocked(dialog) {
|
|
2168
|
-
return dialog.classList.contains("left") || dialog.classList.contains("left-sheet") || dialog.classList.contains("start");
|
|
2169
|
-
}
|
|
2170
|
-
static _inHandle(event, dialog) {
|
|
2171
|
-
const target = event.target;
|
|
2172
|
-
if (target instanceof Element && target.closest("header")) return true;
|
|
2173
|
-
const rect = dialog.getBoundingClientRect();
|
|
2174
|
-
if (_SideSheets._startDocked(dialog)) {
|
|
2175
|
-
return event.clientX >= rect.right - 24 && event.clientX <= rect.right;
|
|
2176
|
-
}
|
|
2177
|
-
return event.clientX >= rect.left && event.clientX <= rect.left + 24;
|
|
2178
|
-
}
|
|
2179
2478
|
};
|
|
2180
|
-
_SideSheets._drag = null;
|
|
2181
|
-
var SideSheets = _SideSheets;
|
|
2182
2479
|
|
|
2183
2480
|
// src/ts/behaviors/forms.ts
|
|
2184
2481
|
var Forms = class _Forms {
|
|
@@ -2234,7 +2531,7 @@ var Forms = class _Forms {
|
|
|
2234
2531
|
document.addEventListener("keyup", (e) => {
|
|
2235
2532
|
const target = e.target;
|
|
2236
2533
|
if (target instanceof HTMLInputElement && ["radio", "checkbox"].includes(target.type)) {
|
|
2237
|
-
if (Utils.keys.TAB
|
|
2534
|
+
if (e.key === Utils.keys.TAB) {
|
|
2238
2535
|
target.classList.add("tabbed");
|
|
2239
2536
|
target.addEventListener("blur", () => target.classList.remove("tabbed"), {
|
|
2240
2537
|
once: true
|
|
@@ -2272,61 +2569,89 @@ var Forms = class _Forms {
|
|
|
2272
2569
|
}
|
|
2273
2570
|
};
|
|
2274
2571
|
|
|
2275
|
-
// src/ts/
|
|
2276
|
-
var
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
if (
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
const waveColor = `rgba(${color?.r || 0}, ${color?.g || 0}, ${color?.b || 0}, ${0.3 * (1 - easing)})`;
|
|
2299
|
-
const stop = 90 * easing + "%";
|
|
2300
|
-
targetElement.style.backgroundImage = "radial-gradient(" + circle + ", " + waveColor + " " + stop + ", transparent " + stop + ")";
|
|
2301
|
-
animationFrame = window.requestAnimationFrame(animationStep);
|
|
2302
|
-
} else {
|
|
2303
|
-
targetElement.style.backgroundImage = "none";
|
|
2304
|
-
window.cancelAnimationFrame(animationFrame);
|
|
2572
|
+
// src/ts/components/appBar.ts
|
|
2573
|
+
var _defaults7 = {};
|
|
2574
|
+
var AppBar = class _AppBar extends Component {
|
|
2575
|
+
constructor(el, options) {
|
|
2576
|
+
super(el, options, _AppBar);
|
|
2577
|
+
this._observer = null;
|
|
2578
|
+
this._sentinel = null;
|
|
2579
|
+
this._input = null;
|
|
2580
|
+
this._view = null;
|
|
2581
|
+
this._suppressSearchOpen = false;
|
|
2582
|
+
this._onIntersect = (entries) => {
|
|
2583
|
+
const entry = entries[0];
|
|
2584
|
+
if (!entry) return;
|
|
2585
|
+
this.el.classList.toggle("collapsed", !entry.isIntersecting);
|
|
2586
|
+
};
|
|
2587
|
+
this._onSearchViewClose = () => {
|
|
2588
|
+
this._suppressSearchOpen = true;
|
|
2589
|
+
};
|
|
2590
|
+
this._onSearchFocus = () => {
|
|
2591
|
+
if (!this._view) return;
|
|
2592
|
+
if (this._suppressSearchOpen) {
|
|
2593
|
+
this._suppressSearchOpen = false;
|
|
2594
|
+
return;
|
|
2305
2595
|
}
|
|
2596
|
+
if (this._view instanceof HTMLDialogElement) {
|
|
2597
|
+
if (!this._view.open) this._view.showModal();
|
|
2598
|
+
return;
|
|
2599
|
+
}
|
|
2600
|
+
this._view.hidden = false;
|
|
2601
|
+
this._input?.setAttribute("aria-expanded", "true");
|
|
2306
2602
|
};
|
|
2307
|
-
|
|
2603
|
+
this.el["Expressive_AppBar"] = this;
|
|
2604
|
+
this.options = { ..._AppBar.defaults, ...options };
|
|
2605
|
+
this._setupCollapse();
|
|
2606
|
+
this._setupSearch();
|
|
2308
2607
|
}
|
|
2309
|
-
static
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2608
|
+
static get defaults() {
|
|
2609
|
+
return _defaults7;
|
|
2610
|
+
}
|
|
2611
|
+
static init(els, options = {}) {
|
|
2612
|
+
return super.init(els, options, _AppBar);
|
|
2613
|
+
}
|
|
2614
|
+
static getInstance(el) {
|
|
2615
|
+
return el["Expressive_AppBar"];
|
|
2616
|
+
}
|
|
2617
|
+
destroy() {
|
|
2618
|
+
this._observer?.disconnect();
|
|
2619
|
+
this._observer = null;
|
|
2620
|
+
this._sentinel?.remove();
|
|
2621
|
+
this._sentinel = null;
|
|
2622
|
+
this._input?.removeEventListener("focus", this._onSearchFocus);
|
|
2623
|
+
this._view?.removeEventListener("close", this._onSearchViewClose);
|
|
2624
|
+
this.el.classList.remove("collapsed");
|
|
2625
|
+
this.el["Expressive_AppBar"] = void 0;
|
|
2626
|
+
}
|
|
2627
|
+
_setupCollapse() {
|
|
2628
|
+
if (!this.el.classList.contains("medium") && !this.el.classList.contains("large")) {
|
|
2629
|
+
return;
|
|
2630
|
+
}
|
|
2631
|
+
if (typeof IntersectionObserver === "undefined") return;
|
|
2632
|
+
this._sentinel = document.createElement("span");
|
|
2633
|
+
this._sentinel.setAttribute("aria-hidden", "true");
|
|
2634
|
+
this._sentinel.style.cssText = "display:block;width:100%;height:1px;margin-top:-1px;pointer-events:none;visibility:hidden";
|
|
2635
|
+
this.el.insertAdjacentElement("beforebegin", this._sentinel);
|
|
2636
|
+
this._observer = new IntersectionObserver(this._onIntersect);
|
|
2637
|
+
this._observer.observe(this._sentinel);
|
|
2638
|
+
}
|
|
2639
|
+
_setupSearch() {
|
|
2640
|
+
this._input = this.el.querySelector('input[type="search"]');
|
|
2641
|
+
if (!this._input) return;
|
|
2642
|
+
const id = this._input.getAttribute("aria-controls");
|
|
2643
|
+
if (id) this._view = document.getElementById(id);
|
|
2644
|
+
if (!this._view) this._view = this.el.querySelector(".search-view");
|
|
2645
|
+
if (!this._view) return;
|
|
2646
|
+
this._input.addEventListener("focus", this._onSearchFocus);
|
|
2647
|
+
if (this._view instanceof HTMLDialogElement) {
|
|
2648
|
+
this._view.addEventListener("close", this._onSearchViewClose);
|
|
2649
|
+
}
|
|
2325
2650
|
}
|
|
2326
2651
|
};
|
|
2327
2652
|
|
|
2328
2653
|
// src/ts/components/buttons.ts
|
|
2329
|
-
var
|
|
2654
|
+
var _defaults8 = {
|
|
2330
2655
|
direction: "top",
|
|
2331
2656
|
hoverEnabled: true,
|
|
2332
2657
|
toolbarEnabled: false
|
|
@@ -2361,13 +2686,13 @@ var FloatingActionButton = class _FloatingActionButton extends Component {
|
|
|
2361
2686
|
this._toggle();
|
|
2362
2687
|
};
|
|
2363
2688
|
this._handleAnchorKeydown = (e) => {
|
|
2364
|
-
if (Utils.keys.ENTER
|
|
2689
|
+
if (e.key === Utils.keys.ENTER || e.key === " ") {
|
|
2365
2690
|
e.preventDefault();
|
|
2366
2691
|
this._toggle();
|
|
2367
2692
|
}
|
|
2368
2693
|
};
|
|
2369
2694
|
this._handleDocumentKeydown = (e) => {
|
|
2370
|
-
if (Utils.keys.ESC
|
|
2695
|
+
if (e.key === Utils.keys.ESC) this.close();
|
|
2371
2696
|
};
|
|
2372
2697
|
this._handleDocumentClick = (e) => {
|
|
2373
2698
|
const target = e.target;
|
|
@@ -2387,22 +2712,19 @@ var FloatingActionButton = class _FloatingActionButton extends Component {
|
|
|
2387
2712
|
};
|
|
2388
2713
|
this.isOpen = false;
|
|
2389
2714
|
this._anchor = this.el.querySelector(":scope > a, :scope > button");
|
|
2390
|
-
this._menu = this.el.querySelector("ul, menu");
|
|
2391
2715
|
this.el.classList.add(`direction-${this.options.direction}`);
|
|
2392
2716
|
if (clickToToggle) this.el.classList.add("click-to-toggle");
|
|
2393
2717
|
if (toolbar) this.el.classList.add("toolbar");
|
|
2394
2718
|
if (this._anchor) {
|
|
2395
|
-
this._anchor.setAttribute("aria-haspopup", "menu");
|
|
2396
2719
|
this._anchor.setAttribute("aria-expanded", "false");
|
|
2397
2720
|
if (this._anchor instanceof HTMLAnchorElement && !this._anchor.hasAttribute("href") && this._anchor.tabIndex < 0) {
|
|
2398
2721
|
this._anchor.tabIndex = 0;
|
|
2399
2722
|
}
|
|
2400
2723
|
}
|
|
2401
|
-
if (this._menu) this._menu.setAttribute("role", "menu");
|
|
2402
2724
|
this._setupEventHandlers();
|
|
2403
2725
|
}
|
|
2404
2726
|
static get defaults() {
|
|
2405
|
-
return
|
|
2727
|
+
return _defaults8;
|
|
2406
2728
|
}
|
|
2407
2729
|
static init(els, options = {}) {
|
|
2408
2730
|
return super.init(els, options, _FloatingActionButton);
|
|
@@ -2439,17 +2761,240 @@ var FloatingActionButton = class _FloatingActionButton extends Component {
|
|
|
2439
2761
|
}
|
|
2440
2762
|
};
|
|
2441
2763
|
|
|
2764
|
+
// src/ts/components/buttonGroup.ts
|
|
2765
|
+
var _defaults9 = {};
|
|
2766
|
+
var VALID_SELECTION_MODES = /* @__PURE__ */ new Set(["single", "multiple"]);
|
|
2767
|
+
var PRESSED_CLASS = "button-group-pressed";
|
|
2768
|
+
var MAX_ICON_COMPRESSION = 0.15;
|
|
2769
|
+
var ButtonGroup = class _ButtonGroup extends Component {
|
|
2770
|
+
constructor(el, options = {}) {
|
|
2771
|
+
super(el, options, _ButtonGroup);
|
|
2772
|
+
this._pressedStyles = /* @__PURE__ */ new Map();
|
|
2773
|
+
this._releaseStyles = /* @__PURE__ */ new Map();
|
|
2774
|
+
this._releaseTimer = null;
|
|
2775
|
+
this._originalPressed = /* @__PURE__ */ new Map();
|
|
2776
|
+
this._activeItem = null;
|
|
2777
|
+
this._handleClick = (event) => {
|
|
2778
|
+
if (!this._selectionMode) return;
|
|
2779
|
+
const item = this._itemFromEvent(event);
|
|
2780
|
+
if (!(item instanceof HTMLButtonElement) || this._isDisabled(item)) return;
|
|
2781
|
+
this._rememberPressed(item);
|
|
2782
|
+
const willSelect = item.getAttribute("aria-pressed") !== "true";
|
|
2783
|
+
const selectedCount = this._toggleItems.filter(
|
|
2784
|
+
(button) => button.getAttribute("aria-pressed") === "true"
|
|
2785
|
+
).length;
|
|
2786
|
+
if (!willSelect && this.el.hasAttribute("data-selection-required") && selectedCount === 1) {
|
|
2787
|
+
return;
|
|
2788
|
+
}
|
|
2789
|
+
if (this._selectionMode === "single" && willSelect) {
|
|
2790
|
+
this._toggleItems.forEach((button) => {
|
|
2791
|
+
this._rememberPressed(button);
|
|
2792
|
+
button.setAttribute("aria-pressed", "false");
|
|
2793
|
+
});
|
|
2794
|
+
}
|
|
2795
|
+
item.setAttribute("aria-pressed", willSelect ? "true" : "false");
|
|
2796
|
+
};
|
|
2797
|
+
this._handlePointerDown = (event) => {
|
|
2798
|
+
if (event.button !== 0) return;
|
|
2799
|
+
const item = this._itemFromEvent(event);
|
|
2800
|
+
if (item && !this._isDisabled(item)) this._startPress(item);
|
|
2801
|
+
};
|
|
2802
|
+
this._handleKeyDown = (event) => {
|
|
2803
|
+
if (event.repeat || event.key !== " " && event.key !== "Enter") return;
|
|
2804
|
+
const item = this._itemFromEvent(event);
|
|
2805
|
+
if (item && !this._isDisabled(item)) this._startPress(item);
|
|
2806
|
+
};
|
|
2807
|
+
this._handleKeyUp = (event) => {
|
|
2808
|
+
if (event.key === " " || event.key === "Enter") this._resetPress();
|
|
2809
|
+
};
|
|
2810
|
+
this._handleFocusOut = (event) => {
|
|
2811
|
+
if (event.target === this._activeItem) this._resetPress();
|
|
2812
|
+
};
|
|
2813
|
+
this._resetPress = () => {
|
|
2814
|
+
this._activeItem?.classList.remove(PRESSED_CLASS);
|
|
2815
|
+
this._activeItem = null;
|
|
2816
|
+
if (!this._pressedStyles.size) return;
|
|
2817
|
+
this._finishRelease();
|
|
2818
|
+
this._releaseStyles = new Map(this._pressedStyles);
|
|
2819
|
+
for (const [item, style] of this._releaseStyles) {
|
|
2820
|
+
item.style.width = `${style.baseWidth}px`;
|
|
2821
|
+
}
|
|
2822
|
+
this._pressedStyles.clear();
|
|
2823
|
+
this._releaseTimer = window.setTimeout(this._finishRelease, 200);
|
|
2824
|
+
};
|
|
2825
|
+
this._finishRelease = () => {
|
|
2826
|
+
if (this._releaseTimer !== null) window.clearTimeout(this._releaseTimer);
|
|
2827
|
+
this._releaseTimer = null;
|
|
2828
|
+
for (const [item, style] of this._releaseStyles) item.style.width = style.width;
|
|
2829
|
+
this._releaseStyles.clear();
|
|
2830
|
+
};
|
|
2831
|
+
this.el["Expressive_ButtonGroup"] = this;
|
|
2832
|
+
this.options = { ..._ButtonGroup.defaults, ...options };
|
|
2833
|
+
if (this._selectionMode) {
|
|
2834
|
+
this._normalizeSelection();
|
|
2835
|
+
this.el.addEventListener("click", this._handleClick, true);
|
|
2836
|
+
}
|
|
2837
|
+
this.el.addEventListener("pointerdown", this._handlePointerDown);
|
|
2838
|
+
this.el.addEventListener("keydown", this._handleKeyDown);
|
|
2839
|
+
this.el.addEventListener("focusout", this._handleFocusOut);
|
|
2840
|
+
document.addEventListener("pointerup", this._resetPress);
|
|
2841
|
+
document.addEventListener("pointercancel", this._resetPress);
|
|
2842
|
+
document.addEventListener("keyup", this._handleKeyUp);
|
|
2843
|
+
window.addEventListener("blur", this._resetPress);
|
|
2844
|
+
}
|
|
2845
|
+
static get defaults() {
|
|
2846
|
+
return _defaults9;
|
|
2847
|
+
}
|
|
2848
|
+
static init(els, options = {}) {
|
|
2849
|
+
return super.init(els, options, _ButtonGroup);
|
|
2850
|
+
}
|
|
2851
|
+
static getInstance(el) {
|
|
2852
|
+
return el["Expressive_ButtonGroup"];
|
|
2853
|
+
}
|
|
2854
|
+
destroy() {
|
|
2855
|
+
this._resetPress();
|
|
2856
|
+
this._finishRelease();
|
|
2857
|
+
this.el.removeEventListener("click", this._handleClick, true);
|
|
2858
|
+
this.el.removeEventListener("pointerdown", this._handlePointerDown);
|
|
2859
|
+
this.el.removeEventListener("keydown", this._handleKeyDown);
|
|
2860
|
+
this.el.removeEventListener("focusout", this._handleFocusOut);
|
|
2861
|
+
document.removeEventListener("pointerup", this._resetPress);
|
|
2862
|
+
document.removeEventListener("pointercancel", this._resetPress);
|
|
2863
|
+
document.removeEventListener("keyup", this._handleKeyUp);
|
|
2864
|
+
window.removeEventListener("blur", this._resetPress);
|
|
2865
|
+
for (const [item, value] of this._originalPressed) {
|
|
2866
|
+
if (value === null) item.removeAttribute("aria-pressed");
|
|
2867
|
+
else item.setAttribute("aria-pressed", value);
|
|
2868
|
+
}
|
|
2869
|
+
this._originalPressed.clear();
|
|
2870
|
+
this.el["Expressive_ButtonGroup"] = void 0;
|
|
2871
|
+
}
|
|
2872
|
+
get _selectionMode() {
|
|
2873
|
+
const mode = this.el.dataset.selection;
|
|
2874
|
+
return VALID_SELECTION_MODES.has(mode) ? mode : null;
|
|
2875
|
+
}
|
|
2876
|
+
get _items() {
|
|
2877
|
+
return Array.from(this.el.children).filter(
|
|
2878
|
+
(child) => child instanceof HTMLButtonElement || child instanceof HTMLAnchorElement && child.classList.contains("button")
|
|
2879
|
+
);
|
|
2880
|
+
}
|
|
2881
|
+
get _toggleItems() {
|
|
2882
|
+
return this._items.filter(
|
|
2883
|
+
(item) => item instanceof HTMLButtonElement
|
|
2884
|
+
);
|
|
2885
|
+
}
|
|
2886
|
+
_normalizeSelection() {
|
|
2887
|
+
const items = this._toggleItems;
|
|
2888
|
+
items.forEach((item) => {
|
|
2889
|
+
this._rememberPressed(item);
|
|
2890
|
+
if (!["true", "false"].includes(item.getAttribute("aria-pressed") || "")) {
|
|
2891
|
+
item.setAttribute("aria-pressed", "false");
|
|
2892
|
+
}
|
|
2893
|
+
});
|
|
2894
|
+
if (this._selectionMode === "single") {
|
|
2895
|
+
const selected = items.filter((item) => item.getAttribute("aria-pressed") === "true");
|
|
2896
|
+
selected.slice(1).forEach((item) => item.setAttribute("aria-pressed", "false"));
|
|
2897
|
+
}
|
|
2898
|
+
if (this.el.hasAttribute("data-selection-required") && !items.some((item) => item.getAttribute("aria-pressed") === "true")) {
|
|
2899
|
+
items.find((item) => !this._isDisabled(item))?.setAttribute("aria-pressed", "true");
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
_itemFromEvent(event) {
|
|
2903
|
+
if (!(event.target instanceof Element)) return null;
|
|
2904
|
+
const item = event.target.closest("button, a.button");
|
|
2905
|
+
return item instanceof HTMLElement && item.parentElement === this.el ? item : null;
|
|
2906
|
+
}
|
|
2907
|
+
_isDisabled(item) {
|
|
2908
|
+
return item instanceof HTMLButtonElement && item.disabled || item.getAttribute("aria-disabled") === "true" || item.classList.contains("disabled");
|
|
2909
|
+
}
|
|
2910
|
+
_rememberPressed(item) {
|
|
2911
|
+
if (!this._originalPressed.has(item)) {
|
|
2912
|
+
this._originalPressed.set(item, item.getAttribute("aria-pressed"));
|
|
2913
|
+
}
|
|
2914
|
+
}
|
|
2915
|
+
_startPress(item) {
|
|
2916
|
+
if (this._activeItem) return;
|
|
2917
|
+
this._finishRelease();
|
|
2918
|
+
const items = this._items;
|
|
2919
|
+
const activeIndex = items.indexOf(item);
|
|
2920
|
+
if (activeIndex < 0) return;
|
|
2921
|
+
this._activeItem = item;
|
|
2922
|
+
item.classList.add(PRESSED_CLASS);
|
|
2923
|
+
if (this.el.classList.contains("connected") || items.length < 2) return;
|
|
2924
|
+
const rects = items.map((candidate) => candidate.getBoundingClientRect());
|
|
2925
|
+
const activeWidth = rects[activeIndex].width;
|
|
2926
|
+
if (activeWidth <= 0) return;
|
|
2927
|
+
const parsedMultiplier = Number.parseFloat(
|
|
2928
|
+
getComputedStyle(this.el).getPropertyValue(
|
|
2929
|
+
"--md-comp-button-group-pressed-item-width-multiplier"
|
|
2930
|
+
)
|
|
2931
|
+
);
|
|
2932
|
+
const multiplier = Number.isFinite(parsedMultiplier) ? parsedMultiplier : 0.15;
|
|
2933
|
+
const desiredGrowth = activeWidth * multiplier;
|
|
2934
|
+
const neighborIndexes = [activeIndex - 1, activeIndex + 1].filter(
|
|
2935
|
+
(index) => index >= 0 && index < items.length
|
|
2936
|
+
);
|
|
2937
|
+
const compression = /* @__PURE__ */ new Map();
|
|
2938
|
+
if (neighborIndexes.length === 1) {
|
|
2939
|
+
const index = neighborIndexes[0];
|
|
2940
|
+
compression.set(
|
|
2941
|
+
index,
|
|
2942
|
+
Math.min(desiredGrowth, this._compressionCapacity(items[index], rects[index]))
|
|
2943
|
+
);
|
|
2944
|
+
} else {
|
|
2945
|
+
const half = desiredGrowth / 2;
|
|
2946
|
+
for (const index of neighborIndexes) {
|
|
2947
|
+
compression.set(
|
|
2948
|
+
index,
|
|
2949
|
+
Math.min(half, this._compressionCapacity(items[index], rects[index]))
|
|
2950
|
+
);
|
|
2951
|
+
}
|
|
2952
|
+
let remaining = desiredGrowth - [...compression.values()].reduce((sum, value) => sum + value, 0);
|
|
2953
|
+
for (const index of neighborIndexes) {
|
|
2954
|
+
if (remaining <= 0) break;
|
|
2955
|
+
const capacity = this._compressionCapacity(items[index], rects[index]) - compression.get(index);
|
|
2956
|
+
const extra = Math.min(remaining, capacity);
|
|
2957
|
+
compression.set(index, compression.get(index) + extra);
|
|
2958
|
+
remaining -= extra;
|
|
2959
|
+
}
|
|
2960
|
+
}
|
|
2961
|
+
const actualGrowth = [...compression.values()].reduce((sum, value) => sum + value, 0);
|
|
2962
|
+
if (actualGrowth <= 0) return;
|
|
2963
|
+
items.forEach((candidate, index) => {
|
|
2964
|
+
this._pressedStyles.set(candidate, {
|
|
2965
|
+
width: candidate.style.width,
|
|
2966
|
+
baseWidth: rects[index].width
|
|
2967
|
+
});
|
|
2968
|
+
candidate.style.width = `${rects[index].width}px`;
|
|
2969
|
+
});
|
|
2970
|
+
void this.el.offsetWidth;
|
|
2971
|
+
items.forEach((candidate, index) => {
|
|
2972
|
+
const adjustment = index === activeIndex ? actualGrowth : -(compression.get(index) || 0);
|
|
2973
|
+
candidate.style.width = `${rects[index].width + adjustment}px`;
|
|
2974
|
+
});
|
|
2975
|
+
}
|
|
2976
|
+
_compressionCapacity(item, rect) {
|
|
2977
|
+
const minimumWidth = item.classList.contains("icon-button") ? rect.width * (1 - MAX_ICON_COMPRESSION) : rect.height;
|
|
2978
|
+
return Math.max(0, rect.width - minimumWidth);
|
|
2979
|
+
}
|
|
2980
|
+
};
|
|
2981
|
+
|
|
2442
2982
|
// src/ts/components/carousel.ts
|
|
2443
|
-
var
|
|
2983
|
+
var _defaults10 = {
|
|
2444
2984
|
duration: 200,
|
|
2445
|
-
dist: -100,
|
|
2446
|
-
shift: 0,
|
|
2447
|
-
padding: 0,
|
|
2448
|
-
numVisible: 5,
|
|
2449
2985
|
fullWidth: false,
|
|
2450
2986
|
indicators: false,
|
|
2451
2987
|
noWrap: false,
|
|
2452
|
-
|
|
2988
|
+
interval: 0,
|
|
2989
|
+
height: null,
|
|
2990
|
+
onCycleTo: null,
|
|
2991
|
+
i18n: {
|
|
2992
|
+
carousel: "Carousel",
|
|
2993
|
+
item: "Item",
|
|
2994
|
+
of: "of",
|
|
2995
|
+
indicators: "Slides",
|
|
2996
|
+
slide: "Slide"
|
|
2997
|
+
}
|
|
2453
2998
|
};
|
|
2454
2999
|
var _Carousel = class _Carousel extends Component {
|
|
2455
3000
|
constructor(el, options) {
|
|
@@ -2460,101 +3005,112 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2460
3005
|
this._ignoreScroll = false;
|
|
2461
3006
|
this._trackRaf = null;
|
|
2462
3007
|
this._started = false;
|
|
3008
|
+
this._vertical = false;
|
|
3009
|
+
this._resizeObserver = null;
|
|
3010
|
+
this._usesWindowResize = false;
|
|
3011
|
+
this._dragPointerId = null;
|
|
3012
|
+
this._dragStartX = 0;
|
|
3013
|
+
this._dragStartY = 0;
|
|
3014
|
+
this._dragStartScroll = 0;
|
|
3015
|
+
this._suppressClick = false;
|
|
3016
|
+
this._suppressClickTimeout = null;
|
|
3017
|
+
this._generatedContainerRole = false;
|
|
3018
|
+
this._generatedContainerLabel = false;
|
|
3019
|
+
this._generatedContainerDescription = false;
|
|
3020
|
+
this._generatedWideLayout = false;
|
|
3021
|
+
this._generatedFixedHeight = false;
|
|
3022
|
+
this._authoredInlineHeight = null;
|
|
3023
|
+
this._autoAdvanceTimer = null;
|
|
3024
|
+
this._autoAdvances = false;
|
|
3025
|
+
this._autoPaused = false;
|
|
3026
|
+
this._hovered = false;
|
|
3027
|
+
this._focused = false;
|
|
3028
|
+
this._generatedItemTabIndexes = /* @__PURE__ */ new Set();
|
|
3029
|
+
this._generatedItemLabels = /* @__PURE__ */ new Set();
|
|
3030
|
+
this._generatedItemDescriptions = /* @__PURE__ */ new Set();
|
|
3031
|
+
this._generatedItemSizes = /* @__PURE__ */ new Set();
|
|
3032
|
+
this._authoredItemSizes = /* @__PURE__ */ new Set();
|
|
3033
|
+
this._itemA11yOriginal = /* @__PURE__ */ new Map();
|
|
2463
3034
|
this._handleThrottledResize = Utils.throttle(() => this._handleResize(), 200);
|
|
2464
|
-
this.
|
|
2465
|
-
if (e.
|
|
2466
|
-
if (e.
|
|
2467
|
-
|
|
3035
|
+
this._handleAutoAdvanceState = (e) => {
|
|
3036
|
+
if (e.type === "mouseenter") this._hovered = true;
|
|
3037
|
+
else if (e.type === "mouseleave") this._hovered = false;
|
|
3038
|
+
else if (e.type === "focusin") this._focused = true;
|
|
3039
|
+
else if (e.type === "focusout") this._focused = false;
|
|
3040
|
+
this._syncAutoAdvance();
|
|
3041
|
+
};
|
|
3042
|
+
this._tick = () => {
|
|
3043
|
+
this._autoAdvanceTimer = null;
|
|
3044
|
+
this._advance();
|
|
3045
|
+
this._syncAutoAdvance();
|
|
3046
|
+
};
|
|
3047
|
+
this._advance = () => {
|
|
3048
|
+
const next = this.center + 1;
|
|
3049
|
+
if (next < this.count) {
|
|
3050
|
+
this.set(next);
|
|
3051
|
+
return;
|
|
3052
|
+
}
|
|
3053
|
+
if (this.options.noWrap) {
|
|
3054
|
+
this._autoAdvances = false;
|
|
3055
|
+
this._syncAutoAdvance();
|
|
3056
|
+
return;
|
|
2468
3057
|
}
|
|
3058
|
+
this.set(0);
|
|
3059
|
+
};
|
|
3060
|
+
this._handleTrackPointerDown = (e) => {
|
|
3061
|
+
if (e.pointerType !== "mouse" || e.button !== 0) return;
|
|
2469
3062
|
this.pressed = true;
|
|
2470
3063
|
this.dragged = false;
|
|
2471
|
-
this.
|
|
2472
|
-
this.
|
|
2473
|
-
this.
|
|
2474
|
-
this.
|
|
2475
|
-
this.
|
|
2476
|
-
this.timestamp = Date.now();
|
|
3064
|
+
this._suppressClick = false;
|
|
3065
|
+
this._dragPointerId = e.pointerId;
|
|
3066
|
+
this._dragStartX = e.clientX;
|
|
3067
|
+
this._dragStartY = e.clientY;
|
|
3068
|
+
this._dragStartScroll = this._vertical ? this._scroller.scrollTop : this._scroller.scrollLeft;
|
|
2477
3069
|
try {
|
|
2478
|
-
this.
|
|
3070
|
+
this._scroller.setPointerCapture(e.pointerId);
|
|
2479
3071
|
} catch {
|
|
2480
3072
|
}
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
this.
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
const deltaY = Math.abs(this.referenceY - e.clientY);
|
|
2493
|
-
if (deltaY < 30 && !this.verticalDragged) {
|
|
2494
|
-
if (delta > 2 || delta < -2) {
|
|
2495
|
-
this.dragged = true;
|
|
2496
|
-
this.reference = e.clientX;
|
|
2497
|
-
this._scroll(this.offset + delta);
|
|
2498
|
-
}
|
|
2499
|
-
} else if (this.dragged) {
|
|
2500
|
-
e.preventDefault();
|
|
2501
|
-
} else {
|
|
2502
|
-
this.verticalDragged = true;
|
|
3073
|
+
};
|
|
3074
|
+
this._handleTrackPointerMove = (e) => {
|
|
3075
|
+
if (!this.pressed || e.pointerId !== this._dragPointerId) return;
|
|
3076
|
+
const deltaX = e.clientX - this._dragStartX;
|
|
3077
|
+
const deltaY = e.clientY - this._dragStartY;
|
|
3078
|
+
const primaryDelta = this._vertical ? deltaY : deltaX;
|
|
3079
|
+
const crossDelta = this._vertical ? deltaX : deltaY;
|
|
3080
|
+
if (!this.dragged) {
|
|
3081
|
+
if (Math.abs(primaryDelta) < 6 || Math.abs(primaryDelta) <= Math.abs(crossDelta)) return;
|
|
3082
|
+
this.dragged = true;
|
|
3083
|
+
this.el.classList.add("dragging");
|
|
2503
3084
|
}
|
|
2504
|
-
if (this.
|
|
3085
|
+
if (this._vertical) this._scroller.scrollTop = this._dragStartScroll - deltaY;
|
|
3086
|
+
else this._scroller.scrollLeft = this._dragStartScroll - deltaX;
|
|
3087
|
+
e.preventDefault();
|
|
2505
3088
|
};
|
|
2506
|
-
this.
|
|
2507
|
-
if (!this.pressed) return;
|
|
3089
|
+
this._handleTrackPointerUp = (e) => {
|
|
3090
|
+
if (!this.pressed || e.pointerId !== this._dragPointerId) return;
|
|
2508
3091
|
this.pressed = false;
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
this._trackRaf = null;
|
|
2512
|
-
}
|
|
3092
|
+
this._dragPointerId = null;
|
|
3093
|
+
this.el.classList.remove("dragging");
|
|
2513
3094
|
try {
|
|
2514
|
-
this.
|
|
3095
|
+
this._scroller.releasePointerCapture(e.pointerId);
|
|
2515
3096
|
} catch {
|
|
2516
3097
|
}
|
|
2517
|
-
this.
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
this.amplitude = this.target - this.offset;
|
|
2531
|
-
this.timestamp = Date.now();
|
|
2532
|
-
requestAnimationFrame(this._autoScroll);
|
|
2533
|
-
if (this.dragged) e.preventDefault();
|
|
3098
|
+
if (!this.dragged) return;
|
|
3099
|
+
this._suppressClick = true;
|
|
3100
|
+
window.clearTimeout(this._suppressClickTimeout);
|
|
3101
|
+
this._suppressClickTimeout = setTimeout(() => {
|
|
3102
|
+
this._suppressClick = false;
|
|
3103
|
+
}, 0);
|
|
3104
|
+
this._syncActive(this._nearestIndex(), true);
|
|
3105
|
+
};
|
|
3106
|
+
this._handleTrackClick = (e) => {
|
|
3107
|
+
if (!this._suppressClick) return;
|
|
3108
|
+
this._suppressClick = false;
|
|
3109
|
+
e.preventDefault();
|
|
3110
|
+
e.stopImmediatePropagation();
|
|
2534
3111
|
};
|
|
2535
|
-
this.
|
|
2536
|
-
if (
|
|
2537
|
-
e.preventDefault();
|
|
2538
|
-
e.stopPropagation();
|
|
2539
|
-
return;
|
|
2540
|
-
}
|
|
2541
|
-
const clickedElem = e.target.closest(".carousel-item");
|
|
2542
|
-
if (!clickedElem || !this.el.contains(clickedElem)) return;
|
|
2543
|
-
const clickedIndex = this.images.indexOf(clickedElem);
|
|
2544
|
-
const diff = this._wrap(this.center) - clickedIndex;
|
|
2545
|
-
if (diff !== 0) {
|
|
2546
|
-
e.preventDefault();
|
|
2547
|
-
e.stopPropagation();
|
|
2548
|
-
}
|
|
2549
|
-
if (clickedIndex < 0) {
|
|
2550
|
-
if (e.clientX - e.target.getBoundingClientRect().left > this.el.clientWidth / 2) {
|
|
2551
|
-
this.next();
|
|
2552
|
-
} else {
|
|
2553
|
-
this.prev();
|
|
2554
|
-
}
|
|
2555
|
-
} else {
|
|
2556
|
-
this._cycleTo(clickedIndex);
|
|
2557
|
-
}
|
|
3112
|
+
this._handleTrackDragStart = (e) => {
|
|
3113
|
+
if (e.target.closest("img, picture, video")) e.preventDefault();
|
|
2558
3114
|
};
|
|
2559
3115
|
this._handleIndicatorClick = (e) => {
|
|
2560
3116
|
e.stopPropagation();
|
|
@@ -2567,112 +3123,107 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2567
3123
|
this._handleKeydown = (e) => {
|
|
2568
3124
|
const target = e.target;
|
|
2569
3125
|
if (target.closest('input, textarea, select, [contenteditable="true"]')) return;
|
|
2570
|
-
|
|
3126
|
+
const forward = this._vertical ? e.key === "ArrowDown" : e.key === Utils.keys.ARROW_RIGHT;
|
|
3127
|
+
const backward = this._vertical ? e.key === "ArrowUp" : e.key === Utils.keys.ARROW_LEFT;
|
|
3128
|
+
if (e.key === "Home") {
|
|
3129
|
+
e.preventDefault();
|
|
3130
|
+
this.set(0);
|
|
3131
|
+
this._focusItem(0);
|
|
3132
|
+
} else if (e.key === "End") {
|
|
3133
|
+
e.preventDefault();
|
|
3134
|
+
this.set(this.count - 1);
|
|
3135
|
+
this._focusItem(this.count - 1);
|
|
3136
|
+
} else if (forward) {
|
|
2571
3137
|
e.preventDefault();
|
|
2572
3138
|
this.next();
|
|
2573
|
-
|
|
3139
|
+
this._focusItem(this.center);
|
|
3140
|
+
} else if (backward) {
|
|
2574
3141
|
e.preventDefault();
|
|
2575
3142
|
this.prev();
|
|
3143
|
+
this._focusItem(this.center);
|
|
2576
3144
|
}
|
|
2577
3145
|
};
|
|
2578
|
-
this.
|
|
2579
|
-
if (this.
|
|
2580
|
-
|
|
2581
|
-
|
|
3146
|
+
this._handleTrackScroll = () => {
|
|
3147
|
+
if (!this.el.classList.contains("scrolling")) this.el.classList.add("scrolling");
|
|
3148
|
+
window.clearTimeout(this.scrollingTimeout);
|
|
3149
|
+
this.scrollingTimeout = setTimeout(() => this.el.classList.remove("scrolling"), 120);
|
|
3150
|
+
if (this._trackRaf !== null) return;
|
|
3151
|
+
this._trackRaf = requestAnimationFrame(() => {
|
|
3152
|
+
this._trackRaf = null;
|
|
3153
|
+
this._updateParallax();
|
|
3154
|
+
if (this._ignoreScroll) return;
|
|
3155
|
+
const index = this._nearestIndex();
|
|
3156
|
+
if (index !== this.center) this._syncActive(index, this.dragged);
|
|
3157
|
+
});
|
|
2582
3158
|
};
|
|
2583
3159
|
this._handleResize = () => {
|
|
2584
3160
|
if (!this.images.length) return;
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
if (this.options.fullWidth) {
|
|
2590
|
-
const firstItem = this.images[0];
|
|
2591
|
-
if (!firstItem) return;
|
|
2592
|
-
this.itemWidth = firstItem.clientWidth;
|
|
2593
|
-
this.dim = this.itemWidth * 2 + this.options.padding;
|
|
2594
|
-
this.offset = this.center * 2 * this.itemWidth;
|
|
2595
|
-
this.target = this.offset;
|
|
2596
|
-
} else {
|
|
2597
|
-
this._scroll();
|
|
2598
|
-
}
|
|
2599
|
-
};
|
|
2600
|
-
this._track = () => {
|
|
2601
|
-
const now = Date.now();
|
|
2602
|
-
const elapsed = now - this.timestamp;
|
|
2603
|
-
const delta = this.offset - this.frame;
|
|
2604
|
-
const v = 1e3 * delta / (1 + elapsed);
|
|
2605
|
-
this.timestamp = now;
|
|
2606
|
-
this.frame = this.offset;
|
|
2607
|
-
this.velocity = 0.8 * v + 0.2 * this.velocity;
|
|
2608
|
-
};
|
|
2609
|
-
this._autoScroll = () => {
|
|
2610
|
-
if (!this.amplitude) return;
|
|
2611
|
-
const elapsed = Date.now() - this.timestamp;
|
|
2612
|
-
const delta = this.amplitude * Math.exp(-elapsed / this.options.duration);
|
|
2613
|
-
if (delta > 2 || delta < -2) {
|
|
2614
|
-
this._scroll(this.target - delta);
|
|
2615
|
-
requestAnimationFrame(this._autoScroll);
|
|
2616
|
-
} else {
|
|
2617
|
-
this._scroll(this.target);
|
|
2618
|
-
}
|
|
3161
|
+
this._syncAdaptiveMode();
|
|
3162
|
+
this._syncLayoutRoles(this.center);
|
|
3163
|
+
this._scrollToIndex(this.center, false);
|
|
3164
|
+
this._updateParallax();
|
|
2619
3165
|
};
|
|
2620
3166
|
this.el["Expressive_Carousel"] = this;
|
|
2621
3167
|
this.options = {
|
|
2622
3168
|
..._Carousel.defaults,
|
|
2623
3169
|
...options
|
|
2624
3170
|
};
|
|
2625
|
-
|
|
2626
|
-
|
|
3171
|
+
if (options?.i18n) {
|
|
3172
|
+
this.options.i18n = { ..._Carousel.defaults.i18n, ...options.i18n };
|
|
3173
|
+
}
|
|
3174
|
+
if (this.options.fullWidth || this.el.classList.contains("flat")) {
|
|
2627
3175
|
this.el.classList.add("flat");
|
|
2628
3176
|
this.options.fullWidth = true;
|
|
2629
|
-
this.options.dist = 0;
|
|
2630
|
-
}
|
|
2631
|
-
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
2632
|
-
this.options.duration = 1;
|
|
2633
|
-
if (!this._flat) this.options.dist = 0;
|
|
2634
3177
|
}
|
|
3178
|
+
this._vertical = this.el.classList.contains("full-screen");
|
|
3179
|
+
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
3180
|
+
if (reducedMotion) this.options.duration = 1;
|
|
2635
3181
|
this.pressed = false;
|
|
2636
3182
|
this.dragged = false;
|
|
2637
|
-
this.offset = this.target = 0;
|
|
2638
3183
|
this.images = this._collectItems();
|
|
2639
3184
|
if (!this.images.length) {
|
|
2640
3185
|
console.error("Carousel: no .carousel-item elements to show");
|
|
2641
3186
|
return;
|
|
2642
3187
|
}
|
|
3188
|
+
this.images.forEach((item) => {
|
|
3189
|
+
this._itemA11yOriginal.set(item, {
|
|
3190
|
+
ariaHidden: item.getAttribute("aria-hidden"),
|
|
3191
|
+
tabIndex: item.getAttribute("tabindex")
|
|
3192
|
+
});
|
|
3193
|
+
if (item.hasAttribute("data-carousel-size")) this._authoredItemSizes.add(item);
|
|
3194
|
+
});
|
|
2643
3195
|
this.hasMultipleSlides = this.images.length > 1;
|
|
2644
3196
|
this.showIndicators = this.options.indicators && this.hasMultipleSlides;
|
|
2645
|
-
this.noWrap = this.options.noWrap || !this.hasMultipleSlides || this._flat;
|
|
2646
3197
|
this.count = this.images.length;
|
|
2647
|
-
this.
|
|
3198
|
+
this._autoAdvances = this.options.interval > 0 && this.hasMultipleSlides && !reducedMotion;
|
|
2648
3199
|
this.images.forEach((item) => item.classList.add("carousel-item"));
|
|
2649
|
-
if (this.
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
3200
|
+
if (this.options.height !== null) {
|
|
3201
|
+
this._generatedFixedHeight = !this.el.classList.contains("fixed-height");
|
|
3202
|
+
this._authoredInlineHeight = this.el.style.getPropertyValue("--carousel-height") || null;
|
|
3203
|
+
this.el.classList.add("fixed-height");
|
|
3204
|
+
this.el.style.setProperty("--carousel-height", `${this.options.height}px`);
|
|
3205
|
+
}
|
|
3206
|
+
this._wrapTrack();
|
|
3207
|
+
this._syncAdaptiveMode();
|
|
2654
3208
|
if (this.showIndicators) this._setupIndicators();
|
|
2655
|
-
this.
|
|
2656
|
-
this.el.setAttribute("aria-roledescription", "carousel");
|
|
3209
|
+
this._setupAccessibility();
|
|
2657
3210
|
this._setupEventHandlers();
|
|
2658
3211
|
this._started = true;
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
this._scroll(this.offset);
|
|
2669
|
-
}
|
|
3212
|
+
const start = Math.max(
|
|
3213
|
+
0,
|
|
3214
|
+
this.images.findIndex((el2) => el2.classList.contains("active"))
|
|
3215
|
+
);
|
|
3216
|
+
this.center = start;
|
|
3217
|
+
this._syncActive(start, false);
|
|
3218
|
+
this._updateParallax();
|
|
3219
|
+
this._scrollToIndex(start, false);
|
|
3220
|
+
this._syncAutoAdvance();
|
|
2670
3221
|
}
|
|
2671
3222
|
get _scroller() {
|
|
2672
3223
|
return this._trackEl ?? this.el;
|
|
2673
3224
|
}
|
|
2674
3225
|
static get defaults() {
|
|
2675
|
-
return
|
|
3226
|
+
return _defaults10;
|
|
2676
3227
|
}
|
|
2677
3228
|
static init(els, options = {}) {
|
|
2678
3229
|
return super.init(els, options, _Carousel);
|
|
@@ -2697,6 +3248,39 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2697
3248
|
return el.tagName !== "NAV";
|
|
2698
3249
|
});
|
|
2699
3250
|
}
|
|
3251
|
+
_setupAccessibility() {
|
|
3252
|
+
if (!this.el.hasAttribute("role")) {
|
|
3253
|
+
this.el.setAttribute("role", "region");
|
|
3254
|
+
this._generatedContainerRole = true;
|
|
3255
|
+
}
|
|
3256
|
+
if (!this.el.hasAttribute("aria-label") && !this.el.hasAttribute("aria-labelledby")) {
|
|
3257
|
+
this.el.setAttribute("aria-label", this.options.i18n.carousel);
|
|
3258
|
+
this._generatedContainerLabel = true;
|
|
3259
|
+
}
|
|
3260
|
+
if (!this.el.hasAttribute("aria-roledescription")) {
|
|
3261
|
+
this.el.setAttribute("aria-roledescription", "carousel");
|
|
3262
|
+
this._generatedContainerDescription = true;
|
|
3263
|
+
}
|
|
3264
|
+
const naturallyFocusable = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
3265
|
+
this.images.forEach((item, index) => {
|
|
3266
|
+
if (!item.hasAttribute("aria-roledescription")) {
|
|
3267
|
+
item.setAttribute("aria-roledescription", "slide");
|
|
3268
|
+
this._generatedItemDescriptions.add(item);
|
|
3269
|
+
}
|
|
3270
|
+
if (!item.hasAttribute("aria-label") && !item.hasAttribute("aria-labelledby")) {
|
|
3271
|
+
const mediaName = item.querySelector("img[alt]")?.getAttribute("alt")?.trim();
|
|
3272
|
+
const textName = item.textContent?.replace(/\s+/g, " ").trim();
|
|
3273
|
+
const name = mediaName || textName;
|
|
3274
|
+
const position = `${this.options.i18n.item} ${index + 1} ${this.options.i18n.of} ${this.count}`;
|
|
3275
|
+
item.setAttribute("aria-label", name ? `${name}, ${position}` : position);
|
|
3276
|
+
this._generatedItemLabels.add(item);
|
|
3277
|
+
}
|
|
3278
|
+
if (!item.matches(naturallyFocusable) && !item.querySelector(naturallyFocusable)) {
|
|
3279
|
+
item.tabIndex = 0;
|
|
3280
|
+
this._generatedItemTabIndexes.add(item);
|
|
3281
|
+
}
|
|
3282
|
+
});
|
|
3283
|
+
}
|
|
2700
3284
|
_setupIndicators() {
|
|
2701
3285
|
const existing = Array.from(this.el.children).find(
|
|
2702
3286
|
(el) => el instanceof HTMLElement && el.classList.contains("indicators")
|
|
@@ -2704,7 +3288,7 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2704
3288
|
this._indicators = existing ?? document.createElement("nav");
|
|
2705
3289
|
this._ownIndicators = !existing;
|
|
2706
3290
|
this._indicators.classList.add("indicators");
|
|
2707
|
-
this._indicators.setAttribute("aria-label",
|
|
3291
|
+
this._indicators.setAttribute("aria-label", this.options.i18n.indicators);
|
|
2708
3292
|
this._indicators.replaceChildren();
|
|
2709
3293
|
this.images.forEach((_, i) => {
|
|
2710
3294
|
const button = document.createElement("button");
|
|
@@ -2714,158 +3298,124 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2714
3298
|
button.classList.add("active");
|
|
2715
3299
|
button.setAttribute("aria-current", "true");
|
|
2716
3300
|
}
|
|
2717
|
-
button.setAttribute("aria-label",
|
|
3301
|
+
button.setAttribute("aria-label", `${this.options.i18n.slide} ${i + 1}`);
|
|
2718
3302
|
this._indicators.appendChild(button);
|
|
2719
3303
|
});
|
|
2720
3304
|
if (this._ownIndicators) this.el.appendChild(this._indicators);
|
|
2721
|
-
|
|
2722
|
-
this.el.querySelector(".carousel-fixed-item")?.classList.add("with-indicators");
|
|
2723
|
-
}
|
|
3305
|
+
this.el.querySelector(".carousel-fixed-item")?.classList.add("with-indicators");
|
|
2724
3306
|
}
|
|
2725
3307
|
_setupEventHandlers() {
|
|
2726
3308
|
this.el.addEventListener("keydown", this._handleKeydown);
|
|
3309
|
+
if (this._autoAdvances) {
|
|
3310
|
+
this.el.addEventListener("mouseenter", this._handleAutoAdvanceState);
|
|
3311
|
+
this.el.addEventListener("mouseleave", this._handleAutoAdvanceState);
|
|
3312
|
+
this.el.addEventListener("focusin", this._handleAutoAdvanceState);
|
|
3313
|
+
this.el.addEventListener("focusout", this._handleAutoAdvanceState);
|
|
3314
|
+
document.addEventListener("visibilitychange", this._handleAutoAdvanceState);
|
|
3315
|
+
}
|
|
2727
3316
|
if (this.showIndicators && this._indicators) {
|
|
2728
3317
|
this._indicators.addEventListener("click", this._handleIndicatorClick);
|
|
2729
3318
|
}
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
_Carousel._resizeListening = true;
|
|
3319
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
3320
|
+
this._resizeObserver = new ResizeObserver(() => this._handleThrottledResize());
|
|
3321
|
+
this._resizeObserver.observe(this.el);
|
|
2734
3322
|
}
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
3323
|
+
this._usesWindowResize = !this._resizeObserver || this.el.classList.contains("full-screen");
|
|
3324
|
+
if (this._usesWindowResize) {
|
|
3325
|
+
_Carousel._live.add(this);
|
|
3326
|
+
if (!_Carousel._resizeListening) {
|
|
3327
|
+
window.addEventListener("resize", _Carousel._onResize, {
|
|
3328
|
+
passive: true
|
|
3329
|
+
});
|
|
3330
|
+
_Carousel._resizeListening = true;
|
|
3331
|
+
}
|
|
2738
3332
|
}
|
|
2739
|
-
this.
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
this.
|
|
2743
|
-
this.
|
|
3333
|
+
this._scroller.addEventListener("scroll", this._handleTrackScroll, {
|
|
3334
|
+
passive: true
|
|
3335
|
+
});
|
|
3336
|
+
this._scroller.addEventListener("pointerdown", this._handleTrackPointerDown);
|
|
3337
|
+
this._scroller.addEventListener("pointermove", this._handleTrackPointerMove);
|
|
3338
|
+
this._scroller.addEventListener("pointerup", this._handleTrackPointerUp);
|
|
3339
|
+
this._scroller.addEventListener("pointercancel", this._handleTrackPointerUp);
|
|
3340
|
+
this._scroller.addEventListener("click", this._handleTrackClick, true);
|
|
3341
|
+
this._scroller.addEventListener("dragstart", this._handleTrackDragStart);
|
|
2744
3342
|
}
|
|
2745
3343
|
_removeEventHandlers() {
|
|
2746
3344
|
this.el.removeEventListener("keydown", this._handleKeydown);
|
|
3345
|
+
this.el.removeEventListener("mouseenter", this._handleAutoAdvanceState);
|
|
3346
|
+
this.el.removeEventListener("mouseleave", this._handleAutoAdvanceState);
|
|
3347
|
+
this.el.removeEventListener("focusin", this._handleAutoAdvanceState);
|
|
3348
|
+
this.el.removeEventListener("focusout", this._handleAutoAdvanceState);
|
|
3349
|
+
document.removeEventListener("visibilitychange", this._handleAutoAdvanceState);
|
|
2747
3350
|
if (this._indicators) {
|
|
2748
3351
|
this._indicators.removeEventListener("click", this._handleIndicatorClick);
|
|
2749
3352
|
}
|
|
2750
|
-
this._scroller.removeEventListener("scroll", this.
|
|
2751
|
-
this.
|
|
2752
|
-
this.
|
|
2753
|
-
this.
|
|
2754
|
-
this.
|
|
2755
|
-
this.
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
3353
|
+
this._scroller.removeEventListener("scroll", this._handleTrackScroll);
|
|
3354
|
+
this._scroller.removeEventListener("pointerdown", this._handleTrackPointerDown);
|
|
3355
|
+
this._scroller.removeEventListener("pointermove", this._handleTrackPointerMove);
|
|
3356
|
+
this._scroller.removeEventListener("pointerup", this._handleTrackPointerUp);
|
|
3357
|
+
this._scroller.removeEventListener("pointercancel", this._handleTrackPointerUp);
|
|
3358
|
+
this._scroller.removeEventListener("click", this._handleTrackClick, true);
|
|
3359
|
+
this._scroller.removeEventListener("dragstart", this._handleTrackDragStart);
|
|
3360
|
+
this._resizeObserver?.disconnect();
|
|
3361
|
+
this._resizeObserver = null;
|
|
3362
|
+
if (this._usesWindowResize) {
|
|
3363
|
+
_Carousel._live.delete(this);
|
|
3364
|
+
if (_Carousel._live.size === 0 && _Carousel._resizeListening) {
|
|
3365
|
+
window.removeEventListener("resize", _Carousel._onResize);
|
|
3366
|
+
_Carousel._resizeListening = false;
|
|
3367
|
+
}
|
|
2760
3368
|
}
|
|
2761
3369
|
}
|
|
2762
3370
|
_teardown() {
|
|
2763
3371
|
this._removeEventHandlers();
|
|
3372
|
+
this._autoAdvances = false;
|
|
3373
|
+
this._syncAutoAdvance();
|
|
2764
3374
|
if (this._trackRaf !== null) cancelAnimationFrame(this._trackRaf);
|
|
2765
3375
|
window.clearTimeout(this.scrollingTimeout);
|
|
3376
|
+
window.clearTimeout(this._suppressClickTimeout);
|
|
2766
3377
|
if (this._ownIndicators) this._indicators?.remove();
|
|
2767
3378
|
this._unwrapTrack();
|
|
2768
3379
|
this.images.forEach((el) => {
|
|
2769
|
-
el.style.
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
3380
|
+
el.style.removeProperty("--md-comp-carousel-item-parallax");
|
|
3381
|
+
if (this._generatedItemLabels.has(el)) el.removeAttribute("aria-label");
|
|
3382
|
+
if (this._generatedItemDescriptions.has(el)) el.removeAttribute("aria-roledescription");
|
|
3383
|
+
if (this._generatedItemSizes.has(el)) el.removeAttribute("data-carousel-size");
|
|
3384
|
+
const original = this._itemA11yOriginal.get(el);
|
|
3385
|
+
if (original?.ariaHidden === null) el.removeAttribute("aria-hidden");
|
|
3386
|
+
else if (original) el.setAttribute("aria-hidden", original.ariaHidden);
|
|
3387
|
+
if (original?.tabIndex === null) el.removeAttribute("tabindex");
|
|
3388
|
+
else if (original) el.setAttribute("tabindex", original.tabIndex);
|
|
2773
3389
|
});
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
if ("
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
}
|
|
2790
|
-
window.clearTimeout(this.scrollingTimeout);
|
|
2791
|
-
this.scrollingTimeout = setTimeout(() => {
|
|
2792
|
-
this.el.classList.remove("scrolling");
|
|
2793
|
-
}, this.options.duration);
|
|
2794
|
-
this.offset = typeof x === "number" ? x : this.offset;
|
|
2795
|
-
this.center = Math.floor((this.offset + this.dim / 2) / this.dim);
|
|
2796
|
-
const half = this.count >> 1;
|
|
2797
|
-
const delta = this.offset - this.center * this.dim;
|
|
2798
|
-
const dir = delta < 0 ? 1 : -1;
|
|
2799
|
-
const tween = -dir * delta * 2 / this.dim;
|
|
2800
|
-
const lastCenter = this.center;
|
|
2801
|
-
const numVisibleOffset = 1 / this.options.numVisible;
|
|
2802
|
-
let alignment;
|
|
2803
|
-
let centerTweenedOpacity;
|
|
2804
|
-
if (this.options.fullWidth) {
|
|
2805
|
-
alignment = "translateX(0)";
|
|
2806
|
-
centerTweenedOpacity = 1;
|
|
2807
|
-
} else {
|
|
2808
|
-
alignment = "translateX(" + (this.el.clientWidth - this.itemWidth) / 2 + "px) ";
|
|
2809
|
-
alignment += "translateY(" + (this.el.clientHeight - this.itemHeight) / 2 + "px)";
|
|
2810
|
-
centerTweenedOpacity = 1 - numVisibleOffset * tween;
|
|
2811
|
-
}
|
|
2812
|
-
this._paintIndicators(this.center);
|
|
2813
|
-
if (!this.noWrap || this.center >= 0 && this.center < this.count) {
|
|
2814
|
-
const el = this.images[this._wrap(this.center)];
|
|
2815
|
-
if (el && !el.classList.contains("active")) {
|
|
2816
|
-
this.el.querySelector(".carousel-item.active")?.classList.remove("active");
|
|
2817
|
-
el.classList.add("active");
|
|
2818
|
-
}
|
|
2819
|
-
}
|
|
2820
|
-
for (let i = 1; i <= half; ++i) {
|
|
2821
|
-
let zTranslation;
|
|
2822
|
-
let tweenedOpacity;
|
|
2823
|
-
if (this.options.fullWidth) {
|
|
2824
|
-
zTranslation = this.options.dist;
|
|
2825
|
-
tweenedOpacity = i === half && delta < 0 ? 1 - tween : 1;
|
|
2826
|
-
} else {
|
|
2827
|
-
zTranslation = this.options.dist * (i * 2 + tween * dir);
|
|
2828
|
-
tweenedOpacity = 1 - numVisibleOffset * (i * 2 + tween * dir);
|
|
2829
|
-
}
|
|
2830
|
-
if (!this.noWrap || this.center + i < this.count) {
|
|
2831
|
-
const el = this.images[this._wrap(this.center + i)];
|
|
2832
|
-
const transformString = `${alignment} translateX(${this.options.shift + (this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
2833
|
-
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
2834
|
-
}
|
|
2835
|
-
if (this.options.fullWidth) {
|
|
2836
|
-
zTranslation = this.options.dist;
|
|
2837
|
-
tweenedOpacity = i === half && delta > 0 ? 1 - tween : 1;
|
|
2838
|
-
} else {
|
|
2839
|
-
zTranslation = this.options.dist * (i * 2 - tween * dir);
|
|
2840
|
-
tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
|
|
2841
|
-
}
|
|
2842
|
-
if (!this.noWrap || this.center - i >= 0) {
|
|
2843
|
-
const el = this.images[this._wrap(this.center - i)];
|
|
2844
|
-
const transformString = `${alignment} translateX(${-this.options.shift + (-this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
2845
|
-
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
2846
|
-
}
|
|
2847
|
-
}
|
|
2848
|
-
if (!this.noWrap || this.center >= 0 && this.center < this.count) {
|
|
2849
|
-
const el = this.images[this._wrap(this.center)];
|
|
2850
|
-
const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir * this.options.shift * tween}px) translateZ(${this.options.dist * tween}px)`;
|
|
2851
|
-
this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
|
|
2852
|
-
}
|
|
2853
|
-
const currItem = this.images[this._wrap(this.center)];
|
|
2854
|
-
this._syncA11y(this._wrap(this.center));
|
|
2855
|
-
if (lastCenter !== this.center && typeof this.options.onCycleTo === "function") {
|
|
2856
|
-
this.options.onCycleTo.call(this, currItem, this.dragged);
|
|
2857
|
-
}
|
|
2858
|
-
if (typeof this.oneTimeCallback === "function") {
|
|
2859
|
-
this.oneTimeCallback.call(this, currItem, this.dragged);
|
|
2860
|
-
this.oneTimeCallback = null;
|
|
3390
|
+
if (this._generatedContainerRole) this.el.removeAttribute("role");
|
|
3391
|
+
if (this._generatedContainerLabel) this.el.removeAttribute("aria-label");
|
|
3392
|
+
if (this._generatedContainerDescription) this.el.removeAttribute("aria-roledescription");
|
|
3393
|
+
if (this._generatedFixedHeight) this.el.classList.remove("fixed-height");
|
|
3394
|
+
if (this.options.height !== null) {
|
|
3395
|
+
if (this._authoredInlineHeight === null) this.el.style.removeProperty("--carousel-height");
|
|
3396
|
+
else this.el.style.setProperty("--carousel-height", this._authoredInlineHeight);
|
|
3397
|
+
}
|
|
3398
|
+
if (this._generatedWideLayout) {
|
|
3399
|
+
this.el.classList.remove(
|
|
3400
|
+
"multi-wide",
|
|
3401
|
+
"multi-large",
|
|
3402
|
+
"multi-extra-large",
|
|
3403
|
+
"full-screen-horizontal"
|
|
3404
|
+
);
|
|
2861
3405
|
}
|
|
2862
3406
|
}
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
3407
|
+
/** Start or stop the timer to match the current pause state. */
|
|
3408
|
+
_syncAutoAdvance() {
|
|
3409
|
+
const run = this._autoAdvances && !this._autoPaused && !this._hovered && !this._focused && !document.hidden;
|
|
3410
|
+
if (run && this._autoAdvanceTimer === null) {
|
|
3411
|
+
this._autoAdvanceTimer = setTimeout(
|
|
3412
|
+
this._tick,
|
|
3413
|
+
this.options.duration + this.options.interval
|
|
3414
|
+
);
|
|
3415
|
+
} else if (!run && this._autoAdvanceTimer !== null) {
|
|
3416
|
+
clearTimeout(this._autoAdvanceTimer);
|
|
3417
|
+
this._autoAdvanceTimer = null;
|
|
3418
|
+
}
|
|
2869
3419
|
}
|
|
2870
3420
|
_paintIndicators(center) {
|
|
2871
3421
|
if (!this.showIndicators || !this._indicators) return;
|
|
@@ -2877,18 +3427,12 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2877
3427
|
else el.removeAttribute("aria-current");
|
|
2878
3428
|
});
|
|
2879
3429
|
}
|
|
2880
|
-
_syncA11y(index) {
|
|
2881
|
-
this.images.forEach((el, i) => {
|
|
2882
|
-
if (i === index) el.removeAttribute("aria-hidden");
|
|
2883
|
-
else el.setAttribute("aria-hidden", "true");
|
|
2884
|
-
});
|
|
2885
|
-
}
|
|
2886
3430
|
_syncActive(index, dragged) {
|
|
2887
3431
|
const prev = this.center;
|
|
2888
3432
|
this.center = index;
|
|
2889
3433
|
this.images.forEach((el, i) => el.classList.toggle("active", i === index));
|
|
2890
3434
|
this._paintIndicators(index);
|
|
2891
|
-
this.
|
|
3435
|
+
this._syncLayoutRoles(index);
|
|
2892
3436
|
const curr = this.images[index];
|
|
2893
3437
|
if (prev !== index && typeof this.options.onCycleTo === "function") {
|
|
2894
3438
|
this.options.onCycleTo.call(this, curr, dragged);
|
|
@@ -2898,6 +3442,81 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2898
3442
|
this.oneTimeCallback = null;
|
|
2899
3443
|
}
|
|
2900
3444
|
}
|
|
3445
|
+
_syncLayoutRoles(index) {
|
|
3446
|
+
const setSize = (item, size) => {
|
|
3447
|
+
if (this._authoredItemSizes.has(item)) return;
|
|
3448
|
+
item.setAttribute("data-carousel-size", size);
|
|
3449
|
+
this._generatedItemSizes.add(item);
|
|
3450
|
+
};
|
|
3451
|
+
this.images.forEach((item) => setSize(item, "large"));
|
|
3452
|
+
if (this.el.classList.contains("flat") || this.el.classList.contains("uncontained") || this.el.classList.contains("full-screen") && this._vertical) {
|
|
3453
|
+
return;
|
|
3454
|
+
}
|
|
3455
|
+
if (this.el.classList.contains("hero") || this.el.classList.contains("full-screen-horizontal")) {
|
|
3456
|
+
const next = this.images[index + 1];
|
|
3457
|
+
if (next) setSize(next, "small");
|
|
3458
|
+
if (this.el.classList.contains("center-aligned")) {
|
|
3459
|
+
const previous = this.images[index - 1];
|
|
3460
|
+
if (previous) setSize(previous, "small");
|
|
3461
|
+
}
|
|
3462
|
+
return;
|
|
3463
|
+
}
|
|
3464
|
+
const width = this.el.clientWidth;
|
|
3465
|
+
const desiredLargeCount = width >= 1600 ? 4 : width >= 1200 ? 3 : width >= 600 ? 2 : 1;
|
|
3466
|
+
const largeCount = Math.min(desiredLargeCount, Math.max(1, this.count - 2));
|
|
3467
|
+
this.el.classList.remove("multi-wide", "multi-large", "multi-extra-large");
|
|
3468
|
+
if (largeCount === 2) this.el.classList.add("multi-wide");
|
|
3469
|
+
else if (largeCount === 3) this.el.classList.add("multi-large");
|
|
3470
|
+
else if (largeCount >= 4) this.el.classList.add("multi-extra-large");
|
|
3471
|
+
this._generatedWideLayout = this._generatedWideLayout || largeCount > 1;
|
|
3472
|
+
for (let offset = 1; offset < largeCount; offset += 1) {
|
|
3473
|
+
const item = this.images[index + offset];
|
|
3474
|
+
if (item) setSize(item, "large");
|
|
3475
|
+
}
|
|
3476
|
+
const medium = this.images[index + largeCount];
|
|
3477
|
+
const small = this.images[index + largeCount + 1];
|
|
3478
|
+
if (medium) setSize(medium, "medium");
|
|
3479
|
+
if (small) setSize(small, "small");
|
|
3480
|
+
}
|
|
3481
|
+
_syncAdaptiveMode() {
|
|
3482
|
+
if (!this.el.classList.contains("full-screen")) return;
|
|
3483
|
+
const landscape = window.matchMedia("(orientation: landscape)").matches;
|
|
3484
|
+
const horizontal = this.el.clientWidth >= 840 || landscape;
|
|
3485
|
+
const wasVertical = this._vertical;
|
|
3486
|
+
this._vertical = !horizontal;
|
|
3487
|
+
this.el.classList.toggle("full-screen-horizontal", horizontal);
|
|
3488
|
+
this._generatedWideLayout = this._generatedWideLayout || horizontal;
|
|
3489
|
+
if (this._started && wasVertical !== this._vertical) {
|
|
3490
|
+
this._scroller.scrollTo({ left: 0, top: 0, behavior: "auto" });
|
|
3491
|
+
}
|
|
3492
|
+
}
|
|
3493
|
+
_focusItem(index) {
|
|
3494
|
+
const item = this.images[index];
|
|
3495
|
+
if (!item) return;
|
|
3496
|
+
const focusable = item.matches(
|
|
3497
|
+
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
3498
|
+
) ? item : item.querySelector(
|
|
3499
|
+
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
3500
|
+
);
|
|
3501
|
+
(focusable ?? item).focus({ preventScroll: true });
|
|
3502
|
+
}
|
|
3503
|
+
_updateParallax() {
|
|
3504
|
+
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
3505
|
+
this.images.forEach(
|
|
3506
|
+
(item) => item.style.setProperty("--md-comp-carousel-item-parallax", "0px")
|
|
3507
|
+
);
|
|
3508
|
+
return;
|
|
3509
|
+
}
|
|
3510
|
+
const scrollerRect = this._scroller.getBoundingClientRect();
|
|
3511
|
+
const viewportCenter = this._vertical ? scrollerRect.top + scrollerRect.height / 2 : scrollerRect.left + scrollerRect.width / 2;
|
|
3512
|
+
const viewportSize = Math.max(1, this._vertical ? scrollerRect.height : scrollerRect.width);
|
|
3513
|
+
this.images.forEach((item) => {
|
|
3514
|
+
const rect = item.getBoundingClientRect();
|
|
3515
|
+
const itemCenter = this._vertical ? rect.top + rect.height / 2 : rect.left + rect.width / 2;
|
|
3516
|
+
const progress = Math.max(-1, Math.min(1, (itemCenter - viewportCenter) / viewportSize));
|
|
3517
|
+
item.style.setProperty("--md-comp-carousel-item-parallax", `${progress * -24}px`);
|
|
3518
|
+
});
|
|
3519
|
+
}
|
|
2901
3520
|
_wrapTrack() {
|
|
2902
3521
|
const track = document.createElement("div");
|
|
2903
3522
|
track.className = "carousel-track";
|
|
@@ -2912,11 +3531,16 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2912
3531
|
this._trackEl = null;
|
|
2913
3532
|
}
|
|
2914
3533
|
_nearestIndex() {
|
|
2915
|
-
const
|
|
3534
|
+
const centered = this.el.classList.contains("center-aligned");
|
|
3535
|
+
const position = this._vertical ? this._scroller.scrollTop : this._scroller.scrollLeft;
|
|
3536
|
+
const viewportCenter = position + (this._vertical ? this._scroller.clientHeight : this._scroller.clientWidth) / 2;
|
|
2916
3537
|
let best = 0;
|
|
2917
3538
|
let bestDist = Infinity;
|
|
2918
3539
|
this.images.forEach((el, i) => {
|
|
2919
|
-
const
|
|
3540
|
+
const start = this._vertical ? el.offsetTop : el.offsetLeft;
|
|
3541
|
+
const size = this._vertical ? el.offsetHeight : el.offsetWidth;
|
|
3542
|
+
const target = centered ? start + size / 2 : start;
|
|
3543
|
+
const dist = Math.abs(target - (centered ? viewportCenter : position));
|
|
2920
3544
|
if (dist < bestDist) {
|
|
2921
3545
|
bestDist = dist;
|
|
2922
3546
|
best = i;
|
|
@@ -2927,13 +3551,24 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2927
3551
|
_scrollToIndex(n, smooth = true) {
|
|
2928
3552
|
const el = this.images[n];
|
|
2929
3553
|
if (!el) return;
|
|
2930
|
-
const
|
|
2931
|
-
|
|
3554
|
+
const centered = this.el.classList.contains("center-aligned");
|
|
3555
|
+
const style = getComputedStyle(this._scroller);
|
|
3556
|
+
const inlinePadding = Number.parseFloat(style.paddingInlineStart) || 0;
|
|
3557
|
+
const blockPadding = Number.parseFloat(style.paddingBlockStart) || 0;
|
|
3558
|
+
const left = centered ? el.offsetLeft - (this._scroller.clientWidth - el.offsetWidth) / 2 : el.offsetLeft - inlinePadding;
|
|
3559
|
+
const top = el.offsetTop - blockPadding;
|
|
3560
|
+
const current = this._vertical ? this._scroller.scrollTop : this._scroller.scrollLeft;
|
|
3561
|
+
const target = this._vertical ? top : left;
|
|
3562
|
+
if (Math.abs(current - target) < 1) {
|
|
2932
3563
|
this._syncActive(n, false);
|
|
2933
3564
|
return;
|
|
2934
3565
|
}
|
|
2935
3566
|
this._ignoreScroll = true;
|
|
2936
|
-
this._scroller.scrollTo({
|
|
3567
|
+
this._scroller.scrollTo({
|
|
3568
|
+
left: this._vertical ? 0 : left,
|
|
3569
|
+
top: this._vertical ? top : 0,
|
|
3570
|
+
behavior: smooth ? "smooth" : "auto"
|
|
3571
|
+
});
|
|
2937
3572
|
const done = () => {
|
|
2938
3573
|
this._ignoreScroll = false;
|
|
2939
3574
|
};
|
|
@@ -2941,63 +3576,38 @@ var _Carousel = class _Carousel extends Component {
|
|
|
2941
3576
|
window.setTimeout(done, this.options.duration + 350);
|
|
2942
3577
|
}
|
|
2943
3578
|
_cycleTo(n, callback = null) {
|
|
2944
|
-
if (this.
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
}
|
|
2961
|
-
}
|
|
2962
|
-
this.target = this.dim * Math.round(this.offset / this.dim);
|
|
2963
|
-
if (diff < 0) {
|
|
2964
|
-
this.target += this.dim * Math.abs(diff);
|
|
2965
|
-
} else if (diff > 0) {
|
|
2966
|
-
this.target -= this.dim * diff;
|
|
2967
|
-
}
|
|
2968
|
-
if (typeof callback === "function") {
|
|
2969
|
-
this.oneTimeCallback = callback;
|
|
2970
|
-
}
|
|
2971
|
-
if (this.offset !== this.target) {
|
|
2972
|
-
this.amplitude = this.target - this.offset;
|
|
2973
|
-
this.timestamp = Date.now();
|
|
2974
|
-
requestAnimationFrame(this._autoScroll);
|
|
2975
|
-
}
|
|
3579
|
+
if (typeof callback === "function") this.oneTimeCallback = callback;
|
|
3580
|
+
this._syncActive(n, false);
|
|
3581
|
+
this._scrollToIndex(n);
|
|
3582
|
+
}
|
|
3583
|
+
/**
|
|
3584
|
+
* Stop auto-advance until start() is called. Without an `interval` there is
|
|
3585
|
+
* nothing to stop and this does nothing.
|
|
3586
|
+
*/
|
|
3587
|
+
pause() {
|
|
3588
|
+
this._autoPaused = true;
|
|
3589
|
+
this._syncAutoAdvance();
|
|
3590
|
+
}
|
|
3591
|
+
/** Resume auto-advance after pause(). */
|
|
3592
|
+
start() {
|
|
3593
|
+
this._autoPaused = false;
|
|
3594
|
+
this._syncAutoAdvance();
|
|
2976
3595
|
}
|
|
2977
3596
|
next(n = 1) {
|
|
2978
3597
|
if (n === void 0 || isNaN(n)) n = 1;
|
|
2979
|
-
|
|
2980
|
-
if (index >= this.count || index < 0)
|
|
2981
|
-
if (this.noWrap) return;
|
|
2982
|
-
index = this._wrap(index);
|
|
2983
|
-
}
|
|
3598
|
+
const index = this.center + n;
|
|
3599
|
+
if (index >= this.count || index < 0) return;
|
|
2984
3600
|
this._cycleTo(index);
|
|
2985
3601
|
}
|
|
2986
3602
|
prev(n = 1) {
|
|
2987
3603
|
if (n === void 0 || isNaN(n)) n = 1;
|
|
2988
|
-
|
|
2989
|
-
if (index >= this.count || index < 0)
|
|
2990
|
-
if (this.noWrap) return;
|
|
2991
|
-
index = this._wrap(index);
|
|
2992
|
-
}
|
|
3604
|
+
const index = this.center - n;
|
|
3605
|
+
if (index >= this.count || index < 0) return;
|
|
2993
3606
|
this._cycleTo(index);
|
|
2994
3607
|
}
|
|
2995
3608
|
set(n, callback) {
|
|
2996
3609
|
if (n === void 0 || isNaN(n)) n = 0;
|
|
2997
|
-
if (n
|
|
2998
|
-
if (this.noWrap) return;
|
|
2999
|
-
n = this._wrap(n);
|
|
3000
|
-
}
|
|
3610
|
+
if (n >= this.count || n < 0) return;
|
|
3001
3611
|
this._cycleTo(n, callback);
|
|
3002
3612
|
}
|
|
3003
3613
|
};
|
|
@@ -3009,7 +3619,7 @@ _Carousel._onResize = Utils.throttle(() => {
|
|
|
3009
3619
|
var Carousel = _Carousel;
|
|
3010
3620
|
|
|
3011
3621
|
// src/ts/components/characterCounter.ts
|
|
3012
|
-
var
|
|
3622
|
+
var _defaults11 = Object.freeze({});
|
|
3013
3623
|
var CharacterCounter = class _CharacterCounter extends Component {
|
|
3014
3624
|
constructor(el, options) {
|
|
3015
3625
|
super(el, {}, _CharacterCounter);
|
|
@@ -3034,7 +3644,7 @@ var CharacterCounter = class _CharacterCounter extends Component {
|
|
|
3034
3644
|
this._setupEventHandlers();
|
|
3035
3645
|
}
|
|
3036
3646
|
static get defaults() {
|
|
3037
|
-
return
|
|
3647
|
+
return _defaults11;
|
|
3038
3648
|
}
|
|
3039
3649
|
/**
|
|
3040
3650
|
* Initializes instances of CharacterCounter.
|
|
@@ -3063,6 +3673,8 @@ var CharacterCounter = class _CharacterCounter extends Component {
|
|
|
3063
3673
|
_setupCounter() {
|
|
3064
3674
|
this.counterEl = document.createElement("span");
|
|
3065
3675
|
this.counterEl.classList.add("character-counter");
|
|
3676
|
+
this.counterEl.setAttribute("aria-live", "polite");
|
|
3677
|
+
this.counterEl.setAttribute("aria-atomic", "true");
|
|
3066
3678
|
this.counterEl.style.float = "right";
|
|
3067
3679
|
this.counterEl.style.fontSize = "12px";
|
|
3068
3680
|
this.counterEl.style.height = "1";
|
|
@@ -3084,7 +3696,7 @@ var CharacterCounter = class _CharacterCounter extends Component {
|
|
|
3084
3696
|
};
|
|
3085
3697
|
|
|
3086
3698
|
// src/ts/components/select.ts
|
|
3087
|
-
var
|
|
3699
|
+
var _defaults12 = {
|
|
3088
3700
|
classes: "",
|
|
3089
3701
|
menuOptions: {}
|
|
3090
3702
|
};
|
|
@@ -3133,7 +3745,7 @@ var FormSelect = class _FormSelect extends Component {
|
|
|
3133
3745
|
this._setupEventHandlers();
|
|
3134
3746
|
}
|
|
3135
3747
|
static get defaults() {
|
|
3136
|
-
return
|
|
3748
|
+
return _defaults12;
|
|
3137
3749
|
}
|
|
3138
3750
|
/**
|
|
3139
3751
|
* Initializes instances of FormSelect.
|
|
@@ -3264,7 +3876,7 @@ var FormSelect = class _FormSelect extends Component {
|
|
|
3264
3876
|
_buildInput() {
|
|
3265
3877
|
this.input = document.createElement("input");
|
|
3266
3878
|
this.input.id = "select-input-" + Utils.guid();
|
|
3267
|
-
this.input.classList.add("menu-trigger");
|
|
3879
|
+
this.input.classList.add("menu-trigger", "no-autoinit");
|
|
3268
3880
|
this.input.type = "text";
|
|
3269
3881
|
this.input.readOnly = true;
|
|
3270
3882
|
this.input.setAttribute("data-target", this.menuEl.id);
|
|
@@ -3304,10 +3916,8 @@ var FormSelect = class _FormSelect extends Component {
|
|
|
3304
3916
|
menuOptions.onOpenEnd = () => {
|
|
3305
3917
|
const selectedOption = this.menuEl.querySelector(".selected");
|
|
3306
3918
|
if (selectedOption) {
|
|
3307
|
-
Utils.keyDown = true;
|
|
3308
3919
|
this.menu.focusedIndex = [...selectedOption.parentNode.children].indexOf(selectedOption);
|
|
3309
3920
|
this.menu._focusFocusedItem();
|
|
3310
|
-
Utils.keyDown = false;
|
|
3311
3921
|
if (this.menu.isScrollable) {
|
|
3312
3922
|
let scrollOffset = selectedOption.getBoundingClientRect().top - this.menuEl.getBoundingClientRect().top;
|
|
3313
3923
|
scrollOffset -= this.menuEl.clientHeight / 2;
|
|
@@ -3507,7 +4117,7 @@ var FormSelect = class _FormSelect extends Component {
|
|
|
3507
4117
|
};
|
|
3508
4118
|
|
|
3509
4119
|
// src/ts/plugins/dockedDisplayPlugin.ts
|
|
3510
|
-
var
|
|
4120
|
+
var _defaults13 = {
|
|
3511
4121
|
margin: 5,
|
|
3512
4122
|
transition: 10,
|
|
3513
4123
|
duration: 250,
|
|
@@ -3556,7 +4166,7 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
|
|
|
3556
4166
|
};
|
|
3557
4167
|
this.el = el;
|
|
3558
4168
|
this.options = {
|
|
3559
|
-
...
|
|
4169
|
+
..._defaults13,
|
|
3560
4170
|
...options
|
|
3561
4171
|
};
|
|
3562
4172
|
this.container = document.createElement("div");
|
|
@@ -3577,7 +4187,7 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
|
|
|
3577
4187
|
};
|
|
3578
4188
|
|
|
3579
4189
|
// src/ts/components/datepicker.ts
|
|
3580
|
-
var
|
|
4190
|
+
var _defaults14 = {
|
|
3581
4191
|
// the default output format for the input field value
|
|
3582
4192
|
format: "mmm dd, yyyy",
|
|
3583
4193
|
// Used to create date object from current input string
|
|
@@ -3702,7 +4312,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
3702
4312
|
if (this.options.onInputInteraction) this.options.onInputInteraction.call(this);
|
|
3703
4313
|
};
|
|
3704
4314
|
this._handleInputKeydown = (e) => {
|
|
3705
|
-
if (Utils.keys.ENTER
|
|
4315
|
+
if (e.key === Utils.keys.ENTER) {
|
|
3706
4316
|
e.preventDefault();
|
|
3707
4317
|
this._batchDraws(() => {
|
|
3708
4318
|
this.setDateFromInput(e.target);
|
|
@@ -3842,7 +4452,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
3842
4452
|
}
|
|
3843
4453
|
}
|
|
3844
4454
|
static get defaults() {
|
|
3845
|
-
return
|
|
4455
|
+
return _defaults14;
|
|
3846
4456
|
}
|
|
3847
4457
|
/**
|
|
3848
4458
|
* Initializes instances of Datepicker.
|
|
@@ -4425,11 +5035,11 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
4425
5035
|
const monthSelect = this.calendarEl.querySelector(".orig-select-month");
|
|
4426
5036
|
FormSelect.init(yearSelect, {
|
|
4427
5037
|
classes: "select-year",
|
|
4428
|
-
menuOptions: { container:
|
|
5038
|
+
menuOptions: { container: Utils.portalRoot(this.el), constrainWidth: false }
|
|
4429
5039
|
});
|
|
4430
5040
|
FormSelect.init(monthSelect, {
|
|
4431
5041
|
classes: "select-month",
|
|
4432
|
-
menuOptions: { container:
|
|
5042
|
+
menuOptions: { container: Utils.portalRoot(this.el), constrainWidth: false }
|
|
4433
5043
|
});
|
|
4434
5044
|
yearSelect.addEventListener("change", this._handleYearChange);
|
|
4435
5045
|
monthSelect.addEventListener("change", this._handleMonthChange);
|
|
@@ -4560,7 +5170,7 @@ _Datepicker._template = `
|
|
|
4560
5170
|
var Datepicker = _Datepicker;
|
|
4561
5171
|
|
|
4562
5172
|
// src/ts/components/lightbox.ts
|
|
4563
|
-
var
|
|
5173
|
+
var _defaults15 = {
|
|
4564
5174
|
inDuration: 275,
|
|
4565
5175
|
outDuration: 200,
|
|
4566
5176
|
onOpenStart: null,
|
|
@@ -4575,7 +5185,7 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4575
5185
|
this._handleLightboxToggle();
|
|
4576
5186
|
};
|
|
4577
5187
|
this._handleLightboxKeypress = (e) => {
|
|
4578
|
-
if (Utils.keys.ENTER
|
|
5188
|
+
if (e.key === Utils.keys.ENTER) {
|
|
4579
5189
|
this._handleLightboxToggle();
|
|
4580
5190
|
}
|
|
4581
5191
|
};
|
|
@@ -4590,7 +5200,7 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4590
5200
|
if (this.overlayActive) this.close();
|
|
4591
5201
|
};
|
|
4592
5202
|
this._handleWindowEscape = (e) => {
|
|
4593
|
-
if (Utils.keys.ESC
|
|
5203
|
+
if (e.key === Utils.keys.ESC && this.doneAnimating && this.overlayActive) this.close();
|
|
4594
5204
|
};
|
|
4595
5205
|
/**
|
|
4596
5206
|
* Open lightbox.
|
|
@@ -4679,7 +5289,7 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4679
5289
|
this._setupEventHandlers();
|
|
4680
5290
|
}
|
|
4681
5291
|
static get defaults() {
|
|
4682
|
-
return
|
|
5292
|
+
return _defaults15;
|
|
4683
5293
|
}
|
|
4684
5294
|
/**
|
|
4685
5295
|
* Initializes instances of Lightbox.
|
|
@@ -4709,13 +5319,13 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4709
5319
|
_makeAncestorsOverflowVisible() {
|
|
4710
5320
|
this._changedAncestorList = [];
|
|
4711
5321
|
let ancestor = this.placeholder.parentNode;
|
|
4712
|
-
while (ancestor !== null && ancestor !== document) {
|
|
5322
|
+
while (ancestor !== null && ancestor !== void 0 && ancestor !== document) {
|
|
4713
5323
|
const curr = ancestor;
|
|
4714
|
-
if (curr.style.overflow !== "visible") {
|
|
5324
|
+
if (curr.style && curr.style.overflow !== "visible") {
|
|
5325
|
+
this._changedAncestorList.push([curr, curr.style.overflow]);
|
|
4715
5326
|
curr.style.overflow = "visible";
|
|
4716
|
-
this._changedAncestorList.push(curr);
|
|
4717
5327
|
}
|
|
4718
|
-
ancestor = ancestor.parentNode;
|
|
5328
|
+
ancestor = ancestor.parentNode ?? ancestor.host;
|
|
4719
5329
|
}
|
|
4720
5330
|
}
|
|
4721
5331
|
_offset(el) {
|
|
@@ -4779,7 +5389,7 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4779
5389
|
if (this.originInlineStyles) this.el.setAttribute("style", this.originInlineStyles);
|
|
4780
5390
|
this.el.classList.remove("active");
|
|
4781
5391
|
this.doneAnimating = true;
|
|
4782
|
-
this._changedAncestorList.forEach((
|
|
5392
|
+
this._changedAncestorList.forEach(([ancestor, overflow]) => ancestor.style.overflow = overflow);
|
|
4783
5393
|
if (typeof this.options.onCloseEnd === "function")
|
|
4784
5394
|
this.options.onCloseEnd.call(this, this.el);
|
|
4785
5395
|
}, duration);
|
|
@@ -4789,7 +5399,7 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4789
5399
|
this._photoCaption = document.createElement("div");
|
|
4790
5400
|
this._photoCaption.classList.add("lightbox-caption");
|
|
4791
5401
|
this._photoCaption.innerText = this.caption;
|
|
4792
|
-
|
|
5402
|
+
Utils.portalRoot(this.el).append(this._photoCaption);
|
|
4793
5403
|
this._photoCaption.style.display = "inline";
|
|
4794
5404
|
this._photoCaption.style.transition = "none";
|
|
4795
5405
|
this._photoCaption.style.opacity = "0";
|
|
@@ -4843,37 +5453,9 @@ var Lightbox = class _Lightbox extends Component {
|
|
|
4843
5453
|
}
|
|
4844
5454
|
};
|
|
4845
5455
|
|
|
4846
|
-
// src/ts/components/parallax.ts
|
|
4847
|
-
var _defaults13 = {};
|
|
4848
|
-
var Parallax = class _Parallax extends Component {
|
|
4849
|
-
constructor(el, options) {
|
|
4850
|
-
super(el, options, _Parallax);
|
|
4851
|
-
this.el["Expressive_Parallax"] = this;
|
|
4852
|
-
this.options = {
|
|
4853
|
-
..._Parallax.defaults,
|
|
4854
|
-
...options
|
|
4855
|
-
};
|
|
4856
|
-
if (!this.el.querySelector("img, video")) {
|
|
4857
|
-
console.error("Parallax: no <img> or <video> to move inside the .parallax element");
|
|
4858
|
-
}
|
|
4859
|
-
}
|
|
4860
|
-
static get defaults() {
|
|
4861
|
-
return _defaults13;
|
|
4862
|
-
}
|
|
4863
|
-
static init(els, options = {}) {
|
|
4864
|
-
return super.init(els, options, _Parallax);
|
|
4865
|
-
}
|
|
4866
|
-
static getInstance(el) {
|
|
4867
|
-
return el["Expressive_Parallax"];
|
|
4868
|
-
}
|
|
4869
|
-
destroy() {
|
|
4870
|
-
this.el["Expressive_Parallax"] = void 0;
|
|
4871
|
-
}
|
|
4872
|
-
};
|
|
4873
|
-
|
|
4874
5456
|
// src/ts/components/scrollspy.ts
|
|
4875
5457
|
var _defaultGetActiveElement = (id) => `a[href="#${id}"]`;
|
|
4876
|
-
var
|
|
5458
|
+
var _defaults16 = {
|
|
4877
5459
|
scrollOffset: 200,
|
|
4878
5460
|
activeClass: "active",
|
|
4879
5461
|
getActiveElement: _defaultGetActiveElement,
|
|
@@ -4896,7 +5478,7 @@ var _ScrollSpy = class _ScrollSpy extends Component {
|
|
|
4896
5478
|
_ScrollSpy._observer?.observe(this.el);
|
|
4897
5479
|
}
|
|
4898
5480
|
static get defaults() {
|
|
4899
|
-
return
|
|
5481
|
+
return _defaults16;
|
|
4900
5482
|
}
|
|
4901
5483
|
static init(els, options = {}) {
|
|
4902
5484
|
return super.init(els, options, _ScrollSpy);
|
|
@@ -5017,8 +5599,8 @@ _ScrollSpy._onIntersect = (entries) => {
|
|
|
5017
5599
|
};
|
|
5018
5600
|
var ScrollSpy = _ScrollSpy;
|
|
5019
5601
|
|
|
5020
|
-
// src/ts/components/
|
|
5021
|
-
var
|
|
5602
|
+
// src/ts/components/navigationDrawer.ts
|
|
5603
|
+
var _defaults17 = {
|
|
5022
5604
|
edge: "left",
|
|
5023
5605
|
draggable: true,
|
|
5024
5606
|
dragTargetWidth: "10px",
|
|
@@ -5027,17 +5609,17 @@ var _defaults15 = {
|
|
|
5027
5609
|
onCloseStart: null,
|
|
5028
5610
|
onCloseEnd: null
|
|
5029
5611
|
};
|
|
5030
|
-
var
|
|
5031
|
-
var
|
|
5612
|
+
var EXPANDED_UP = "(width >= 840px)";
|
|
5613
|
+
var _NavigationDrawer = class _NavigationDrawer extends Component {
|
|
5032
5614
|
constructor(el, options) {
|
|
5033
|
-
super(el, options,
|
|
5615
|
+
super(el, options, _NavigationDrawer);
|
|
5034
5616
|
/**
|
|
5035
5617
|
* Opens the overlay drawer. No-op while the sidenav is docked
|
|
5036
|
-
* (
|
|
5618
|
+
* (navigation-drawer-fixed at the Expanded breakpoint).
|
|
5037
5619
|
*/
|
|
5038
5620
|
this.open = () => {
|
|
5039
5621
|
if (this._isCurrentlyFixed() || this.isOpen || !this._dialog) return;
|
|
5040
|
-
|
|
5622
|
+
_NavigationDrawer._sidenavs.forEach((other) => {
|
|
5041
5623
|
if (other !== this && other.isOpen) other.close();
|
|
5042
5624
|
});
|
|
5043
5625
|
if (typeof this.options.onOpenStart === "function") {
|
|
@@ -5089,7 +5671,7 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5089
5671
|
this._handleCloseTriggerClick = (e) => {
|
|
5090
5672
|
const target = e.target;
|
|
5091
5673
|
if (!(target instanceof Element)) return;
|
|
5092
|
-
const closeTrigger = target.closest(".sidenav-close");
|
|
5674
|
+
const closeTrigger = target.closest(".sidenav-close, .navigation-drawer-close");
|
|
5093
5675
|
if (closeTrigger && !this._isCurrentlyFixed()) {
|
|
5094
5676
|
this.close();
|
|
5095
5677
|
}
|
|
@@ -5133,14 +5715,14 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5133
5715
|
this.isDragged = false;
|
|
5134
5716
|
this._verticallyScrolling = false;
|
|
5135
5717
|
};
|
|
5136
|
-
this.el["
|
|
5718
|
+
this.el["Expressive_NavigationDrawer"] = this;
|
|
5137
5719
|
this.options = {
|
|
5138
|
-
...
|
|
5720
|
+
..._NavigationDrawer.defaults,
|
|
5139
5721
|
...options
|
|
5140
5722
|
};
|
|
5141
5723
|
this.id = this.el.id;
|
|
5142
5724
|
this.isOpen = false;
|
|
5143
|
-
this.isFixed = this.el.classList.contains("sidenav-fixed");
|
|
5725
|
+
this.isFixed = this.el.classList.contains("navigation-drawer-fixed") || this.el.classList.contains("sidenav-fixed");
|
|
5144
5726
|
this.isDragged = false;
|
|
5145
5727
|
this.dragTarget = null;
|
|
5146
5728
|
this._dialog = null;
|
|
@@ -5152,27 +5734,27 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5152
5734
|
this._width = 0;
|
|
5153
5735
|
this._initialScrollTop = 0;
|
|
5154
5736
|
this._verticallyScrolling = false;
|
|
5155
|
-
this._mql = window.matchMedia(
|
|
5737
|
+
this._mql = window.matchMedia(EXPANDED_UP);
|
|
5156
5738
|
this._setupDialog();
|
|
5157
5739
|
this._createDragTarget();
|
|
5158
5740
|
this._setupClasses();
|
|
5159
5741
|
this._setupEventHandlers();
|
|
5160
5742
|
this._syncTriggers();
|
|
5161
|
-
|
|
5743
|
+
_NavigationDrawer._sidenavs.push(this);
|
|
5162
5744
|
}
|
|
5163
5745
|
static get defaults() {
|
|
5164
|
-
return
|
|
5746
|
+
return _defaults17;
|
|
5165
5747
|
}
|
|
5166
5748
|
/**
|
|
5167
|
-
* Initializes instances of
|
|
5749
|
+
* Initializes instances of NavigationDrawer.
|
|
5168
5750
|
* @param els HTML elements.
|
|
5169
5751
|
* @param options Component options.
|
|
5170
5752
|
*/
|
|
5171
5753
|
static init(els, options = {}) {
|
|
5172
|
-
return super.init(els, options,
|
|
5754
|
+
return super.init(els, options, _NavigationDrawer);
|
|
5173
5755
|
}
|
|
5174
5756
|
static getInstance(el) {
|
|
5175
|
-
return el["
|
|
5757
|
+
return el["Expressive_NavigationDrawer"];
|
|
5176
5758
|
}
|
|
5177
5759
|
destroy() {
|
|
5178
5760
|
this._removeEventHandlers();
|
|
@@ -5185,10 +5767,10 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5185
5767
|
this._clearShift();
|
|
5186
5768
|
this._unwrapDialog();
|
|
5187
5769
|
this._removeDragTarget();
|
|
5188
|
-
this.el["
|
|
5189
|
-
const index =
|
|
5770
|
+
this.el["Expressive_NavigationDrawer"] = void 0;
|
|
5771
|
+
const index = _NavigationDrawer._sidenavs.indexOf(this);
|
|
5190
5772
|
if (index >= 0) {
|
|
5191
|
-
|
|
5773
|
+
_NavigationDrawer._sidenavs.splice(index, 1);
|
|
5192
5774
|
}
|
|
5193
5775
|
}
|
|
5194
5776
|
_beginClose() {
|
|
@@ -5219,6 +5801,11 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5219
5801
|
}
|
|
5220
5802
|
const dialog = document.createElement("dialog");
|
|
5221
5803
|
dialog.classList.add("sidenav-overlay");
|
|
5804
|
+
const named = this.el.closest("[aria-label], [aria-labelledby]") ?? this.el;
|
|
5805
|
+
const label = named.getAttribute("aria-label");
|
|
5806
|
+
const labelledBy = named.getAttribute("aria-labelledby");
|
|
5807
|
+
if (label) dialog.setAttribute("aria-label", label);
|
|
5808
|
+
else if (labelledBy) dialog.setAttribute("aria-labelledby", labelledBy);
|
|
5222
5809
|
this.el.replaceWith(dialog);
|
|
5223
5810
|
dialog.appendChild(this.el);
|
|
5224
5811
|
this._dialog = dialog;
|
|
@@ -5236,7 +5823,7 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5236
5823
|
dragTarget.classList.add("drag-target");
|
|
5237
5824
|
dragTarget.style.width = this.options.dragTargetWidth;
|
|
5238
5825
|
if (this.isFixed) dragTarget.dataset.fixed = "";
|
|
5239
|
-
|
|
5826
|
+
Utils.portalRoot(this.el).appendChild(dragTarget);
|
|
5240
5827
|
this.dragTarget = dragTarget;
|
|
5241
5828
|
}
|
|
5242
5829
|
_removeDragTarget() {
|
|
@@ -5251,8 +5838,8 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5251
5838
|
}
|
|
5252
5839
|
}
|
|
5253
5840
|
_setupEventHandlers() {
|
|
5254
|
-
if (
|
|
5255
|
-
document.body.addEventListener("click",
|
|
5841
|
+
if (_NavigationDrawer._sidenavs.length === 0) {
|
|
5842
|
+
document.body.addEventListener("click", _NavigationDrawer._handleTriggerClick);
|
|
5256
5843
|
}
|
|
5257
5844
|
const passive = { passive: true };
|
|
5258
5845
|
this.dragTarget?.addEventListener("touchmove", this._handleDragTargetDrag, passive);
|
|
@@ -5264,8 +5851,8 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5264
5851
|
this._mql.addEventListener("change", this._onBreakpointChange);
|
|
5265
5852
|
}
|
|
5266
5853
|
_removeEventHandlers() {
|
|
5267
|
-
if (
|
|
5268
|
-
document.body.removeEventListener("click",
|
|
5854
|
+
if (_NavigationDrawer._sidenavs.length === 1) {
|
|
5855
|
+
document.body.removeEventListener("click", _NavigationDrawer._handleTriggerClick);
|
|
5269
5856
|
}
|
|
5270
5857
|
this.dragTarget?.removeEventListener("touchmove", this._handleDragTargetDrag);
|
|
5271
5858
|
this.dragTarget?.removeEventListener("touchend", this._handleDragTargetRelease);
|
|
@@ -5278,10 +5865,10 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5278
5865
|
static _handleTriggerClick(e) {
|
|
5279
5866
|
const target = e.target;
|
|
5280
5867
|
if (!(target instanceof Element)) return;
|
|
5281
|
-
const trigger = target.closest(".sidenav-trigger");
|
|
5868
|
+
const trigger = target.closest(".sidenav-trigger, .navigation-drawer-trigger");
|
|
5282
5869
|
if (!trigger || !(trigger instanceof HTMLElement)) return;
|
|
5283
5870
|
const sidenavId = Utils.getIdFromTrigger(trigger);
|
|
5284
|
-
const sidenavInstance =
|
|
5871
|
+
const sidenavInstance = Utils.getElementById(trigger, sidenavId)?.["Expressive_NavigationDrawer"];
|
|
5285
5872
|
if (sidenavInstance) {
|
|
5286
5873
|
sidenavInstance.open();
|
|
5287
5874
|
e.preventDefault();
|
|
@@ -5335,7 +5922,7 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5335
5922
|
}
|
|
5336
5923
|
_syncTriggers() {
|
|
5337
5924
|
if (!this.id) return;
|
|
5338
|
-
document.querySelectorAll(".sidenav-trigger").forEach((trigger) => {
|
|
5925
|
+
document.querySelectorAll(".sidenav-trigger, .navigation-drawer-trigger").forEach((trigger) => {
|
|
5339
5926
|
if (!(trigger instanceof HTMLElement)) return;
|
|
5340
5927
|
if (Utils.getIdFromTrigger(trigger) !== this.id) return;
|
|
5341
5928
|
trigger.setAttribute("aria-expanded", this.isOpen ? "true" : "false");
|
|
@@ -5343,17 +5930,17 @@ var _Sidenav = class _Sidenav extends Component {
|
|
|
5343
5930
|
});
|
|
5344
5931
|
}
|
|
5345
5932
|
};
|
|
5346
|
-
|
|
5347
|
-
var
|
|
5933
|
+
_NavigationDrawer._sidenavs = [];
|
|
5934
|
+
var NavigationDrawer = _NavigationDrawer;
|
|
5348
5935
|
|
|
5349
5936
|
// src/ts/components/navigationRail.ts
|
|
5350
|
-
var
|
|
5937
|
+
var _defaults18 = {
|
|
5351
5938
|
onOpenStart: null,
|
|
5352
5939
|
onOpenEnd: null,
|
|
5353
5940
|
onCloseStart: null,
|
|
5354
5941
|
onCloseEnd: null
|
|
5355
5942
|
};
|
|
5356
|
-
var COMPACT = "(width <
|
|
5943
|
+
var COMPACT = "(width < 600px)";
|
|
5357
5944
|
var NavigationRail = class _NavigationRail extends Component {
|
|
5358
5945
|
constructor(el, options) {
|
|
5359
5946
|
super(el, options, _NavigationRail);
|
|
@@ -5423,7 +6010,7 @@ var NavigationRail = class _NavigationRail extends Component {
|
|
|
5423
6010
|
document.addEventListener("keydown", this._onKeyDown);
|
|
5424
6011
|
}
|
|
5425
6012
|
static get defaults() {
|
|
5426
|
-
return
|
|
6013
|
+
return _defaults18;
|
|
5427
6014
|
}
|
|
5428
6015
|
static init(els, options = {}) {
|
|
5429
6016
|
return super.init(els, options, _NavigationRail);
|
|
@@ -5452,309 +6039,8 @@ var NavigationRail = class _NavigationRail extends Component {
|
|
|
5452
6039
|
}
|
|
5453
6040
|
};
|
|
5454
6041
|
|
|
5455
|
-
// src/ts/components/slider.ts
|
|
5456
|
-
var _defaults17 = {
|
|
5457
|
-
indicators: true,
|
|
5458
|
-
height: 400,
|
|
5459
|
-
duration: 500,
|
|
5460
|
-
interval: 6e3,
|
|
5461
|
-
pauseOnFocus: true,
|
|
5462
|
-
pauseOnHover: true,
|
|
5463
|
-
indicatorLabelFunc: null
|
|
5464
|
-
// Function which will generate a label for the indicators (ARIA)
|
|
5465
|
-
};
|
|
5466
|
-
var Slider = class _Slider extends Component {
|
|
5467
|
-
constructor(el, options) {
|
|
5468
|
-
super(el, options, _Slider);
|
|
5469
|
-
// Nobody is watching a backgrounded tab. Browsers clamp the timer rather
|
|
5470
|
-
// than stopping it, so without this the slider keeps cycling slides - and
|
|
5471
|
-
// running their transitions - out of sight.
|
|
5472
|
-
this._handleVisibilityChange = () => {
|
|
5473
|
-
if (document.hidden) {
|
|
5474
|
-
if (this.interval != null) this._pause(true);
|
|
5475
|
-
} else if (this.eventPause && !(this.options.pauseOnHover && this._hovered) && !(this.options.pauseOnFocus && this._focused)) {
|
|
5476
|
-
this.start();
|
|
5477
|
-
}
|
|
5478
|
-
};
|
|
5479
|
-
this._handleIndicatorClick = (e) => {
|
|
5480
|
-
const el = e.target.parentElement;
|
|
5481
|
-
const currIndex = [...el.parentNode.children].indexOf(el);
|
|
5482
|
-
this._focusCurrent = true;
|
|
5483
|
-
this.set(currIndex);
|
|
5484
|
-
};
|
|
5485
|
-
this._handleAutoPauseHover = () => {
|
|
5486
|
-
this._hovered = true;
|
|
5487
|
-
if (this.interval != null) {
|
|
5488
|
-
this._pause(true);
|
|
5489
|
-
}
|
|
5490
|
-
};
|
|
5491
|
-
this._handleAutoPauseFocus = () => {
|
|
5492
|
-
this._focused = true;
|
|
5493
|
-
if (this.interval != null) {
|
|
5494
|
-
this._pause(true);
|
|
5495
|
-
}
|
|
5496
|
-
};
|
|
5497
|
-
this._handleAutoStartHover = () => {
|
|
5498
|
-
this._hovered = false;
|
|
5499
|
-
if (!(this.options.pauseOnFocus && this._focused) && this.eventPause) {
|
|
5500
|
-
this.start();
|
|
5501
|
-
}
|
|
5502
|
-
};
|
|
5503
|
-
this._handleAutoStartFocus = () => {
|
|
5504
|
-
this._focused = false;
|
|
5505
|
-
if (!(this.options.pauseOnHover && this._hovered) && this.eventPause) {
|
|
5506
|
-
this.start();
|
|
5507
|
-
}
|
|
5508
|
-
};
|
|
5509
|
-
this._handleInterval = () => {
|
|
5510
|
-
const activeElem = this._slider.querySelector(".active");
|
|
5511
|
-
let newActiveIndex = [...activeElem.parentNode.children].indexOf(activeElem);
|
|
5512
|
-
if (this._slides.length === newActiveIndex + 1)
|
|
5513
|
-
newActiveIndex = 0;
|
|
5514
|
-
else newActiveIndex += 1;
|
|
5515
|
-
this.set(newActiveIndex);
|
|
5516
|
-
};
|
|
5517
|
-
/**
|
|
5518
|
-
* Pause slider autoslide.
|
|
5519
|
-
*/
|
|
5520
|
-
this.pause = () => {
|
|
5521
|
-
this._pause(false);
|
|
5522
|
-
};
|
|
5523
|
-
/**
|
|
5524
|
-
* Start slider autoslide.
|
|
5525
|
-
*/
|
|
5526
|
-
this.start = () => {
|
|
5527
|
-
clearInterval(this.interval);
|
|
5528
|
-
this.interval = setInterval(
|
|
5529
|
-
this._handleInterval,
|
|
5530
|
-
this.options.duration + this.options.interval
|
|
5531
|
-
);
|
|
5532
|
-
this.eventPause = false;
|
|
5533
|
-
};
|
|
5534
|
-
/**
|
|
5535
|
-
* Move to next slider.
|
|
5536
|
-
*/
|
|
5537
|
-
this.next = () => {
|
|
5538
|
-
let newIndex = this.activeIndex + 1;
|
|
5539
|
-
if (newIndex >= this._slides.length) newIndex = 0;
|
|
5540
|
-
else if (newIndex < 0) newIndex = this._slides.length - 1;
|
|
5541
|
-
this.set(newIndex);
|
|
5542
|
-
};
|
|
5543
|
-
/**
|
|
5544
|
-
* Move to prev slider.
|
|
5545
|
-
*/
|
|
5546
|
-
this.prev = () => {
|
|
5547
|
-
let newIndex = this.activeIndex - 1;
|
|
5548
|
-
if (newIndex >= this._slides.length) newIndex = 0;
|
|
5549
|
-
else if (newIndex < 0) newIndex = this._slides.length - 1;
|
|
5550
|
-
this.set(newIndex);
|
|
5551
|
-
};
|
|
5552
|
-
this.el["Expressive_Slider"] = this;
|
|
5553
|
-
this.options = {
|
|
5554
|
-
..._Slider.defaults,
|
|
5555
|
-
...options
|
|
5556
|
-
};
|
|
5557
|
-
this.interval = null;
|
|
5558
|
-
this.eventPause = false;
|
|
5559
|
-
this._hovered = false;
|
|
5560
|
-
this._focused = false;
|
|
5561
|
-
this._focusCurrent = false;
|
|
5562
|
-
this._slider = this.el.querySelector(".slides");
|
|
5563
|
-
this._slides = Array.from(this._slider.querySelectorAll("li"));
|
|
5564
|
-
this.activeIndex = this._slides.findIndex((li) => li.classList.contains("active"));
|
|
5565
|
-
if (this.activeIndex !== -1) {
|
|
5566
|
-
this._activeSlide = this._slides[this.activeIndex];
|
|
5567
|
-
}
|
|
5568
|
-
this._setSliderHeight();
|
|
5569
|
-
if (this._slider.hasAttribute("id")) this._sliderId = this._slider.getAttribute("id");
|
|
5570
|
-
else {
|
|
5571
|
-
this._sliderId = "slider-" + Utils.guid();
|
|
5572
|
-
this._slider.setAttribute("id", this._sliderId);
|
|
5573
|
-
}
|
|
5574
|
-
const placeholderBase64 = "data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
|
|
5575
|
-
this._slides.forEach((slide) => {
|
|
5576
|
-
const img = slide.querySelector("img");
|
|
5577
|
-
if (img) {
|
|
5578
|
-
if (img.src !== placeholderBase64) {
|
|
5579
|
-
img.style.backgroundImage = "url(" + img.src + ")";
|
|
5580
|
-
img.src = placeholderBase64;
|
|
5581
|
-
}
|
|
5582
|
-
}
|
|
5583
|
-
if (!slide.hasAttribute("tabindex")) slide.setAttribute("tabindex", "-1");
|
|
5584
|
-
slide.style.visibility = "hidden";
|
|
5585
|
-
});
|
|
5586
|
-
this._setupIndicators();
|
|
5587
|
-
if (this._activeSlide) {
|
|
5588
|
-
this._activeSlide.style.display = "block";
|
|
5589
|
-
this._activeSlide.style.visibility = "visible";
|
|
5590
|
-
} else {
|
|
5591
|
-
this.activeIndex = 0;
|
|
5592
|
-
this._slides[0].classList.add("active");
|
|
5593
|
-
this._slides[0].style.visibility = "visible";
|
|
5594
|
-
this._activeSlide = this._slides[0];
|
|
5595
|
-
this._animateSlide(this._slides[0], true);
|
|
5596
|
-
if (this.options.indicators) {
|
|
5597
|
-
this._indicators[this.activeIndex].children[0].classList.add("active");
|
|
5598
|
-
}
|
|
5599
|
-
}
|
|
5600
|
-
this._setupEventHandlers();
|
|
5601
|
-
this.start();
|
|
5602
|
-
}
|
|
5603
|
-
static get defaults() {
|
|
5604
|
-
return _defaults17;
|
|
5605
|
-
}
|
|
5606
|
-
/**
|
|
5607
|
-
* Initializes instances of Slider.
|
|
5608
|
-
* @param els HTML elements.
|
|
5609
|
-
* @param options Component options.
|
|
5610
|
-
*/
|
|
5611
|
-
static init(els, options = {}) {
|
|
5612
|
-
return super.init(els, options, _Slider);
|
|
5613
|
-
}
|
|
5614
|
-
static getInstance(el) {
|
|
5615
|
-
return el["Expressive_Slider"];
|
|
5616
|
-
}
|
|
5617
|
-
destroy() {
|
|
5618
|
-
this.pause();
|
|
5619
|
-
this._removeIndicators();
|
|
5620
|
-
this._removeEventHandlers();
|
|
5621
|
-
this.el["Expressive_Slider"] = void 0;
|
|
5622
|
-
}
|
|
5623
|
-
_setupEventHandlers() {
|
|
5624
|
-
if (this.options.pauseOnFocus) {
|
|
5625
|
-
this.el.addEventListener("focusin", this._handleAutoPauseFocus);
|
|
5626
|
-
this.el.addEventListener("focusout", this._handleAutoStartFocus);
|
|
5627
|
-
}
|
|
5628
|
-
if (this.options.pauseOnHover) {
|
|
5629
|
-
this.el.addEventListener("mouseenter", this._handleAutoPauseHover);
|
|
5630
|
-
this.el.addEventListener("mouseleave", this._handleAutoStartHover);
|
|
5631
|
-
}
|
|
5632
|
-
if (this.options.indicators) {
|
|
5633
|
-
this._indicators.forEach((el) => {
|
|
5634
|
-
el.addEventListener("click", this._handleIndicatorClick);
|
|
5635
|
-
});
|
|
5636
|
-
}
|
|
5637
|
-
document.addEventListener("visibilitychange", this._handleVisibilityChange);
|
|
5638
|
-
}
|
|
5639
|
-
_removeEventHandlers() {
|
|
5640
|
-
if (this.options.pauseOnFocus) {
|
|
5641
|
-
this.el.removeEventListener("focusin", this._handleAutoPauseFocus);
|
|
5642
|
-
this.el.removeEventListener("focusout", this._handleAutoStartFocus);
|
|
5643
|
-
}
|
|
5644
|
-
if (this.options.pauseOnHover) {
|
|
5645
|
-
this.el.removeEventListener("mouseenter", this._handleAutoPauseHover);
|
|
5646
|
-
this.el.removeEventListener("mouseleave", this._handleAutoStartHover);
|
|
5647
|
-
}
|
|
5648
|
-
if (this.options.indicators) {
|
|
5649
|
-
this._indicators.forEach((el) => {
|
|
5650
|
-
el.removeEventListener("click", this._handleIndicatorClick);
|
|
5651
|
-
});
|
|
5652
|
-
}
|
|
5653
|
-
document.removeEventListener("visibilitychange", this._handleVisibilityChange);
|
|
5654
|
-
}
|
|
5655
|
-
_animateSlide(slide, isDirectionIn) {
|
|
5656
|
-
let dx = 0, dy = 0;
|
|
5657
|
-
slide.style.opacity = isDirectionIn ? "0" : "1";
|
|
5658
|
-
setTimeout(() => {
|
|
5659
|
-
slide.style.transition = `opacity ${this.options.duration}ms ease`;
|
|
5660
|
-
slide.style.opacity = isDirectionIn ? "1" : "0";
|
|
5661
|
-
}, 1);
|
|
5662
|
-
const caption = slide.querySelector(".caption");
|
|
5663
|
-
if (!caption) return;
|
|
5664
|
-
if (caption.classList.contains("center-align")) dy = -100;
|
|
5665
|
-
else if (caption.classList.contains("right-align")) dx = 100;
|
|
5666
|
-
else if (caption.classList.contains("left-align")) dx = -100;
|
|
5667
|
-
caption.style.opacity = isDirectionIn ? "0" : "1";
|
|
5668
|
-
caption.style.transform = isDirectionIn ? `translate(${dx}px, ${dy}px)` : `translate(0, 0)`;
|
|
5669
|
-
setTimeout(() => {
|
|
5670
|
-
caption.style.transition = `opacity ${this.options.duration}ms ease, transform ${this.options.duration}ms ease`;
|
|
5671
|
-
caption.style.opacity = isDirectionIn ? "1" : "0";
|
|
5672
|
-
caption.style.transform = isDirectionIn ? `translate(0, 0)` : `translate(${dx}px, ${dy}px)`;
|
|
5673
|
-
}, this.options.duration);
|
|
5674
|
-
}
|
|
5675
|
-
_setSliderHeight() {
|
|
5676
|
-
if (!this.el.classList.contains("fullscreen")) {
|
|
5677
|
-
if (this.options.indicators) {
|
|
5678
|
-
this.el.style.height = this.options.height + 40 + "px";
|
|
5679
|
-
} else {
|
|
5680
|
-
this.el.style.height = this.options.height + "px";
|
|
5681
|
-
}
|
|
5682
|
-
this._slider.style.height = this.options.height + "px";
|
|
5683
|
-
}
|
|
5684
|
-
}
|
|
5685
|
-
_setupIndicators() {
|
|
5686
|
-
if (this.options.indicators) {
|
|
5687
|
-
const ul = document.createElement("ul");
|
|
5688
|
-
ul.classList.add("indicators");
|
|
5689
|
-
const arrLi = [];
|
|
5690
|
-
this._slides.forEach((el, i) => {
|
|
5691
|
-
const label = this.options.indicatorLabelFunc ? this.options.indicatorLabelFunc.call(this, i + 1, i === 0) : `${i + 1}`;
|
|
5692
|
-
const li = document.createElement("li");
|
|
5693
|
-
li.classList.add("indicator-item");
|
|
5694
|
-
const button = document.createElement("button");
|
|
5695
|
-
button.type = "button";
|
|
5696
|
-
button.classList.add("indicator-item-btn");
|
|
5697
|
-
button.setAttribute("aria-label", label);
|
|
5698
|
-
button.setAttribute("aria-controls", this._sliderId);
|
|
5699
|
-
li.appendChild(button);
|
|
5700
|
-
arrLi.push(li);
|
|
5701
|
-
ul.append(li);
|
|
5702
|
-
});
|
|
5703
|
-
this.el.append(ul);
|
|
5704
|
-
this._indicators = arrLi;
|
|
5705
|
-
}
|
|
5706
|
-
}
|
|
5707
|
-
_removeIndicators() {
|
|
5708
|
-
this.el.querySelector("ul.indicators").remove();
|
|
5709
|
-
}
|
|
5710
|
-
set(index) {
|
|
5711
|
-
if (index >= this._slides.length) index = 0;
|
|
5712
|
-
else if (index < 0) index = this._slides.length - 1;
|
|
5713
|
-
if (this.activeIndex === index) return;
|
|
5714
|
-
this._activeSlide = this._slides[this.activeIndex];
|
|
5715
|
-
const _caption = this._activeSlide.querySelector(".caption");
|
|
5716
|
-
this._activeSlide.classList.remove("active");
|
|
5717
|
-
this._slides.forEach((slide) => slide.style.visibility = "visible");
|
|
5718
|
-
this._activeSlide.style.opacity = "0";
|
|
5719
|
-
setTimeout(() => {
|
|
5720
|
-
this._slides.forEach((slide) => {
|
|
5721
|
-
if (slide.classList.contains("active")) return;
|
|
5722
|
-
slide.style.opacity = "0";
|
|
5723
|
-
slide.style.transform = "translate(0, 0)";
|
|
5724
|
-
slide.style.visibility = "hidden";
|
|
5725
|
-
});
|
|
5726
|
-
}, this.options.duration);
|
|
5727
|
-
if (_caption) _caption.style.opacity = "0";
|
|
5728
|
-
if (this.options.indicators) {
|
|
5729
|
-
const activeIndicator = this._indicators[this.activeIndex].children[0];
|
|
5730
|
-
const nextIndicator = this._indicators[index].children[0];
|
|
5731
|
-
activeIndicator.classList.remove("active");
|
|
5732
|
-
nextIndicator.classList.add("active");
|
|
5733
|
-
if (typeof this.options.indicatorLabelFunc === "function") {
|
|
5734
|
-
activeIndicator.ariaLabel = this.options.indicatorLabelFunc.call(
|
|
5735
|
-
this,
|
|
5736
|
-
this.activeIndex,
|
|
5737
|
-
false
|
|
5738
|
-
);
|
|
5739
|
-
nextIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, index, true);
|
|
5740
|
-
}
|
|
5741
|
-
}
|
|
5742
|
-
this._animateSlide(this._slides[index], true);
|
|
5743
|
-
this._slides[index].classList.add("active");
|
|
5744
|
-
this.activeIndex = index;
|
|
5745
|
-
if (this.interval != null) {
|
|
5746
|
-
this.start();
|
|
5747
|
-
}
|
|
5748
|
-
}
|
|
5749
|
-
_pause(fromEvent) {
|
|
5750
|
-
clearInterval(this.interval);
|
|
5751
|
-
this.eventPause = fromEvent;
|
|
5752
|
-
this.interval = null;
|
|
5753
|
-
}
|
|
5754
|
-
};
|
|
5755
|
-
|
|
5756
6042
|
// src/ts/components/tabs.ts
|
|
5757
|
-
var
|
|
6043
|
+
var _defaults19 = {
|
|
5758
6044
|
duration: 300,
|
|
5759
6045
|
onShow: null,
|
|
5760
6046
|
swipeable: false,
|
|
@@ -5783,12 +6069,10 @@ var Tabs = class _Tabs extends Component {
|
|
|
5783
6069
|
return;
|
|
5784
6070
|
}
|
|
5785
6071
|
if (tabLink.hasAttribute("target")) return;
|
|
5786
|
-
this._activeTabLink.classList.remove("active");
|
|
5787
6072
|
const _oldContent = this._content;
|
|
5788
|
-
this._activeTabLink = tabLink;
|
|
5789
6073
|
if (tabLink.hash) this._content = document.querySelector(tabLink.hash);
|
|
5790
6074
|
this._tabLinks = this._queryTabLinks();
|
|
5791
|
-
this.
|
|
6075
|
+
this._setActiveTabLink(tabLink);
|
|
5792
6076
|
const prevIndex = this._index;
|
|
5793
6077
|
this._index = Math.max(Array.from(this._tabLinks).indexOf(tabLink), 0);
|
|
5794
6078
|
if (this.options.swipeable) {
|
|
@@ -5832,7 +6116,7 @@ var Tabs = class _Tabs extends Component {
|
|
|
5832
6116
|
this._setupEventHandlers();
|
|
5833
6117
|
}
|
|
5834
6118
|
static get defaults() {
|
|
5835
|
-
return
|
|
6119
|
+
return _defaults19;
|
|
5836
6120
|
}
|
|
5837
6121
|
/**
|
|
5838
6122
|
* Initializes instances of Tabs.
|
|
@@ -5883,6 +6167,26 @@ var Tabs = class _Tabs extends Component {
|
|
|
5883
6167
|
this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + "px";
|
|
5884
6168
|
this._indicator.style.right = this._calcRightPos(this._activeTabLink) + "px";
|
|
5885
6169
|
}
|
|
6170
|
+
/**
|
|
6171
|
+
* Which tab is current, for the eye and for assistive technology.
|
|
6172
|
+
*
|
|
6173
|
+
* The class alone is a colour. `aria-current` is the part a screen reader
|
|
6174
|
+
* reads, and because tabs are navigation rather than a tablist (rule 2 -
|
|
6175
|
+
* there is no keyboard model here to back a tablist), "current" is exactly
|
|
6176
|
+
* the right word for it. Its *value* changes as the user clicks, which makes
|
|
6177
|
+
* maintaining it the component's job, not the author's - see CONTEXT.md on
|
|
6178
|
+
* static semantics versus dynamic state. Writing it once in the markup and
|
|
6179
|
+
* never moving it left the old tab announcing itself as current.
|
|
6180
|
+
*/
|
|
6181
|
+
_setActiveTabLink(tabLink) {
|
|
6182
|
+
Array.from(this._tabLinks).forEach((a) => {
|
|
6183
|
+
a.classList.remove("active");
|
|
6184
|
+
a.removeAttribute("aria-current");
|
|
6185
|
+
});
|
|
6186
|
+
this._activeTabLink = tabLink;
|
|
6187
|
+
tabLink.classList.add("active");
|
|
6188
|
+
tabLink.setAttribute("aria-current", "page");
|
|
6189
|
+
}
|
|
5886
6190
|
_setupActiveTabLink() {
|
|
5887
6191
|
this._activeTabLink = Array.from(this._tabLinks).find(
|
|
5888
6192
|
(a) => a.getAttribute("href") === location.hash
|
|
@@ -5894,8 +6198,7 @@ var Tabs = class _Tabs extends Component {
|
|
|
5894
6198
|
}
|
|
5895
6199
|
this._activeTabLink = activeTabLink;
|
|
5896
6200
|
}
|
|
5897
|
-
|
|
5898
|
-
this._activeTabLink.classList.add("active");
|
|
6201
|
+
this._setActiveTabLink(this._activeTabLink);
|
|
5899
6202
|
this._index = Math.max(Array.from(this._tabLinks).indexOf(this._activeTabLink), 0);
|
|
5900
6203
|
if (this._activeTabLink && this._activeTabLink.hash) {
|
|
5901
6204
|
this._content = document.querySelector(this._activeTabLink.hash);
|
|
@@ -6000,7 +6303,7 @@ var Tabs = class _Tabs extends Component {
|
|
|
6000
6303
|
};
|
|
6001
6304
|
|
|
6002
6305
|
// src/ts/components/timepicker.ts
|
|
6003
|
-
var
|
|
6306
|
+
var _defaults20 = {
|
|
6004
6307
|
dialRadius: 135,
|
|
6005
6308
|
outerRadius: 105,
|
|
6006
6309
|
innerRadius: 70,
|
|
@@ -6034,6 +6337,8 @@ var _defaults19 = {
|
|
|
6034
6337
|
var _Timepicker = class _Timepicker extends Component {
|
|
6035
6338
|
constructor(el, options) {
|
|
6036
6339
|
super(el, options, _Timepicker);
|
|
6340
|
+
/** Which pointer is dragging the clock hand; a second finger is ignored. */
|
|
6341
|
+
this._dragPointerId = null;
|
|
6037
6342
|
/** Whether the dial (ticks + SVG + AM/PM buttons) has been built yet. */
|
|
6038
6343
|
this._clockBuilt = false;
|
|
6039
6344
|
this._handleInputClick = () => {
|
|
@@ -6043,7 +6348,7 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6043
6348
|
if (this.displayPlugin) this.displayPlugin.show();
|
|
6044
6349
|
};
|
|
6045
6350
|
this._handleInputKeydown = (e) => {
|
|
6046
|
-
if (Utils.keys.ENTER
|
|
6351
|
+
if (e.key === Utils.keys.ENTER) {
|
|
6047
6352
|
e.preventDefault();
|
|
6048
6353
|
this._ensureClockBuilt();
|
|
6049
6354
|
this.inputHours.focus();
|
|
@@ -6051,13 +6356,9 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6051
6356
|
if (this.displayPlugin) this.displayPlugin.show();
|
|
6052
6357
|
}
|
|
6053
6358
|
};
|
|
6054
|
-
this._handleTimeInputEnterKey = (e) => {
|
|
6055
|
-
if (Utils.keys.ENTER.includes(e.key)) {
|
|
6056
|
-
e.preventDefault();
|
|
6057
|
-
this._inputFromTextField();
|
|
6058
|
-
}
|
|
6059
|
-
};
|
|
6060
6359
|
this._handleClockClickStart = (e) => {
|
|
6360
|
+
if (!e.isPrimary) return;
|
|
6361
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
6061
6362
|
e.preventDefault();
|
|
6062
6363
|
this._ensureClockBuilt();
|
|
6063
6364
|
const clockPlateBR = this.plate.getBoundingClientRect();
|
|
@@ -6065,30 +6366,30 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6065
6366
|
this.x0 = offset.x + this.options.dialRadius;
|
|
6066
6367
|
this.y0 = offset.y + this.options.dialRadius;
|
|
6067
6368
|
this.moved = false;
|
|
6068
|
-
|
|
6069
|
-
this.dx =
|
|
6070
|
-
this.dy =
|
|
6369
|
+
this._dragPointerId = e.pointerId;
|
|
6370
|
+
this.dx = e.clientX - this.x0;
|
|
6371
|
+
this.dy = e.clientY - this.y0;
|
|
6071
6372
|
this.setHand(this.dx, this.dy, false);
|
|
6072
|
-
document.addEventListener("
|
|
6073
|
-
document.addEventListener("
|
|
6074
|
-
document.addEventListener("
|
|
6075
|
-
document.addEventListener("touchend", this._handleDocumentClickEnd);
|
|
6373
|
+
document.addEventListener("pointermove", this._handleDocumentClickMove);
|
|
6374
|
+
document.addEventListener("pointerup", this._handleDocumentClickEnd);
|
|
6375
|
+
document.addEventListener("pointercancel", this._handleDocumentClickCancel);
|
|
6076
6376
|
};
|
|
6077
6377
|
this._handleDocumentClickMove = (e) => {
|
|
6378
|
+
if (e.pointerId !== this._dragPointerId) return;
|
|
6078
6379
|
e.preventDefault();
|
|
6079
|
-
const
|
|
6080
|
-
const
|
|
6081
|
-
const y = clickPos.y - this.y0;
|
|
6380
|
+
const x = e.clientX - this.x0;
|
|
6381
|
+
const y = e.clientY - this.y0;
|
|
6082
6382
|
this.moved = true;
|
|
6083
6383
|
this.setHand(x, y, false);
|
|
6084
6384
|
};
|
|
6085
6385
|
this._handleDocumentClickEnd = (e) => {
|
|
6386
|
+
if (e.pointerId !== this._dragPointerId) return;
|
|
6387
|
+
this._dragPointerId = null;
|
|
6086
6388
|
e.preventDefault();
|
|
6087
|
-
document.removeEventListener("
|
|
6088
|
-
document.removeEventListener("
|
|
6089
|
-
const
|
|
6090
|
-
const
|
|
6091
|
-
const y = clickPos.y - this.y0;
|
|
6389
|
+
document.removeEventListener("pointerup", this._handleDocumentClickEnd);
|
|
6390
|
+
document.removeEventListener("pointercancel", this._handleDocumentClickCancel);
|
|
6391
|
+
const x = e.clientX - this.x0;
|
|
6392
|
+
const y = e.clientY - this.y0;
|
|
6092
6393
|
if (this.moved && x === this.dx && y === this.dy) {
|
|
6093
6394
|
this.setHand(x, y);
|
|
6094
6395
|
}
|
|
@@ -6103,14 +6404,27 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6103
6404
|
if (typeof this.options.onSelect === "function") {
|
|
6104
6405
|
this.options.onSelect.call(this, this.hours, this.minutes);
|
|
6105
6406
|
}
|
|
6106
|
-
document.removeEventListener("
|
|
6107
|
-
|
|
6407
|
+
document.removeEventListener("pointermove", this._handleDocumentClickMove);
|
|
6408
|
+
};
|
|
6409
|
+
/**
|
|
6410
|
+
* A cancelled pointer is not a completed selection. The browser or the OS
|
|
6411
|
+
* took the gesture over, so this only lets go of the drag - it must not run
|
|
6412
|
+
* the pointer-up path, which advances hours to minutes, fires `onSelect`,
|
|
6413
|
+
* and under `autoSubmit` closes the picker on a time the user never chose.
|
|
6414
|
+
*/
|
|
6415
|
+
this._handleDocumentClickCancel = (e) => {
|
|
6416
|
+
if (e.pointerId !== this._dragPointerId) return;
|
|
6417
|
+
this._dragPointerId = null;
|
|
6418
|
+
this.moved = false;
|
|
6419
|
+
document.removeEventListener("pointermove", this._handleDocumentClickMove);
|
|
6420
|
+
document.removeEventListener("pointerup", this._handleDocumentClickEnd);
|
|
6421
|
+
document.removeEventListener("pointercancel", this._handleDocumentClickCancel);
|
|
6108
6422
|
};
|
|
6109
6423
|
this._handleAmPmClick = (e) => {
|
|
6110
6424
|
this._handleAmPmInteraction(e.target);
|
|
6111
6425
|
};
|
|
6112
6426
|
this._handleAmPmKeypress = (e) => {
|
|
6113
|
-
if (Utils.keys.ENTER
|
|
6427
|
+
if (e.key === Utils.keys.ENTER) {
|
|
6114
6428
|
this._handleAmPmInteraction(e.target);
|
|
6115
6429
|
}
|
|
6116
6430
|
};
|
|
@@ -6125,8 +6439,6 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6125
6439
|
*/
|
|
6126
6440
|
this.showView = (view, delay = null) => {
|
|
6127
6441
|
this._ensureClockBuilt();
|
|
6128
|
-
if (view === "minutes" && getComputedStyle(this.hoursView).visibility === "visible") {
|
|
6129
|
-
}
|
|
6130
6442
|
const isHours = view === "hours", nextView = isHours ? this.hoursView : this.minutesView, hideView = isHours ? this.minutesView : this.hoursView;
|
|
6131
6443
|
this.currentView = view;
|
|
6132
6444
|
hideView.classList.add("timepicker-dial-out");
|
|
@@ -6198,7 +6510,7 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6198
6510
|
}
|
|
6199
6511
|
}
|
|
6200
6512
|
static get defaults() {
|
|
6201
|
-
return
|
|
6513
|
+
return _defaults20;
|
|
6202
6514
|
}
|
|
6203
6515
|
/**
|
|
6204
6516
|
* Initializes instances of Timepicker.
|
|
@@ -6215,15 +6527,6 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6215
6527
|
const svgNS = "http://www.w3.org/2000/svg";
|
|
6216
6528
|
return document.createElementNS(svgNS, name);
|
|
6217
6529
|
}
|
|
6218
|
-
static _Pos(e) {
|
|
6219
|
-
if (e.type.startsWith("touch") && e.targetTouches.length >= 1) {
|
|
6220
|
-
return {
|
|
6221
|
-
x: e.targetTouches[0].clientX,
|
|
6222
|
-
y: e.targetTouches[0].clientY
|
|
6223
|
-
};
|
|
6224
|
-
}
|
|
6225
|
-
return { x: e.clientX, y: e.clientY };
|
|
6226
|
-
}
|
|
6227
6530
|
static getInstance(el) {
|
|
6228
6531
|
return el["Expressive_Timepicker"];
|
|
6229
6532
|
}
|
|
@@ -6236,8 +6539,7 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6236
6539
|
_setupEventHandlers() {
|
|
6237
6540
|
this.el.addEventListener("click", this._handleInputClick);
|
|
6238
6541
|
this.el.addEventListener("keydown", this._handleInputKeydown);
|
|
6239
|
-
this.plate.addEventListener("
|
|
6240
|
-
this.plate.addEventListener("touchstart", this._handleClockClickStart);
|
|
6542
|
+
this.plate.addEventListener("pointerdown", this._handleClockClickStart);
|
|
6241
6543
|
this.digitalClock.addEventListener("keyup", this._inputFromTextField);
|
|
6242
6544
|
this.inputHours.addEventListener("focus", () => this.showView("hours"));
|
|
6243
6545
|
this.inputHours.addEventListener("focusout", () => this.formatHours());
|
|
@@ -6247,10 +6549,9 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6247
6549
|
_removeEventHandlers() {
|
|
6248
6550
|
this.el.removeEventListener("click", this._handleInputClick);
|
|
6249
6551
|
this.el.removeEventListener("keydown", this._handleInputKeydown);
|
|
6250
|
-
document.removeEventListener("
|
|
6251
|
-
document.removeEventListener("
|
|
6252
|
-
document.removeEventListener("
|
|
6253
|
-
document.removeEventListener("touchend", this._handleDocumentClickEnd);
|
|
6552
|
+
document.removeEventListener("pointermove", this._handleDocumentClickMove);
|
|
6553
|
+
document.removeEventListener("pointerup", this._handleDocumentClickEnd);
|
|
6554
|
+
document.removeEventListener("pointercancel", this._handleDocumentClickCancel);
|
|
6254
6555
|
}
|
|
6255
6556
|
_insertHTMLIntoDOM() {
|
|
6256
6557
|
const template = document.createElement("template");
|
|
@@ -6279,15 +6580,6 @@ var _Timepicker = class _Timepicker extends Component {
|
|
|
6279
6580
|
this.footer = this.containerEl.querySelector(".timepicker-footer");
|
|
6280
6581
|
this.amOrPm = "PM";
|
|
6281
6582
|
}
|
|
6282
|
-
/*private _createButton(text: string, visibility: string): HTMLButtonElement {
|
|
6283
|
-
const button = document.createElement('button');
|
|
6284
|
-
button.classList.add('waves-effect', 'text');
|
|
6285
|
-
button.style.visibility = visibility;
|
|
6286
|
-
button.type = 'button';
|
|
6287
|
-
button.tabIndex = -1;
|
|
6288
|
-
button.innerText = text;
|
|
6289
|
-
return button;
|
|
6290
|
-
}*/
|
|
6291
6583
|
_pickerSetup() {
|
|
6292
6584
|
Utils.createButton(
|
|
6293
6585
|
this.footer,
|
|
@@ -6568,7 +6860,7 @@ _Timepicker._template = `<div class="timepicker-container">
|
|
|
6568
6860
|
var Timepicker = _Timepicker;
|
|
6569
6861
|
|
|
6570
6862
|
// src/ts/components/snackbar.ts
|
|
6571
|
-
var
|
|
6863
|
+
var _defaults21 = {
|
|
6572
6864
|
text: "",
|
|
6573
6865
|
action: "",
|
|
6574
6866
|
onAction: null,
|
|
@@ -6578,7 +6870,8 @@ var _defaults20 = {
|
|
|
6578
6870
|
outDuration: 375,
|
|
6579
6871
|
classes: "",
|
|
6580
6872
|
completeCallback: null,
|
|
6581
|
-
activationPercent: 0.8
|
|
6873
|
+
activationPercent: 0.8,
|
|
6874
|
+
root: null
|
|
6582
6875
|
};
|
|
6583
6876
|
var _Snackbar = class _Snackbar {
|
|
6584
6877
|
constructor(options = {}) {
|
|
@@ -6601,8 +6894,10 @@ var _Snackbar = class _Snackbar {
|
|
|
6601
6894
|
}
|
|
6602
6895
|
_Snackbar._snackbars.length = 0;
|
|
6603
6896
|
}
|
|
6604
|
-
|
|
6605
|
-
|
|
6897
|
+
const root = Utils.portalRoot(this.options.root ?? document.body);
|
|
6898
|
+
if (!_Snackbar._container || !_Snackbar._container.isConnected || _Snackbar._container.parentNode !== root) {
|
|
6899
|
+
if (_Snackbar._container) _Snackbar._removeContainer();
|
|
6900
|
+
_Snackbar._createContainer(root);
|
|
6606
6901
|
}
|
|
6607
6902
|
_Snackbar._snackbars.push(this);
|
|
6608
6903
|
const snackbarElement = this._createSnackbar();
|
|
@@ -6612,30 +6907,31 @@ var _Snackbar = class _Snackbar {
|
|
|
6612
6907
|
this._setTimer();
|
|
6613
6908
|
}
|
|
6614
6909
|
static get defaults() {
|
|
6615
|
-
return
|
|
6910
|
+
return _defaults21;
|
|
6616
6911
|
}
|
|
6617
6912
|
static getInstance(el) {
|
|
6618
6913
|
return el["Expressive_Snackbar"];
|
|
6619
6914
|
}
|
|
6620
|
-
static _createContainer() {
|
|
6915
|
+
static _createContainer(root = document.body) {
|
|
6621
6916
|
const container = document.createElement("div");
|
|
6622
6917
|
container.setAttribute("id", "snackbar-container");
|
|
6623
|
-
container.addEventListener("
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
document.addEventListener("mouseup", _Snackbar._onDragEnd);
|
|
6629
|
-
document.body.appendChild(container);
|
|
6918
|
+
container.addEventListener("pointerdown", _Snackbar._onDragStart);
|
|
6919
|
+
document.addEventListener("pointermove", _Snackbar._onDragMove);
|
|
6920
|
+
document.addEventListener("pointerup", _Snackbar._onDragEnd);
|
|
6921
|
+
document.addEventListener("pointercancel", _Snackbar._onDragCancel);
|
|
6922
|
+
root.appendChild(container);
|
|
6630
6923
|
_Snackbar._container = container;
|
|
6631
6924
|
}
|
|
6632
6925
|
static _removeContainer() {
|
|
6633
|
-
document.removeEventListener("
|
|
6634
|
-
document.removeEventListener("
|
|
6926
|
+
document.removeEventListener("pointermove", _Snackbar._onDragMove);
|
|
6927
|
+
document.removeEventListener("pointerup", _Snackbar._onDragEnd);
|
|
6928
|
+
document.removeEventListener("pointercancel", _Snackbar._onDragCancel);
|
|
6635
6929
|
_Snackbar._container.remove();
|
|
6636
6930
|
_Snackbar._container = null;
|
|
6637
6931
|
}
|
|
6638
6932
|
static _onDragStart(e) {
|
|
6933
|
+
if (!e.isPrimary) return;
|
|
6934
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
6639
6935
|
const target = e.target;
|
|
6640
6936
|
if (target && !target.closest("button, a") && target.closest(".snackbar")) {
|
|
6641
6937
|
const snackbarElem = target.closest(".snackbar");
|
|
@@ -6646,17 +6942,19 @@ var _Snackbar = class _Snackbar {
|
|
|
6646
6942
|
_Snackbar._draggedSnackbar = snackbar;
|
|
6647
6943
|
snackbar.el.classList.add("panning");
|
|
6648
6944
|
snackbar.el.style.transition = "";
|
|
6649
|
-
|
|
6945
|
+
_Snackbar._dragPointerId = e.pointerId;
|
|
6946
|
+
snackbar.startingXPos = e.clientX;
|
|
6650
6947
|
snackbar.time = Date.now();
|
|
6651
|
-
snackbar.xPos =
|
|
6948
|
+
snackbar.xPos = e.clientX;
|
|
6652
6949
|
}
|
|
6653
6950
|
}
|
|
6654
6951
|
static _onDragMove(e) {
|
|
6952
|
+
if (_Snackbar._dragPointerId !== e.pointerId) return;
|
|
6655
6953
|
if (!!_Snackbar._draggedSnackbar) {
|
|
6656
6954
|
e.preventDefault();
|
|
6657
6955
|
const snackbar = _Snackbar._draggedSnackbar;
|
|
6658
|
-
snackbar.deltaX = Math.abs(snackbar.xPos -
|
|
6659
|
-
snackbar.xPos =
|
|
6956
|
+
snackbar.deltaX = Math.abs(snackbar.xPos - e.clientX);
|
|
6957
|
+
snackbar.xPos = e.clientX;
|
|
6660
6958
|
snackbar.velocityX = snackbar.deltaX / (Date.now() - snackbar.time);
|
|
6661
6959
|
snackbar.time = Date.now();
|
|
6662
6960
|
const totalDeltaX = snackbar.xPos - snackbar.startingXPos;
|
|
@@ -6665,7 +6963,9 @@ var _Snackbar = class _Snackbar {
|
|
|
6665
6963
|
snackbar.el.style.opacity = (1 - Math.abs(totalDeltaX / activationDistance)).toString();
|
|
6666
6964
|
}
|
|
6667
6965
|
}
|
|
6668
|
-
static _onDragEnd() {
|
|
6966
|
+
static _onDragEnd(e) {
|
|
6967
|
+
if (_Snackbar._dragPointerId !== e.pointerId) return;
|
|
6968
|
+
_Snackbar._dragPointerId = null;
|
|
6669
6969
|
if (!!_Snackbar._draggedSnackbar) {
|
|
6670
6970
|
const snackbar = _Snackbar._draggedSnackbar;
|
|
6671
6971
|
snackbar.panning = false;
|
|
@@ -6685,11 +6985,23 @@ var _Snackbar = class _Snackbar {
|
|
|
6685
6985
|
_Snackbar._draggedSnackbar = null;
|
|
6686
6986
|
}
|
|
6687
6987
|
}
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6988
|
+
/**
|
|
6989
|
+
* A cancelled pointer is not a short swipe. Snap back and resume the timer
|
|
6990
|
+
* without consulting the distance travelled - the browser took the gesture
|
|
6991
|
+
* over, so the movement so far says nothing about what the user wanted.
|
|
6992
|
+
*/
|
|
6993
|
+
static _onDragCancel(e) {
|
|
6994
|
+
if (_Snackbar._dragPointerId !== e.pointerId) return;
|
|
6995
|
+
_Snackbar._dragPointerId = null;
|
|
6996
|
+
const snackbar = _Snackbar._draggedSnackbar;
|
|
6997
|
+
if (!snackbar) return;
|
|
6998
|
+
snackbar.panning = false;
|
|
6999
|
+
snackbar.el.classList.remove("panning");
|
|
7000
|
+
snackbar.el.style.transition = "transform .2s, opacity .2s";
|
|
7001
|
+
snackbar.el.style.transform = "";
|
|
7002
|
+
snackbar.el.style.opacity = "";
|
|
7003
|
+
snackbar._resumeTimer();
|
|
7004
|
+
_Snackbar._draggedSnackbar = null;
|
|
6693
7005
|
}
|
|
6694
7006
|
/**
|
|
6695
7007
|
* dismiss all snackbars.
|
|
@@ -6700,7 +7012,7 @@ var _Snackbar = class _Snackbar {
|
|
|
6700
7012
|
}
|
|
6701
7013
|
}
|
|
6702
7014
|
_createSnackbar() {
|
|
6703
|
-
let snackbar = this.options.snackbarId ?
|
|
7015
|
+
let snackbar = this.options.snackbarId ? Utils.getElementById(this.options.root ?? document.body, this.options.snackbarId) : document.createElement("div");
|
|
6704
7016
|
if (snackbar instanceof HTMLTemplateElement) {
|
|
6705
7017
|
const node = snackbar.content.cloneNode(true);
|
|
6706
7018
|
snackbar = node.firstElementChild;
|
|
@@ -6822,13 +7134,15 @@ var _Snackbar = class _Snackbar {
|
|
|
6822
7134
|
}, this.options.outDuration);
|
|
6823
7135
|
}
|
|
6824
7136
|
};
|
|
7137
|
+
/** Which pointer owns the drag in flight; a second finger is ignored. */
|
|
7138
|
+
_Snackbar._dragPointerId = null;
|
|
6825
7139
|
_Snackbar._snackbars = [];
|
|
6826
7140
|
_Snackbar._container = null;
|
|
6827
7141
|
_Snackbar._draggedSnackbar = null;
|
|
6828
7142
|
var Snackbar = _Snackbar;
|
|
6829
7143
|
|
|
6830
7144
|
// src/ts/components/tooltip.ts
|
|
6831
|
-
var
|
|
7145
|
+
var _defaults22 = {
|
|
6832
7146
|
exitDelay: 200,
|
|
6833
7147
|
enterDelay: 0,
|
|
6834
7148
|
text: "",
|
|
@@ -6873,8 +7187,10 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
6873
7187
|
this.isFocused = false;
|
|
6874
7188
|
this.close();
|
|
6875
7189
|
};
|
|
7190
|
+
// Focus opens the tooltip only when it arrived by keyboard: a pointer press
|
|
7191
|
+
// on the trigger also focuses it, and _handleMouseEnter already covers that.
|
|
6876
7192
|
this._handleFocus = () => {
|
|
6877
|
-
if (
|
|
7193
|
+
if (this.el.matches(":focus-visible")) {
|
|
6878
7194
|
this.isFocused = true;
|
|
6879
7195
|
this.open(false);
|
|
6880
7196
|
}
|
|
@@ -6896,7 +7212,7 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
6896
7212
|
this._setupEventHandlers();
|
|
6897
7213
|
}
|
|
6898
7214
|
static get defaults() {
|
|
6899
|
-
return
|
|
7215
|
+
return _defaults22;
|
|
6900
7216
|
}
|
|
6901
7217
|
/**
|
|
6902
7218
|
* Initializes instances of Tooltip.
|
|
@@ -6910,6 +7226,12 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
6910
7226
|
return el["Expressive_Tooltip"];
|
|
6911
7227
|
}
|
|
6912
7228
|
destroy() {
|
|
7229
|
+
clearTimeout(this._enterDelayTimeout);
|
|
7230
|
+
clearTimeout(this._exitDelayTimeout);
|
|
7231
|
+
clearTimeout(this._animationTimeout);
|
|
7232
|
+
this.isOpen = false;
|
|
7233
|
+
this.isHovered = false;
|
|
7234
|
+
this.isFocused = false;
|
|
6913
7235
|
if (this.el.getAttribute("aria-describedby") === this.tooltipEl.id) {
|
|
6914
7236
|
this.el.removeAttribute("aria-describedby");
|
|
6915
7237
|
}
|
|
@@ -6923,7 +7245,7 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
6923
7245
|
this.tooltipEl.id = `tooltip-${Utils.guid()}`;
|
|
6924
7246
|
this.tooltipEl.setAttribute("role", "tooltip");
|
|
6925
7247
|
this.el.setAttribute("aria-describedby", this.tooltipEl.id);
|
|
6926
|
-
const tooltipContentEl = this.options.tooltipId ?
|
|
7248
|
+
const tooltipContentEl = this.options.tooltipId ? Utils.getElementById(this.el, this.options.tooltipId) : document.createElement("div");
|
|
6927
7249
|
if (this.options.tooltipId) {
|
|
6928
7250
|
this.tooltipEl.classList.add("rich");
|
|
6929
7251
|
}
|
|
@@ -6931,7 +7253,7 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
6931
7253
|
tooltipContentEl.classList.add("tooltip-content");
|
|
6932
7254
|
this._setTooltipContent(tooltipContentEl);
|
|
6933
7255
|
this.tooltipEl.appendChild(tooltipContentEl);
|
|
6934
|
-
|
|
7256
|
+
Utils.portalRoot(this.el).appendChild(this.tooltipEl);
|
|
6935
7257
|
}
|
|
6936
7258
|
_setTooltipContent(tooltipContentEl) {
|
|
6937
7259
|
if (this.options.tooltipId) return;
|
|
@@ -7001,32 +7323,15 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
7001
7323
|
tooltip.style.left = newCoordinates.x + "px";
|
|
7002
7324
|
}
|
|
7003
7325
|
_repositionWithinScreen(x, y, width, height) {
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
let newY = y - scrollTop;
|
|
7008
|
-
const bounding = {
|
|
7009
|
-
left: newX,
|
|
7010
|
-
top: newY,
|
|
7326
|
+
return Utils._repositionWithinScreen(
|
|
7327
|
+
x,
|
|
7328
|
+
y,
|
|
7011
7329
|
width,
|
|
7012
|
-
height
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
newX = offset;
|
|
7018
|
-
} else if (edges.right) {
|
|
7019
|
-
newX -= newX + width - window.innerWidth;
|
|
7020
|
-
}
|
|
7021
|
-
if (edges.top) {
|
|
7022
|
-
newY = offset;
|
|
7023
|
-
} else if (edges.bottom) {
|
|
7024
|
-
newY -= newY + height - window.innerHeight;
|
|
7025
|
-
}
|
|
7026
|
-
return {
|
|
7027
|
-
x: newX + scrollLeft,
|
|
7028
|
-
y: newY + scrollTop
|
|
7029
|
-
};
|
|
7330
|
+
height,
|
|
7331
|
+
this.options.margin,
|
|
7332
|
+
this.options.transitionMovement,
|
|
7333
|
+
"center"
|
|
7334
|
+
);
|
|
7030
7335
|
}
|
|
7031
7336
|
_animateIn() {
|
|
7032
7337
|
this._positionTooltip();
|
|
@@ -7035,7 +7340,8 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
7035
7340
|
this.tooltipEl.style.transition = `
|
|
7036
7341
|
transform ${duration}ms ease-out,
|
|
7037
7342
|
opacity ${duration}ms ease-out`;
|
|
7038
|
-
|
|
7343
|
+
clearTimeout(this._animationTimeout);
|
|
7344
|
+
this._animationTimeout = setTimeout(() => {
|
|
7039
7345
|
this.tooltipEl.style.transform = `translateX(${this.xMovement}px) translateY(${this.yMovement}px)`;
|
|
7040
7346
|
this.tooltipEl.style.opacity = (this.options.opacity || 1).toString();
|
|
7041
7347
|
}, 1);
|
|
@@ -7045,7 +7351,8 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
7045
7351
|
this.tooltipEl.style.transition = `
|
|
7046
7352
|
transform ${duration}ms ease-out,
|
|
7047
7353
|
opacity ${duration}ms ease-out`;
|
|
7048
|
-
|
|
7354
|
+
clearTimeout(this._animationTimeout);
|
|
7355
|
+
this._animationTimeout = setTimeout(() => {
|
|
7049
7356
|
this.tooltipEl.style.transform = `translateX(0px) translateY(0px)`;
|
|
7050
7357
|
this.tooltipEl.style.opacity = "0";
|
|
7051
7358
|
}, 1);
|
|
@@ -7070,79 +7377,107 @@ var Tooltip = class _Tooltip extends Component {
|
|
|
7070
7377
|
|
|
7071
7378
|
// src/ts/components/registry.ts
|
|
7072
7379
|
var AUTO_INIT_COMPONENTS = {
|
|
7073
|
-
|
|
7380
|
+
AppBar: {
|
|
7381
|
+
component: AppBar,
|
|
7382
|
+
selector: "header.medium, header.large, header:has(> :is(nav:not(.tabs, .navigation-bar, .navigation-rail), .bar) > :is(.search-bar, .searchbar))"
|
|
7383
|
+
},
|
|
7384
|
+
Autocomplete: {
|
|
7385
|
+
component: Autocomplete,
|
|
7386
|
+
selector: ".autocomplete"
|
|
7387
|
+
},
|
|
7388
|
+
ButtonGroup: {
|
|
7389
|
+
component: ButtonGroup,
|
|
7390
|
+
selector: ".button-group"
|
|
7391
|
+
},
|
|
7074
7392
|
// Shared with Cards.Init() - see CARDS_SELECTOR. This entry used to read
|
|
7075
7393
|
// '.cards', which no card markup uses.
|
|
7076
|
-
Cards: { component: Cards, selector: CARDS_SELECTOR },
|
|
7394
|
+
Cards: { component: Cards, selector: CARDS_SELECTOR, filter: isCardReveal },
|
|
7395
|
+
ExpandingCard: {
|
|
7396
|
+
component: ExpandingCard,
|
|
7397
|
+
selector: EXPANDING_CARD_SELECTOR
|
|
7398
|
+
},
|
|
7077
7399
|
Carousel: { component: Carousel, selector: ".carousel" },
|
|
7078
7400
|
Chips: { component: Chips, selector: ".chips" },
|
|
7079
|
-
Datepicker: {
|
|
7401
|
+
Datepicker: {
|
|
7402
|
+
component: Datepicker,
|
|
7403
|
+
selector: ".datepicker, .date-picker"
|
|
7404
|
+
},
|
|
7080
7405
|
Menu: { component: Menu, selector: ".menu-trigger" },
|
|
7081
7406
|
Lightbox: { component: Lightbox, selector: ".lightboxed" },
|
|
7082
|
-
Parallax: { component: Parallax, selector: ".parallax" },
|
|
7083
7407
|
ScrollSpy: { component: ScrollSpy, selector: ".scrollspy" },
|
|
7084
7408
|
FormSelect: { component: FormSelect, selector: "select" },
|
|
7085
|
-
|
|
7086
|
-
|
|
7409
|
+
NavigationDrawer: {
|
|
7410
|
+
component: NavigationDrawer,
|
|
7411
|
+
selector: ".sidenav, .navigation-drawer"
|
|
7412
|
+
},
|
|
7413
|
+
NavigationRail: {
|
|
7414
|
+
component: NavigationRail,
|
|
7415
|
+
selector: ".navigation-rail"
|
|
7416
|
+
},
|
|
7087
7417
|
Tabs: { component: Tabs, selector: ".tabs" },
|
|
7088
|
-
Timepicker: {
|
|
7418
|
+
Timepicker: {
|
|
7419
|
+
component: Timepicker,
|
|
7420
|
+
selector: ".timepicker, .time-picker"
|
|
7421
|
+
},
|
|
7089
7422
|
Tooltip: { component: Tooltip, selector: ".tooltipped" },
|
|
7090
7423
|
FloatingActionButton: {
|
|
7091
7424
|
component: FloatingActionButton,
|
|
7092
|
-
selector: ".fixed-action-btn"
|
|
7425
|
+
selector: ".fab, .fixed-action-btn, .fab-menu"
|
|
7093
7426
|
}
|
|
7094
7427
|
};
|
|
7095
7428
|
function AutoInit(context = document.body, options) {
|
|
7096
7429
|
for (const name of Object.keys(AUTO_INIT_COMPONENTS)) {
|
|
7097
|
-
const { component, selector } = AUTO_INIT_COMPONENTS[name];
|
|
7430
|
+
const { component, selector, filter } = AUTO_INIT_COMPONENTS[name];
|
|
7098
7431
|
const els = context.querySelectorAll(`:is(${selector}):not(.no-autoinit)`);
|
|
7099
|
-
|
|
7432
|
+
if (filter) {
|
|
7433
|
+
els.forEach((el) => {
|
|
7434
|
+
if (filter(el)) component.init(el, options?.[name] ?? {});
|
|
7435
|
+
});
|
|
7436
|
+
} else {
|
|
7437
|
+
component.init(els, options?.[name] ?? {});
|
|
7438
|
+
}
|
|
7100
7439
|
}
|
|
7101
7440
|
}
|
|
7102
7441
|
|
|
7103
7442
|
// src/ts/index.ts
|
|
7104
|
-
var version = "0.
|
|
7105
|
-
if (typeof document !== "undefined") {
|
|
7106
|
-
document.addEventListener("keydown", Utils.docHandleKeydown, true);
|
|
7107
|
-
document.addEventListener("keyup", Utils.docHandleKeyup, true);
|
|
7108
|
-
document.addEventListener("focus", Utils.docHandleFocus, true);
|
|
7109
|
-
document.addEventListener("blur", Utils.docHandleBlur, true);
|
|
7110
|
-
}
|
|
7443
|
+
var version = "0.9.0";
|
|
7111
7444
|
Forms.Init();
|
|
7112
7445
|
Chips.Init();
|
|
7113
|
-
|
|
7114
|
-
Range.Init();
|
|
7446
|
+
Slider.Init();
|
|
7115
7447
|
Cards.Init();
|
|
7448
|
+
ExpandingCard.Init();
|
|
7116
7449
|
Dialogs.Init();
|
|
7117
7450
|
BottomSheets.Init();
|
|
7118
7451
|
SideSheets.Init();
|
|
7119
7452
|
export {
|
|
7453
|
+
AppBar,
|
|
7120
7454
|
AutoInit,
|
|
7121
7455
|
Autocomplete,
|
|
7122
7456
|
BottomSheets,
|
|
7457
|
+
ButtonGroup,
|
|
7123
7458
|
Cards,
|
|
7124
7459
|
Carousel,
|
|
7125
7460
|
CharacterCounter,
|
|
7126
7461
|
Chips,
|
|
7127
7462
|
Datepicker,
|
|
7128
7463
|
Dialogs,
|
|
7464
|
+
ExpandingCard,
|
|
7129
7465
|
FloatingActionButton,
|
|
7130
7466
|
FormSelect,
|
|
7131
7467
|
Forms,
|
|
7132
7468
|
Lightbox,
|
|
7133
7469
|
Menu,
|
|
7470
|
+
NavigationDrawer,
|
|
7134
7471
|
NavigationRail,
|
|
7135
|
-
|
|
7136
|
-
Range,
|
|
7472
|
+
Slider as Range,
|
|
7137
7473
|
ScrollSpy,
|
|
7138
7474
|
SideSheets,
|
|
7139
|
-
Sidenav,
|
|
7475
|
+
NavigationDrawer as Sidenav,
|
|
7140
7476
|
Slider,
|
|
7141
7477
|
Snackbar,
|
|
7142
7478
|
Tabs,
|
|
7143
7479
|
Timepicker,
|
|
7144
7480
|
Tooltip,
|
|
7145
|
-
Waves,
|
|
7146
7481
|
version
|
|
7147
7482
|
};
|
|
7148
7483
|
//# sourceMappingURL=expressive.mjs.map
|