@expressivecss/expressive 0.7.0-rc.0 → 0.8.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 +1311 -1
- package/README.md +14 -11
- package/dist/css/expressive.css +4215 -1668
- 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/js/expressive.cjs +1231 -1253
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +1231 -1253
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +12 -12
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +1231 -1253
- 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/autocomplete.d.ts +15 -3
- package/dist/types/components/buttons.d.ts +5 -1
- 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 +21 -20
- package/dist/types/components/lightbox.d.ts +1 -0
- package/dist/types/components/menu.d.ts +7 -1
- package/dist/types/components/{sidenav.d.ts → navigationDrawer.d.ts} +16 -16
- package/dist/types/components/registry.d.ts +8 -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 -9
- package/dist/types/core/utils.d.ts +64 -53
- package/dist/types/index.d.ts +8 -9
- package/package.json +15 -1
- package/src/sass/README.md +61 -11
- package/src/sass/abstracts/_breakpoints.scss +17 -19
- package/src/sass/abstracts/_mixins.scss +103 -21
- package/src/sass/abstracts/_variables.scss +50 -5
- 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 +2 -3
- 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 +186 -0
- package/src/sass/components/_buttons.scss +245 -92
- package/src/sass/components/_cards.scss +494 -73
- 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 +260 -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 +194 -0
- package/src/sass/components/_icons-material-design.scss +16 -4
- 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 +71 -24
- package/src/sass/components/_navigation-bar.scss +13 -10
- package/src/sass/components/{_sidenav.scss → _navigation-drawer.scss} +123 -33
- package/src/sass/components/_navigation-rail.scss +22 -22
- 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/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 +0 -1
- package/src/sass/components/forms/{_range.scss → _slider.scss} +8 -9
- package/src/sass/components/forms/_switches.scss +6 -7
- 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.js
CHANGED
|
@@ -29,68 +29,28 @@ var Expressive = (() => {
|
|
|
29
29
|
Chips: () => Chips,
|
|
30
30
|
Datepicker: () => Datepicker,
|
|
31
31
|
Dialogs: () => Dialogs,
|
|
32
|
+
ExpandingCard: () => ExpandingCard,
|
|
32
33
|
FloatingActionButton: () => FloatingActionButton,
|
|
33
34
|
FormSelect: () => FormSelect,
|
|
34
35
|
Forms: () => Forms,
|
|
35
36
|
Lightbox: () => Lightbox,
|
|
36
37
|
Menu: () => Menu,
|
|
38
|
+
NavigationDrawer: () => NavigationDrawer,
|
|
37
39
|
NavigationRail: () => NavigationRail,
|
|
38
|
-
|
|
39
|
-
Range: () => Range,
|
|
40
|
+
Range: () => Slider,
|
|
40
41
|
ScrollSpy: () => ScrollSpy,
|
|
41
42
|
SideSheets: () => SideSheets,
|
|
42
|
-
Sidenav: () =>
|
|
43
|
+
Sidenav: () => NavigationDrawer,
|
|
43
44
|
Slider: () => Slider,
|
|
44
45
|
Snackbar: () => Snackbar,
|
|
45
46
|
Tabs: () => Tabs,
|
|
46
47
|
Timepicker: () => Timepicker,
|
|
47
48
|
Tooltip: () => Tooltip,
|
|
48
|
-
Waves: () => Waves,
|
|
49
49
|
version: () => version
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
// src/ts/core/utils.ts
|
|
53
53
|
var _Utils = class _Utils {
|
|
54
|
-
/**
|
|
55
|
-
* Detects when a key is pressed.
|
|
56
|
-
* @param e Event instance.
|
|
57
|
-
*/
|
|
58
|
-
static docHandleKeydown(e) {
|
|
59
|
-
_Utils.keyDown = true;
|
|
60
|
-
if (_Utils._navigationKeys.has(e.key)) {
|
|
61
|
-
_Utils.tabPressed = true;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Detects when a key is released.
|
|
66
|
-
* @param e Event instance.
|
|
67
|
-
*/
|
|
68
|
-
static docHandleKeyup(e) {
|
|
69
|
-
_Utils.keyDown = false;
|
|
70
|
-
if (_Utils._navigationKeys.has(e.key)) {
|
|
71
|
-
_Utils.tabPressed = false;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Detects when document is focused.
|
|
76
|
-
* @param e Event instance.
|
|
77
|
-
*/
|
|
78
|
-
/* eslint-disabled as of required event type condition check */
|
|
79
|
-
/* eslint-disable-next-line */
|
|
80
|
-
static docHandleFocus(e) {
|
|
81
|
-
if (_Utils.keyDown) {
|
|
82
|
-
document.body.classList.add("keyboard-focused");
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Detects when document is not focused.
|
|
87
|
-
* @param e Event instance.
|
|
88
|
-
*/
|
|
89
|
-
/* eslint-disabled as of required event type condition check */
|
|
90
|
-
/* eslint-disable-next-line */
|
|
91
|
-
static docHandleBlur(e) {
|
|
92
|
-
document.body.classList.remove("keyboard-focused");
|
|
93
|
-
}
|
|
94
54
|
/**
|
|
95
55
|
* Run `callback` once the document is parsed.
|
|
96
56
|
*
|
|
@@ -108,13 +68,46 @@ var Expressive = (() => {
|
|
|
108
68
|
}
|
|
109
69
|
}
|
|
110
70
|
/**
|
|
111
|
-
* Generates a unique string identifier.
|
|
71
|
+
* Generates a unique string identifier. Every caller prefixes the result and
|
|
72
|
+
* uses it as an element id, and a UUID is valid in that position.
|
|
73
|
+
*
|
|
74
|
+
* `randomUUID` is exposed only in secure contexts, and a dev server on a
|
|
75
|
+
* plain-HTTP LAN address - the usual way a page is opened on a phone - is
|
|
76
|
+
* not one. Without the fallback every component that stamps an id would
|
|
77
|
+
* throw there. The ids only have to be unique within one document, so the
|
|
78
|
+
* fallback does not need to be cryptographic.
|
|
112
79
|
*/
|
|
113
80
|
static guid() {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
81
|
+
return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Where an element created at runtime has to be appended to stay in the same
|
|
85
|
+
* tree as `el`. A stylesheet adopted into a shadow root cannot match a node
|
|
86
|
+
* in the document, so a portal that lands on `document.body` is unstyled
|
|
87
|
+
* whenever its origin lives in a shadow root (adr/0002).
|
|
88
|
+
*
|
|
89
|
+
* Light-DOM elements still get `document.body`, which is what escapes an
|
|
90
|
+
* ancestor's `overflow: hidden` and stacking context. Inside a shadow root
|
|
91
|
+
* both hazards come back: the host's own ancestors still form the containing
|
|
92
|
+
* block, so a transformed ancestor re-anchors `position: fixed` and a
|
|
93
|
+
* positioned one re-anchors `position: absolute`.
|
|
94
|
+
*/
|
|
95
|
+
static portalRoot(el) {
|
|
96
|
+
const root = el.getRootNode();
|
|
97
|
+
return root.host ? root : document.body;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* `getElementById` against the tree `el` lives in. The mirror of
|
|
101
|
+
* `portalRoot`: an id in a shadow root is invisible to
|
|
102
|
+
* `document.getElementById`, so a trigger and its target inside the same
|
|
103
|
+
* root could not find each other at all.
|
|
104
|
+
*
|
|
105
|
+
* Falls back to the document for a detached `el`, whose root is a plain
|
|
106
|
+
* element with no lookup of its own.
|
|
107
|
+
*/
|
|
108
|
+
static getElementById(el, id) {
|
|
109
|
+
const root = el.getRootNode();
|
|
110
|
+
return root.getElementById ? root.getElementById(id) : document.getElementById(id);
|
|
118
111
|
}
|
|
119
112
|
/**
|
|
120
113
|
* Checks for exceeded edges
|
|
@@ -211,43 +204,50 @@ var Expressive = (() => {
|
|
|
211
204
|
* Retrieves document scroll postion from top.
|
|
212
205
|
*/
|
|
213
206
|
static getDocumentScrollTop() {
|
|
214
|
-
return window.scrollY
|
|
207
|
+
return window.scrollY;
|
|
215
208
|
}
|
|
216
209
|
/**
|
|
217
210
|
* Retrieves document scroll postion from left.
|
|
218
211
|
*/
|
|
219
212
|
static getDocumentScrollLeft() {
|
|
220
|
-
return window.scrollX
|
|
213
|
+
return window.scrollX;
|
|
221
214
|
}
|
|
222
215
|
/**
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
216
|
+
* Trailing-edge throttle: run `func` now, then at most once per `wait` ms
|
|
217
|
+
* with the most recent arguments.
|
|
218
|
+
*
|
|
219
|
+
* This used to carry its underscore ancestor's whole configuration - leading
|
|
220
|
+
* and trailing switches, a result passthrough - and both call sites are
|
|
221
|
+
* resize handlers passing nothing but a function and a delay.
|
|
222
|
+
*
|
|
223
|
+
* Assign the return value once. `x = Utils.throttle(fn, 200)` is right;
|
|
224
|
+
* wrapping it in an arrow builds a fresh closure per event and never calls
|
|
225
|
+
* it, which is how resize handling was dead in three components.
|
|
227
226
|
*/
|
|
228
|
-
static throttle(func, wait
|
|
229
|
-
let
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
timeout = null;
|
|
233
|
-
result = func(...lastArgs ?? []);
|
|
234
|
-
lastArgs = null;
|
|
235
|
-
};
|
|
227
|
+
static throttle(func, wait) {
|
|
228
|
+
let timeout = null;
|
|
229
|
+
let lastArgs = null;
|
|
230
|
+
let previous = 0;
|
|
236
231
|
return (...args) => {
|
|
237
232
|
const now = Date.now();
|
|
238
|
-
if (!previous && options?.leading === false) previous = now;
|
|
239
233
|
const remaining = wait - (now - previous);
|
|
240
|
-
lastArgs = args;
|
|
241
234
|
if (remaining <= 0) {
|
|
242
235
|
clearTimeout(timeout);
|
|
243
236
|
timeout = null;
|
|
244
237
|
previous = now;
|
|
245
238
|
lastArgs = null;
|
|
246
|
-
|
|
247
|
-
} else if (!timeout
|
|
248
|
-
|
|
239
|
+
func(...args);
|
|
240
|
+
} else if (!timeout) {
|
|
241
|
+
lastArgs = args;
|
|
242
|
+
timeout = setTimeout(() => {
|
|
243
|
+
previous = Date.now();
|
|
244
|
+
timeout = null;
|
|
245
|
+
func(...lastArgs ?? []);
|
|
246
|
+
lastArgs = null;
|
|
247
|
+
}, remaining);
|
|
248
|
+
} else {
|
|
249
|
+
lastArgs = args;
|
|
249
250
|
}
|
|
250
|
-
return result;
|
|
251
251
|
};
|
|
252
252
|
}
|
|
253
253
|
/**
|
|
@@ -264,7 +264,7 @@ var Expressive = (() => {
|
|
|
264
264
|
* Renders a button with optional callback function
|
|
265
265
|
*/
|
|
266
266
|
static createButton(container, text, className = [], visibility = true, callback = null) {
|
|
267
|
-
className = className.concat(["
|
|
267
|
+
className = className.concat(["text"]);
|
|
268
268
|
const button = document.createElement("button");
|
|
269
269
|
button.className = className.join(" ");
|
|
270
270
|
button.style.visibility = visibility ? "visible" : "hidden";
|
|
@@ -274,7 +274,7 @@ var Expressive = (() => {
|
|
|
274
274
|
if (typeof callback === "function") {
|
|
275
275
|
button.addEventListener("click", callback);
|
|
276
276
|
button.addEventListener("keypress", (e) => {
|
|
277
|
-
if (_Utils.keys.ENTER
|
|
277
|
+
if (e.key === _Utils.keys.ENTER) callback(e);
|
|
278
278
|
});
|
|
279
279
|
}
|
|
280
280
|
container.append(button);
|
|
@@ -353,36 +353,22 @@ var Expressive = (() => {
|
|
|
353
353
|
};
|
|
354
354
|
}
|
|
355
355
|
};
|
|
356
|
-
/** Specifies wether tab is pressed or not. */
|
|
357
|
-
_Utils.tabPressed = false;
|
|
358
|
-
/** Specifies wether there is a key pressed. */
|
|
359
|
-
_Utils.keyDown = false;
|
|
360
356
|
/**
|
|
361
|
-
* Key maps.
|
|
357
|
+
* Key maps. One `KeyboardEvent.key` value each: the second entries these used
|
|
358
|
+
* to carry (`Esc`, `Up`, `Del`, ...) were IE and Edge Legacy spellings, and
|
|
359
|
+
* the support baseline excludes both.
|
|
362
360
|
*/
|
|
363
361
|
_Utils.keys = {
|
|
364
|
-
TAB:
|
|
365
|
-
ENTER:
|
|
366
|
-
ESC:
|
|
367
|
-
BACKSPACE:
|
|
368
|
-
ARROW_UP:
|
|
369
|
-
ARROW_DOWN:
|
|
370
|
-
ARROW_LEFT:
|
|
371
|
-
ARROW_RIGHT:
|
|
372
|
-
DELETE:
|
|
362
|
+
TAB: "Tab",
|
|
363
|
+
ENTER: "Enter",
|
|
364
|
+
ESC: "Escape",
|
|
365
|
+
BACKSPACE: "Backspace",
|
|
366
|
+
ARROW_UP: "ArrowUp",
|
|
367
|
+
ARROW_DOWN: "ArrowDown",
|
|
368
|
+
ARROW_LEFT: "ArrowLeft",
|
|
369
|
+
ARROW_RIGHT: "ArrowRight",
|
|
370
|
+
DELETE: "Delete"
|
|
373
371
|
};
|
|
374
|
-
/**
|
|
375
|
-
* Keys that count as keyboard navigation, precomputed.
|
|
376
|
-
*
|
|
377
|
-
* These handlers run at capture phase on the document for every keystroke on
|
|
378
|
-
* the page, and used to rebuild three arrays and spread them into a fourth
|
|
379
|
-
* on each one.
|
|
380
|
-
*/
|
|
381
|
-
_Utils._navigationKeys = /* @__PURE__ */ new Set([
|
|
382
|
-
..._Utils.keys.TAB,
|
|
383
|
-
..._Utils.keys.ARROW_DOWN,
|
|
384
|
-
..._Utils.keys.ARROW_UP
|
|
385
|
-
]);
|
|
386
372
|
var Utils = _Utils;
|
|
387
373
|
|
|
388
374
|
// src/ts/core/component.ts
|
|
@@ -466,13 +452,14 @@ var Expressive = (() => {
|
|
|
466
452
|
this._handleRevealEvent();
|
|
467
453
|
};
|
|
468
454
|
this._handleKeypressEvent = (e) => {
|
|
469
|
-
if (Utils.keys.ENTER
|
|
455
|
+
if (e.key === Utils.keys.ENTER || e.key === " ") {
|
|
456
|
+
e.preventDefault();
|
|
470
457
|
this._handleRevealEvent();
|
|
471
458
|
}
|
|
472
459
|
};
|
|
473
460
|
this._handleRevealEvent = () => {
|
|
474
|
-
this.
|
|
475
|
-
this.open();
|
|
461
|
+
if (this.isOpen) this.close();
|
|
462
|
+
else this.open();
|
|
476
463
|
};
|
|
477
464
|
this._setupRevealCloseEventHandlers = () => {
|
|
478
465
|
this.cardRevealClose.addEventListener("click", this.close);
|
|
@@ -483,7 +470,7 @@ var Expressive = (() => {
|
|
|
483
470
|
this.cardRevealClose.removeEventListener("keypress", this._handleKeypressCloseEvent);
|
|
484
471
|
};
|
|
485
472
|
this._handleKeypressCloseEvent = (e) => {
|
|
486
|
-
if (Utils.keys.ENTER
|
|
473
|
+
if (e.key === Utils.keys.ENTER) {
|
|
487
474
|
this.close();
|
|
488
475
|
}
|
|
489
476
|
};
|
|
@@ -494,6 +481,7 @@ var Expressive = (() => {
|
|
|
494
481
|
if (this.isOpen || !this.cardReveal) return;
|
|
495
482
|
this.isOpen = true;
|
|
496
483
|
this.cardReveal.ariaExpanded = "true";
|
|
484
|
+
this._activators.forEach((el) => el.ariaExpanded = "true");
|
|
497
485
|
if (this.cardRevealClose) this.cardRevealClose.tabIndex = 0;
|
|
498
486
|
if (typeof this.options.onOpen === "function") {
|
|
499
487
|
this.options.onOpen.call(this);
|
|
@@ -507,7 +495,7 @@ var Expressive = (() => {
|
|
|
507
495
|
if (!this.isOpen || !this.cardReveal) return;
|
|
508
496
|
this.isOpen = false;
|
|
509
497
|
this.cardReveal.ariaExpanded = "false";
|
|
510
|
-
this._activators.forEach((el) => el.
|
|
498
|
+
this._activators.forEach((el) => el.ariaExpanded = "false");
|
|
511
499
|
if (this.cardRevealClose) this.cardRevealClose.tabIndex = -1;
|
|
512
500
|
if (typeof this.options.onClose === "function") {
|
|
513
501
|
this.options.onClose.call(this);
|
|
@@ -522,9 +510,18 @@ var Expressive = (() => {
|
|
|
522
510
|
this._activators = [];
|
|
523
511
|
this.cardReveal = this.el.querySelector(":scope > aside");
|
|
524
512
|
if (this.cardReveal) {
|
|
525
|
-
this._activators = Array.from(
|
|
513
|
+
this._activators = Array.from(
|
|
514
|
+
this.el.querySelectorAll(".activator")
|
|
515
|
+
).filter(
|
|
516
|
+
(activator) => !this.cardReveal.contains(activator)
|
|
517
|
+
);
|
|
526
518
|
this._activators.forEach((el2) => {
|
|
527
|
-
if (el2)
|
|
519
|
+
if (!el2) return;
|
|
520
|
+
el2.tabIndex = 0;
|
|
521
|
+
el2.ariaExpanded = "false";
|
|
522
|
+
if (!el2.matches("a[href], button, input, select, textarea")) {
|
|
523
|
+
el2.setAttribute("role", "button");
|
|
524
|
+
}
|
|
528
525
|
});
|
|
529
526
|
this.cardRevealClose = this.cardReveal.querySelector(
|
|
530
527
|
":scope > :is(h1, h2, h3, h4, h5, h6)"
|
|
@@ -567,8 +564,171 @@ var Expressive = (() => {
|
|
|
567
564
|
}
|
|
568
565
|
};
|
|
569
566
|
|
|
570
|
-
// src/ts/components/
|
|
567
|
+
// src/ts/components/expandingCard.ts
|
|
571
568
|
var _defaults2 = {
|
|
569
|
+
onOpen: null,
|
|
570
|
+
onClose: null
|
|
571
|
+
};
|
|
572
|
+
var MOTION_DURATION = 500;
|
|
573
|
+
var EXPANDING_CARD_SELECTOR = "article.expanding-card:has(> dialog.expanding-card-dialog)";
|
|
574
|
+
var ExpandingCard = class _ExpandingCard extends Component {
|
|
575
|
+
constructor(el, options) {
|
|
576
|
+
super(el, options, _ExpandingCard);
|
|
577
|
+
this.isOpen = false;
|
|
578
|
+
this.closeTimer = null;
|
|
579
|
+
this._setupEventHandlers = () => {
|
|
580
|
+
this.trigger?.addEventListener("click", this.open);
|
|
581
|
+
this.trigger?.addEventListener("keypress", this._handleTriggerKeypress);
|
|
582
|
+
this.closeButton?.addEventListener("click", this.close);
|
|
583
|
+
this.dialog?.addEventListener("cancel", this._handleCancel);
|
|
584
|
+
this.dialog?.addEventListener("close", this._handleNativeClose);
|
|
585
|
+
};
|
|
586
|
+
this._removeEventHandlers = () => {
|
|
587
|
+
this.trigger?.removeEventListener("click", this.open);
|
|
588
|
+
this.trigger?.removeEventListener("keypress", this._handleTriggerKeypress);
|
|
589
|
+
this.closeButton?.removeEventListener("click", this.close);
|
|
590
|
+
this.dialog?.removeEventListener("cancel", this._handleCancel);
|
|
591
|
+
this.dialog?.removeEventListener("close", this._handleNativeClose);
|
|
592
|
+
};
|
|
593
|
+
this._handleTriggerKeypress = (event) => {
|
|
594
|
+
if (event.key === Utils.keys.ENTER || event.key === " ") {
|
|
595
|
+
event.preventDefault();
|
|
596
|
+
this.open();
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
this._handleCancel = (event) => {
|
|
600
|
+
event.preventDefault();
|
|
601
|
+
this.close();
|
|
602
|
+
};
|
|
603
|
+
this._handleNativeClose = () => {
|
|
604
|
+
if (!this.isOpen) return;
|
|
605
|
+
this.isOpen = false;
|
|
606
|
+
this.trigger.ariaExpanded = "false";
|
|
607
|
+
this.dialog.ariaExpanded = "false";
|
|
608
|
+
this.dialog.classList.remove("expanded");
|
|
609
|
+
};
|
|
610
|
+
this._setTransitionOrigin = () => {
|
|
611
|
+
if (!this.dialog) return;
|
|
612
|
+
const card = this.el.getBoundingClientRect();
|
|
613
|
+
const media = this.el.querySelector(
|
|
614
|
+
":scope > figure, :scope > img"
|
|
615
|
+
);
|
|
616
|
+
const mediaRect = media?.getBoundingClientRect();
|
|
617
|
+
this.dialog.style.setProperty(
|
|
618
|
+
"--md-comp-expanding-card-from-top",
|
|
619
|
+
`${Math.max(0, card.top)}px`
|
|
620
|
+
);
|
|
621
|
+
this.dialog.style.setProperty(
|
|
622
|
+
"--md-comp-expanding-card-from-right",
|
|
623
|
+
`${Math.max(0, window.innerWidth - card.right)}px`
|
|
624
|
+
);
|
|
625
|
+
this.dialog.style.setProperty(
|
|
626
|
+
"--md-comp-expanding-card-from-bottom",
|
|
627
|
+
`${Math.max(0, window.innerHeight - card.bottom)}px`
|
|
628
|
+
);
|
|
629
|
+
this.dialog.style.setProperty(
|
|
630
|
+
"--md-comp-expanding-card-from-left",
|
|
631
|
+
`${Math.max(0, card.left)}px`
|
|
632
|
+
);
|
|
633
|
+
this.dialog.style.setProperty(
|
|
634
|
+
"--md-comp-expanding-card-from-media-height",
|
|
635
|
+
`${Math.max(0, mediaRect?.height ?? 0)}px`
|
|
636
|
+
);
|
|
637
|
+
};
|
|
638
|
+
this.open = () => {
|
|
639
|
+
if (this.isOpen || !this.dialog || !this.trigger) return;
|
|
640
|
+
if (this.closeTimer !== null) {
|
|
641
|
+
window.clearTimeout(this.closeTimer);
|
|
642
|
+
this.closeTimer = null;
|
|
643
|
+
}
|
|
644
|
+
this._setTransitionOrigin();
|
|
645
|
+
this.isOpen = true;
|
|
646
|
+
this.trigger.ariaExpanded = "true";
|
|
647
|
+
this.dialog.ariaExpanded = "true";
|
|
648
|
+
this.dialog.showModal();
|
|
649
|
+
void this.dialog.offsetWidth;
|
|
650
|
+
this.dialog.classList.add("expanded");
|
|
651
|
+
this.closeButton?.focus();
|
|
652
|
+
if (typeof this.options.onOpen === "function") {
|
|
653
|
+
this.options.onOpen.call(this, this.el);
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
this.close = () => {
|
|
657
|
+
if (!this.isOpen || !this.dialog || !this.trigger) return;
|
|
658
|
+
this._setTransitionOrigin();
|
|
659
|
+
this.isOpen = false;
|
|
660
|
+
this.trigger.ariaExpanded = "false";
|
|
661
|
+
this.dialog.ariaExpanded = "false";
|
|
662
|
+
this.dialog.classList.remove("expanded");
|
|
663
|
+
if (typeof this.options.onClose === "function") {
|
|
664
|
+
this.options.onClose.call(this, this.el);
|
|
665
|
+
}
|
|
666
|
+
const finish = () => {
|
|
667
|
+
this.closeTimer = null;
|
|
668
|
+
if (this.dialog.open) this.dialog.close();
|
|
669
|
+
this.trigger.focus();
|
|
670
|
+
};
|
|
671
|
+
const reducedMotion = window.matchMedia(
|
|
672
|
+
"(prefers-reduced-motion: reduce)"
|
|
673
|
+
).matches;
|
|
674
|
+
if (reducedMotion) finish();
|
|
675
|
+
else this.closeTimer = window.setTimeout(finish, MOTION_DURATION);
|
|
676
|
+
};
|
|
677
|
+
this.el["Expressive_ExpandingCard"] = this;
|
|
678
|
+
this.options = {
|
|
679
|
+
..._ExpandingCard.defaults,
|
|
680
|
+
...options
|
|
681
|
+
};
|
|
682
|
+
this.dialog = this.el.querySelector(
|
|
683
|
+
":scope > dialog.expanding-card-dialog"
|
|
684
|
+
);
|
|
685
|
+
this.trigger = this.el.querySelector(
|
|
686
|
+
":scope > .expanding-card-trigger, :scope > figure > .expanding-card-trigger"
|
|
687
|
+
);
|
|
688
|
+
this.closeButton = this.dialog?.querySelector(".expanding-card-close") ?? null;
|
|
689
|
+
if (this.trigger && this.dialog) {
|
|
690
|
+
this.trigger.ariaExpanded = "false";
|
|
691
|
+
if (this.dialog.id)
|
|
692
|
+
this.trigger.setAttribute("aria-controls", this.dialog.id);
|
|
693
|
+
if (!this.trigger.matches("a[href], button, input, select, textarea")) {
|
|
694
|
+
this.trigger.tabIndex = 0;
|
|
695
|
+
this.trigger.setAttribute("role", "button");
|
|
696
|
+
}
|
|
697
|
+
this.dialog.ariaExpanded = "false";
|
|
698
|
+
this._setupEventHandlers();
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
static get defaults() {
|
|
702
|
+
return _defaults2;
|
|
703
|
+
}
|
|
704
|
+
static init(els, options) {
|
|
705
|
+
return super.init(els, options, _ExpandingCard);
|
|
706
|
+
}
|
|
707
|
+
static getInstance(el) {
|
|
708
|
+
return el["Expressive_ExpandingCard"];
|
|
709
|
+
}
|
|
710
|
+
destroy() {
|
|
711
|
+
this._removeEventHandlers();
|
|
712
|
+
if (this.closeTimer !== null) window.clearTimeout(this.closeTimer);
|
|
713
|
+
this.dialog?.classList.remove("expanded");
|
|
714
|
+
if (this.dialog?.open) this.dialog.close();
|
|
715
|
+
this.el["Expressive_ExpandingCard"] = void 0;
|
|
716
|
+
}
|
|
717
|
+
static Init() {
|
|
718
|
+
Utils.onDocumentReady(() => {
|
|
719
|
+
document.querySelectorAll(EXPANDING_CARD_SELECTOR).forEach((el) => {
|
|
720
|
+
if (el && el["Expressive_ExpandingCard"] == void 0) {
|
|
721
|
+
this.init(el);
|
|
722
|
+
}
|
|
723
|
+
});
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
// src/ts/components/menu.ts
|
|
729
|
+
var MIN_SURFACE_WIDTH = 112;
|
|
730
|
+
var MAX_SURFACE_WIDTH = 280;
|
|
731
|
+
var _defaults3 = {
|
|
572
732
|
alignment: "left",
|
|
573
733
|
autoFocus: true,
|
|
574
734
|
constrainWidth: true,
|
|
@@ -584,6 +744,7 @@ var Expressive = (() => {
|
|
|
584
744
|
onCloseEnd: null,
|
|
585
745
|
onItemClick: null
|
|
586
746
|
};
|
|
747
|
+
var SPACE = " ";
|
|
587
748
|
var _Menu = class _Menu extends Component {
|
|
588
749
|
constructor(el, options) {
|
|
589
750
|
super(el, options, _Menu);
|
|
@@ -629,8 +790,8 @@ var Expressive = (() => {
|
|
|
629
790
|
this.isTouchMoving = false;
|
|
630
791
|
};
|
|
631
792
|
this._handleTriggerKeydown = (e) => {
|
|
632
|
-
const
|
|
633
|
-
if (
|
|
793
|
+
const opensMenu = e.key === SPACE || e.key === Utils.keys.ENTER || e.key === Utils.keys.ARROW_DOWN || e.key === Utils.keys.ARROW_UP;
|
|
794
|
+
if (opensMenu && !this.isOpen) {
|
|
634
795
|
e.preventDefault();
|
|
635
796
|
this.open();
|
|
636
797
|
}
|
|
@@ -644,13 +805,18 @@ var Expressive = (() => {
|
|
|
644
805
|
this._handleMenuClick = (e) => {
|
|
645
806
|
const target = e.target;
|
|
646
807
|
const li = target.closest("li");
|
|
808
|
+
if (li?.matches('.disabled, [aria-disabled="true"]')) {
|
|
809
|
+
e.preventDefault();
|
|
810
|
+
e.stopPropagation();
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
647
813
|
if (li && this._isSubmenuTriggerClick(target)) {
|
|
648
814
|
e.preventDefault();
|
|
649
815
|
e.stopPropagation();
|
|
650
816
|
this._toggleSubmenu(li);
|
|
651
817
|
return;
|
|
652
818
|
}
|
|
653
|
-
if (typeof this.options.onItemClick === "function") {
|
|
819
|
+
if (li && typeof this.options.onItemClick === "function") {
|
|
654
820
|
this.options.onItemClick.call(this, li);
|
|
655
821
|
}
|
|
656
822
|
};
|
|
@@ -663,11 +829,11 @@ var Expressive = (() => {
|
|
|
663
829
|
}
|
|
664
830
|
};
|
|
665
831
|
this._handleMenuKeydown = (e) => {
|
|
666
|
-
const arrowUpOrDown = Utils.keys.ARROW_DOWN
|
|
667
|
-
if (Utils.keys.TAB
|
|
832
|
+
const arrowUpOrDown = e.key === Utils.keys.ARROW_DOWN || e.key === Utils.keys.ARROW_UP;
|
|
833
|
+
if (e.key === Utils.keys.TAB) {
|
|
668
834
|
e.preventDefault();
|
|
669
835
|
this.close();
|
|
670
|
-
} else if (Utils.keys.ARROW_RIGHT
|
|
836
|
+
} else if (e.key === Utils.keys.ARROW_RIGHT && this.isOpen) {
|
|
671
837
|
const li = this._focusedRow(e);
|
|
672
838
|
if (li?.querySelector(":scope > menu")) {
|
|
673
839
|
e.preventDefault();
|
|
@@ -677,7 +843,7 @@ var Expressive = (() => {
|
|
|
677
843
|
const first = li.querySelector(":scope > menu > li");
|
|
678
844
|
first?.focus();
|
|
679
845
|
}
|
|
680
|
-
} else if (Utils.keys.ARROW_LEFT
|
|
846
|
+
} else if (e.key === Utils.keys.ARROW_LEFT && this.isOpen) {
|
|
681
847
|
const submenu = this._containingSubmenu(e);
|
|
682
848
|
if (submenu) {
|
|
683
849
|
e.preventDefault();
|
|
@@ -688,7 +854,7 @@ var Expressive = (() => {
|
|
|
688
854
|
}
|
|
689
855
|
} else if (arrowUpOrDown && this.isOpen) {
|
|
690
856
|
e.preventDefault();
|
|
691
|
-
const direction = Utils.keys.ARROW_DOWN
|
|
857
|
+
const direction = e.key === Utils.keys.ARROW_DOWN ? 1 : -1;
|
|
692
858
|
const list = this._containingSubmenu(e) ?? this.menuEl;
|
|
693
859
|
let newFocusedIndex = this.focusedIndex;
|
|
694
860
|
let hasFoundNewIndex = false;
|
|
@@ -700,17 +866,17 @@ var Expressive = (() => {
|
|
|
700
866
|
}
|
|
701
867
|
} while (newFocusedIndex < list.children.length && newFocusedIndex >= 0);
|
|
702
868
|
if (hasFoundNewIndex) {
|
|
703
|
-
if (this.focusedIndex >= 0)
|
|
704
|
-
list.children[this.focusedIndex]?.classList.remove("active");
|
|
869
|
+
if (this.focusedIndex >= 0) list.children[this.focusedIndex]?.classList.remove("active");
|
|
705
870
|
this.focusedIndex = newFocusedIndex;
|
|
706
871
|
const item = list.children[this.focusedIndex];
|
|
707
872
|
item.classList.add("active");
|
|
708
873
|
item.focus({ preventScroll: true });
|
|
709
874
|
}
|
|
710
|
-
} else if (Utils.keys.ENTER
|
|
875
|
+
} else if ((e.key === Utils.keys.ENTER || e.key === SPACE) && this.isOpen) {
|
|
711
876
|
const li = this._focusedRow(e);
|
|
877
|
+
e.preventDefault();
|
|
878
|
+
if (li?.matches('.disabled, [aria-disabled="true"]')) return;
|
|
712
879
|
if (li?.querySelector(":scope > menu")) {
|
|
713
|
-
e.preventDefault();
|
|
714
880
|
this._toggleSubmenu(li);
|
|
715
881
|
return;
|
|
716
882
|
}
|
|
@@ -721,7 +887,7 @@ var Expressive = (() => {
|
|
|
721
887
|
} else if (focusedElement instanceof HTMLElement) {
|
|
722
888
|
focusedElement.click();
|
|
723
889
|
}
|
|
724
|
-
} else if (Utils.keys.ESC
|
|
890
|
+
} else if (e.key === Utils.keys.ESC && this.isOpen) {
|
|
725
891
|
e.preventDefault();
|
|
726
892
|
const openSub = this.menuEl.querySelector("li.open");
|
|
727
893
|
if (openSub) {
|
|
@@ -735,11 +901,12 @@ var Expressive = (() => {
|
|
|
735
901
|
const keyText = e.key.toLowerCase();
|
|
736
902
|
const isLetter = /[a-zA-Z0-9-_]/.test(keyText);
|
|
737
903
|
const specialKeys = [
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
904
|
+
Utils.keys.ARROW_DOWN,
|
|
905
|
+
Utils.keys.ARROW_UP,
|
|
906
|
+
Utils.keys.ENTER,
|
|
907
|
+
Utils.keys.ESC,
|
|
908
|
+
Utils.keys.TAB,
|
|
909
|
+
SPACE
|
|
743
910
|
];
|
|
744
911
|
if (isLetter && !specialKeys.includes(e.key)) {
|
|
745
912
|
this.filterQuery.push(keyText);
|
|
@@ -810,7 +977,7 @@ var Expressive = (() => {
|
|
|
810
977
|
this.el["Expressive_Menu"] = this;
|
|
811
978
|
_Menu._menus.push(this);
|
|
812
979
|
this.id = Utils.getIdFromTrigger(el);
|
|
813
|
-
this.menuEl =
|
|
980
|
+
this.menuEl = Utils.getElementById(el, this.id);
|
|
814
981
|
this.options = {
|
|
815
982
|
..._Menu.defaults,
|
|
816
983
|
...options
|
|
@@ -821,13 +988,17 @@ var Expressive = (() => {
|
|
|
821
988
|
this.focusedIndex = -1;
|
|
822
989
|
this.filterQuery = [];
|
|
823
990
|
this.el.ariaExpanded = "false";
|
|
991
|
+
if (!this.el.hasAttribute("aria-haspopup")) this.el.setAttribute("aria-haspopup", "menu");
|
|
992
|
+
if (this.id && !this.el.hasAttribute("aria-controls"))
|
|
993
|
+
this.el.setAttribute("aria-controls", this.id);
|
|
824
994
|
this._moveMenuToElement();
|
|
995
|
+
this._setupAccessibility();
|
|
825
996
|
this._makeMenuFocusable();
|
|
826
997
|
this._setupSubmenus();
|
|
827
998
|
this._setupEventHandlers();
|
|
828
999
|
}
|
|
829
1000
|
static get defaults() {
|
|
830
|
-
return
|
|
1001
|
+
return _defaults3;
|
|
831
1002
|
}
|
|
832
1003
|
/**
|
|
833
1004
|
* Initializes instances of Menu.
|
|
@@ -877,7 +1048,9 @@ var Expressive = (() => {
|
|
|
877
1048
|
}
|
|
878
1049
|
_setupTemporaryEventHandlers() {
|
|
879
1050
|
document.body.addEventListener("click", this._handleDocumentClick);
|
|
880
|
-
document.body.addEventListener("touchmove", this._handleDocumentTouchmove, {
|
|
1051
|
+
document.body.addEventListener("touchmove", this._handleDocumentTouchmove, {
|
|
1052
|
+
passive: true
|
|
1053
|
+
});
|
|
881
1054
|
this.menuEl?.addEventListener("keydown", this._handleMenuKeydown);
|
|
882
1055
|
window.addEventListener("resize", this._handleWindowResize);
|
|
883
1056
|
}
|
|
@@ -887,6 +1060,33 @@ var Expressive = (() => {
|
|
|
887
1060
|
this.menuEl?.removeEventListener("keydown", this._handleMenuKeydown);
|
|
888
1061
|
window.removeEventListener("resize", this._handleWindowResize);
|
|
889
1062
|
}
|
|
1063
|
+
_setupAccessibility() {
|
|
1064
|
+
if (!this.menuEl) return;
|
|
1065
|
+
if (!this.menuEl.hasAttribute("role")) this.menuEl.setAttribute("role", "menu");
|
|
1066
|
+
const menus = [this.menuEl, ...this.menuEl.querySelectorAll("menu")];
|
|
1067
|
+
menus.forEach((menu) => {
|
|
1068
|
+
if (!menu.hasAttribute("role")) menu.setAttribute("role", "menu");
|
|
1069
|
+
if (menu.getAttribute("role") !== "menu") return;
|
|
1070
|
+
menu.querySelectorAll(":scope > li").forEach((li) => {
|
|
1071
|
+
if (li.classList.contains("divider")) {
|
|
1072
|
+
if (!li.hasAttribute("role")) li.setAttribute("role", "separator");
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1075
|
+
if (li.classList.contains("gap")) {
|
|
1076
|
+
li.setAttribute("aria-hidden", "true");
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
if (li.classList.contains("label") || li.classList.contains("optgroup")) {
|
|
1080
|
+
if (!li.hasAttribute("role")) li.setAttribute("role", "presentation");
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
if (!li.hasAttribute("role")) li.setAttribute("role", "menuitem");
|
|
1084
|
+
if (li.classList.contains("disabled") && !li.hasAttribute("aria-disabled")) {
|
|
1085
|
+
li.setAttribute("aria-disabled", "true");
|
|
1086
|
+
}
|
|
1087
|
+
});
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
890
1090
|
_isSubmenuTriggerClick(target) {
|
|
891
1091
|
if (!this.menuEl) return false;
|
|
892
1092
|
const li = target.closest("li");
|
|
@@ -973,7 +1173,7 @@ var Expressive = (() => {
|
|
|
973
1173
|
_makeMenuFocusable() {
|
|
974
1174
|
if (!this.menuEl) return;
|
|
975
1175
|
this.menuEl.popover = "";
|
|
976
|
-
this.menuEl.tabIndex =
|
|
1176
|
+
this.menuEl.tabIndex = -1;
|
|
977
1177
|
this.menuEl.querySelectorAll(":scope li, :scope > hr").forEach((el) => {
|
|
978
1178
|
if (el instanceof HTMLHRElement || el.classList.contains("divider") || el.classList.contains("gap") || el.classList.contains("label") || el.classList.contains("optgroup")) {
|
|
979
1179
|
el.setAttribute("tabindex", "-1");
|
|
@@ -982,6 +1182,15 @@ var Expressive = (() => {
|
|
|
982
1182
|
if (!el.getAttribute("tabindex")) el.setAttribute("tabindex", "0");
|
|
983
1183
|
});
|
|
984
1184
|
}
|
|
1185
|
+
_focusInitialItem() {
|
|
1186
|
+
if (!this.menuEl || !this.options.autoFocus) return;
|
|
1187
|
+
const first = Array.from(this.menuEl.children).find(
|
|
1188
|
+
(child) => child instanceof HTMLElement && child.tabIndex !== -1
|
|
1189
|
+
);
|
|
1190
|
+
if (!first) return;
|
|
1191
|
+
this.focusedIndex = Array.from(this.menuEl.children).indexOf(first);
|
|
1192
|
+
first.focus({ preventScroll: true });
|
|
1193
|
+
}
|
|
985
1194
|
_focusFocusedItem() {
|
|
986
1195
|
if (this.focusedIndex >= 0 && this.focusedIndex < this.menuEl.children.length && this.options.autoFocus) {
|
|
987
1196
|
this.menuEl.children[this.focusedIndex].focus({
|
|
@@ -1076,7 +1285,7 @@ var Expressive = (() => {
|
|
|
1076
1285
|
this.menuEl.style.transform = "scale(1)";
|
|
1077
1286
|
}, 1);
|
|
1078
1287
|
setTimeout(() => {
|
|
1079
|
-
|
|
1288
|
+
this._focusInitialItem();
|
|
1080
1289
|
if (typeof this.options.onOpenEnd === "function") this.options.onOpenEnd.call(this, this.el);
|
|
1081
1290
|
}, duration);
|
|
1082
1291
|
}
|
|
@@ -1093,11 +1302,11 @@ var Expressive = (() => {
|
|
|
1093
1302
|
}
|
|
1094
1303
|
_getClosestAncestor(el, condition) {
|
|
1095
1304
|
let ancestor = el.parentNode;
|
|
1096
|
-
while (ancestor !== null && ancestor !== document) {
|
|
1097
|
-
if (condition(ancestor)) {
|
|
1305
|
+
while (ancestor !== null && ancestor !== void 0 && ancestor !== document) {
|
|
1306
|
+
if (ancestor.nodeType === Node.ELEMENT_NODE && condition(ancestor)) {
|
|
1098
1307
|
return ancestor;
|
|
1099
1308
|
}
|
|
1100
|
-
ancestor = ancestor.
|
|
1309
|
+
ancestor = ancestor.parentNode ?? ancestor.host;
|
|
1101
1310
|
}
|
|
1102
1311
|
return null;
|
|
1103
1312
|
}
|
|
@@ -1109,12 +1318,14 @@ var Expressive = (() => {
|
|
|
1109
1318
|
}
|
|
1110
1319
|
);
|
|
1111
1320
|
if (!closestOverflowParent) {
|
|
1112
|
-
|
|
1321
|
+
const parent = !!this.menuEl.offsetParent ? this.menuEl.offsetParent : this.menuEl.parentNode;
|
|
1322
|
+
closestOverflowParent = parent.host ?? parent;
|
|
1113
1323
|
}
|
|
1114
1324
|
if (getComputedStyle(closestOverflowParent).position === "static")
|
|
1115
1325
|
closestOverflowParent.style.position = "relative";
|
|
1116
1326
|
const natural = this.menuEl.getBoundingClientRect().width;
|
|
1117
|
-
const
|
|
1327
|
+
const triggerWidth = this.el.getBoundingClientRect().width;
|
|
1328
|
+
const idealWidth = this.options.constrainWidth && triggerWidth >= MIN_SURFACE_WIDTH ? triggerWidth : Math.min(MAX_SURFACE_WIDTH, Math.max(MIN_SURFACE_WIDTH, natural));
|
|
1118
1329
|
this.menuEl.style.width = idealWidth + "px";
|
|
1119
1330
|
const positionInfo = this._getMenuPosition(closestOverflowParent);
|
|
1120
1331
|
this.menuEl.style.left = positionInfo.x + "px";
|
|
@@ -1128,7 +1339,7 @@ var Expressive = (() => {
|
|
|
1128
1339
|
var Menu = _Menu;
|
|
1129
1340
|
|
|
1130
1341
|
// src/ts/components/autocomplete.ts
|
|
1131
|
-
var
|
|
1342
|
+
var _defaults4 = {
|
|
1132
1343
|
data: [],
|
|
1133
1344
|
// Autocomplete data set
|
|
1134
1345
|
onAutocomplete: null,
|
|
@@ -1158,7 +1369,7 @@ var Expressive = (() => {
|
|
|
1158
1369
|
constructor(el, options) {
|
|
1159
1370
|
super(el, options, _Autocomplete);
|
|
1160
1371
|
this._handleInputBlur = () => {
|
|
1161
|
-
if (!this.
|
|
1372
|
+
if (!this._pointerDown) {
|
|
1162
1373
|
this.close();
|
|
1163
1374
|
this._resetAutocomplete();
|
|
1164
1375
|
}
|
|
@@ -1167,9 +1378,9 @@ var Expressive = (() => {
|
|
|
1167
1378
|
if (e.type === "keyup") _Autocomplete._keydown = false;
|
|
1168
1379
|
this.count = 0;
|
|
1169
1380
|
const actualValue = this.el.value.toLocaleLowerCase();
|
|
1170
|
-
if (Utils.keys.ENTER
|
|
1381
|
+
if (e.key === Utils.keys.ENTER || e.key === Utils.keys.ARROW_UP || e.key === Utils.keys.ARROW_DOWN)
|
|
1171
1382
|
return;
|
|
1172
|
-
if (this.oldVal !== actualValue &&
|
|
1383
|
+
if (this.oldVal !== actualValue && this.el.matches(":focus-visible")) {
|
|
1173
1384
|
this.open();
|
|
1174
1385
|
}
|
|
1175
1386
|
this._inputChangeDetection(actualValue);
|
|
@@ -1193,7 +1404,7 @@ var Expressive = (() => {
|
|
|
1193
1404
|
this._handleInputKeydown = (e) => {
|
|
1194
1405
|
_Autocomplete._keydown = true;
|
|
1195
1406
|
const numItems = this.container.querySelectorAll("li").length;
|
|
1196
|
-
if (Utils.keys.ENTER
|
|
1407
|
+
if (e.key === Utils.keys.ENTER && this.activeIndex >= 0) {
|
|
1197
1408
|
const liElement = this.container.querySelectorAll("li")[this.activeIndex];
|
|
1198
1409
|
if (liElement) {
|
|
1199
1410
|
this.selectOption(liElement.getAttribute("data-id"));
|
|
@@ -1201,15 +1412,14 @@ var Expressive = (() => {
|
|
|
1201
1412
|
}
|
|
1202
1413
|
return;
|
|
1203
1414
|
}
|
|
1204
|
-
if (Utils.keys.ARROW_UP
|
|
1415
|
+
if (e.key === Utils.keys.ARROW_UP || e.key === Utils.keys.ARROW_DOWN) {
|
|
1205
1416
|
e.preventDefault();
|
|
1206
|
-
if (Utils.keys.ARROW_UP
|
|
1207
|
-
if (Utils.keys.ARROW_DOWN
|
|
1417
|
+
if (e.key === Utils.keys.ARROW_UP && this.activeIndex > 0) this.activeIndex--;
|
|
1418
|
+
if (e.key === Utils.keys.ARROW_DOWN && this.activeIndex < numItems - 1)
|
|
1208
1419
|
this.activeIndex++;
|
|
1209
|
-
this
|
|
1420
|
+
this._setActive(null);
|
|
1210
1421
|
if (this.activeIndex >= 0) {
|
|
1211
|
-
this
|
|
1212
|
-
this.$active?.classList.add("active");
|
|
1422
|
+
this._setActive(this.container.querySelectorAll("li")[this.activeIndex]);
|
|
1213
1423
|
this.container.children[this.activeIndex].scrollIntoView({
|
|
1214
1424
|
behavior: "smooth",
|
|
1215
1425
|
block: "nearest",
|
|
@@ -1221,11 +1431,17 @@ var Expressive = (() => {
|
|
|
1221
1431
|
this._handleInputClick = () => {
|
|
1222
1432
|
this.open();
|
|
1223
1433
|
};
|
|
1224
|
-
|
|
1225
|
-
|
|
1434
|
+
// The flag says "a press is in flight inside the option list", so that a blur
|
|
1435
|
+
// caused by that press does not close the list out from under it. Without the
|
|
1436
|
+
// cancel half, a cancelled gesture left the flag set and the next blur could
|
|
1437
|
+
// not close the list at all.
|
|
1438
|
+
this._handleContainerPointerDown = (e) => {
|
|
1439
|
+
if (!e.isPrimary) return;
|
|
1440
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
1441
|
+
this._pointerDown = true;
|
|
1226
1442
|
};
|
|
1227
|
-
this.
|
|
1228
|
-
this.
|
|
1443
|
+
this._handleContainerPointerUp = () => {
|
|
1444
|
+
this._pointerDown = false;
|
|
1229
1445
|
};
|
|
1230
1446
|
/**
|
|
1231
1447
|
* Show autocomplete.
|
|
@@ -1238,7 +1454,9 @@ var Expressive = (() => {
|
|
|
1238
1454
|
this._renderMenu();
|
|
1239
1455
|
}
|
|
1240
1456
|
if (!this.menu.isOpen) {
|
|
1241
|
-
|
|
1457
|
+
if (this._openTimer !== void 0) clearTimeout(this._openTimer);
|
|
1458
|
+
this._openTimer = setTimeout(() => {
|
|
1459
|
+
this._openTimer = void 0;
|
|
1242
1460
|
this.menu.open();
|
|
1243
1461
|
}, 0);
|
|
1244
1462
|
} else this.menu.recalculateDimensions();
|
|
@@ -1261,12 +1479,32 @@ var Expressive = (() => {
|
|
|
1261
1479
|
this.selectedValues = this.selectedValues || this.options.selected.map((value) => ({ id: value })) || [];
|
|
1262
1480
|
this.menuItems = this.options.data || [];
|
|
1263
1481
|
this.$active = null;
|
|
1264
|
-
this.
|
|
1482
|
+
this._pointerDown = false;
|
|
1265
1483
|
this._setupMenu();
|
|
1266
1484
|
this._setupEventHandlers();
|
|
1267
1485
|
}
|
|
1486
|
+
/**
|
|
1487
|
+
* The active entry, for both the eye and the screen reader. The class alone
|
|
1488
|
+
* was invisible to assistive technology; aria-activedescendant on the input
|
|
1489
|
+
* is what reports the move.
|
|
1490
|
+
*
|
|
1491
|
+
* Deliberately does not touch aria-selected. Active and selected are two
|
|
1492
|
+
* different things - in a multi-select the checkboxes track real choices,
|
|
1493
|
+
* and folding the highlight into aria-selected would announce a committed
|
|
1494
|
+
* choice as unselected the moment the user arrowed past it.
|
|
1495
|
+
*/
|
|
1496
|
+
_setActive(item) {
|
|
1497
|
+
this.$active?.classList.remove("active");
|
|
1498
|
+
this.$active = item;
|
|
1499
|
+
if (item) {
|
|
1500
|
+
item.classList.add("active");
|
|
1501
|
+
this.el.setAttribute("aria-activedescendant", item.id);
|
|
1502
|
+
} else {
|
|
1503
|
+
this.el.removeAttribute("aria-activedescendant");
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1268
1506
|
static get defaults() {
|
|
1269
|
-
return
|
|
1507
|
+
return _defaults4;
|
|
1270
1508
|
}
|
|
1271
1509
|
/**
|
|
1272
1510
|
* Initializes instances of Autocomplete.
|
|
@@ -1292,6 +1530,10 @@ var Expressive = (() => {
|
|
|
1292
1530
|
return _Autocomplete._loadingTemplate.cloneNode(true);
|
|
1293
1531
|
}
|
|
1294
1532
|
destroy() {
|
|
1533
|
+
if (this._openTimer !== void 0) {
|
|
1534
|
+
clearTimeout(this._openTimer);
|
|
1535
|
+
this._openTimer = void 0;
|
|
1536
|
+
}
|
|
1295
1537
|
this._removeEventHandlers();
|
|
1296
1538
|
this._removeMenu();
|
|
1297
1539
|
this.el["Expressive_Autocomplete"] = void 0;
|
|
@@ -1302,12 +1544,9 @@ var Expressive = (() => {
|
|
|
1302
1544
|
this.el.addEventListener("focus", this._handleInputFocus);
|
|
1303
1545
|
this.el.addEventListener("keydown", this._handleInputKeydown);
|
|
1304
1546
|
this.el.addEventListener("click", this._handleInputClick);
|
|
1305
|
-
this.container.addEventListener("
|
|
1306
|
-
this.container.addEventListener("
|
|
1307
|
-
|
|
1308
|
-
this.container.addEventListener("touchstart", this._handleContainerMousedownAndTouchstart);
|
|
1309
|
-
this.container.addEventListener("touchend", this._handleContainerMouseupAndTouchend);
|
|
1310
|
-
}
|
|
1547
|
+
this.container.addEventListener("pointerdown", this._handleContainerPointerDown);
|
|
1548
|
+
this.container.addEventListener("pointerup", this._handleContainerPointerUp);
|
|
1549
|
+
this.container.addEventListener("pointercancel", this._handleContainerPointerUp);
|
|
1311
1550
|
}
|
|
1312
1551
|
_removeEventHandlers() {
|
|
1313
1552
|
this.el.removeEventListener("blur", this._handleInputBlur);
|
|
@@ -1315,12 +1554,9 @@ var Expressive = (() => {
|
|
|
1315
1554
|
this.el.removeEventListener("focus", this._handleInputFocus);
|
|
1316
1555
|
this.el.removeEventListener("keydown", this._handleInputKeydown);
|
|
1317
1556
|
this.el.removeEventListener("click", this._handleInputClick);
|
|
1318
|
-
this.container.removeEventListener("
|
|
1319
|
-
this.container.removeEventListener("
|
|
1320
|
-
|
|
1321
|
-
this.container.removeEventListener("touchstart", this._handleContainerMousedownAndTouchstart);
|
|
1322
|
-
this.container.removeEventListener("touchend", this._handleContainerMouseupAndTouchend);
|
|
1323
|
-
}
|
|
1557
|
+
this.container.removeEventListener("pointerdown", this._handleContainerPointerDown);
|
|
1558
|
+
this.container.removeEventListener("pointerup", this._handleContainerPointerUp);
|
|
1559
|
+
this.container.removeEventListener("pointercancel", this._handleContainerPointerUp);
|
|
1324
1560
|
}
|
|
1325
1561
|
_setupMenu() {
|
|
1326
1562
|
this.container = document.createElement("menu");
|
|
@@ -1328,6 +1564,10 @@ var Expressive = (() => {
|
|
|
1328
1564
|
this.container.id = `autocomplete-options-${Utils.guid()}`;
|
|
1329
1565
|
this.container.classList.add("autocomplete-content");
|
|
1330
1566
|
this.container.ariaExpanded = "true";
|
|
1567
|
+
this.container.setAttribute("role", "listbox");
|
|
1568
|
+
this.el.setAttribute("role", "combobox");
|
|
1569
|
+
this.el.setAttribute("aria-autocomplete", "list");
|
|
1570
|
+
this.el.setAttribute("aria-controls", this.container.id);
|
|
1331
1571
|
this.el.setAttribute("data-target", this.container.id);
|
|
1332
1572
|
this.menuItems.forEach((menuItem) => {
|
|
1333
1573
|
const itemElement = this._createMenuItem(menuItem);
|
|
@@ -1366,14 +1606,14 @@ var Expressive = (() => {
|
|
|
1366
1606
|
}
|
|
1367
1607
|
_resetCurrentElementPosition() {
|
|
1368
1608
|
this.activeIndex = -1;
|
|
1369
|
-
this
|
|
1609
|
+
this._setActive(null);
|
|
1370
1610
|
}
|
|
1371
1611
|
_resetAutocomplete() {
|
|
1372
1612
|
this.container.replaceChildren();
|
|
1373
1613
|
this._resetCurrentElementPosition();
|
|
1374
1614
|
this.oldVal = null;
|
|
1375
1615
|
this.isOpen = false;
|
|
1376
|
-
this.
|
|
1616
|
+
this._pointerDown = false;
|
|
1377
1617
|
}
|
|
1378
1618
|
_highlightPartialText(input, label) {
|
|
1379
1619
|
const start = label.toLocaleLowerCase().indexOf("" + input.toLocaleLowerCase());
|
|
@@ -1385,6 +1625,10 @@ var Expressive = (() => {
|
|
|
1385
1625
|
}
|
|
1386
1626
|
_createMenuItem(entry) {
|
|
1387
1627
|
const item = document.createElement("li");
|
|
1628
|
+
item.id = `autocomplete-option-${Utils.guid()}`;
|
|
1629
|
+
item.setAttribute("role", "option");
|
|
1630
|
+
const isSelected = this.selectedValues.some((sel) => sel.id === entry.id);
|
|
1631
|
+
item.setAttribute("aria-selected", isSelected ? "true" : "false");
|
|
1388
1632
|
item.setAttribute("data-id", entry.id);
|
|
1389
1633
|
item.setAttribute(
|
|
1390
1634
|
"style",
|
|
@@ -1397,7 +1641,7 @@ var Expressive = (() => {
|
|
|
1397
1641
|
selection.style.textAlign = "center";
|
|
1398
1642
|
const checkbox = document.createElement("input");
|
|
1399
1643
|
checkbox.type = "checkbox";
|
|
1400
|
-
checkbox.checked =
|
|
1644
|
+
checkbox.checked = isSelected;
|
|
1401
1645
|
const spacer = document.createElement("span");
|
|
1402
1646
|
spacer.style.paddingLeft = "21px";
|
|
1403
1647
|
selection.append(checkbox, spacer);
|
|
@@ -1543,7 +1787,7 @@ var Expressive = (() => {
|
|
|
1543
1787
|
var Autocomplete = _Autocomplete;
|
|
1544
1788
|
|
|
1545
1789
|
// src/ts/components/chips.ts
|
|
1546
|
-
var
|
|
1790
|
+
var _defaults5 = {
|
|
1547
1791
|
data: [],
|
|
1548
1792
|
placeholder: "",
|
|
1549
1793
|
secondaryPlaceholder: "",
|
|
@@ -1552,6 +1796,7 @@ var Expressive = (() => {
|
|
|
1552
1796
|
autocompleteOnly: false,
|
|
1553
1797
|
limit: Infinity,
|
|
1554
1798
|
allowUserInput: false,
|
|
1799
|
+
i18n: { remove: "Remove" },
|
|
1555
1800
|
onChipAdd: null,
|
|
1556
1801
|
onChipSelect: null,
|
|
1557
1802
|
onChipDelete: null
|
|
@@ -1561,7 +1806,7 @@ var Expressive = (() => {
|
|
|
1561
1806
|
super(el, options, _Chips);
|
|
1562
1807
|
this._handleChipClick = (e) => {
|
|
1563
1808
|
const _chip = e.target.closest(".chip");
|
|
1564
|
-
const clickedClose = e.target.
|
|
1809
|
+
const clickedClose = !!e.target.closest(".close");
|
|
1565
1810
|
if (_chip) {
|
|
1566
1811
|
const index = this._chips.indexOf(_chip);
|
|
1567
1812
|
if (index < 0) return;
|
|
@@ -1583,7 +1828,7 @@ var Expressive = (() => {
|
|
|
1583
1828
|
};
|
|
1584
1829
|
this._handleInputKeydown = (e) => {
|
|
1585
1830
|
_Chips._keydown = true;
|
|
1586
|
-
if (Utils.keys.ENTER
|
|
1831
|
+
if (e.key === Utils.keys.ENTER) {
|
|
1587
1832
|
if (this.hasAutocomplete && this.autocomplete && this.autocomplete.isOpen) {
|
|
1588
1833
|
return;
|
|
1589
1834
|
}
|
|
@@ -1592,7 +1837,7 @@ var Expressive = (() => {
|
|
|
1592
1837
|
this.addChip({ id: this._input.value });
|
|
1593
1838
|
}
|
|
1594
1839
|
this._input.value = "";
|
|
1595
|
-
} else if ((Utils.keys.BACKSPACE
|
|
1840
|
+
} else if ((e.key === Utils.keys.BACKSPACE || e.key === Utils.keys.ARROW_LEFT) && this._input.value === "" && this.chipsData.length) {
|
|
1596
1841
|
e.preventDefault();
|
|
1597
1842
|
this.selectChip(this.chipsData.length - 1);
|
|
1598
1843
|
}
|
|
@@ -1602,6 +1847,7 @@ var Expressive = (() => {
|
|
|
1602
1847
|
..._Chips.defaults,
|
|
1603
1848
|
...options
|
|
1604
1849
|
};
|
|
1850
|
+
if (options?.i18n) this.options.i18n = { ..._Chips.defaults.i18n, ...options.i18n };
|
|
1605
1851
|
this.el.classList.add("chips");
|
|
1606
1852
|
this.chipsData = [];
|
|
1607
1853
|
this._chips = [];
|
|
@@ -1617,8 +1863,22 @@ var Expressive = (() => {
|
|
|
1617
1863
|
}
|
|
1618
1864
|
this._setupLabel();
|
|
1619
1865
|
}
|
|
1866
|
+
/**
|
|
1867
|
+
* Selection is drawn by a class now, not by `:focus`, so it does not clear
|
|
1868
|
+
* itself when focus moves - every path that changes the selection has to go
|
|
1869
|
+
* through here or the class and the field drift apart.
|
|
1870
|
+
*
|
|
1871
|
+
* Deliberately no `aria-selected`: the chip is not an option in a listbox,
|
|
1872
|
+
* and putting the attribute on an element with no such role is the same
|
|
1873
|
+
* defect the semantics standard exists to remove.
|
|
1874
|
+
*/
|
|
1875
|
+
_setSelected(chip) {
|
|
1876
|
+
this._selectedChip?.classList.remove("selected");
|
|
1877
|
+
this._selectedChip = chip;
|
|
1878
|
+
chip?.classList.add("selected");
|
|
1879
|
+
}
|
|
1620
1880
|
static get defaults() {
|
|
1621
|
-
return
|
|
1881
|
+
return _defaults5;
|
|
1622
1882
|
}
|
|
1623
1883
|
/**
|
|
1624
1884
|
* Initializes instances of Chips.
|
|
@@ -1668,28 +1928,30 @@ var Expressive = (() => {
|
|
|
1668
1928
|
if (tag === "INPUT" || tag === "TEXTAREA" || !chipsKeydown) return;
|
|
1669
1929
|
const currChips = chips["Expressive_Chips"];
|
|
1670
1930
|
if (!currChips) return;
|
|
1671
|
-
if (Utils.keys.BACKSPACE
|
|
1931
|
+
if (e.key === Utils.keys.BACKSPACE || e.key === Utils.keys.DELETE) {
|
|
1672
1932
|
e.preventDefault();
|
|
1673
1933
|
let selectIndex = currChips.chipsData.length;
|
|
1674
1934
|
if (currChips._selectedChip) {
|
|
1675
1935
|
const index = currChips._chips.indexOf(currChips._selectedChip);
|
|
1676
1936
|
currChips.deleteChip(index);
|
|
1677
|
-
currChips.
|
|
1937
|
+
currChips._setSelected(null);
|
|
1678
1938
|
selectIndex = Math.max(index - 1, 0);
|
|
1679
1939
|
}
|
|
1680
1940
|
if (currChips.chipsData.length) currChips.selectChip(selectIndex);
|
|
1681
1941
|
else currChips._input.focus();
|
|
1682
|
-
} else if (Utils.keys.ARROW_LEFT
|
|
1942
|
+
} else if (e.key === Utils.keys.ARROW_LEFT) {
|
|
1683
1943
|
if (currChips._selectedChip) {
|
|
1684
1944
|
const selectIndex = currChips._chips.indexOf(currChips._selectedChip) - 1;
|
|
1685
1945
|
if (selectIndex < 0) return;
|
|
1686
1946
|
currChips.selectChip(selectIndex);
|
|
1687
1947
|
}
|
|
1688
|
-
} else if (Utils.keys.ARROW_RIGHT
|
|
1948
|
+
} else if (e.key === Utils.keys.ARROW_RIGHT) {
|
|
1689
1949
|
if (currChips._selectedChip) {
|
|
1690
1950
|
const selectIndex = currChips._chips.indexOf(currChips._selectedChip) + 1;
|
|
1691
|
-
if (selectIndex >= currChips.chipsData.length)
|
|
1692
|
-
|
|
1951
|
+
if (selectIndex >= currChips.chipsData.length) {
|
|
1952
|
+
currChips._setSelected(null);
|
|
1953
|
+
currChips._input.focus();
|
|
1954
|
+
} else currChips.selectChip(selectIndex);
|
|
1693
1955
|
}
|
|
1694
1956
|
}
|
|
1695
1957
|
}
|
|
@@ -1700,25 +1962,31 @@ var Expressive = (() => {
|
|
|
1700
1962
|
if (!_Chips._keydown && document.hidden) {
|
|
1701
1963
|
const chips = e.target.closest(".chips");
|
|
1702
1964
|
const currChips = chips?.["Expressive_Chips"];
|
|
1703
|
-
if (currChips) currChips.
|
|
1965
|
+
if (currChips) currChips._setSelected(null);
|
|
1704
1966
|
}
|
|
1705
1967
|
}
|
|
1706
1968
|
_renderChip(chip) {
|
|
1707
1969
|
if (!chip.id) return;
|
|
1708
|
-
const
|
|
1970
|
+
const label = chip.text || chip.id;
|
|
1971
|
+
const renderedChip = document.createElement("span");
|
|
1709
1972
|
renderedChip.classList.add("chip");
|
|
1710
|
-
renderedChip.innerText =
|
|
1973
|
+
renderedChip.innerText = label;
|
|
1711
1974
|
if (chip.image) {
|
|
1712
1975
|
const img = document.createElement("img");
|
|
1713
1976
|
img.setAttribute("src", chip.image);
|
|
1714
1977
|
renderedChip.insertBefore(img, renderedChip.firstChild);
|
|
1715
1978
|
}
|
|
1716
1979
|
if (this.options.allowUserInput) {
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1980
|
+
const closeButton = document.createElement("button");
|
|
1981
|
+
closeButton.type = "button";
|
|
1982
|
+
closeButton.classList.add("close");
|
|
1983
|
+
closeButton.setAttribute("aria-label", `${this.options.i18n.remove} ${label}`);
|
|
1984
|
+
const closeIcon = document.createElement("span");
|
|
1985
|
+
closeIcon.classList.add(this.options.closeIconClass);
|
|
1986
|
+
closeIcon.setAttribute("aria-hidden", "true");
|
|
1720
1987
|
closeIcon.innerText = "close";
|
|
1721
|
-
|
|
1988
|
+
closeButton.appendChild(closeIcon);
|
|
1989
|
+
renderedChip.appendChild(closeButton);
|
|
1722
1990
|
}
|
|
1723
1991
|
return renderedChip;
|
|
1724
1992
|
}
|
|
@@ -1793,6 +2061,7 @@ var Expressive = (() => {
|
|
|
1793
2061
|
deleteChip(chipIndex) {
|
|
1794
2062
|
const chip = this._chips[chipIndex];
|
|
1795
2063
|
if (!chip) return;
|
|
2064
|
+
if (this._selectedChip === chip) this._setSelected(null);
|
|
1796
2065
|
chip.remove();
|
|
1797
2066
|
this._chips.splice(chipIndex, 1);
|
|
1798
2067
|
this.chipsData.splice(chipIndex, 1);
|
|
@@ -1808,8 +2077,8 @@ var Expressive = (() => {
|
|
|
1808
2077
|
selectChip(chipIndex) {
|
|
1809
2078
|
const chip = this._chips[chipIndex];
|
|
1810
2079
|
if (!chip) return;
|
|
1811
|
-
this.
|
|
1812
|
-
chip.focus();
|
|
2080
|
+
this._setSelected(chip);
|
|
2081
|
+
chip.querySelector(".close")?.focus();
|
|
1813
2082
|
if (typeof this.options.onChipSelect === "function") {
|
|
1814
2083
|
this.options.onChipSelect(this.el, chip);
|
|
1815
2084
|
}
|
|
@@ -1820,7 +2089,7 @@ var Expressive = (() => {
|
|
|
1820
2089
|
chips.forEach((el) => {
|
|
1821
2090
|
el.addEventListener("click", (e) => {
|
|
1822
2091
|
if (el["Expressive_Chips"]) return;
|
|
1823
|
-
if (e.target.
|
|
2092
|
+
if (e.target.closest(".close")) {
|
|
1824
2093
|
const chip = e.target.closest(".chip");
|
|
1825
2094
|
if (chip) chip.remove();
|
|
1826
2095
|
}
|
|
@@ -1832,97 +2101,93 @@ var Expressive = (() => {
|
|
|
1832
2101
|
_Chips._keydown = false;
|
|
1833
2102
|
var Chips = _Chips;
|
|
1834
2103
|
|
|
1835
|
-
// src/ts/components/
|
|
1836
|
-
var
|
|
1837
|
-
var
|
|
2104
|
+
// src/ts/components/slider.ts
|
|
2105
|
+
var _defaults6 = {};
|
|
2106
|
+
var Slider = class _Slider extends Component {
|
|
1838
2107
|
constructor(el, options) {
|
|
1839
|
-
super(el, options,
|
|
2108
|
+
super(el, options, _Slider);
|
|
1840
2109
|
this._handleRangeChange = () => {
|
|
1841
2110
|
this._clampDual();
|
|
1842
2111
|
this._sync();
|
|
1843
2112
|
this.thumb.classList.add("active");
|
|
1844
2113
|
};
|
|
1845
|
-
this.
|
|
1846
|
-
|
|
2114
|
+
this._handleRangePointerDown = (e) => {
|
|
2115
|
+
if (!e.isPrimary) return;
|
|
2116
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
2117
|
+
this._pointerDown = true;
|
|
1847
2118
|
this.el.classList.add("active");
|
|
1848
2119
|
this._clampDual();
|
|
1849
2120
|
this._sync();
|
|
1850
|
-
|
|
1851
|
-
this.thumb.classList.add("active");
|
|
1852
|
-
}
|
|
2121
|
+
this.thumb.classList.add("active");
|
|
1853
2122
|
};
|
|
1854
|
-
this.
|
|
1855
|
-
if (this.
|
|
2123
|
+
this._handleRangeInputOrMove = () => {
|
|
2124
|
+
if (this._pointerDown) {
|
|
1856
2125
|
this._clampDual();
|
|
1857
2126
|
this._sync();
|
|
1858
2127
|
this.thumb.classList.add("active");
|
|
1859
2128
|
}
|
|
1860
2129
|
};
|
|
1861
|
-
this.
|
|
1862
|
-
|
|
2130
|
+
this._handleRangePointerUp = (e) => {
|
|
2131
|
+
if (!e.isPrimary) return;
|
|
2132
|
+
this._pointerDown = false;
|
|
1863
2133
|
this.el.classList.remove("active");
|
|
1864
2134
|
};
|
|
1865
|
-
this.
|
|
1866
|
-
if (!this.
|
|
2135
|
+
this._handleRangeRelease = () => {
|
|
2136
|
+
if (!this._pointerDown) {
|
|
1867
2137
|
this.thumb.classList.remove("active");
|
|
1868
2138
|
}
|
|
1869
2139
|
};
|
|
1870
|
-
this.el["
|
|
2140
|
+
this.el["Expressive_Slider"] = this;
|
|
1871
2141
|
this.options = {
|
|
1872
|
-
...
|
|
2142
|
+
..._Slider.defaults,
|
|
1873
2143
|
...options
|
|
1874
2144
|
};
|
|
1875
|
-
this.
|
|
2145
|
+
this._pointerDown = false;
|
|
1876
2146
|
this._setupThumb();
|
|
1877
2147
|
this._sync();
|
|
1878
2148
|
this._setupEventHandlers();
|
|
1879
2149
|
}
|
|
1880
2150
|
static get defaults() {
|
|
1881
|
-
return
|
|
2151
|
+
return _defaults6;
|
|
1882
2152
|
}
|
|
1883
2153
|
/**
|
|
1884
|
-
* Initializes instances of
|
|
2154
|
+
* Initializes instances of Slider.
|
|
1885
2155
|
* @param els HTML elements.
|
|
1886
2156
|
* @param options Component options.
|
|
1887
2157
|
*/
|
|
1888
2158
|
static init(els, options = {}) {
|
|
1889
|
-
return super.init(els, options,
|
|
2159
|
+
return super.init(els, options, _Slider);
|
|
1890
2160
|
}
|
|
1891
2161
|
static getInstance(el) {
|
|
1892
|
-
return el["
|
|
2162
|
+
return el["Expressive_Slider"];
|
|
1893
2163
|
}
|
|
1894
2164
|
destroy() {
|
|
1895
2165
|
this._removeEventHandlers();
|
|
1896
2166
|
this._removeThumb();
|
|
1897
|
-
this.el["
|
|
2167
|
+
this.el["Expressive_Slider"] = void 0;
|
|
1898
2168
|
}
|
|
2169
|
+
// Eleven listeners used to cover four stages, because each one was written
|
|
2170
|
+
// twice - once for mouse, once for touch. One of the touch spellings,
|
|
2171
|
+
// `touchleave`, was never implemented by any browser at all.
|
|
1899
2172
|
_setupEventHandlers() {
|
|
1900
2173
|
this.el.addEventListener("change", this._handleRangeChange);
|
|
1901
|
-
this.el.addEventListener("
|
|
1902
|
-
this.el.addEventListener("
|
|
1903
|
-
this.el.addEventListener("
|
|
1904
|
-
this.el.addEventListener("
|
|
1905
|
-
this.el.addEventListener("
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
this.el.addEventListener("mouseup", this._handleRangeMouseupTouchend);
|
|
1909
|
-
this.el.addEventListener("touchend", this._handleRangeMouseupTouchend);
|
|
1910
|
-
this.el.addEventListener("blur", this._handleRangeBlurMouseoutTouchleave);
|
|
1911
|
-
this.el.addEventListener("mouseout", this._handleRangeBlurMouseoutTouchleave);
|
|
1912
|
-
this.el.addEventListener("touchleave", this._handleRangeBlurMouseoutTouchleave);
|
|
2174
|
+
this.el.addEventListener("pointerdown", this._handleRangePointerDown);
|
|
2175
|
+
this.el.addEventListener("input", this._handleRangeInputOrMove);
|
|
2176
|
+
this.el.addEventListener("pointermove", this._handleRangeInputOrMove, { passive: true });
|
|
2177
|
+
this.el.addEventListener("pointerup", this._handleRangePointerUp);
|
|
2178
|
+
this.el.addEventListener("pointercancel", this._handleRangePointerUp);
|
|
2179
|
+
this.el.addEventListener("blur", this._handleRangeRelease);
|
|
2180
|
+
this.el.addEventListener("mouseout", this._handleRangeRelease);
|
|
1913
2181
|
}
|
|
1914
2182
|
_removeEventHandlers() {
|
|
1915
2183
|
this.el.removeEventListener("change", this._handleRangeChange);
|
|
1916
|
-
this.el.removeEventListener("
|
|
1917
|
-
this.el.removeEventListener("
|
|
1918
|
-
this.el.removeEventListener("
|
|
1919
|
-
this.el.removeEventListener("
|
|
1920
|
-
this.el.removeEventListener("
|
|
1921
|
-
this.el.removeEventListener("
|
|
1922
|
-
this.el.removeEventListener("
|
|
1923
|
-
this.el.removeEventListener("blur", this._handleRangeBlurMouseoutTouchleave);
|
|
1924
|
-
this.el.removeEventListener("mouseout", this._handleRangeBlurMouseoutTouchleave);
|
|
1925
|
-
this.el.removeEventListener("touchleave", this._handleRangeBlurMouseoutTouchleave);
|
|
2184
|
+
this.el.removeEventListener("pointerdown", this._handleRangePointerDown);
|
|
2185
|
+
this.el.removeEventListener("input", this._handleRangeInputOrMove);
|
|
2186
|
+
this.el.removeEventListener("pointermove", this._handleRangeInputOrMove);
|
|
2187
|
+
this.el.removeEventListener("pointerup", this._handleRangePointerUp);
|
|
2188
|
+
this.el.removeEventListener("pointercancel", this._handleRangePointerUp);
|
|
2189
|
+
this.el.removeEventListener("blur", this._handleRangeRelease);
|
|
2190
|
+
this.el.removeEventListener("mouseout", this._handleRangeRelease);
|
|
1926
2191
|
}
|
|
1927
2192
|
_setupThumb() {
|
|
1928
2193
|
this.thumb = document.createElement("span");
|
|
@@ -1939,7 +2204,7 @@ var Expressive = (() => {
|
|
|
1939
2204
|
return !!this.el.closest(".vertical");
|
|
1940
2205
|
}
|
|
1941
2206
|
_host() {
|
|
1942
|
-
return this.el.closest(".range, .range-field, label");
|
|
2207
|
+
return this.el.closest(".slider, .range, .range-field, label");
|
|
1943
2208
|
}
|
|
1944
2209
|
_clampDual() {
|
|
1945
2210
|
const host = this._host();
|
|
@@ -1994,7 +2259,7 @@ var Expressive = (() => {
|
|
|
1994
2259
|
*/
|
|
1995
2260
|
static Init() {
|
|
1996
2261
|
Utils.onDocumentReady(() => {
|
|
1997
|
-
|
|
2262
|
+
_Slider.init(document.querySelectorAll("input[type=range]"), {});
|
|
1998
2263
|
});
|
|
1999
2264
|
}
|
|
2000
2265
|
};
|
|
@@ -2067,169 +2332,144 @@ var Expressive = (() => {
|
|
|
2067
2332
|
_Dialogs._down = null;
|
|
2068
2333
|
var Dialogs = _Dialogs;
|
|
2069
2334
|
|
|
2070
|
-
// src/ts/behaviors/
|
|
2071
|
-
var
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2335
|
+
// src/ts/behaviors/sheetDrag.ts
|
|
2336
|
+
var DISMISS_DISTANCE = 96;
|
|
2337
|
+
var DISMISS_VELOCITY = 0.5;
|
|
2338
|
+
var DRAG_SLOP = 4;
|
|
2339
|
+
function installSheetDrag(config) {
|
|
2340
|
+
const coord = (event) => config.axis === "x" ? event.clientX : event.clientY;
|
|
2341
|
+
let drag = null;
|
|
2342
|
+
const sheetFor = (target) => {
|
|
2343
|
+
if (!(target instanceof Element)) return null;
|
|
2344
|
+
const dialog = target.closest(config.selector);
|
|
2345
|
+
return dialog instanceof HTMLDialogElement ? dialog : null;
|
|
2346
|
+
};
|
|
2347
|
+
const reset = (dialog) => {
|
|
2348
|
+
dialog.style.transition = "";
|
|
2349
|
+
dialog.style.setProperty(config.property, "0px");
|
|
2350
|
+
};
|
|
2351
|
+
const onDown = (event) => {
|
|
2352
|
+
config.onPress?.();
|
|
2081
2353
|
if (!event.isPrimary) return;
|
|
2082
2354
|
if (event.pointerType === "mouse" && event.button !== 0) return;
|
|
2083
|
-
const dialog =
|
|
2355
|
+
const dialog = sheetFor(event.target);
|
|
2084
2356
|
if (!dialog?.open) {
|
|
2085
|
-
|
|
2357
|
+
drag = null;
|
|
2086
2358
|
return;
|
|
2087
2359
|
}
|
|
2088
|
-
if (!
|
|
2089
|
-
|
|
2360
|
+
if (!config.inHandle(event, dialog)) {
|
|
2361
|
+
drag = null;
|
|
2090
2362
|
return;
|
|
2091
2363
|
}
|
|
2092
2364
|
dialog.style.transition = "none";
|
|
2093
|
-
|
|
2365
|
+
drag = {
|
|
2094
2366
|
dialog,
|
|
2095
2367
|
pointerId: event.pointerId,
|
|
2096
|
-
|
|
2097
|
-
|
|
2368
|
+
direction: config.direction(dialog),
|
|
2369
|
+
start: coord(event),
|
|
2370
|
+
last: coord(event),
|
|
2098
2371
|
lastT: Date.now(),
|
|
2099
2372
|
shift: 0
|
|
2100
2373
|
};
|
|
2101
|
-
}
|
|
2102
|
-
|
|
2103
|
-
const drag = _BottomSheets._drag;
|
|
2374
|
+
};
|
|
2375
|
+
const onMove = (event) => {
|
|
2104
2376
|
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
2105
|
-
const
|
|
2106
|
-
drag.shift =
|
|
2107
|
-
drag.
|
|
2377
|
+
const delta = coord(event) - drag.start;
|
|
2378
|
+
drag.shift = drag.direction === 1 ? Math.max(0, delta) : Math.min(0, delta);
|
|
2379
|
+
drag.last = coord(event);
|
|
2108
2380
|
drag.lastT = Date.now();
|
|
2109
|
-
drag.dialog.style.setProperty(
|
|
2110
|
-
}
|
|
2111
|
-
|
|
2112
|
-
const
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
const
|
|
2118
|
-
|
|
2119
|
-
const dismiss =
|
|
2120
|
-
if (dismiss && dialog.open)
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2381
|
+
drag.dialog.style.setProperty(config.property, `${drag.shift}px`);
|
|
2382
|
+
};
|
|
2383
|
+
const onUp = (event) => {
|
|
2384
|
+
const held = drag;
|
|
2385
|
+
if (!held || held.pointerId !== event.pointerId) return;
|
|
2386
|
+
drag = null;
|
|
2387
|
+
held.dialog.style.transition = "";
|
|
2388
|
+
const dt = Math.max(1, Date.now() - held.lastT);
|
|
2389
|
+
const velocity = (coord(event) - held.last) / dt;
|
|
2390
|
+
config.onRelease?.(Math.abs(held.shift) > DRAG_SLOP);
|
|
2391
|
+
const dismiss = held.direction === 1 ? held.shift > DISMISS_DISTANCE || velocity > DISMISS_VELOCITY : held.shift < -DISMISS_DISTANCE || velocity < -DISMISS_VELOCITY;
|
|
2392
|
+
if (dismiss && held.dialog.open) held.dialog.close();
|
|
2393
|
+
held.dialog.style.setProperty(config.property, "0px");
|
|
2394
|
+
};
|
|
2395
|
+
const onCancel = () => {
|
|
2396
|
+
config.onRelease?.(false);
|
|
2397
|
+
const held = drag;
|
|
2398
|
+
drag = null;
|
|
2399
|
+
if (held) reset(held.dialog);
|
|
2400
|
+
};
|
|
2401
|
+
Utils.onDocumentReady(() => {
|
|
2402
|
+
document.addEventListener("pointerdown", onDown, { passive: true });
|
|
2403
|
+
document.addEventListener("pointermove", onMove, { passive: true });
|
|
2404
|
+
document.addEventListener("pointerup", onUp, { passive: true });
|
|
2405
|
+
document.addEventListener("pointercancel", onCancel, { passive: true });
|
|
2406
|
+
});
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
// src/ts/behaviors/bottomSheets.ts
|
|
2410
|
+
var SHEET_SELECTOR = "dialog.bottom-sheet, dialog.bottom";
|
|
2411
|
+
var _BottomSheets = class _BottomSheets {
|
|
2412
|
+
static Init() {
|
|
2413
|
+
installSheetDrag({
|
|
2414
|
+
selector: SHEET_SELECTOR,
|
|
2415
|
+
axis: "y",
|
|
2416
|
+
property: "--md-comp-bottom-sheet-shift",
|
|
2417
|
+
direction: () => 1,
|
|
2418
|
+
inHandle: (event, dialog) => {
|
|
2419
|
+
const target = event.target;
|
|
2420
|
+
if (target instanceof Element && target.closest(".handle")) return true;
|
|
2421
|
+
const rect = dialog.getBoundingClientRect();
|
|
2422
|
+
return event.clientY >= rect.top && event.clientY <= rect.top + 48;
|
|
2423
|
+
},
|
|
2424
|
+
onPress: () => {
|
|
2425
|
+
_BottomSheets._dragged = false;
|
|
2426
|
+
},
|
|
2427
|
+
onRelease: (dragged) => {
|
|
2428
|
+
_BottomSheets._dragged = dragged;
|
|
2429
|
+
}
|
|
2430
|
+
});
|
|
2431
|
+
Utils.onDocumentReady(() => {
|
|
2432
|
+
document.addEventListener("click", _BottomSheets._onClick);
|
|
2433
|
+
});
|
|
2136
2434
|
}
|
|
2137
|
-
static
|
|
2435
|
+
static _onClick(event) {
|
|
2138
2436
|
const target = event.target;
|
|
2139
|
-
if (target instanceof Element
|
|
2140
|
-
const
|
|
2141
|
-
|
|
2437
|
+
if (!(target instanceof Element)) return;
|
|
2438
|
+
const handle = target.closest(".handle, .drag-handle");
|
|
2439
|
+
if (!(handle instanceof HTMLButtonElement)) return;
|
|
2440
|
+
if (event.detail !== 0 && _BottomSheets._dragged) return;
|
|
2441
|
+
const dialog = handle.closest(SHEET_SELECTOR);
|
|
2442
|
+
if (dialog instanceof HTMLDialogElement && dialog.open) dialog.close();
|
|
2142
2443
|
}
|
|
2143
2444
|
};
|
|
2144
|
-
|
|
2445
|
+
/**
|
|
2446
|
+
* Whether the last pointer sequence moved. A drag ends with a `click` on the
|
|
2447
|
+
* element it started on, so without this the tail of a drag that snapped back
|
|
2448
|
+
* would dismiss the sheet the drag had just declined to dismiss.
|
|
2449
|
+
*/
|
|
2450
|
+
_BottomSheets._dragged = false;
|
|
2145
2451
|
var BottomSheets = _BottomSheets;
|
|
2146
2452
|
|
|
2147
2453
|
// src/ts/behaviors/sideSheets.ts
|
|
2148
|
-
var
|
|
2454
|
+
var startDocked = (dialog) => dialog.classList.contains("left") || dialog.classList.contains("left-sheet") || dialog.classList.contains("start");
|
|
2455
|
+
var SideSheets = class {
|
|
2149
2456
|
static Init() {
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2457
|
+
installSheetDrag({
|
|
2458
|
+
selector: "dialog.side-sheet, dialog.right, dialog.right-sheet, dialog.left, dialog.left-sheet",
|
|
2459
|
+
axis: "x",
|
|
2460
|
+
property: "--md-comp-side-sheet-shift",
|
|
2461
|
+
// A start-docked sheet leaves toward the start edge, so its dismissal
|
|
2462
|
+
// direction is the negative one.
|
|
2463
|
+
direction: (dialog) => startDocked(dialog) ? -1 : 1,
|
|
2464
|
+
inHandle: (event, dialog) => {
|
|
2465
|
+
const target = event.target;
|
|
2466
|
+
if (target instanceof Element && target.closest("header")) return true;
|
|
2467
|
+
const rect = dialog.getBoundingClientRect();
|
|
2468
|
+
return startDocked(dialog) ? event.clientX >= rect.right - 24 && event.clientX <= rect.right : event.clientX >= rect.left && event.clientX <= rect.left + 24;
|
|
2469
|
+
}
|
|
2155
2470
|
});
|
|
2156
2471
|
}
|
|
2157
|
-
static _onDown(event) {
|
|
2158
|
-
if (!event.isPrimary) return;
|
|
2159
|
-
if (event.pointerType === "mouse" && event.button !== 0) return;
|
|
2160
|
-
const dialog = _SideSheets._sheet(event.target);
|
|
2161
|
-
if (!dialog?.open) {
|
|
2162
|
-
_SideSheets._drag = null;
|
|
2163
|
-
return;
|
|
2164
|
-
}
|
|
2165
|
-
if (!_SideSheets._inHandle(event, dialog)) {
|
|
2166
|
-
_SideSheets._drag = null;
|
|
2167
|
-
return;
|
|
2168
|
-
}
|
|
2169
|
-
dialog.style.transition = "none";
|
|
2170
|
-
_SideSheets._drag = {
|
|
2171
|
-
dialog,
|
|
2172
|
-
pointerId: event.pointerId,
|
|
2173
|
-
startX: event.clientX,
|
|
2174
|
-
lastX: event.clientX,
|
|
2175
|
-
lastT: Date.now(),
|
|
2176
|
-
shift: 0,
|
|
2177
|
-
startDocked: _SideSheets._startDocked(dialog)
|
|
2178
|
-
};
|
|
2179
|
-
}
|
|
2180
|
-
static _onMove(event) {
|
|
2181
|
-
const drag = _SideSheets._drag;
|
|
2182
|
-
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
2183
|
-
const delta = event.clientX - drag.startX;
|
|
2184
|
-
const shift = drag.startDocked ? Math.min(0, delta) : Math.max(0, delta);
|
|
2185
|
-
drag.shift = shift;
|
|
2186
|
-
drag.lastX = event.clientX;
|
|
2187
|
-
drag.lastT = Date.now();
|
|
2188
|
-
drag.dialog.style.setProperty("--md-comp-side-sheet-shift", `${shift}px`);
|
|
2189
|
-
}
|
|
2190
|
-
static _onUp(event) {
|
|
2191
|
-
const drag = _SideSheets._drag;
|
|
2192
|
-
_SideSheets._drag = null;
|
|
2193
|
-
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
2194
|
-
const dialog = drag.dialog;
|
|
2195
|
-
dialog.style.transition = "";
|
|
2196
|
-
const dt = Math.max(1, Date.now() - drag.lastT);
|
|
2197
|
-
const velocity = (event.clientX - drag.lastX) / dt;
|
|
2198
|
-
const dismiss = drag.startDocked ? drag.shift < -96 || velocity < -0.5 : drag.shift > 96 || velocity > 0.5;
|
|
2199
|
-
if (dismiss && dialog.open) {
|
|
2200
|
-
dialog.close();
|
|
2201
|
-
}
|
|
2202
|
-
dialog.style.setProperty("--md-comp-side-sheet-shift", "0px");
|
|
2203
|
-
}
|
|
2204
|
-
static _onCancel() {
|
|
2205
|
-
const drag = _SideSheets._drag;
|
|
2206
|
-
_SideSheets._drag = null;
|
|
2207
|
-
if (!drag) return;
|
|
2208
|
-
drag.dialog.style.transition = "";
|
|
2209
|
-
drag.dialog.style.setProperty("--md-comp-side-sheet-shift", "0px");
|
|
2210
|
-
}
|
|
2211
|
-
static _sheet(target) {
|
|
2212
|
-
if (!(target instanceof Element)) return null;
|
|
2213
|
-
const dialog = target.closest(
|
|
2214
|
-
"dialog.side-sheet, dialog.right, dialog.right-sheet, dialog.left, dialog.left-sheet"
|
|
2215
|
-
);
|
|
2216
|
-
return dialog instanceof HTMLDialogElement ? dialog : null;
|
|
2217
|
-
}
|
|
2218
|
-
static _startDocked(dialog) {
|
|
2219
|
-
return dialog.classList.contains("left") || dialog.classList.contains("left-sheet") || dialog.classList.contains("start");
|
|
2220
|
-
}
|
|
2221
|
-
static _inHandle(event, dialog) {
|
|
2222
|
-
const target = event.target;
|
|
2223
|
-
if (target instanceof Element && target.closest("header")) return true;
|
|
2224
|
-
const rect = dialog.getBoundingClientRect();
|
|
2225
|
-
if (_SideSheets._startDocked(dialog)) {
|
|
2226
|
-
return event.clientX >= rect.right - 24 && event.clientX <= rect.right;
|
|
2227
|
-
}
|
|
2228
|
-
return event.clientX >= rect.left && event.clientX <= rect.left + 24;
|
|
2229
|
-
}
|
|
2230
2472
|
};
|
|
2231
|
-
_SideSheets._drag = null;
|
|
2232
|
-
var SideSheets = _SideSheets;
|
|
2233
2473
|
|
|
2234
2474
|
// src/ts/behaviors/forms.ts
|
|
2235
2475
|
var Forms = class _Forms {
|
|
@@ -2285,7 +2525,7 @@ var Expressive = (() => {
|
|
|
2285
2525
|
document.addEventListener("keyup", (e) => {
|
|
2286
2526
|
const target = e.target;
|
|
2287
2527
|
if (target instanceof HTMLInputElement && ["radio", "checkbox"].includes(target.type)) {
|
|
2288
|
-
if (Utils.keys.TAB
|
|
2528
|
+
if (e.key === Utils.keys.TAB) {
|
|
2289
2529
|
target.classList.add("tabbed");
|
|
2290
2530
|
target.addEventListener("blur", () => target.classList.remove("tabbed"), {
|
|
2291
2531
|
once: true
|
|
@@ -2323,61 +2563,8 @@ var Expressive = (() => {
|
|
|
2323
2563
|
}
|
|
2324
2564
|
};
|
|
2325
2565
|
|
|
2326
|
-
// src/ts/behaviors/waves.ts
|
|
2327
|
-
var Waves = class _Waves {
|
|
2328
|
-
static _offset(el) {
|
|
2329
|
-
const box = el.getBoundingClientRect();
|
|
2330
|
-
const docElem = document.documentElement;
|
|
2331
|
-
return {
|
|
2332
|
-
top: box.top + window.pageYOffset - docElem.clientTop,
|
|
2333
|
-
left: box.left + window.pageXOffset - docElem.clientLeft
|
|
2334
|
-
};
|
|
2335
|
-
}
|
|
2336
|
-
// https://phoenix-dx.com/css-techniques-for-material-ripple-effect/
|
|
2337
|
-
static renderWaveEffect(targetElement, position = null, color = null) {
|
|
2338
|
-
const isCentered = position === null;
|
|
2339
|
-
const duration = 500;
|
|
2340
|
-
let animationFrame, animationStart;
|
|
2341
|
-
const animationStep = function(timestamp) {
|
|
2342
|
-
if (!animationStart) {
|
|
2343
|
-
animationStart = timestamp;
|
|
2344
|
-
}
|
|
2345
|
-
const frame = timestamp - animationStart;
|
|
2346
|
-
if (frame < duration) {
|
|
2347
|
-
const easing = frame / duration * (2 - frame / duration);
|
|
2348
|
-
const circle = isCentered ? "circle at 50% 50%" : `circle at ${position.x}px ${position.y}px`;
|
|
2349
|
-
const waveColor = `rgba(${color?.r || 0}, ${color?.g || 0}, ${color?.b || 0}, ${0.3 * (1 - easing)})`;
|
|
2350
|
-
const stop = 90 * easing + "%";
|
|
2351
|
-
targetElement.style.backgroundImage = "radial-gradient(" + circle + ", " + waveColor + " " + stop + ", transparent " + stop + ")";
|
|
2352
|
-
animationFrame = window.requestAnimationFrame(animationStep);
|
|
2353
|
-
} else {
|
|
2354
|
-
targetElement.style.backgroundImage = "none";
|
|
2355
|
-
window.cancelAnimationFrame(animationFrame);
|
|
2356
|
-
}
|
|
2357
|
-
};
|
|
2358
|
-
animationFrame = window.requestAnimationFrame(animationStep);
|
|
2359
|
-
}
|
|
2360
|
-
static Init() {
|
|
2361
|
-
Utils.onDocumentReady(() => {
|
|
2362
|
-
document.body.addEventListener("click", (e) => {
|
|
2363
|
-
const trigger = e.target;
|
|
2364
|
-
const el = trigger.closest(".waves-effect");
|
|
2365
|
-
if (el && el.contains(trigger)) {
|
|
2366
|
-
const isCircular = el.classList.contains("waves-circle");
|
|
2367
|
-
const offset = _Waves._offset(el);
|
|
2368
|
-
const x = e.pageX - offset.left;
|
|
2369
|
-
const y = e.pageY - offset.top;
|
|
2370
|
-
let color = null;
|
|
2371
|
-
if (el.classList.contains("waves-light")) color = { r: 255, g: 255, b: 255 };
|
|
2372
|
-
_Waves.renderWaveEffect(el, isCircular ? null : { x, y }, color);
|
|
2373
|
-
}
|
|
2374
|
-
});
|
|
2375
|
-
});
|
|
2376
|
-
}
|
|
2377
|
-
};
|
|
2378
|
-
|
|
2379
2566
|
// src/ts/components/buttons.ts
|
|
2380
|
-
var
|
|
2567
|
+
var _defaults7 = {
|
|
2381
2568
|
direction: "top",
|
|
2382
2569
|
hoverEnabled: true,
|
|
2383
2570
|
toolbarEnabled: false
|
|
@@ -2412,13 +2599,13 @@ var Expressive = (() => {
|
|
|
2412
2599
|
this._toggle();
|
|
2413
2600
|
};
|
|
2414
2601
|
this._handleAnchorKeydown = (e) => {
|
|
2415
|
-
if (Utils.keys.ENTER
|
|
2602
|
+
if (e.key === Utils.keys.ENTER || e.key === " ") {
|
|
2416
2603
|
e.preventDefault();
|
|
2417
2604
|
this._toggle();
|
|
2418
2605
|
}
|
|
2419
2606
|
};
|
|
2420
2607
|
this._handleDocumentKeydown = (e) => {
|
|
2421
|
-
if (Utils.keys.ESC
|
|
2608
|
+
if (e.key === Utils.keys.ESC) this.close();
|
|
2422
2609
|
};
|
|
2423
2610
|
this._handleDocumentClick = (e) => {
|
|
2424
2611
|
const target = e.target;
|
|
@@ -2438,22 +2625,19 @@ var Expressive = (() => {
|
|
|
2438
2625
|
};
|
|
2439
2626
|
this.isOpen = false;
|
|
2440
2627
|
this._anchor = this.el.querySelector(":scope > a, :scope > button");
|
|
2441
|
-
this._menu = this.el.querySelector("ul, menu");
|
|
2442
2628
|
this.el.classList.add(`direction-${this.options.direction}`);
|
|
2443
2629
|
if (clickToToggle) this.el.classList.add("click-to-toggle");
|
|
2444
2630
|
if (toolbar) this.el.classList.add("toolbar");
|
|
2445
2631
|
if (this._anchor) {
|
|
2446
|
-
this._anchor.setAttribute("aria-haspopup", "menu");
|
|
2447
2632
|
this._anchor.setAttribute("aria-expanded", "false");
|
|
2448
2633
|
if (this._anchor instanceof HTMLAnchorElement && !this._anchor.hasAttribute("href") && this._anchor.tabIndex < 0) {
|
|
2449
2634
|
this._anchor.tabIndex = 0;
|
|
2450
2635
|
}
|
|
2451
2636
|
}
|
|
2452
|
-
if (this._menu) this._menu.setAttribute("role", "menu");
|
|
2453
2637
|
this._setupEventHandlers();
|
|
2454
2638
|
}
|
|
2455
2639
|
static get defaults() {
|
|
2456
|
-
return
|
|
2640
|
+
return _defaults7;
|
|
2457
2641
|
}
|
|
2458
2642
|
static init(els, options = {}) {
|
|
2459
2643
|
return super.init(els, options, _FloatingActionButton);
|
|
@@ -2491,16 +2675,21 @@ var Expressive = (() => {
|
|
|
2491
2675
|
};
|
|
2492
2676
|
|
|
2493
2677
|
// src/ts/components/carousel.ts
|
|
2494
|
-
var
|
|
2678
|
+
var _defaults8 = {
|
|
2495
2679
|
duration: 200,
|
|
2496
|
-
dist: -100,
|
|
2497
|
-
shift: 0,
|
|
2498
|
-
padding: 0,
|
|
2499
|
-
numVisible: 5,
|
|
2500
2680
|
fullWidth: false,
|
|
2501
2681
|
indicators: false,
|
|
2502
2682
|
noWrap: false,
|
|
2503
|
-
|
|
2683
|
+
interval: 0,
|
|
2684
|
+
height: null,
|
|
2685
|
+
onCycleTo: null,
|
|
2686
|
+
i18n: {
|
|
2687
|
+
carousel: "Carousel",
|
|
2688
|
+
item: "Item",
|
|
2689
|
+
of: "of",
|
|
2690
|
+
indicators: "Slides",
|
|
2691
|
+
slide: "Slide"
|
|
2692
|
+
}
|
|
2504
2693
|
};
|
|
2505
2694
|
var _Carousel = class _Carousel extends Component {
|
|
2506
2695
|
constructor(el, options) {
|
|
@@ -2511,101 +2700,112 @@ var Expressive = (() => {
|
|
|
2511
2700
|
this._ignoreScroll = false;
|
|
2512
2701
|
this._trackRaf = null;
|
|
2513
2702
|
this._started = false;
|
|
2703
|
+
this._vertical = false;
|
|
2704
|
+
this._resizeObserver = null;
|
|
2705
|
+
this._usesWindowResize = false;
|
|
2706
|
+
this._dragPointerId = null;
|
|
2707
|
+
this._dragStartX = 0;
|
|
2708
|
+
this._dragStartY = 0;
|
|
2709
|
+
this._dragStartScroll = 0;
|
|
2710
|
+
this._suppressClick = false;
|
|
2711
|
+
this._suppressClickTimeout = null;
|
|
2712
|
+
this._generatedContainerRole = false;
|
|
2713
|
+
this._generatedContainerLabel = false;
|
|
2714
|
+
this._generatedContainerDescription = false;
|
|
2715
|
+
this._generatedWideLayout = false;
|
|
2716
|
+
this._generatedFixedHeight = false;
|
|
2717
|
+
this._authoredInlineHeight = null;
|
|
2718
|
+
this._autoAdvanceTimer = null;
|
|
2719
|
+
this._autoAdvances = false;
|
|
2720
|
+
this._autoPaused = false;
|
|
2721
|
+
this._hovered = false;
|
|
2722
|
+
this._focused = false;
|
|
2723
|
+
this._generatedItemTabIndexes = /* @__PURE__ */ new Set();
|
|
2724
|
+
this._generatedItemLabels = /* @__PURE__ */ new Set();
|
|
2725
|
+
this._generatedItemDescriptions = /* @__PURE__ */ new Set();
|
|
2726
|
+
this._generatedItemSizes = /* @__PURE__ */ new Set();
|
|
2727
|
+
this._authoredItemSizes = /* @__PURE__ */ new Set();
|
|
2728
|
+
this._itemA11yOriginal = /* @__PURE__ */ new Map();
|
|
2514
2729
|
this._handleThrottledResize = Utils.throttle(() => this._handleResize(), 200);
|
|
2515
|
-
this.
|
|
2516
|
-
if (e.
|
|
2517
|
-
if (e.
|
|
2518
|
-
|
|
2730
|
+
this._handleAutoAdvanceState = (e) => {
|
|
2731
|
+
if (e.type === "mouseenter") this._hovered = true;
|
|
2732
|
+
else if (e.type === "mouseleave") this._hovered = false;
|
|
2733
|
+
else if (e.type === "focusin") this._focused = true;
|
|
2734
|
+
else if (e.type === "focusout") this._focused = false;
|
|
2735
|
+
this._syncAutoAdvance();
|
|
2736
|
+
};
|
|
2737
|
+
this._tick = () => {
|
|
2738
|
+
this._autoAdvanceTimer = null;
|
|
2739
|
+
this._advance();
|
|
2740
|
+
this._syncAutoAdvance();
|
|
2741
|
+
};
|
|
2742
|
+
this._advance = () => {
|
|
2743
|
+
const next = this.center + 1;
|
|
2744
|
+
if (next < this.count) {
|
|
2745
|
+
this.set(next);
|
|
2746
|
+
return;
|
|
2747
|
+
}
|
|
2748
|
+
if (this.options.noWrap) {
|
|
2749
|
+
this._autoAdvances = false;
|
|
2750
|
+
this._syncAutoAdvance();
|
|
2751
|
+
return;
|
|
2519
2752
|
}
|
|
2753
|
+
this.set(0);
|
|
2754
|
+
};
|
|
2755
|
+
this._handleTrackPointerDown = (e) => {
|
|
2756
|
+
if (e.pointerType !== "mouse" || e.button !== 0) return;
|
|
2520
2757
|
this.pressed = true;
|
|
2521
2758
|
this.dragged = false;
|
|
2522
|
-
this.
|
|
2523
|
-
this.
|
|
2524
|
-
this.
|
|
2525
|
-
this.
|
|
2526
|
-
this.
|
|
2527
|
-
this.timestamp = Date.now();
|
|
2759
|
+
this._suppressClick = false;
|
|
2760
|
+
this._dragPointerId = e.pointerId;
|
|
2761
|
+
this._dragStartX = e.clientX;
|
|
2762
|
+
this._dragStartY = e.clientY;
|
|
2763
|
+
this._dragStartScroll = this._vertical ? this._scroller.scrollTop : this._scroller.scrollLeft;
|
|
2528
2764
|
try {
|
|
2529
|
-
this.
|
|
2765
|
+
this._scroller.setPointerCapture(e.pointerId);
|
|
2530
2766
|
} catch {
|
|
2531
2767
|
}
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
this.
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
const deltaY = Math.abs(this.referenceY - e.clientY);
|
|
2544
|
-
if (deltaY < 30 && !this.verticalDragged) {
|
|
2545
|
-
if (delta > 2 || delta < -2) {
|
|
2546
|
-
this.dragged = true;
|
|
2547
|
-
this.reference = e.clientX;
|
|
2548
|
-
this._scroll(this.offset + delta);
|
|
2549
|
-
}
|
|
2550
|
-
} else if (this.dragged) {
|
|
2551
|
-
e.preventDefault();
|
|
2552
|
-
} else {
|
|
2553
|
-
this.verticalDragged = true;
|
|
2768
|
+
};
|
|
2769
|
+
this._handleTrackPointerMove = (e) => {
|
|
2770
|
+
if (!this.pressed || e.pointerId !== this._dragPointerId) return;
|
|
2771
|
+
const deltaX = e.clientX - this._dragStartX;
|
|
2772
|
+
const deltaY = e.clientY - this._dragStartY;
|
|
2773
|
+
const primaryDelta = this._vertical ? deltaY : deltaX;
|
|
2774
|
+
const crossDelta = this._vertical ? deltaX : deltaY;
|
|
2775
|
+
if (!this.dragged) {
|
|
2776
|
+
if (Math.abs(primaryDelta) < 6 || Math.abs(primaryDelta) <= Math.abs(crossDelta)) return;
|
|
2777
|
+
this.dragged = true;
|
|
2778
|
+
this.el.classList.add("dragging");
|
|
2554
2779
|
}
|
|
2555
|
-
if (this.
|
|
2780
|
+
if (this._vertical) this._scroller.scrollTop = this._dragStartScroll - deltaY;
|
|
2781
|
+
else this._scroller.scrollLeft = this._dragStartScroll - deltaX;
|
|
2782
|
+
e.preventDefault();
|
|
2556
2783
|
};
|
|
2557
|
-
this.
|
|
2558
|
-
if (!this.pressed) return;
|
|
2784
|
+
this._handleTrackPointerUp = (e) => {
|
|
2785
|
+
if (!this.pressed || e.pointerId !== this._dragPointerId) return;
|
|
2559
2786
|
this.pressed = false;
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
this._trackRaf = null;
|
|
2563
|
-
}
|
|
2787
|
+
this._dragPointerId = null;
|
|
2788
|
+
this.el.classList.remove("dragging");
|
|
2564
2789
|
try {
|
|
2565
|
-
this.
|
|
2790
|
+
this._scroller.releasePointerCapture(e.pointerId);
|
|
2566
2791
|
} catch {
|
|
2567
2792
|
}
|
|
2568
|
-
this.
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
this.amplitude = this.target - this.offset;
|
|
2582
|
-
this.timestamp = Date.now();
|
|
2583
|
-
requestAnimationFrame(this._autoScroll);
|
|
2584
|
-
if (this.dragged) e.preventDefault();
|
|
2793
|
+
if (!this.dragged) return;
|
|
2794
|
+
this._suppressClick = true;
|
|
2795
|
+
window.clearTimeout(this._suppressClickTimeout);
|
|
2796
|
+
this._suppressClickTimeout = setTimeout(() => {
|
|
2797
|
+
this._suppressClick = false;
|
|
2798
|
+
}, 0);
|
|
2799
|
+
this._syncActive(this._nearestIndex(), true);
|
|
2800
|
+
};
|
|
2801
|
+
this._handleTrackClick = (e) => {
|
|
2802
|
+
if (!this._suppressClick) return;
|
|
2803
|
+
this._suppressClick = false;
|
|
2804
|
+
e.preventDefault();
|
|
2805
|
+
e.stopImmediatePropagation();
|
|
2585
2806
|
};
|
|
2586
|
-
this.
|
|
2587
|
-
if (
|
|
2588
|
-
e.preventDefault();
|
|
2589
|
-
e.stopPropagation();
|
|
2590
|
-
return;
|
|
2591
|
-
}
|
|
2592
|
-
const clickedElem = e.target.closest(".carousel-item");
|
|
2593
|
-
if (!clickedElem || !this.el.contains(clickedElem)) return;
|
|
2594
|
-
const clickedIndex = this.images.indexOf(clickedElem);
|
|
2595
|
-
const diff = this._wrap(this.center) - clickedIndex;
|
|
2596
|
-
if (diff !== 0) {
|
|
2597
|
-
e.preventDefault();
|
|
2598
|
-
e.stopPropagation();
|
|
2599
|
-
}
|
|
2600
|
-
if (clickedIndex < 0) {
|
|
2601
|
-
if (e.clientX - e.target.getBoundingClientRect().left > this.el.clientWidth / 2) {
|
|
2602
|
-
this.next();
|
|
2603
|
-
} else {
|
|
2604
|
-
this.prev();
|
|
2605
|
-
}
|
|
2606
|
-
} else {
|
|
2607
|
-
this._cycleTo(clickedIndex);
|
|
2608
|
-
}
|
|
2807
|
+
this._handleTrackDragStart = (e) => {
|
|
2808
|
+
if (e.target.closest("img, picture, video")) e.preventDefault();
|
|
2609
2809
|
};
|
|
2610
2810
|
this._handleIndicatorClick = (e) => {
|
|
2611
2811
|
e.stopPropagation();
|
|
@@ -2618,112 +2818,107 @@ var Expressive = (() => {
|
|
|
2618
2818
|
this._handleKeydown = (e) => {
|
|
2619
2819
|
const target = e.target;
|
|
2620
2820
|
if (target.closest('input, textarea, select, [contenteditable="true"]')) return;
|
|
2621
|
-
|
|
2821
|
+
const forward = this._vertical ? e.key === "ArrowDown" : e.key === Utils.keys.ARROW_RIGHT;
|
|
2822
|
+
const backward = this._vertical ? e.key === "ArrowUp" : e.key === Utils.keys.ARROW_LEFT;
|
|
2823
|
+
if (e.key === "Home") {
|
|
2824
|
+
e.preventDefault();
|
|
2825
|
+
this.set(0);
|
|
2826
|
+
this._focusItem(0);
|
|
2827
|
+
} else if (e.key === "End") {
|
|
2828
|
+
e.preventDefault();
|
|
2829
|
+
this.set(this.count - 1);
|
|
2830
|
+
this._focusItem(this.count - 1);
|
|
2831
|
+
} else if (forward) {
|
|
2622
2832
|
e.preventDefault();
|
|
2623
2833
|
this.next();
|
|
2624
|
-
|
|
2834
|
+
this._focusItem(this.center);
|
|
2835
|
+
} else if (backward) {
|
|
2625
2836
|
e.preventDefault();
|
|
2626
2837
|
this.prev();
|
|
2838
|
+
this._focusItem(this.center);
|
|
2627
2839
|
}
|
|
2628
2840
|
};
|
|
2629
|
-
this.
|
|
2630
|
-
if (this.
|
|
2631
|
-
|
|
2632
|
-
|
|
2841
|
+
this._handleTrackScroll = () => {
|
|
2842
|
+
if (!this.el.classList.contains("scrolling")) this.el.classList.add("scrolling");
|
|
2843
|
+
window.clearTimeout(this.scrollingTimeout);
|
|
2844
|
+
this.scrollingTimeout = setTimeout(() => this.el.classList.remove("scrolling"), 120);
|
|
2845
|
+
if (this._trackRaf !== null) return;
|
|
2846
|
+
this._trackRaf = requestAnimationFrame(() => {
|
|
2847
|
+
this._trackRaf = null;
|
|
2848
|
+
this._updateParallax();
|
|
2849
|
+
if (this._ignoreScroll) return;
|
|
2850
|
+
const index = this._nearestIndex();
|
|
2851
|
+
if (index !== this.center) this._syncActive(index, this.dragged);
|
|
2852
|
+
});
|
|
2633
2853
|
};
|
|
2634
2854
|
this._handleResize = () => {
|
|
2635
2855
|
if (!this.images.length) return;
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
if (this.options.fullWidth) {
|
|
2641
|
-
const firstItem = this.images[0];
|
|
2642
|
-
if (!firstItem) return;
|
|
2643
|
-
this.itemWidth = firstItem.clientWidth;
|
|
2644
|
-
this.dim = this.itemWidth * 2 + this.options.padding;
|
|
2645
|
-
this.offset = this.center * 2 * this.itemWidth;
|
|
2646
|
-
this.target = this.offset;
|
|
2647
|
-
} else {
|
|
2648
|
-
this._scroll();
|
|
2649
|
-
}
|
|
2650
|
-
};
|
|
2651
|
-
this._track = () => {
|
|
2652
|
-
const now = Date.now();
|
|
2653
|
-
const elapsed = now - this.timestamp;
|
|
2654
|
-
const delta = this.offset - this.frame;
|
|
2655
|
-
const v = 1e3 * delta / (1 + elapsed);
|
|
2656
|
-
this.timestamp = now;
|
|
2657
|
-
this.frame = this.offset;
|
|
2658
|
-
this.velocity = 0.8 * v + 0.2 * this.velocity;
|
|
2659
|
-
};
|
|
2660
|
-
this._autoScroll = () => {
|
|
2661
|
-
if (!this.amplitude) return;
|
|
2662
|
-
const elapsed = Date.now() - this.timestamp;
|
|
2663
|
-
const delta = this.amplitude * Math.exp(-elapsed / this.options.duration);
|
|
2664
|
-
if (delta > 2 || delta < -2) {
|
|
2665
|
-
this._scroll(this.target - delta);
|
|
2666
|
-
requestAnimationFrame(this._autoScroll);
|
|
2667
|
-
} else {
|
|
2668
|
-
this._scroll(this.target);
|
|
2669
|
-
}
|
|
2856
|
+
this._syncAdaptiveMode();
|
|
2857
|
+
this._syncLayoutRoles(this.center);
|
|
2858
|
+
this._scrollToIndex(this.center, false);
|
|
2859
|
+
this._updateParallax();
|
|
2670
2860
|
};
|
|
2671
2861
|
this.el["Expressive_Carousel"] = this;
|
|
2672
2862
|
this.options = {
|
|
2673
2863
|
..._Carousel.defaults,
|
|
2674
2864
|
...options
|
|
2675
2865
|
};
|
|
2676
|
-
|
|
2677
|
-
|
|
2866
|
+
if (options?.i18n) {
|
|
2867
|
+
this.options.i18n = { ..._Carousel.defaults.i18n, ...options.i18n };
|
|
2868
|
+
}
|
|
2869
|
+
if (this.options.fullWidth || this.el.classList.contains("flat")) {
|
|
2678
2870
|
this.el.classList.add("flat");
|
|
2679
2871
|
this.options.fullWidth = true;
|
|
2680
|
-
this.options.dist = 0;
|
|
2681
|
-
}
|
|
2682
|
-
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
2683
|
-
this.options.duration = 1;
|
|
2684
|
-
if (!this._flat) this.options.dist = 0;
|
|
2685
2872
|
}
|
|
2873
|
+
this._vertical = this.el.classList.contains("full-screen");
|
|
2874
|
+
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
2875
|
+
if (reducedMotion) this.options.duration = 1;
|
|
2686
2876
|
this.pressed = false;
|
|
2687
2877
|
this.dragged = false;
|
|
2688
|
-
this.offset = this.target = 0;
|
|
2689
2878
|
this.images = this._collectItems();
|
|
2690
2879
|
if (!this.images.length) {
|
|
2691
2880
|
console.error("Carousel: no .carousel-item elements to show");
|
|
2692
2881
|
return;
|
|
2693
2882
|
}
|
|
2883
|
+
this.images.forEach((item) => {
|
|
2884
|
+
this._itemA11yOriginal.set(item, {
|
|
2885
|
+
ariaHidden: item.getAttribute("aria-hidden"),
|
|
2886
|
+
tabIndex: item.getAttribute("tabindex")
|
|
2887
|
+
});
|
|
2888
|
+
if (item.hasAttribute("data-carousel-size")) this._authoredItemSizes.add(item);
|
|
2889
|
+
});
|
|
2694
2890
|
this.hasMultipleSlides = this.images.length > 1;
|
|
2695
2891
|
this.showIndicators = this.options.indicators && this.hasMultipleSlides;
|
|
2696
|
-
this.noWrap = this.options.noWrap || !this.hasMultipleSlides || this._flat;
|
|
2697
2892
|
this.count = this.images.length;
|
|
2698
|
-
this.
|
|
2893
|
+
this._autoAdvances = this.options.interval > 0 && this.hasMultipleSlides && !reducedMotion;
|
|
2699
2894
|
this.images.forEach((item) => item.classList.add("carousel-item"));
|
|
2700
|
-
if (this.
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2895
|
+
if (this.options.height !== null) {
|
|
2896
|
+
this._generatedFixedHeight = !this.el.classList.contains("fixed-height");
|
|
2897
|
+
this._authoredInlineHeight = this.el.style.getPropertyValue("--carousel-height") || null;
|
|
2898
|
+
this.el.classList.add("fixed-height");
|
|
2899
|
+
this.el.style.setProperty("--carousel-height", `${this.options.height}px`);
|
|
2900
|
+
}
|
|
2901
|
+
this._wrapTrack();
|
|
2902
|
+
this._syncAdaptiveMode();
|
|
2705
2903
|
if (this.showIndicators) this._setupIndicators();
|
|
2706
|
-
this.
|
|
2707
|
-
this.el.setAttribute("aria-roledescription", "carousel");
|
|
2904
|
+
this._setupAccessibility();
|
|
2708
2905
|
this._setupEventHandlers();
|
|
2709
2906
|
this._started = true;
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
this._scroll(this.offset);
|
|
2720
|
-
}
|
|
2907
|
+
const start = Math.max(
|
|
2908
|
+
0,
|
|
2909
|
+
this.images.findIndex((el2) => el2.classList.contains("active"))
|
|
2910
|
+
);
|
|
2911
|
+
this.center = start;
|
|
2912
|
+
this._syncActive(start, false);
|
|
2913
|
+
this._updateParallax();
|
|
2914
|
+
this._scrollToIndex(start, false);
|
|
2915
|
+
this._syncAutoAdvance();
|
|
2721
2916
|
}
|
|
2722
2917
|
get _scroller() {
|
|
2723
2918
|
return this._trackEl ?? this.el;
|
|
2724
2919
|
}
|
|
2725
2920
|
static get defaults() {
|
|
2726
|
-
return
|
|
2921
|
+
return _defaults8;
|
|
2727
2922
|
}
|
|
2728
2923
|
static init(els, options = {}) {
|
|
2729
2924
|
return super.init(els, options, _Carousel);
|
|
@@ -2748,6 +2943,39 @@ var Expressive = (() => {
|
|
|
2748
2943
|
return el.tagName !== "NAV";
|
|
2749
2944
|
});
|
|
2750
2945
|
}
|
|
2946
|
+
_setupAccessibility() {
|
|
2947
|
+
if (!this.el.hasAttribute("role")) {
|
|
2948
|
+
this.el.setAttribute("role", "region");
|
|
2949
|
+
this._generatedContainerRole = true;
|
|
2950
|
+
}
|
|
2951
|
+
if (!this.el.hasAttribute("aria-label") && !this.el.hasAttribute("aria-labelledby")) {
|
|
2952
|
+
this.el.setAttribute("aria-label", this.options.i18n.carousel);
|
|
2953
|
+
this._generatedContainerLabel = true;
|
|
2954
|
+
}
|
|
2955
|
+
if (!this.el.hasAttribute("aria-roledescription")) {
|
|
2956
|
+
this.el.setAttribute("aria-roledescription", "carousel");
|
|
2957
|
+
this._generatedContainerDescription = true;
|
|
2958
|
+
}
|
|
2959
|
+
const naturallyFocusable = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
2960
|
+
this.images.forEach((item, index) => {
|
|
2961
|
+
if (!item.hasAttribute("aria-roledescription")) {
|
|
2962
|
+
item.setAttribute("aria-roledescription", "slide");
|
|
2963
|
+
this._generatedItemDescriptions.add(item);
|
|
2964
|
+
}
|
|
2965
|
+
if (!item.hasAttribute("aria-label") && !item.hasAttribute("aria-labelledby")) {
|
|
2966
|
+
const mediaName = item.querySelector("img[alt]")?.getAttribute("alt")?.trim();
|
|
2967
|
+
const textName = item.textContent?.replace(/\s+/g, " ").trim();
|
|
2968
|
+
const name = mediaName || textName;
|
|
2969
|
+
const position = `${this.options.i18n.item} ${index + 1} ${this.options.i18n.of} ${this.count}`;
|
|
2970
|
+
item.setAttribute("aria-label", name ? `${name}, ${position}` : position);
|
|
2971
|
+
this._generatedItemLabels.add(item);
|
|
2972
|
+
}
|
|
2973
|
+
if (!item.matches(naturallyFocusable) && !item.querySelector(naturallyFocusable)) {
|
|
2974
|
+
item.tabIndex = 0;
|
|
2975
|
+
this._generatedItemTabIndexes.add(item);
|
|
2976
|
+
}
|
|
2977
|
+
});
|
|
2978
|
+
}
|
|
2751
2979
|
_setupIndicators() {
|
|
2752
2980
|
const existing = Array.from(this.el.children).find(
|
|
2753
2981
|
(el) => el instanceof HTMLElement && el.classList.contains("indicators")
|
|
@@ -2755,7 +2983,7 @@ var Expressive = (() => {
|
|
|
2755
2983
|
this._indicators = existing ?? document.createElement("nav");
|
|
2756
2984
|
this._ownIndicators = !existing;
|
|
2757
2985
|
this._indicators.classList.add("indicators");
|
|
2758
|
-
this._indicators.setAttribute("aria-label",
|
|
2986
|
+
this._indicators.setAttribute("aria-label", this.options.i18n.indicators);
|
|
2759
2987
|
this._indicators.replaceChildren();
|
|
2760
2988
|
this.images.forEach((_, i) => {
|
|
2761
2989
|
const button = document.createElement("button");
|
|
@@ -2765,158 +2993,124 @@ var Expressive = (() => {
|
|
|
2765
2993
|
button.classList.add("active");
|
|
2766
2994
|
button.setAttribute("aria-current", "true");
|
|
2767
2995
|
}
|
|
2768
|
-
button.setAttribute("aria-label",
|
|
2996
|
+
button.setAttribute("aria-label", `${this.options.i18n.slide} ${i + 1}`);
|
|
2769
2997
|
this._indicators.appendChild(button);
|
|
2770
2998
|
});
|
|
2771
2999
|
if (this._ownIndicators) this.el.appendChild(this._indicators);
|
|
2772
|
-
|
|
2773
|
-
this.el.querySelector(".carousel-fixed-item")?.classList.add("with-indicators");
|
|
2774
|
-
}
|
|
3000
|
+
this.el.querySelector(".carousel-fixed-item")?.classList.add("with-indicators");
|
|
2775
3001
|
}
|
|
2776
3002
|
_setupEventHandlers() {
|
|
2777
3003
|
this.el.addEventListener("keydown", this._handleKeydown);
|
|
3004
|
+
if (this._autoAdvances) {
|
|
3005
|
+
this.el.addEventListener("mouseenter", this._handleAutoAdvanceState);
|
|
3006
|
+
this.el.addEventListener("mouseleave", this._handleAutoAdvanceState);
|
|
3007
|
+
this.el.addEventListener("focusin", this._handleAutoAdvanceState);
|
|
3008
|
+
this.el.addEventListener("focusout", this._handleAutoAdvanceState);
|
|
3009
|
+
document.addEventListener("visibilitychange", this._handleAutoAdvanceState);
|
|
3010
|
+
}
|
|
2778
3011
|
if (this.showIndicators && this._indicators) {
|
|
2779
3012
|
this._indicators.addEventListener("click", this._handleIndicatorClick);
|
|
2780
3013
|
}
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
_Carousel._resizeListening = true;
|
|
3014
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
3015
|
+
this._resizeObserver = new ResizeObserver(() => this._handleThrottledResize());
|
|
3016
|
+
this._resizeObserver.observe(this.el);
|
|
2785
3017
|
}
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
3018
|
+
this._usesWindowResize = !this._resizeObserver || this.el.classList.contains("full-screen");
|
|
3019
|
+
if (this._usesWindowResize) {
|
|
3020
|
+
_Carousel._live.add(this);
|
|
3021
|
+
if (!_Carousel._resizeListening) {
|
|
3022
|
+
window.addEventListener("resize", _Carousel._onResize, {
|
|
3023
|
+
passive: true
|
|
3024
|
+
});
|
|
3025
|
+
_Carousel._resizeListening = true;
|
|
3026
|
+
}
|
|
2789
3027
|
}
|
|
2790
|
-
this.
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
this.
|
|
2794
|
-
this.
|
|
3028
|
+
this._scroller.addEventListener("scroll", this._handleTrackScroll, {
|
|
3029
|
+
passive: true
|
|
3030
|
+
});
|
|
3031
|
+
this._scroller.addEventListener("pointerdown", this._handleTrackPointerDown);
|
|
3032
|
+
this._scroller.addEventListener("pointermove", this._handleTrackPointerMove);
|
|
3033
|
+
this._scroller.addEventListener("pointerup", this._handleTrackPointerUp);
|
|
3034
|
+
this._scroller.addEventListener("pointercancel", this._handleTrackPointerUp);
|
|
3035
|
+
this._scroller.addEventListener("click", this._handleTrackClick, true);
|
|
3036
|
+
this._scroller.addEventListener("dragstart", this._handleTrackDragStart);
|
|
2795
3037
|
}
|
|
2796
3038
|
_removeEventHandlers() {
|
|
2797
3039
|
this.el.removeEventListener("keydown", this._handleKeydown);
|
|
3040
|
+
this.el.removeEventListener("mouseenter", this._handleAutoAdvanceState);
|
|
3041
|
+
this.el.removeEventListener("mouseleave", this._handleAutoAdvanceState);
|
|
3042
|
+
this.el.removeEventListener("focusin", this._handleAutoAdvanceState);
|
|
3043
|
+
this.el.removeEventListener("focusout", this._handleAutoAdvanceState);
|
|
3044
|
+
document.removeEventListener("visibilitychange", this._handleAutoAdvanceState);
|
|
2798
3045
|
if (this._indicators) {
|
|
2799
3046
|
this._indicators.removeEventListener("click", this._handleIndicatorClick);
|
|
2800
3047
|
}
|
|
2801
|
-
this._scroller.removeEventListener("scroll", this.
|
|
2802
|
-
this.
|
|
2803
|
-
this.
|
|
2804
|
-
this.
|
|
2805
|
-
this.
|
|
2806
|
-
this.
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
3048
|
+
this._scroller.removeEventListener("scroll", this._handleTrackScroll);
|
|
3049
|
+
this._scroller.removeEventListener("pointerdown", this._handleTrackPointerDown);
|
|
3050
|
+
this._scroller.removeEventListener("pointermove", this._handleTrackPointerMove);
|
|
3051
|
+
this._scroller.removeEventListener("pointerup", this._handleTrackPointerUp);
|
|
3052
|
+
this._scroller.removeEventListener("pointercancel", this._handleTrackPointerUp);
|
|
3053
|
+
this._scroller.removeEventListener("click", this._handleTrackClick, true);
|
|
3054
|
+
this._scroller.removeEventListener("dragstart", this._handleTrackDragStart);
|
|
3055
|
+
this._resizeObserver?.disconnect();
|
|
3056
|
+
this._resizeObserver = null;
|
|
3057
|
+
if (this._usesWindowResize) {
|
|
3058
|
+
_Carousel._live.delete(this);
|
|
3059
|
+
if (_Carousel._live.size === 0 && _Carousel._resizeListening) {
|
|
3060
|
+
window.removeEventListener("resize", _Carousel._onResize);
|
|
3061
|
+
_Carousel._resizeListening = false;
|
|
3062
|
+
}
|
|
2811
3063
|
}
|
|
2812
3064
|
}
|
|
2813
3065
|
_teardown() {
|
|
2814
3066
|
this._removeEventHandlers();
|
|
3067
|
+
this._autoAdvances = false;
|
|
3068
|
+
this._syncAutoAdvance();
|
|
2815
3069
|
if (this._trackRaf !== null) cancelAnimationFrame(this._trackRaf);
|
|
2816
3070
|
window.clearTimeout(this.scrollingTimeout);
|
|
3071
|
+
window.clearTimeout(this._suppressClickTimeout);
|
|
2817
3072
|
if (this._ownIndicators) this._indicators?.remove();
|
|
2818
3073
|
this._unwrapTrack();
|
|
2819
3074
|
this.images.forEach((el) => {
|
|
2820
|
-
el.style.
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
3075
|
+
el.style.removeProperty("--md-comp-carousel-item-parallax");
|
|
3076
|
+
if (this._generatedItemLabels.has(el)) el.removeAttribute("aria-label");
|
|
3077
|
+
if (this._generatedItemDescriptions.has(el)) el.removeAttribute("aria-roledescription");
|
|
3078
|
+
if (this._generatedItemSizes.has(el)) el.removeAttribute("data-carousel-size");
|
|
3079
|
+
const original = this._itemA11yOriginal.get(el);
|
|
3080
|
+
if (original?.ariaHidden === null) el.removeAttribute("aria-hidden");
|
|
3081
|
+
else if (original) el.setAttribute("aria-hidden", original.ariaHidden);
|
|
3082
|
+
if (original?.tabIndex === null) el.removeAttribute("tabindex");
|
|
3083
|
+
else if (original) el.setAttribute("tabindex", original.tabIndex);
|
|
2824
3084
|
});
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
if ("
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
}
|
|
2841
|
-
window.clearTimeout(this.scrollingTimeout);
|
|
2842
|
-
this.scrollingTimeout = setTimeout(() => {
|
|
2843
|
-
this.el.classList.remove("scrolling");
|
|
2844
|
-
}, this.options.duration);
|
|
2845
|
-
this.offset = typeof x === "number" ? x : this.offset;
|
|
2846
|
-
this.center = Math.floor((this.offset + this.dim / 2) / this.dim);
|
|
2847
|
-
const half = this.count >> 1;
|
|
2848
|
-
const delta = this.offset - this.center * this.dim;
|
|
2849
|
-
const dir = delta < 0 ? 1 : -1;
|
|
2850
|
-
const tween = -dir * delta * 2 / this.dim;
|
|
2851
|
-
const lastCenter = this.center;
|
|
2852
|
-
const numVisibleOffset = 1 / this.options.numVisible;
|
|
2853
|
-
let alignment;
|
|
2854
|
-
let centerTweenedOpacity;
|
|
2855
|
-
if (this.options.fullWidth) {
|
|
2856
|
-
alignment = "translateX(0)";
|
|
2857
|
-
centerTweenedOpacity = 1;
|
|
2858
|
-
} else {
|
|
2859
|
-
alignment = "translateX(" + (this.el.clientWidth - this.itemWidth) / 2 + "px) ";
|
|
2860
|
-
alignment += "translateY(" + (this.el.clientHeight - this.itemHeight) / 2 + "px)";
|
|
2861
|
-
centerTweenedOpacity = 1 - numVisibleOffset * tween;
|
|
2862
|
-
}
|
|
2863
|
-
this._paintIndicators(this.center);
|
|
2864
|
-
if (!this.noWrap || this.center >= 0 && this.center < this.count) {
|
|
2865
|
-
const el = this.images[this._wrap(this.center)];
|
|
2866
|
-
if (el && !el.classList.contains("active")) {
|
|
2867
|
-
this.el.querySelector(".carousel-item.active")?.classList.remove("active");
|
|
2868
|
-
el.classList.add("active");
|
|
2869
|
-
}
|
|
2870
|
-
}
|
|
2871
|
-
for (let i = 1; i <= half; ++i) {
|
|
2872
|
-
let zTranslation;
|
|
2873
|
-
let tweenedOpacity;
|
|
2874
|
-
if (this.options.fullWidth) {
|
|
2875
|
-
zTranslation = this.options.dist;
|
|
2876
|
-
tweenedOpacity = i === half && delta < 0 ? 1 - tween : 1;
|
|
2877
|
-
} else {
|
|
2878
|
-
zTranslation = this.options.dist * (i * 2 + tween * dir);
|
|
2879
|
-
tweenedOpacity = 1 - numVisibleOffset * (i * 2 + tween * dir);
|
|
2880
|
-
}
|
|
2881
|
-
if (!this.noWrap || this.center + i < this.count) {
|
|
2882
|
-
const el = this.images[this._wrap(this.center + i)];
|
|
2883
|
-
const transformString = `${alignment} translateX(${this.options.shift + (this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
2884
|
-
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
2885
|
-
}
|
|
2886
|
-
if (this.options.fullWidth) {
|
|
2887
|
-
zTranslation = this.options.dist;
|
|
2888
|
-
tweenedOpacity = i === half && delta > 0 ? 1 - tween : 1;
|
|
2889
|
-
} else {
|
|
2890
|
-
zTranslation = this.options.dist * (i * 2 - tween * dir);
|
|
2891
|
-
tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
|
|
2892
|
-
}
|
|
2893
|
-
if (!this.noWrap || this.center - i >= 0) {
|
|
2894
|
-
const el = this.images[this._wrap(this.center - i)];
|
|
2895
|
-
const transformString = `${alignment} translateX(${-this.options.shift + (-this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
2896
|
-
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
2897
|
-
}
|
|
2898
|
-
}
|
|
2899
|
-
if (!this.noWrap || this.center >= 0 && this.center < this.count) {
|
|
2900
|
-
const el = this.images[this._wrap(this.center)];
|
|
2901
|
-
const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir * this.options.shift * tween}px) translateZ(${this.options.dist * tween}px)`;
|
|
2902
|
-
this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
|
|
2903
|
-
}
|
|
2904
|
-
const currItem = this.images[this._wrap(this.center)];
|
|
2905
|
-
this._syncA11y(this._wrap(this.center));
|
|
2906
|
-
if (lastCenter !== this.center && typeof this.options.onCycleTo === "function") {
|
|
2907
|
-
this.options.onCycleTo.call(this, currItem, this.dragged);
|
|
2908
|
-
}
|
|
2909
|
-
if (typeof this.oneTimeCallback === "function") {
|
|
2910
|
-
this.oneTimeCallback.call(this, currItem, this.dragged);
|
|
2911
|
-
this.oneTimeCallback = null;
|
|
3085
|
+
if (this._generatedContainerRole) this.el.removeAttribute("role");
|
|
3086
|
+
if (this._generatedContainerLabel) this.el.removeAttribute("aria-label");
|
|
3087
|
+
if (this._generatedContainerDescription) this.el.removeAttribute("aria-roledescription");
|
|
3088
|
+
if (this._generatedFixedHeight) this.el.classList.remove("fixed-height");
|
|
3089
|
+
if (this.options.height !== null) {
|
|
3090
|
+
if (this._authoredInlineHeight === null) this.el.style.removeProperty("--carousel-height");
|
|
3091
|
+
else this.el.style.setProperty("--carousel-height", this._authoredInlineHeight);
|
|
3092
|
+
}
|
|
3093
|
+
if (this._generatedWideLayout) {
|
|
3094
|
+
this.el.classList.remove(
|
|
3095
|
+
"multi-wide",
|
|
3096
|
+
"multi-large",
|
|
3097
|
+
"multi-extra-large",
|
|
3098
|
+
"full-screen-horizontal"
|
|
3099
|
+
);
|
|
2912
3100
|
}
|
|
2913
3101
|
}
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
3102
|
+
/** Start or stop the timer to match the current pause state. */
|
|
3103
|
+
_syncAutoAdvance() {
|
|
3104
|
+
const run = this._autoAdvances && !this._autoPaused && !this._hovered && !this._focused && !document.hidden;
|
|
3105
|
+
if (run && this._autoAdvanceTimer === null) {
|
|
3106
|
+
this._autoAdvanceTimer = setTimeout(
|
|
3107
|
+
this._tick,
|
|
3108
|
+
this.options.duration + this.options.interval
|
|
3109
|
+
);
|
|
3110
|
+
} else if (!run && this._autoAdvanceTimer !== null) {
|
|
3111
|
+
clearTimeout(this._autoAdvanceTimer);
|
|
3112
|
+
this._autoAdvanceTimer = null;
|
|
3113
|
+
}
|
|
2920
3114
|
}
|
|
2921
3115
|
_paintIndicators(center) {
|
|
2922
3116
|
if (!this.showIndicators || !this._indicators) return;
|
|
@@ -2928,18 +3122,12 @@ var Expressive = (() => {
|
|
|
2928
3122
|
else el.removeAttribute("aria-current");
|
|
2929
3123
|
});
|
|
2930
3124
|
}
|
|
2931
|
-
_syncA11y(index) {
|
|
2932
|
-
this.images.forEach((el, i) => {
|
|
2933
|
-
if (i === index) el.removeAttribute("aria-hidden");
|
|
2934
|
-
else el.setAttribute("aria-hidden", "true");
|
|
2935
|
-
});
|
|
2936
|
-
}
|
|
2937
3125
|
_syncActive(index, dragged) {
|
|
2938
3126
|
const prev = this.center;
|
|
2939
3127
|
this.center = index;
|
|
2940
3128
|
this.images.forEach((el, i) => el.classList.toggle("active", i === index));
|
|
2941
3129
|
this._paintIndicators(index);
|
|
2942
|
-
this.
|
|
3130
|
+
this._syncLayoutRoles(index);
|
|
2943
3131
|
const curr = this.images[index];
|
|
2944
3132
|
if (prev !== index && typeof this.options.onCycleTo === "function") {
|
|
2945
3133
|
this.options.onCycleTo.call(this, curr, dragged);
|
|
@@ -2949,6 +3137,81 @@ var Expressive = (() => {
|
|
|
2949
3137
|
this.oneTimeCallback = null;
|
|
2950
3138
|
}
|
|
2951
3139
|
}
|
|
3140
|
+
_syncLayoutRoles(index) {
|
|
3141
|
+
const setSize = (item, size) => {
|
|
3142
|
+
if (this._authoredItemSizes.has(item)) return;
|
|
3143
|
+
item.setAttribute("data-carousel-size", size);
|
|
3144
|
+
this._generatedItemSizes.add(item);
|
|
3145
|
+
};
|
|
3146
|
+
this.images.forEach((item) => setSize(item, "large"));
|
|
3147
|
+
if (this.el.classList.contains("flat") || this.el.classList.contains("uncontained") || this.el.classList.contains("full-screen") && this._vertical) {
|
|
3148
|
+
return;
|
|
3149
|
+
}
|
|
3150
|
+
if (this.el.classList.contains("hero") || this.el.classList.contains("full-screen-horizontal")) {
|
|
3151
|
+
const next = this.images[index + 1];
|
|
3152
|
+
if (next) setSize(next, "small");
|
|
3153
|
+
if (this.el.classList.contains("center-aligned")) {
|
|
3154
|
+
const previous = this.images[index - 1];
|
|
3155
|
+
if (previous) setSize(previous, "small");
|
|
3156
|
+
}
|
|
3157
|
+
return;
|
|
3158
|
+
}
|
|
3159
|
+
const width = this.el.clientWidth;
|
|
3160
|
+
const desiredLargeCount = width >= 1600 ? 4 : width >= 1200 ? 3 : width >= 600 ? 2 : 1;
|
|
3161
|
+
const largeCount = Math.min(desiredLargeCount, Math.max(1, this.count - 2));
|
|
3162
|
+
this.el.classList.remove("multi-wide", "multi-large", "multi-extra-large");
|
|
3163
|
+
if (largeCount === 2) this.el.classList.add("multi-wide");
|
|
3164
|
+
else if (largeCount === 3) this.el.classList.add("multi-large");
|
|
3165
|
+
else if (largeCount >= 4) this.el.classList.add("multi-extra-large");
|
|
3166
|
+
this._generatedWideLayout = this._generatedWideLayout || largeCount > 1;
|
|
3167
|
+
for (let offset = 1; offset < largeCount; offset += 1) {
|
|
3168
|
+
const item = this.images[index + offset];
|
|
3169
|
+
if (item) setSize(item, "large");
|
|
3170
|
+
}
|
|
3171
|
+
const medium = this.images[index + largeCount];
|
|
3172
|
+
const small = this.images[index + largeCount + 1];
|
|
3173
|
+
if (medium) setSize(medium, "medium");
|
|
3174
|
+
if (small) setSize(small, "small");
|
|
3175
|
+
}
|
|
3176
|
+
_syncAdaptiveMode() {
|
|
3177
|
+
if (!this.el.classList.contains("full-screen")) return;
|
|
3178
|
+
const landscape = window.matchMedia("(orientation: landscape)").matches;
|
|
3179
|
+
const horizontal = this.el.clientWidth >= 840 || landscape;
|
|
3180
|
+
const wasVertical = this._vertical;
|
|
3181
|
+
this._vertical = !horizontal;
|
|
3182
|
+
this.el.classList.toggle("full-screen-horizontal", horizontal);
|
|
3183
|
+
this._generatedWideLayout = this._generatedWideLayout || horizontal;
|
|
3184
|
+
if (this._started && wasVertical !== this._vertical) {
|
|
3185
|
+
this._scroller.scrollTo({ left: 0, top: 0, behavior: "auto" });
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
_focusItem(index) {
|
|
3189
|
+
const item = this.images[index];
|
|
3190
|
+
if (!item) return;
|
|
3191
|
+
const focusable = item.matches(
|
|
3192
|
+
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
3193
|
+
) ? item : item.querySelector(
|
|
3194
|
+
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
3195
|
+
);
|
|
3196
|
+
(focusable ?? item).focus({ preventScroll: true });
|
|
3197
|
+
}
|
|
3198
|
+
_updateParallax() {
|
|
3199
|
+
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
3200
|
+
this.images.forEach(
|
|
3201
|
+
(item) => item.style.setProperty("--md-comp-carousel-item-parallax", "0px")
|
|
3202
|
+
);
|
|
3203
|
+
return;
|
|
3204
|
+
}
|
|
3205
|
+
const scrollerRect = this._scroller.getBoundingClientRect();
|
|
3206
|
+
const viewportCenter = this._vertical ? scrollerRect.top + scrollerRect.height / 2 : scrollerRect.left + scrollerRect.width / 2;
|
|
3207
|
+
const viewportSize = Math.max(1, this._vertical ? scrollerRect.height : scrollerRect.width);
|
|
3208
|
+
this.images.forEach((item) => {
|
|
3209
|
+
const rect = item.getBoundingClientRect();
|
|
3210
|
+
const itemCenter = this._vertical ? rect.top + rect.height / 2 : rect.left + rect.width / 2;
|
|
3211
|
+
const progress = Math.max(-1, Math.min(1, (itemCenter - viewportCenter) / viewportSize));
|
|
3212
|
+
item.style.setProperty("--md-comp-carousel-item-parallax", `${progress * -24}px`);
|
|
3213
|
+
});
|
|
3214
|
+
}
|
|
2952
3215
|
_wrapTrack() {
|
|
2953
3216
|
const track = document.createElement("div");
|
|
2954
3217
|
track.className = "carousel-track";
|
|
@@ -2963,11 +3226,16 @@ var Expressive = (() => {
|
|
|
2963
3226
|
this._trackEl = null;
|
|
2964
3227
|
}
|
|
2965
3228
|
_nearestIndex() {
|
|
2966
|
-
const
|
|
3229
|
+
const centered = this.el.classList.contains("center-aligned");
|
|
3230
|
+
const position = this._vertical ? this._scroller.scrollTop : this._scroller.scrollLeft;
|
|
3231
|
+
const viewportCenter = position + (this._vertical ? this._scroller.clientHeight : this._scroller.clientWidth) / 2;
|
|
2967
3232
|
let best = 0;
|
|
2968
3233
|
let bestDist = Infinity;
|
|
2969
3234
|
this.images.forEach((el, i) => {
|
|
2970
|
-
const
|
|
3235
|
+
const start = this._vertical ? el.offsetTop : el.offsetLeft;
|
|
3236
|
+
const size = this._vertical ? el.offsetHeight : el.offsetWidth;
|
|
3237
|
+
const target = centered ? start + size / 2 : start;
|
|
3238
|
+
const dist = Math.abs(target - (centered ? viewportCenter : position));
|
|
2971
3239
|
if (dist < bestDist) {
|
|
2972
3240
|
bestDist = dist;
|
|
2973
3241
|
best = i;
|
|
@@ -2978,13 +3246,24 @@ var Expressive = (() => {
|
|
|
2978
3246
|
_scrollToIndex(n, smooth = true) {
|
|
2979
3247
|
const el = this.images[n];
|
|
2980
3248
|
if (!el) return;
|
|
2981
|
-
const
|
|
2982
|
-
|
|
3249
|
+
const centered = this.el.classList.contains("center-aligned");
|
|
3250
|
+
const style = getComputedStyle(this._scroller);
|
|
3251
|
+
const inlinePadding = Number.parseFloat(style.paddingInlineStart) || 0;
|
|
3252
|
+
const blockPadding = Number.parseFloat(style.paddingBlockStart) || 0;
|
|
3253
|
+
const left = centered ? el.offsetLeft - (this._scroller.clientWidth - el.offsetWidth) / 2 : el.offsetLeft - inlinePadding;
|
|
3254
|
+
const top = el.offsetTop - blockPadding;
|
|
3255
|
+
const current = this._vertical ? this._scroller.scrollTop : this._scroller.scrollLeft;
|
|
3256
|
+
const target = this._vertical ? top : left;
|
|
3257
|
+
if (Math.abs(current - target) < 1) {
|
|
2983
3258
|
this._syncActive(n, false);
|
|
2984
3259
|
return;
|
|
2985
3260
|
}
|
|
2986
3261
|
this._ignoreScroll = true;
|
|
2987
|
-
this._scroller.scrollTo({
|
|
3262
|
+
this._scroller.scrollTo({
|
|
3263
|
+
left: this._vertical ? 0 : left,
|
|
3264
|
+
top: this._vertical ? top : 0,
|
|
3265
|
+
behavior: smooth ? "smooth" : "auto"
|
|
3266
|
+
});
|
|
2988
3267
|
const done = () => {
|
|
2989
3268
|
this._ignoreScroll = false;
|
|
2990
3269
|
};
|
|
@@ -2992,63 +3271,38 @@ var Expressive = (() => {
|
|
|
2992
3271
|
window.setTimeout(done, this.options.duration + 350);
|
|
2993
3272
|
}
|
|
2994
3273
|
_cycleTo(n, callback = null) {
|
|
2995
|
-
if (this.
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
}
|
|
3012
|
-
}
|
|
3013
|
-
this.target = this.dim * Math.round(this.offset / this.dim);
|
|
3014
|
-
if (diff < 0) {
|
|
3015
|
-
this.target += this.dim * Math.abs(diff);
|
|
3016
|
-
} else if (diff > 0) {
|
|
3017
|
-
this.target -= this.dim * diff;
|
|
3018
|
-
}
|
|
3019
|
-
if (typeof callback === "function") {
|
|
3020
|
-
this.oneTimeCallback = callback;
|
|
3021
|
-
}
|
|
3022
|
-
if (this.offset !== this.target) {
|
|
3023
|
-
this.amplitude = this.target - this.offset;
|
|
3024
|
-
this.timestamp = Date.now();
|
|
3025
|
-
requestAnimationFrame(this._autoScroll);
|
|
3026
|
-
}
|
|
3274
|
+
if (typeof callback === "function") this.oneTimeCallback = callback;
|
|
3275
|
+
this._syncActive(n, false);
|
|
3276
|
+
this._scrollToIndex(n);
|
|
3277
|
+
}
|
|
3278
|
+
/**
|
|
3279
|
+
* Stop auto-advance until start() is called. Without an `interval` there is
|
|
3280
|
+
* nothing to stop and this does nothing.
|
|
3281
|
+
*/
|
|
3282
|
+
pause() {
|
|
3283
|
+
this._autoPaused = true;
|
|
3284
|
+
this._syncAutoAdvance();
|
|
3285
|
+
}
|
|
3286
|
+
/** Resume auto-advance after pause(). */
|
|
3287
|
+
start() {
|
|
3288
|
+
this._autoPaused = false;
|
|
3289
|
+
this._syncAutoAdvance();
|
|
3027
3290
|
}
|
|
3028
3291
|
next(n = 1) {
|
|
3029
3292
|
if (n === void 0 || isNaN(n)) n = 1;
|
|
3030
|
-
|
|
3031
|
-
if (index >= this.count || index < 0)
|
|
3032
|
-
if (this.noWrap) return;
|
|
3033
|
-
index = this._wrap(index);
|
|
3034
|
-
}
|
|
3293
|
+
const index = this.center + n;
|
|
3294
|
+
if (index >= this.count || index < 0) return;
|
|
3035
3295
|
this._cycleTo(index);
|
|
3036
3296
|
}
|
|
3037
3297
|
prev(n = 1) {
|
|
3038
3298
|
if (n === void 0 || isNaN(n)) n = 1;
|
|
3039
|
-
|
|
3040
|
-
if (index >= this.count || index < 0)
|
|
3041
|
-
if (this.noWrap) return;
|
|
3042
|
-
index = this._wrap(index);
|
|
3043
|
-
}
|
|
3299
|
+
const index = this.center - n;
|
|
3300
|
+
if (index >= this.count || index < 0) return;
|
|
3044
3301
|
this._cycleTo(index);
|
|
3045
3302
|
}
|
|
3046
3303
|
set(n, callback) {
|
|
3047
3304
|
if (n === void 0 || isNaN(n)) n = 0;
|
|
3048
|
-
if (n
|
|
3049
|
-
if (this.noWrap) return;
|
|
3050
|
-
n = this._wrap(n);
|
|
3051
|
-
}
|
|
3305
|
+
if (n >= this.count || n < 0) return;
|
|
3052
3306
|
this._cycleTo(n, callback);
|
|
3053
3307
|
}
|
|
3054
3308
|
};
|
|
@@ -3060,7 +3314,7 @@ var Expressive = (() => {
|
|
|
3060
3314
|
var Carousel = _Carousel;
|
|
3061
3315
|
|
|
3062
3316
|
// src/ts/components/characterCounter.ts
|
|
3063
|
-
var
|
|
3317
|
+
var _defaults9 = Object.freeze({});
|
|
3064
3318
|
var CharacterCounter = class _CharacterCounter extends Component {
|
|
3065
3319
|
constructor(el, options) {
|
|
3066
3320
|
super(el, {}, _CharacterCounter);
|
|
@@ -3085,7 +3339,7 @@ var Expressive = (() => {
|
|
|
3085
3339
|
this._setupEventHandlers();
|
|
3086
3340
|
}
|
|
3087
3341
|
static get defaults() {
|
|
3088
|
-
return
|
|
3342
|
+
return _defaults9;
|
|
3089
3343
|
}
|
|
3090
3344
|
/**
|
|
3091
3345
|
* Initializes instances of CharacterCounter.
|
|
@@ -3114,6 +3368,8 @@ var Expressive = (() => {
|
|
|
3114
3368
|
_setupCounter() {
|
|
3115
3369
|
this.counterEl = document.createElement("span");
|
|
3116
3370
|
this.counterEl.classList.add("character-counter");
|
|
3371
|
+
this.counterEl.setAttribute("aria-live", "polite");
|
|
3372
|
+
this.counterEl.setAttribute("aria-atomic", "true");
|
|
3117
3373
|
this.counterEl.style.float = "right";
|
|
3118
3374
|
this.counterEl.style.fontSize = "12px";
|
|
3119
3375
|
this.counterEl.style.height = "1";
|
|
@@ -3135,7 +3391,7 @@ var Expressive = (() => {
|
|
|
3135
3391
|
};
|
|
3136
3392
|
|
|
3137
3393
|
// src/ts/components/select.ts
|
|
3138
|
-
var
|
|
3394
|
+
var _defaults10 = {
|
|
3139
3395
|
classes: "",
|
|
3140
3396
|
menuOptions: {}
|
|
3141
3397
|
};
|
|
@@ -3184,7 +3440,7 @@ var Expressive = (() => {
|
|
|
3184
3440
|
this._setupEventHandlers();
|
|
3185
3441
|
}
|
|
3186
3442
|
static get defaults() {
|
|
3187
|
-
return
|
|
3443
|
+
return _defaults10;
|
|
3188
3444
|
}
|
|
3189
3445
|
/**
|
|
3190
3446
|
* Initializes instances of FormSelect.
|
|
@@ -3355,10 +3611,8 @@ var Expressive = (() => {
|
|
|
3355
3611
|
menuOptions.onOpenEnd = () => {
|
|
3356
3612
|
const selectedOption = this.menuEl.querySelector(".selected");
|
|
3357
3613
|
if (selectedOption) {
|
|
3358
|
-
Utils.keyDown = true;
|
|
3359
3614
|
this.menu.focusedIndex = [...selectedOption.parentNode.children].indexOf(selectedOption);
|
|
3360
3615
|
this.menu._focusFocusedItem();
|
|
3361
|
-
Utils.keyDown = false;
|
|
3362
3616
|
if (this.menu.isScrollable) {
|
|
3363
3617
|
let scrollOffset = selectedOption.getBoundingClientRect().top - this.menuEl.getBoundingClientRect().top;
|
|
3364
3618
|
scrollOffset -= this.menuEl.clientHeight / 2;
|
|
@@ -3558,7 +3812,7 @@ var Expressive = (() => {
|
|
|
3558
3812
|
};
|
|
3559
3813
|
|
|
3560
3814
|
// src/ts/plugins/dockedDisplayPlugin.ts
|
|
3561
|
-
var
|
|
3815
|
+
var _defaults11 = {
|
|
3562
3816
|
margin: 5,
|
|
3563
3817
|
transition: 10,
|
|
3564
3818
|
duration: 250,
|
|
@@ -3607,7 +3861,7 @@ var Expressive = (() => {
|
|
|
3607
3861
|
};
|
|
3608
3862
|
this.el = el;
|
|
3609
3863
|
this.options = {
|
|
3610
|
-
...
|
|
3864
|
+
..._defaults11,
|
|
3611
3865
|
...options
|
|
3612
3866
|
};
|
|
3613
3867
|
this.container = document.createElement("div");
|
|
@@ -3628,7 +3882,7 @@ var Expressive = (() => {
|
|
|
3628
3882
|
};
|
|
3629
3883
|
|
|
3630
3884
|
// src/ts/components/datepicker.ts
|
|
3631
|
-
var
|
|
3885
|
+
var _defaults12 = {
|
|
3632
3886
|
// the default output format for the input field value
|
|
3633
3887
|
format: "mmm dd, yyyy",
|
|
3634
3888
|
// Used to create date object from current input string
|
|
@@ -3753,7 +4007,7 @@ var Expressive = (() => {
|
|
|
3753
4007
|
if (this.options.onInputInteraction) this.options.onInputInteraction.call(this);
|
|
3754
4008
|
};
|
|
3755
4009
|
this._handleInputKeydown = (e) => {
|
|
3756
|
-
if (Utils.keys.ENTER
|
|
4010
|
+
if (e.key === Utils.keys.ENTER) {
|
|
3757
4011
|
e.preventDefault();
|
|
3758
4012
|
this._batchDraws(() => {
|
|
3759
4013
|
this.setDateFromInput(e.target);
|
|
@@ -3893,7 +4147,7 @@ var Expressive = (() => {
|
|
|
3893
4147
|
}
|
|
3894
4148
|
}
|
|
3895
4149
|
static get defaults() {
|
|
3896
|
-
return
|
|
4150
|
+
return _defaults12;
|
|
3897
4151
|
}
|
|
3898
4152
|
/**
|
|
3899
4153
|
* Initializes instances of Datepicker.
|
|
@@ -4476,11 +4730,11 @@ var Expressive = (() => {
|
|
|
4476
4730
|
const monthSelect = this.calendarEl.querySelector(".orig-select-month");
|
|
4477
4731
|
FormSelect.init(yearSelect, {
|
|
4478
4732
|
classes: "select-year",
|
|
4479
|
-
menuOptions: { container:
|
|
4733
|
+
menuOptions: { container: Utils.portalRoot(this.el), constrainWidth: false }
|
|
4480
4734
|
});
|
|
4481
4735
|
FormSelect.init(monthSelect, {
|
|
4482
4736
|
classes: "select-month",
|
|
4483
|
-
menuOptions: { container:
|
|
4737
|
+
menuOptions: { container: Utils.portalRoot(this.el), constrainWidth: false }
|
|
4484
4738
|
});
|
|
4485
4739
|
yearSelect.addEventListener("change", this._handleYearChange);
|
|
4486
4740
|
monthSelect.addEventListener("change", this._handleMonthChange);
|
|
@@ -4611,7 +4865,7 @@ var Expressive = (() => {
|
|
|
4611
4865
|
var Datepicker = _Datepicker;
|
|
4612
4866
|
|
|
4613
4867
|
// src/ts/components/lightbox.ts
|
|
4614
|
-
var
|
|
4868
|
+
var _defaults13 = {
|
|
4615
4869
|
inDuration: 275,
|
|
4616
4870
|
outDuration: 200,
|
|
4617
4871
|
onOpenStart: null,
|
|
@@ -4626,7 +4880,7 @@ var Expressive = (() => {
|
|
|
4626
4880
|
this._handleLightboxToggle();
|
|
4627
4881
|
};
|
|
4628
4882
|
this._handleLightboxKeypress = (e) => {
|
|
4629
|
-
if (Utils.keys.ENTER
|
|
4883
|
+
if (e.key === Utils.keys.ENTER) {
|
|
4630
4884
|
this._handleLightboxToggle();
|
|
4631
4885
|
}
|
|
4632
4886
|
};
|
|
@@ -4641,7 +4895,7 @@ var Expressive = (() => {
|
|
|
4641
4895
|
if (this.overlayActive) this.close();
|
|
4642
4896
|
};
|
|
4643
4897
|
this._handleWindowEscape = (e) => {
|
|
4644
|
-
if (Utils.keys.ESC
|
|
4898
|
+
if (e.key === Utils.keys.ESC && this.doneAnimating && this.overlayActive) this.close();
|
|
4645
4899
|
};
|
|
4646
4900
|
/**
|
|
4647
4901
|
* Open lightbox.
|
|
@@ -4730,7 +4984,7 @@ var Expressive = (() => {
|
|
|
4730
4984
|
this._setupEventHandlers();
|
|
4731
4985
|
}
|
|
4732
4986
|
static get defaults() {
|
|
4733
|
-
return
|
|
4987
|
+
return _defaults13;
|
|
4734
4988
|
}
|
|
4735
4989
|
/**
|
|
4736
4990
|
* Initializes instances of Lightbox.
|
|
@@ -4760,13 +5014,13 @@ var Expressive = (() => {
|
|
|
4760
5014
|
_makeAncestorsOverflowVisible() {
|
|
4761
5015
|
this._changedAncestorList = [];
|
|
4762
5016
|
let ancestor = this.placeholder.parentNode;
|
|
4763
|
-
while (ancestor !== null && ancestor !== document) {
|
|
5017
|
+
while (ancestor !== null && ancestor !== void 0 && ancestor !== document) {
|
|
4764
5018
|
const curr = ancestor;
|
|
4765
|
-
if (curr.style.overflow !== "visible") {
|
|
5019
|
+
if (curr.style && curr.style.overflow !== "visible") {
|
|
5020
|
+
this._changedAncestorList.push([curr, curr.style.overflow]);
|
|
4766
5021
|
curr.style.overflow = "visible";
|
|
4767
|
-
this._changedAncestorList.push(curr);
|
|
4768
5022
|
}
|
|
4769
|
-
ancestor = ancestor.parentNode;
|
|
5023
|
+
ancestor = ancestor.parentNode ?? ancestor.host;
|
|
4770
5024
|
}
|
|
4771
5025
|
}
|
|
4772
5026
|
_offset(el) {
|
|
@@ -4830,7 +5084,7 @@ var Expressive = (() => {
|
|
|
4830
5084
|
if (this.originInlineStyles) this.el.setAttribute("style", this.originInlineStyles);
|
|
4831
5085
|
this.el.classList.remove("active");
|
|
4832
5086
|
this.doneAnimating = true;
|
|
4833
|
-
this._changedAncestorList.forEach((
|
|
5087
|
+
this._changedAncestorList.forEach(([ancestor, overflow]) => ancestor.style.overflow = overflow);
|
|
4834
5088
|
if (typeof this.options.onCloseEnd === "function")
|
|
4835
5089
|
this.options.onCloseEnd.call(this, this.el);
|
|
4836
5090
|
}, duration);
|
|
@@ -4840,7 +5094,7 @@ var Expressive = (() => {
|
|
|
4840
5094
|
this._photoCaption = document.createElement("div");
|
|
4841
5095
|
this._photoCaption.classList.add("lightbox-caption");
|
|
4842
5096
|
this._photoCaption.innerText = this.caption;
|
|
4843
|
-
|
|
5097
|
+
Utils.portalRoot(this.el).append(this._photoCaption);
|
|
4844
5098
|
this._photoCaption.style.display = "inline";
|
|
4845
5099
|
this._photoCaption.style.transition = "none";
|
|
4846
5100
|
this._photoCaption.style.opacity = "0";
|
|
@@ -4894,34 +5148,6 @@ var Expressive = (() => {
|
|
|
4894
5148
|
}
|
|
4895
5149
|
};
|
|
4896
5150
|
|
|
4897
|
-
// src/ts/components/parallax.ts
|
|
4898
|
-
var _defaults13 = {};
|
|
4899
|
-
var Parallax = class _Parallax extends Component {
|
|
4900
|
-
constructor(el, options) {
|
|
4901
|
-
super(el, options, _Parallax);
|
|
4902
|
-
this.el["Expressive_Parallax"] = this;
|
|
4903
|
-
this.options = {
|
|
4904
|
-
..._Parallax.defaults,
|
|
4905
|
-
...options
|
|
4906
|
-
};
|
|
4907
|
-
if (!this.el.querySelector("img, video")) {
|
|
4908
|
-
console.error("Parallax: no <img> or <video> to move inside the .parallax element");
|
|
4909
|
-
}
|
|
4910
|
-
}
|
|
4911
|
-
static get defaults() {
|
|
4912
|
-
return _defaults13;
|
|
4913
|
-
}
|
|
4914
|
-
static init(els, options = {}) {
|
|
4915
|
-
return super.init(els, options, _Parallax);
|
|
4916
|
-
}
|
|
4917
|
-
static getInstance(el) {
|
|
4918
|
-
return el["Expressive_Parallax"];
|
|
4919
|
-
}
|
|
4920
|
-
destroy() {
|
|
4921
|
-
this.el["Expressive_Parallax"] = void 0;
|
|
4922
|
-
}
|
|
4923
|
-
};
|
|
4924
|
-
|
|
4925
5151
|
// src/ts/components/scrollspy.ts
|
|
4926
5152
|
var _defaultGetActiveElement = (id) => `a[href="#${id}"]`;
|
|
4927
5153
|
var _defaults14 = {
|
|
@@ -5068,7 +5294,7 @@ var Expressive = (() => {
|
|
|
5068
5294
|
};
|
|
5069
5295
|
var ScrollSpy = _ScrollSpy;
|
|
5070
5296
|
|
|
5071
|
-
// src/ts/components/
|
|
5297
|
+
// src/ts/components/navigationDrawer.ts
|
|
5072
5298
|
var _defaults15 = {
|
|
5073
5299
|
edge: "left",
|
|
5074
5300
|
draggable: true,
|
|
@@ -5078,17 +5304,17 @@ var Expressive = (() => {
|
|
|
5078
5304
|
onCloseStart: null,
|
|
5079
5305
|
onCloseEnd: null
|
|
5080
5306
|
};
|
|
5081
|
-
var
|
|
5082
|
-
var
|
|
5307
|
+
var EXPANDED_UP = "(width >= 840px)";
|
|
5308
|
+
var _NavigationDrawer = class _NavigationDrawer extends Component {
|
|
5083
5309
|
constructor(el, options) {
|
|
5084
|
-
super(el, options,
|
|
5310
|
+
super(el, options, _NavigationDrawer);
|
|
5085
5311
|
/**
|
|
5086
5312
|
* Opens the overlay drawer. No-op while the sidenav is docked
|
|
5087
|
-
* (
|
|
5313
|
+
* (navigation-drawer-fixed at the Expanded breakpoint).
|
|
5088
5314
|
*/
|
|
5089
5315
|
this.open = () => {
|
|
5090
5316
|
if (this._isCurrentlyFixed() || this.isOpen || !this._dialog) return;
|
|
5091
|
-
|
|
5317
|
+
_NavigationDrawer._sidenavs.forEach((other) => {
|
|
5092
5318
|
if (other !== this && other.isOpen) other.close();
|
|
5093
5319
|
});
|
|
5094
5320
|
if (typeof this.options.onOpenStart === "function") {
|
|
@@ -5140,7 +5366,7 @@ var Expressive = (() => {
|
|
|
5140
5366
|
this._handleCloseTriggerClick = (e) => {
|
|
5141
5367
|
const target = e.target;
|
|
5142
5368
|
if (!(target instanceof Element)) return;
|
|
5143
|
-
const closeTrigger = target.closest(".sidenav-close");
|
|
5369
|
+
const closeTrigger = target.closest(".sidenav-close, .navigation-drawer-close");
|
|
5144
5370
|
if (closeTrigger && !this._isCurrentlyFixed()) {
|
|
5145
5371
|
this.close();
|
|
5146
5372
|
}
|
|
@@ -5184,14 +5410,14 @@ var Expressive = (() => {
|
|
|
5184
5410
|
this.isDragged = false;
|
|
5185
5411
|
this._verticallyScrolling = false;
|
|
5186
5412
|
};
|
|
5187
|
-
this.el["
|
|
5413
|
+
this.el["Expressive_NavigationDrawer"] = this;
|
|
5188
5414
|
this.options = {
|
|
5189
|
-
...
|
|
5415
|
+
..._NavigationDrawer.defaults,
|
|
5190
5416
|
...options
|
|
5191
5417
|
};
|
|
5192
5418
|
this.id = this.el.id;
|
|
5193
5419
|
this.isOpen = false;
|
|
5194
|
-
this.isFixed = this.el.classList.contains("sidenav-fixed");
|
|
5420
|
+
this.isFixed = this.el.classList.contains("navigation-drawer-fixed") || this.el.classList.contains("sidenav-fixed");
|
|
5195
5421
|
this.isDragged = false;
|
|
5196
5422
|
this.dragTarget = null;
|
|
5197
5423
|
this._dialog = null;
|
|
@@ -5203,27 +5429,27 @@ var Expressive = (() => {
|
|
|
5203
5429
|
this._width = 0;
|
|
5204
5430
|
this._initialScrollTop = 0;
|
|
5205
5431
|
this._verticallyScrolling = false;
|
|
5206
|
-
this._mql = window.matchMedia(
|
|
5432
|
+
this._mql = window.matchMedia(EXPANDED_UP);
|
|
5207
5433
|
this._setupDialog();
|
|
5208
5434
|
this._createDragTarget();
|
|
5209
5435
|
this._setupClasses();
|
|
5210
5436
|
this._setupEventHandlers();
|
|
5211
5437
|
this._syncTriggers();
|
|
5212
|
-
|
|
5438
|
+
_NavigationDrawer._sidenavs.push(this);
|
|
5213
5439
|
}
|
|
5214
5440
|
static get defaults() {
|
|
5215
5441
|
return _defaults15;
|
|
5216
5442
|
}
|
|
5217
5443
|
/**
|
|
5218
|
-
* Initializes instances of
|
|
5444
|
+
* Initializes instances of NavigationDrawer.
|
|
5219
5445
|
* @param els HTML elements.
|
|
5220
5446
|
* @param options Component options.
|
|
5221
5447
|
*/
|
|
5222
5448
|
static init(els, options = {}) {
|
|
5223
|
-
return super.init(els, options,
|
|
5449
|
+
return super.init(els, options, _NavigationDrawer);
|
|
5224
5450
|
}
|
|
5225
5451
|
static getInstance(el) {
|
|
5226
|
-
return el["
|
|
5452
|
+
return el["Expressive_NavigationDrawer"];
|
|
5227
5453
|
}
|
|
5228
5454
|
destroy() {
|
|
5229
5455
|
this._removeEventHandlers();
|
|
@@ -5236,10 +5462,10 @@ var Expressive = (() => {
|
|
|
5236
5462
|
this._clearShift();
|
|
5237
5463
|
this._unwrapDialog();
|
|
5238
5464
|
this._removeDragTarget();
|
|
5239
|
-
this.el["
|
|
5240
|
-
const index =
|
|
5465
|
+
this.el["Expressive_NavigationDrawer"] = void 0;
|
|
5466
|
+
const index = _NavigationDrawer._sidenavs.indexOf(this);
|
|
5241
5467
|
if (index >= 0) {
|
|
5242
|
-
|
|
5468
|
+
_NavigationDrawer._sidenavs.splice(index, 1);
|
|
5243
5469
|
}
|
|
5244
5470
|
}
|
|
5245
5471
|
_beginClose() {
|
|
@@ -5270,6 +5496,11 @@ var Expressive = (() => {
|
|
|
5270
5496
|
}
|
|
5271
5497
|
const dialog = document.createElement("dialog");
|
|
5272
5498
|
dialog.classList.add("sidenav-overlay");
|
|
5499
|
+
const named = this.el.closest("[aria-label], [aria-labelledby]") ?? this.el;
|
|
5500
|
+
const label = named.getAttribute("aria-label");
|
|
5501
|
+
const labelledBy = named.getAttribute("aria-labelledby");
|
|
5502
|
+
if (label) dialog.setAttribute("aria-label", label);
|
|
5503
|
+
else if (labelledBy) dialog.setAttribute("aria-labelledby", labelledBy);
|
|
5273
5504
|
this.el.replaceWith(dialog);
|
|
5274
5505
|
dialog.appendChild(this.el);
|
|
5275
5506
|
this._dialog = dialog;
|
|
@@ -5287,7 +5518,7 @@ var Expressive = (() => {
|
|
|
5287
5518
|
dragTarget.classList.add("drag-target");
|
|
5288
5519
|
dragTarget.style.width = this.options.dragTargetWidth;
|
|
5289
5520
|
if (this.isFixed) dragTarget.dataset.fixed = "";
|
|
5290
|
-
|
|
5521
|
+
Utils.portalRoot(this.el).appendChild(dragTarget);
|
|
5291
5522
|
this.dragTarget = dragTarget;
|
|
5292
5523
|
}
|
|
5293
5524
|
_removeDragTarget() {
|
|
@@ -5302,8 +5533,8 @@ var Expressive = (() => {
|
|
|
5302
5533
|
}
|
|
5303
5534
|
}
|
|
5304
5535
|
_setupEventHandlers() {
|
|
5305
|
-
if (
|
|
5306
|
-
document.body.addEventListener("click",
|
|
5536
|
+
if (_NavigationDrawer._sidenavs.length === 0) {
|
|
5537
|
+
document.body.addEventListener("click", _NavigationDrawer._handleTriggerClick);
|
|
5307
5538
|
}
|
|
5308
5539
|
const passive = { passive: true };
|
|
5309
5540
|
this.dragTarget?.addEventListener("touchmove", this._handleDragTargetDrag, passive);
|
|
@@ -5315,8 +5546,8 @@ var Expressive = (() => {
|
|
|
5315
5546
|
this._mql.addEventListener("change", this._onBreakpointChange);
|
|
5316
5547
|
}
|
|
5317
5548
|
_removeEventHandlers() {
|
|
5318
|
-
if (
|
|
5319
|
-
document.body.removeEventListener("click",
|
|
5549
|
+
if (_NavigationDrawer._sidenavs.length === 1) {
|
|
5550
|
+
document.body.removeEventListener("click", _NavigationDrawer._handleTriggerClick);
|
|
5320
5551
|
}
|
|
5321
5552
|
this.dragTarget?.removeEventListener("touchmove", this._handleDragTargetDrag);
|
|
5322
5553
|
this.dragTarget?.removeEventListener("touchend", this._handleDragTargetRelease);
|
|
@@ -5329,10 +5560,10 @@ var Expressive = (() => {
|
|
|
5329
5560
|
static _handleTriggerClick(e) {
|
|
5330
5561
|
const target = e.target;
|
|
5331
5562
|
if (!(target instanceof Element)) return;
|
|
5332
|
-
const trigger = target.closest(".sidenav-trigger");
|
|
5563
|
+
const trigger = target.closest(".sidenav-trigger, .navigation-drawer-trigger");
|
|
5333
5564
|
if (!trigger || !(trigger instanceof HTMLElement)) return;
|
|
5334
5565
|
const sidenavId = Utils.getIdFromTrigger(trigger);
|
|
5335
|
-
const sidenavInstance =
|
|
5566
|
+
const sidenavInstance = Utils.getElementById(trigger, sidenavId)?.["Expressive_NavigationDrawer"];
|
|
5336
5567
|
if (sidenavInstance) {
|
|
5337
5568
|
sidenavInstance.open();
|
|
5338
5569
|
e.preventDefault();
|
|
@@ -5386,7 +5617,7 @@ var Expressive = (() => {
|
|
|
5386
5617
|
}
|
|
5387
5618
|
_syncTriggers() {
|
|
5388
5619
|
if (!this.id) return;
|
|
5389
|
-
document.querySelectorAll(".sidenav-trigger").forEach((trigger) => {
|
|
5620
|
+
document.querySelectorAll(".sidenav-trigger, .navigation-drawer-trigger").forEach((trigger) => {
|
|
5390
5621
|
if (!(trigger instanceof HTMLElement)) return;
|
|
5391
5622
|
if (Utils.getIdFromTrigger(trigger) !== this.id) return;
|
|
5392
5623
|
trigger.setAttribute("aria-expanded", this.isOpen ? "true" : "false");
|
|
@@ -5394,8 +5625,8 @@ var Expressive = (() => {
|
|
|
5394
5625
|
});
|
|
5395
5626
|
}
|
|
5396
5627
|
};
|
|
5397
|
-
|
|
5398
|
-
var
|
|
5628
|
+
_NavigationDrawer._sidenavs = [];
|
|
5629
|
+
var NavigationDrawer = _NavigationDrawer;
|
|
5399
5630
|
|
|
5400
5631
|
// src/ts/components/navigationRail.ts
|
|
5401
5632
|
var _defaults16 = {
|
|
@@ -5404,7 +5635,7 @@ var Expressive = (() => {
|
|
|
5404
5635
|
onCloseStart: null,
|
|
5405
5636
|
onCloseEnd: null
|
|
5406
5637
|
};
|
|
5407
|
-
var COMPACT = "(width <
|
|
5638
|
+
var COMPACT = "(width < 600px)";
|
|
5408
5639
|
var NavigationRail = class _NavigationRail extends Component {
|
|
5409
5640
|
constructor(el, options) {
|
|
5410
5641
|
super(el, options, _NavigationRail);
|
|
@@ -5503,309 +5734,8 @@ var Expressive = (() => {
|
|
|
5503
5734
|
}
|
|
5504
5735
|
};
|
|
5505
5736
|
|
|
5506
|
-
// src/ts/components/slider.ts
|
|
5507
|
-
var _defaults17 = {
|
|
5508
|
-
indicators: true,
|
|
5509
|
-
height: 400,
|
|
5510
|
-
duration: 500,
|
|
5511
|
-
interval: 6e3,
|
|
5512
|
-
pauseOnFocus: true,
|
|
5513
|
-
pauseOnHover: true,
|
|
5514
|
-
indicatorLabelFunc: null
|
|
5515
|
-
// Function which will generate a label for the indicators (ARIA)
|
|
5516
|
-
};
|
|
5517
|
-
var Slider = class _Slider extends Component {
|
|
5518
|
-
constructor(el, options) {
|
|
5519
|
-
super(el, options, _Slider);
|
|
5520
|
-
// Nobody is watching a backgrounded tab. Browsers clamp the timer rather
|
|
5521
|
-
// than stopping it, so without this the slider keeps cycling slides - and
|
|
5522
|
-
// running their transitions - out of sight.
|
|
5523
|
-
this._handleVisibilityChange = () => {
|
|
5524
|
-
if (document.hidden) {
|
|
5525
|
-
if (this.interval != null) this._pause(true);
|
|
5526
|
-
} else if (this.eventPause && !(this.options.pauseOnHover && this._hovered) && !(this.options.pauseOnFocus && this._focused)) {
|
|
5527
|
-
this.start();
|
|
5528
|
-
}
|
|
5529
|
-
};
|
|
5530
|
-
this._handleIndicatorClick = (e) => {
|
|
5531
|
-
const el = e.target.parentElement;
|
|
5532
|
-
const currIndex = [...el.parentNode.children].indexOf(el);
|
|
5533
|
-
this._focusCurrent = true;
|
|
5534
|
-
this.set(currIndex);
|
|
5535
|
-
};
|
|
5536
|
-
this._handleAutoPauseHover = () => {
|
|
5537
|
-
this._hovered = true;
|
|
5538
|
-
if (this.interval != null) {
|
|
5539
|
-
this._pause(true);
|
|
5540
|
-
}
|
|
5541
|
-
};
|
|
5542
|
-
this._handleAutoPauseFocus = () => {
|
|
5543
|
-
this._focused = true;
|
|
5544
|
-
if (this.interval != null) {
|
|
5545
|
-
this._pause(true);
|
|
5546
|
-
}
|
|
5547
|
-
};
|
|
5548
|
-
this._handleAutoStartHover = () => {
|
|
5549
|
-
this._hovered = false;
|
|
5550
|
-
if (!(this.options.pauseOnFocus && this._focused) && this.eventPause) {
|
|
5551
|
-
this.start();
|
|
5552
|
-
}
|
|
5553
|
-
};
|
|
5554
|
-
this._handleAutoStartFocus = () => {
|
|
5555
|
-
this._focused = false;
|
|
5556
|
-
if (!(this.options.pauseOnHover && this._hovered) && this.eventPause) {
|
|
5557
|
-
this.start();
|
|
5558
|
-
}
|
|
5559
|
-
};
|
|
5560
|
-
this._handleInterval = () => {
|
|
5561
|
-
const activeElem = this._slider.querySelector(".active");
|
|
5562
|
-
let newActiveIndex = [...activeElem.parentNode.children].indexOf(activeElem);
|
|
5563
|
-
if (this._slides.length === newActiveIndex + 1)
|
|
5564
|
-
newActiveIndex = 0;
|
|
5565
|
-
else newActiveIndex += 1;
|
|
5566
|
-
this.set(newActiveIndex);
|
|
5567
|
-
};
|
|
5568
|
-
/**
|
|
5569
|
-
* Pause slider autoslide.
|
|
5570
|
-
*/
|
|
5571
|
-
this.pause = () => {
|
|
5572
|
-
this._pause(false);
|
|
5573
|
-
};
|
|
5574
|
-
/**
|
|
5575
|
-
* Start slider autoslide.
|
|
5576
|
-
*/
|
|
5577
|
-
this.start = () => {
|
|
5578
|
-
clearInterval(this.interval);
|
|
5579
|
-
this.interval = setInterval(
|
|
5580
|
-
this._handleInterval,
|
|
5581
|
-
this.options.duration + this.options.interval
|
|
5582
|
-
);
|
|
5583
|
-
this.eventPause = false;
|
|
5584
|
-
};
|
|
5585
|
-
/**
|
|
5586
|
-
* Move to next slider.
|
|
5587
|
-
*/
|
|
5588
|
-
this.next = () => {
|
|
5589
|
-
let newIndex = this.activeIndex + 1;
|
|
5590
|
-
if (newIndex >= this._slides.length) newIndex = 0;
|
|
5591
|
-
else if (newIndex < 0) newIndex = this._slides.length - 1;
|
|
5592
|
-
this.set(newIndex);
|
|
5593
|
-
};
|
|
5594
|
-
/**
|
|
5595
|
-
* Move to prev slider.
|
|
5596
|
-
*/
|
|
5597
|
-
this.prev = () => {
|
|
5598
|
-
let newIndex = this.activeIndex - 1;
|
|
5599
|
-
if (newIndex >= this._slides.length) newIndex = 0;
|
|
5600
|
-
else if (newIndex < 0) newIndex = this._slides.length - 1;
|
|
5601
|
-
this.set(newIndex);
|
|
5602
|
-
};
|
|
5603
|
-
this.el["Expressive_Slider"] = this;
|
|
5604
|
-
this.options = {
|
|
5605
|
-
..._Slider.defaults,
|
|
5606
|
-
...options
|
|
5607
|
-
};
|
|
5608
|
-
this.interval = null;
|
|
5609
|
-
this.eventPause = false;
|
|
5610
|
-
this._hovered = false;
|
|
5611
|
-
this._focused = false;
|
|
5612
|
-
this._focusCurrent = false;
|
|
5613
|
-
this._slider = this.el.querySelector(".slides");
|
|
5614
|
-
this._slides = Array.from(this._slider.querySelectorAll("li"));
|
|
5615
|
-
this.activeIndex = this._slides.findIndex((li) => li.classList.contains("active"));
|
|
5616
|
-
if (this.activeIndex !== -1) {
|
|
5617
|
-
this._activeSlide = this._slides[this.activeIndex];
|
|
5618
|
-
}
|
|
5619
|
-
this._setSliderHeight();
|
|
5620
|
-
if (this._slider.hasAttribute("id")) this._sliderId = this._slider.getAttribute("id");
|
|
5621
|
-
else {
|
|
5622
|
-
this._sliderId = "slider-" + Utils.guid();
|
|
5623
|
-
this._slider.setAttribute("id", this._sliderId);
|
|
5624
|
-
}
|
|
5625
|
-
const placeholderBase64 = "data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
|
|
5626
|
-
this._slides.forEach((slide) => {
|
|
5627
|
-
const img = slide.querySelector("img");
|
|
5628
|
-
if (img) {
|
|
5629
|
-
if (img.src !== placeholderBase64) {
|
|
5630
|
-
img.style.backgroundImage = "url(" + img.src + ")";
|
|
5631
|
-
img.src = placeholderBase64;
|
|
5632
|
-
}
|
|
5633
|
-
}
|
|
5634
|
-
if (!slide.hasAttribute("tabindex")) slide.setAttribute("tabindex", "-1");
|
|
5635
|
-
slide.style.visibility = "hidden";
|
|
5636
|
-
});
|
|
5637
|
-
this._setupIndicators();
|
|
5638
|
-
if (this._activeSlide) {
|
|
5639
|
-
this._activeSlide.style.display = "block";
|
|
5640
|
-
this._activeSlide.style.visibility = "visible";
|
|
5641
|
-
} else {
|
|
5642
|
-
this.activeIndex = 0;
|
|
5643
|
-
this._slides[0].classList.add("active");
|
|
5644
|
-
this._slides[0].style.visibility = "visible";
|
|
5645
|
-
this._activeSlide = this._slides[0];
|
|
5646
|
-
this._animateSlide(this._slides[0], true);
|
|
5647
|
-
if (this.options.indicators) {
|
|
5648
|
-
this._indicators[this.activeIndex].children[0].classList.add("active");
|
|
5649
|
-
}
|
|
5650
|
-
}
|
|
5651
|
-
this._setupEventHandlers();
|
|
5652
|
-
this.start();
|
|
5653
|
-
}
|
|
5654
|
-
static get defaults() {
|
|
5655
|
-
return _defaults17;
|
|
5656
|
-
}
|
|
5657
|
-
/**
|
|
5658
|
-
* Initializes instances of Slider.
|
|
5659
|
-
* @param els HTML elements.
|
|
5660
|
-
* @param options Component options.
|
|
5661
|
-
*/
|
|
5662
|
-
static init(els, options = {}) {
|
|
5663
|
-
return super.init(els, options, _Slider);
|
|
5664
|
-
}
|
|
5665
|
-
static getInstance(el) {
|
|
5666
|
-
return el["Expressive_Slider"];
|
|
5667
|
-
}
|
|
5668
|
-
destroy() {
|
|
5669
|
-
this.pause();
|
|
5670
|
-
this._removeIndicators();
|
|
5671
|
-
this._removeEventHandlers();
|
|
5672
|
-
this.el["Expressive_Slider"] = void 0;
|
|
5673
|
-
}
|
|
5674
|
-
_setupEventHandlers() {
|
|
5675
|
-
if (this.options.pauseOnFocus) {
|
|
5676
|
-
this.el.addEventListener("focusin", this._handleAutoPauseFocus);
|
|
5677
|
-
this.el.addEventListener("focusout", this._handleAutoStartFocus);
|
|
5678
|
-
}
|
|
5679
|
-
if (this.options.pauseOnHover) {
|
|
5680
|
-
this.el.addEventListener("mouseenter", this._handleAutoPauseHover);
|
|
5681
|
-
this.el.addEventListener("mouseleave", this._handleAutoStartHover);
|
|
5682
|
-
}
|
|
5683
|
-
if (this.options.indicators) {
|
|
5684
|
-
this._indicators.forEach((el) => {
|
|
5685
|
-
el.addEventListener("click", this._handleIndicatorClick);
|
|
5686
|
-
});
|
|
5687
|
-
}
|
|
5688
|
-
document.addEventListener("visibilitychange", this._handleVisibilityChange);
|
|
5689
|
-
}
|
|
5690
|
-
_removeEventHandlers() {
|
|
5691
|
-
if (this.options.pauseOnFocus) {
|
|
5692
|
-
this.el.removeEventListener("focusin", this._handleAutoPauseFocus);
|
|
5693
|
-
this.el.removeEventListener("focusout", this._handleAutoStartFocus);
|
|
5694
|
-
}
|
|
5695
|
-
if (this.options.pauseOnHover) {
|
|
5696
|
-
this.el.removeEventListener("mouseenter", this._handleAutoPauseHover);
|
|
5697
|
-
this.el.removeEventListener("mouseleave", this._handleAutoStartHover);
|
|
5698
|
-
}
|
|
5699
|
-
if (this.options.indicators) {
|
|
5700
|
-
this._indicators.forEach((el) => {
|
|
5701
|
-
el.removeEventListener("click", this._handleIndicatorClick);
|
|
5702
|
-
});
|
|
5703
|
-
}
|
|
5704
|
-
document.removeEventListener("visibilitychange", this._handleVisibilityChange);
|
|
5705
|
-
}
|
|
5706
|
-
_animateSlide(slide, isDirectionIn) {
|
|
5707
|
-
let dx = 0, dy = 0;
|
|
5708
|
-
slide.style.opacity = isDirectionIn ? "0" : "1";
|
|
5709
|
-
setTimeout(() => {
|
|
5710
|
-
slide.style.transition = `opacity ${this.options.duration}ms ease`;
|
|
5711
|
-
slide.style.opacity = isDirectionIn ? "1" : "0";
|
|
5712
|
-
}, 1);
|
|
5713
|
-
const caption = slide.querySelector(".caption");
|
|
5714
|
-
if (!caption) return;
|
|
5715
|
-
if (caption.classList.contains("center-align")) dy = -100;
|
|
5716
|
-
else if (caption.classList.contains("right-align")) dx = 100;
|
|
5717
|
-
else if (caption.classList.contains("left-align")) dx = -100;
|
|
5718
|
-
caption.style.opacity = isDirectionIn ? "0" : "1";
|
|
5719
|
-
caption.style.transform = isDirectionIn ? `translate(${dx}px, ${dy}px)` : `translate(0, 0)`;
|
|
5720
|
-
setTimeout(() => {
|
|
5721
|
-
caption.style.transition = `opacity ${this.options.duration}ms ease, transform ${this.options.duration}ms ease`;
|
|
5722
|
-
caption.style.opacity = isDirectionIn ? "1" : "0";
|
|
5723
|
-
caption.style.transform = isDirectionIn ? `translate(0, 0)` : `translate(${dx}px, ${dy}px)`;
|
|
5724
|
-
}, this.options.duration);
|
|
5725
|
-
}
|
|
5726
|
-
_setSliderHeight() {
|
|
5727
|
-
if (!this.el.classList.contains("fullscreen")) {
|
|
5728
|
-
if (this.options.indicators) {
|
|
5729
|
-
this.el.style.height = this.options.height + 40 + "px";
|
|
5730
|
-
} else {
|
|
5731
|
-
this.el.style.height = this.options.height + "px";
|
|
5732
|
-
}
|
|
5733
|
-
this._slider.style.height = this.options.height + "px";
|
|
5734
|
-
}
|
|
5735
|
-
}
|
|
5736
|
-
_setupIndicators() {
|
|
5737
|
-
if (this.options.indicators) {
|
|
5738
|
-
const ul = document.createElement("ul");
|
|
5739
|
-
ul.classList.add("indicators");
|
|
5740
|
-
const arrLi = [];
|
|
5741
|
-
this._slides.forEach((el, i) => {
|
|
5742
|
-
const label = this.options.indicatorLabelFunc ? this.options.indicatorLabelFunc.call(this, i + 1, i === 0) : `${i + 1}`;
|
|
5743
|
-
const li = document.createElement("li");
|
|
5744
|
-
li.classList.add("indicator-item");
|
|
5745
|
-
const button = document.createElement("button");
|
|
5746
|
-
button.type = "button";
|
|
5747
|
-
button.classList.add("indicator-item-btn");
|
|
5748
|
-
button.setAttribute("aria-label", label);
|
|
5749
|
-
button.setAttribute("aria-controls", this._sliderId);
|
|
5750
|
-
li.appendChild(button);
|
|
5751
|
-
arrLi.push(li);
|
|
5752
|
-
ul.append(li);
|
|
5753
|
-
});
|
|
5754
|
-
this.el.append(ul);
|
|
5755
|
-
this._indicators = arrLi;
|
|
5756
|
-
}
|
|
5757
|
-
}
|
|
5758
|
-
_removeIndicators() {
|
|
5759
|
-
this.el.querySelector("ul.indicators").remove();
|
|
5760
|
-
}
|
|
5761
|
-
set(index) {
|
|
5762
|
-
if (index >= this._slides.length) index = 0;
|
|
5763
|
-
else if (index < 0) index = this._slides.length - 1;
|
|
5764
|
-
if (this.activeIndex === index) return;
|
|
5765
|
-
this._activeSlide = this._slides[this.activeIndex];
|
|
5766
|
-
const _caption = this._activeSlide.querySelector(".caption");
|
|
5767
|
-
this._activeSlide.classList.remove("active");
|
|
5768
|
-
this._slides.forEach((slide) => slide.style.visibility = "visible");
|
|
5769
|
-
this._activeSlide.style.opacity = "0";
|
|
5770
|
-
setTimeout(() => {
|
|
5771
|
-
this._slides.forEach((slide) => {
|
|
5772
|
-
if (slide.classList.contains("active")) return;
|
|
5773
|
-
slide.style.opacity = "0";
|
|
5774
|
-
slide.style.transform = "translate(0, 0)";
|
|
5775
|
-
slide.style.visibility = "hidden";
|
|
5776
|
-
});
|
|
5777
|
-
}, this.options.duration);
|
|
5778
|
-
if (_caption) _caption.style.opacity = "0";
|
|
5779
|
-
if (this.options.indicators) {
|
|
5780
|
-
const activeIndicator = this._indicators[this.activeIndex].children[0];
|
|
5781
|
-
const nextIndicator = this._indicators[index].children[0];
|
|
5782
|
-
activeIndicator.classList.remove("active");
|
|
5783
|
-
nextIndicator.classList.add("active");
|
|
5784
|
-
if (typeof this.options.indicatorLabelFunc === "function") {
|
|
5785
|
-
activeIndicator.ariaLabel = this.options.indicatorLabelFunc.call(
|
|
5786
|
-
this,
|
|
5787
|
-
this.activeIndex,
|
|
5788
|
-
false
|
|
5789
|
-
);
|
|
5790
|
-
nextIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, index, true);
|
|
5791
|
-
}
|
|
5792
|
-
}
|
|
5793
|
-
this._animateSlide(this._slides[index], true);
|
|
5794
|
-
this._slides[index].classList.add("active");
|
|
5795
|
-
this.activeIndex = index;
|
|
5796
|
-
if (this.interval != null) {
|
|
5797
|
-
this.start();
|
|
5798
|
-
}
|
|
5799
|
-
}
|
|
5800
|
-
_pause(fromEvent) {
|
|
5801
|
-
clearInterval(this.interval);
|
|
5802
|
-
this.eventPause = fromEvent;
|
|
5803
|
-
this.interval = null;
|
|
5804
|
-
}
|
|
5805
|
-
};
|
|
5806
|
-
|
|
5807
5737
|
// src/ts/components/tabs.ts
|
|
5808
|
-
var
|
|
5738
|
+
var _defaults17 = {
|
|
5809
5739
|
duration: 300,
|
|
5810
5740
|
onShow: null,
|
|
5811
5741
|
swipeable: false,
|
|
@@ -5834,12 +5764,10 @@ var Expressive = (() => {
|
|
|
5834
5764
|
return;
|
|
5835
5765
|
}
|
|
5836
5766
|
if (tabLink.hasAttribute("target")) return;
|
|
5837
|
-
this._activeTabLink.classList.remove("active");
|
|
5838
5767
|
const _oldContent = this._content;
|
|
5839
|
-
this._activeTabLink = tabLink;
|
|
5840
5768
|
if (tabLink.hash) this._content = document.querySelector(tabLink.hash);
|
|
5841
5769
|
this._tabLinks = this._queryTabLinks();
|
|
5842
|
-
this.
|
|
5770
|
+
this._setActiveTabLink(tabLink);
|
|
5843
5771
|
const prevIndex = this._index;
|
|
5844
5772
|
this._index = Math.max(Array.from(this._tabLinks).indexOf(tabLink), 0);
|
|
5845
5773
|
if (this.options.swipeable) {
|
|
@@ -5883,7 +5811,7 @@ var Expressive = (() => {
|
|
|
5883
5811
|
this._setupEventHandlers();
|
|
5884
5812
|
}
|
|
5885
5813
|
static get defaults() {
|
|
5886
|
-
return
|
|
5814
|
+
return _defaults17;
|
|
5887
5815
|
}
|
|
5888
5816
|
/**
|
|
5889
5817
|
* Initializes instances of Tabs.
|
|
@@ -5934,6 +5862,26 @@ var Expressive = (() => {
|
|
|
5934
5862
|
this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + "px";
|
|
5935
5863
|
this._indicator.style.right = this._calcRightPos(this._activeTabLink) + "px";
|
|
5936
5864
|
}
|
|
5865
|
+
/**
|
|
5866
|
+
* Which tab is current, for the eye and for assistive technology.
|
|
5867
|
+
*
|
|
5868
|
+
* The class alone is a colour. `aria-current` is the part a screen reader
|
|
5869
|
+
* reads, and because tabs are navigation rather than a tablist (rule 2 -
|
|
5870
|
+
* there is no keyboard model here to back a tablist), "current" is exactly
|
|
5871
|
+
* the right word for it. Its *value* changes as the user clicks, which makes
|
|
5872
|
+
* maintaining it the component's job, not the author's - see CONTEXT.md on
|
|
5873
|
+
* static semantics versus dynamic state. Writing it once in the markup and
|
|
5874
|
+
* never moving it left the old tab announcing itself as current.
|
|
5875
|
+
*/
|
|
5876
|
+
_setActiveTabLink(tabLink) {
|
|
5877
|
+
Array.from(this._tabLinks).forEach((a) => {
|
|
5878
|
+
a.classList.remove("active");
|
|
5879
|
+
a.removeAttribute("aria-current");
|
|
5880
|
+
});
|
|
5881
|
+
this._activeTabLink = tabLink;
|
|
5882
|
+
tabLink.classList.add("active");
|
|
5883
|
+
tabLink.setAttribute("aria-current", "page");
|
|
5884
|
+
}
|
|
5937
5885
|
_setupActiveTabLink() {
|
|
5938
5886
|
this._activeTabLink = Array.from(this._tabLinks).find(
|
|
5939
5887
|
(a) => a.getAttribute("href") === location.hash
|
|
@@ -5945,8 +5893,7 @@ var Expressive = (() => {
|
|
|
5945
5893
|
}
|
|
5946
5894
|
this._activeTabLink = activeTabLink;
|
|
5947
5895
|
}
|
|
5948
|
-
|
|
5949
|
-
this._activeTabLink.classList.add("active");
|
|
5896
|
+
this._setActiveTabLink(this._activeTabLink);
|
|
5950
5897
|
this._index = Math.max(Array.from(this._tabLinks).indexOf(this._activeTabLink), 0);
|
|
5951
5898
|
if (this._activeTabLink && this._activeTabLink.hash) {
|
|
5952
5899
|
this._content = document.querySelector(this._activeTabLink.hash);
|
|
@@ -6051,7 +5998,7 @@ var Expressive = (() => {
|
|
|
6051
5998
|
};
|
|
6052
5999
|
|
|
6053
6000
|
// src/ts/components/timepicker.ts
|
|
6054
|
-
var
|
|
6001
|
+
var _defaults18 = {
|
|
6055
6002
|
dialRadius: 135,
|
|
6056
6003
|
outerRadius: 105,
|
|
6057
6004
|
innerRadius: 70,
|
|
@@ -6085,6 +6032,8 @@ var Expressive = (() => {
|
|
|
6085
6032
|
var _Timepicker = class _Timepicker extends Component {
|
|
6086
6033
|
constructor(el, options) {
|
|
6087
6034
|
super(el, options, _Timepicker);
|
|
6035
|
+
/** Which pointer is dragging the clock hand; a second finger is ignored. */
|
|
6036
|
+
this._dragPointerId = null;
|
|
6088
6037
|
/** Whether the dial (ticks + SVG + AM/PM buttons) has been built yet. */
|
|
6089
6038
|
this._clockBuilt = false;
|
|
6090
6039
|
this._handleInputClick = () => {
|
|
@@ -6094,7 +6043,7 @@ var Expressive = (() => {
|
|
|
6094
6043
|
if (this.displayPlugin) this.displayPlugin.show();
|
|
6095
6044
|
};
|
|
6096
6045
|
this._handleInputKeydown = (e) => {
|
|
6097
|
-
if (Utils.keys.ENTER
|
|
6046
|
+
if (e.key === Utils.keys.ENTER) {
|
|
6098
6047
|
e.preventDefault();
|
|
6099
6048
|
this._ensureClockBuilt();
|
|
6100
6049
|
this.inputHours.focus();
|
|
@@ -6103,12 +6052,14 @@ var Expressive = (() => {
|
|
|
6103
6052
|
}
|
|
6104
6053
|
};
|
|
6105
6054
|
this._handleTimeInputEnterKey = (e) => {
|
|
6106
|
-
if (Utils.keys.ENTER
|
|
6055
|
+
if (e.key === Utils.keys.ENTER) {
|
|
6107
6056
|
e.preventDefault();
|
|
6108
6057
|
this._inputFromTextField();
|
|
6109
6058
|
}
|
|
6110
6059
|
};
|
|
6111
6060
|
this._handleClockClickStart = (e) => {
|
|
6061
|
+
if (!e.isPrimary) return;
|
|
6062
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
6112
6063
|
e.preventDefault();
|
|
6113
6064
|
this._ensureClockBuilt();
|
|
6114
6065
|
const clockPlateBR = this.plate.getBoundingClientRect();
|
|
@@ -6116,30 +6067,30 @@ var Expressive = (() => {
|
|
|
6116
6067
|
this.x0 = offset.x + this.options.dialRadius;
|
|
6117
6068
|
this.y0 = offset.y + this.options.dialRadius;
|
|
6118
6069
|
this.moved = false;
|
|
6119
|
-
|
|
6120
|
-
this.dx =
|
|
6121
|
-
this.dy =
|
|
6070
|
+
this._dragPointerId = e.pointerId;
|
|
6071
|
+
this.dx = e.clientX - this.x0;
|
|
6072
|
+
this.dy = e.clientY - this.y0;
|
|
6122
6073
|
this.setHand(this.dx, this.dy, false);
|
|
6123
|
-
document.addEventListener("
|
|
6124
|
-
document.addEventListener("
|
|
6125
|
-
document.addEventListener("
|
|
6126
|
-
document.addEventListener("touchend", this._handleDocumentClickEnd);
|
|
6074
|
+
document.addEventListener("pointermove", this._handleDocumentClickMove);
|
|
6075
|
+
document.addEventListener("pointerup", this._handleDocumentClickEnd);
|
|
6076
|
+
document.addEventListener("pointercancel", this._handleDocumentClickCancel);
|
|
6127
6077
|
};
|
|
6128
6078
|
this._handleDocumentClickMove = (e) => {
|
|
6079
|
+
if (e.pointerId !== this._dragPointerId) return;
|
|
6129
6080
|
e.preventDefault();
|
|
6130
|
-
const
|
|
6131
|
-
const
|
|
6132
|
-
const y = clickPos.y - this.y0;
|
|
6081
|
+
const x = e.clientX - this.x0;
|
|
6082
|
+
const y = e.clientY - this.y0;
|
|
6133
6083
|
this.moved = true;
|
|
6134
6084
|
this.setHand(x, y, false);
|
|
6135
6085
|
};
|
|
6136
6086
|
this._handleDocumentClickEnd = (e) => {
|
|
6087
|
+
if (e.pointerId !== this._dragPointerId) return;
|
|
6088
|
+
this._dragPointerId = null;
|
|
6137
6089
|
e.preventDefault();
|
|
6138
|
-
document.removeEventListener("
|
|
6139
|
-
document.removeEventListener("
|
|
6140
|
-
const
|
|
6141
|
-
const
|
|
6142
|
-
const y = clickPos.y - this.y0;
|
|
6090
|
+
document.removeEventListener("pointerup", this._handleDocumentClickEnd);
|
|
6091
|
+
document.removeEventListener("pointercancel", this._handleDocumentClickCancel);
|
|
6092
|
+
const x = e.clientX - this.x0;
|
|
6093
|
+
const y = e.clientY - this.y0;
|
|
6143
6094
|
if (this.moved && x === this.dx && y === this.dy) {
|
|
6144
6095
|
this.setHand(x, y);
|
|
6145
6096
|
}
|
|
@@ -6154,14 +6105,27 @@ var Expressive = (() => {
|
|
|
6154
6105
|
if (typeof this.options.onSelect === "function") {
|
|
6155
6106
|
this.options.onSelect.call(this, this.hours, this.minutes);
|
|
6156
6107
|
}
|
|
6157
|
-
document.removeEventListener("
|
|
6158
|
-
|
|
6108
|
+
document.removeEventListener("pointermove", this._handleDocumentClickMove);
|
|
6109
|
+
};
|
|
6110
|
+
/**
|
|
6111
|
+
* A cancelled pointer is not a completed selection. The browser or the OS
|
|
6112
|
+
* took the gesture over, so this only lets go of the drag - it must not run
|
|
6113
|
+
* the pointer-up path, which advances hours to minutes, fires `onSelect`,
|
|
6114
|
+
* and under `autoSubmit` closes the picker on a time the user never chose.
|
|
6115
|
+
*/
|
|
6116
|
+
this._handleDocumentClickCancel = (e) => {
|
|
6117
|
+
if (e.pointerId !== this._dragPointerId) return;
|
|
6118
|
+
this._dragPointerId = null;
|
|
6119
|
+
this.moved = false;
|
|
6120
|
+
document.removeEventListener("pointermove", this._handleDocumentClickMove);
|
|
6121
|
+
document.removeEventListener("pointerup", this._handleDocumentClickEnd);
|
|
6122
|
+
document.removeEventListener("pointercancel", this._handleDocumentClickCancel);
|
|
6159
6123
|
};
|
|
6160
6124
|
this._handleAmPmClick = (e) => {
|
|
6161
6125
|
this._handleAmPmInteraction(e.target);
|
|
6162
6126
|
};
|
|
6163
6127
|
this._handleAmPmKeypress = (e) => {
|
|
6164
|
-
if (Utils.keys.ENTER
|
|
6128
|
+
if (e.key === Utils.keys.ENTER) {
|
|
6165
6129
|
this._handleAmPmInteraction(e.target);
|
|
6166
6130
|
}
|
|
6167
6131
|
};
|
|
@@ -6176,8 +6140,6 @@ var Expressive = (() => {
|
|
|
6176
6140
|
*/
|
|
6177
6141
|
this.showView = (view, delay = null) => {
|
|
6178
6142
|
this._ensureClockBuilt();
|
|
6179
|
-
if (view === "minutes" && getComputedStyle(this.hoursView).visibility === "visible") {
|
|
6180
|
-
}
|
|
6181
6143
|
const isHours = view === "hours", nextView = isHours ? this.hoursView : this.minutesView, hideView = isHours ? this.minutesView : this.hoursView;
|
|
6182
6144
|
this.currentView = view;
|
|
6183
6145
|
hideView.classList.add("timepicker-dial-out");
|
|
@@ -6249,7 +6211,7 @@ var Expressive = (() => {
|
|
|
6249
6211
|
}
|
|
6250
6212
|
}
|
|
6251
6213
|
static get defaults() {
|
|
6252
|
-
return
|
|
6214
|
+
return _defaults18;
|
|
6253
6215
|
}
|
|
6254
6216
|
/**
|
|
6255
6217
|
* Initializes instances of Timepicker.
|
|
@@ -6266,15 +6228,6 @@ var Expressive = (() => {
|
|
|
6266
6228
|
const svgNS = "http://www.w3.org/2000/svg";
|
|
6267
6229
|
return document.createElementNS(svgNS, name);
|
|
6268
6230
|
}
|
|
6269
|
-
static _Pos(e) {
|
|
6270
|
-
if (e.type.startsWith("touch") && e.targetTouches.length >= 1) {
|
|
6271
|
-
return {
|
|
6272
|
-
x: e.targetTouches[0].clientX,
|
|
6273
|
-
y: e.targetTouches[0].clientY
|
|
6274
|
-
};
|
|
6275
|
-
}
|
|
6276
|
-
return { x: e.clientX, y: e.clientY };
|
|
6277
|
-
}
|
|
6278
6231
|
static getInstance(el) {
|
|
6279
6232
|
return el["Expressive_Timepicker"];
|
|
6280
6233
|
}
|
|
@@ -6287,8 +6240,7 @@ var Expressive = (() => {
|
|
|
6287
6240
|
_setupEventHandlers() {
|
|
6288
6241
|
this.el.addEventListener("click", this._handleInputClick);
|
|
6289
6242
|
this.el.addEventListener("keydown", this._handleInputKeydown);
|
|
6290
|
-
this.plate.addEventListener("
|
|
6291
|
-
this.plate.addEventListener("touchstart", this._handleClockClickStart);
|
|
6243
|
+
this.plate.addEventListener("pointerdown", this._handleClockClickStart);
|
|
6292
6244
|
this.digitalClock.addEventListener("keyup", this._inputFromTextField);
|
|
6293
6245
|
this.inputHours.addEventListener("focus", () => this.showView("hours"));
|
|
6294
6246
|
this.inputHours.addEventListener("focusout", () => this.formatHours());
|
|
@@ -6298,10 +6250,9 @@ var Expressive = (() => {
|
|
|
6298
6250
|
_removeEventHandlers() {
|
|
6299
6251
|
this.el.removeEventListener("click", this._handleInputClick);
|
|
6300
6252
|
this.el.removeEventListener("keydown", this._handleInputKeydown);
|
|
6301
|
-
document.removeEventListener("
|
|
6302
|
-
document.removeEventListener("
|
|
6303
|
-
document.removeEventListener("
|
|
6304
|
-
document.removeEventListener("touchend", this._handleDocumentClickEnd);
|
|
6253
|
+
document.removeEventListener("pointermove", this._handleDocumentClickMove);
|
|
6254
|
+
document.removeEventListener("pointerup", this._handleDocumentClickEnd);
|
|
6255
|
+
document.removeEventListener("pointercancel", this._handleDocumentClickCancel);
|
|
6305
6256
|
}
|
|
6306
6257
|
_insertHTMLIntoDOM() {
|
|
6307
6258
|
const template = document.createElement("template");
|
|
@@ -6330,15 +6281,6 @@ var Expressive = (() => {
|
|
|
6330
6281
|
this.footer = this.containerEl.querySelector(".timepicker-footer");
|
|
6331
6282
|
this.amOrPm = "PM";
|
|
6332
6283
|
}
|
|
6333
|
-
/*private _createButton(text: string, visibility: string): HTMLButtonElement {
|
|
6334
|
-
const button = document.createElement('button');
|
|
6335
|
-
button.classList.add('waves-effect', 'text');
|
|
6336
|
-
button.style.visibility = visibility;
|
|
6337
|
-
button.type = 'button';
|
|
6338
|
-
button.tabIndex = -1;
|
|
6339
|
-
button.innerText = text;
|
|
6340
|
-
return button;
|
|
6341
|
-
}*/
|
|
6342
6284
|
_pickerSetup() {
|
|
6343
6285
|
Utils.createButton(
|
|
6344
6286
|
this.footer,
|
|
@@ -6619,7 +6561,7 @@ var Expressive = (() => {
|
|
|
6619
6561
|
var Timepicker = _Timepicker;
|
|
6620
6562
|
|
|
6621
6563
|
// src/ts/components/snackbar.ts
|
|
6622
|
-
var
|
|
6564
|
+
var _defaults19 = {
|
|
6623
6565
|
text: "",
|
|
6624
6566
|
action: "",
|
|
6625
6567
|
onAction: null,
|
|
@@ -6629,7 +6571,8 @@ var Expressive = (() => {
|
|
|
6629
6571
|
outDuration: 375,
|
|
6630
6572
|
classes: "",
|
|
6631
6573
|
completeCallback: null,
|
|
6632
|
-
activationPercent: 0.8
|
|
6574
|
+
activationPercent: 0.8,
|
|
6575
|
+
root: null
|
|
6633
6576
|
};
|
|
6634
6577
|
var _Snackbar = class _Snackbar {
|
|
6635
6578
|
constructor(options = {}) {
|
|
@@ -6652,8 +6595,10 @@ var Expressive = (() => {
|
|
|
6652
6595
|
}
|
|
6653
6596
|
_Snackbar._snackbars.length = 0;
|
|
6654
6597
|
}
|
|
6655
|
-
|
|
6656
|
-
|
|
6598
|
+
const root = Utils.portalRoot(this.options.root ?? document.body);
|
|
6599
|
+
if (!_Snackbar._container || !_Snackbar._container.isConnected || _Snackbar._container.parentNode !== root) {
|
|
6600
|
+
if (_Snackbar._container) _Snackbar._removeContainer();
|
|
6601
|
+
_Snackbar._createContainer(root);
|
|
6657
6602
|
}
|
|
6658
6603
|
_Snackbar._snackbars.push(this);
|
|
6659
6604
|
const snackbarElement = this._createSnackbar();
|
|
@@ -6663,30 +6608,31 @@ var Expressive = (() => {
|
|
|
6663
6608
|
this._setTimer();
|
|
6664
6609
|
}
|
|
6665
6610
|
static get defaults() {
|
|
6666
|
-
return
|
|
6611
|
+
return _defaults19;
|
|
6667
6612
|
}
|
|
6668
6613
|
static getInstance(el) {
|
|
6669
6614
|
return el["Expressive_Snackbar"];
|
|
6670
6615
|
}
|
|
6671
|
-
static _createContainer() {
|
|
6616
|
+
static _createContainer(root = document.body) {
|
|
6672
6617
|
const container = document.createElement("div");
|
|
6673
6618
|
container.setAttribute("id", "snackbar-container");
|
|
6674
|
-
container.addEventListener("
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
document.addEventListener("mouseup", _Snackbar._onDragEnd);
|
|
6680
|
-
document.body.appendChild(container);
|
|
6619
|
+
container.addEventListener("pointerdown", _Snackbar._onDragStart);
|
|
6620
|
+
document.addEventListener("pointermove", _Snackbar._onDragMove);
|
|
6621
|
+
document.addEventListener("pointerup", _Snackbar._onDragEnd);
|
|
6622
|
+
document.addEventListener("pointercancel", _Snackbar._onDragCancel);
|
|
6623
|
+
root.appendChild(container);
|
|
6681
6624
|
_Snackbar._container = container;
|
|
6682
6625
|
}
|
|
6683
6626
|
static _removeContainer() {
|
|
6684
|
-
document.removeEventListener("
|
|
6685
|
-
document.removeEventListener("
|
|
6627
|
+
document.removeEventListener("pointermove", _Snackbar._onDragMove);
|
|
6628
|
+
document.removeEventListener("pointerup", _Snackbar._onDragEnd);
|
|
6629
|
+
document.removeEventListener("pointercancel", _Snackbar._onDragCancel);
|
|
6686
6630
|
_Snackbar._container.remove();
|
|
6687
6631
|
_Snackbar._container = null;
|
|
6688
6632
|
}
|
|
6689
6633
|
static _onDragStart(e) {
|
|
6634
|
+
if (!e.isPrimary) return;
|
|
6635
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
6690
6636
|
const target = e.target;
|
|
6691
6637
|
if (target && !target.closest("button, a") && target.closest(".snackbar")) {
|
|
6692
6638
|
const snackbarElem = target.closest(".snackbar");
|
|
@@ -6697,17 +6643,19 @@ var Expressive = (() => {
|
|
|
6697
6643
|
_Snackbar._draggedSnackbar = snackbar;
|
|
6698
6644
|
snackbar.el.classList.add("panning");
|
|
6699
6645
|
snackbar.el.style.transition = "";
|
|
6700
|
-
|
|
6646
|
+
_Snackbar._dragPointerId = e.pointerId;
|
|
6647
|
+
snackbar.startingXPos = e.clientX;
|
|
6701
6648
|
snackbar.time = Date.now();
|
|
6702
|
-
snackbar.xPos =
|
|
6649
|
+
snackbar.xPos = e.clientX;
|
|
6703
6650
|
}
|
|
6704
6651
|
}
|
|
6705
6652
|
static _onDragMove(e) {
|
|
6653
|
+
if (_Snackbar._dragPointerId !== e.pointerId) return;
|
|
6706
6654
|
if (!!_Snackbar._draggedSnackbar) {
|
|
6707
6655
|
e.preventDefault();
|
|
6708
6656
|
const snackbar = _Snackbar._draggedSnackbar;
|
|
6709
|
-
snackbar.deltaX = Math.abs(snackbar.xPos -
|
|
6710
|
-
snackbar.xPos =
|
|
6657
|
+
snackbar.deltaX = Math.abs(snackbar.xPos - e.clientX);
|
|
6658
|
+
snackbar.xPos = e.clientX;
|
|
6711
6659
|
snackbar.velocityX = snackbar.deltaX / (Date.now() - snackbar.time);
|
|
6712
6660
|
snackbar.time = Date.now();
|
|
6713
6661
|
const totalDeltaX = snackbar.xPos - snackbar.startingXPos;
|
|
@@ -6716,7 +6664,9 @@ var Expressive = (() => {
|
|
|
6716
6664
|
snackbar.el.style.opacity = (1 - Math.abs(totalDeltaX / activationDistance)).toString();
|
|
6717
6665
|
}
|
|
6718
6666
|
}
|
|
6719
|
-
static _onDragEnd() {
|
|
6667
|
+
static _onDragEnd(e) {
|
|
6668
|
+
if (_Snackbar._dragPointerId !== e.pointerId) return;
|
|
6669
|
+
_Snackbar._dragPointerId = null;
|
|
6720
6670
|
if (!!_Snackbar._draggedSnackbar) {
|
|
6721
6671
|
const snackbar = _Snackbar._draggedSnackbar;
|
|
6722
6672
|
snackbar.panning = false;
|
|
@@ -6736,11 +6686,23 @@ var Expressive = (() => {
|
|
|
6736
6686
|
_Snackbar._draggedSnackbar = null;
|
|
6737
6687
|
}
|
|
6738
6688
|
}
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6689
|
+
/**
|
|
6690
|
+
* A cancelled pointer is not a short swipe. Snap back and resume the timer
|
|
6691
|
+
* without consulting the distance travelled - the browser took the gesture
|
|
6692
|
+
* over, so the movement so far says nothing about what the user wanted.
|
|
6693
|
+
*/
|
|
6694
|
+
static _onDragCancel(e) {
|
|
6695
|
+
if (_Snackbar._dragPointerId !== e.pointerId) return;
|
|
6696
|
+
_Snackbar._dragPointerId = null;
|
|
6697
|
+
const snackbar = _Snackbar._draggedSnackbar;
|
|
6698
|
+
if (!snackbar) return;
|
|
6699
|
+
snackbar.panning = false;
|
|
6700
|
+
snackbar.el.classList.remove("panning");
|
|
6701
|
+
snackbar.el.style.transition = "transform .2s, opacity .2s";
|
|
6702
|
+
snackbar.el.style.transform = "";
|
|
6703
|
+
snackbar.el.style.opacity = "";
|
|
6704
|
+
snackbar._resumeTimer();
|
|
6705
|
+
_Snackbar._draggedSnackbar = null;
|
|
6744
6706
|
}
|
|
6745
6707
|
/**
|
|
6746
6708
|
* dismiss all snackbars.
|
|
@@ -6751,7 +6713,7 @@ var Expressive = (() => {
|
|
|
6751
6713
|
}
|
|
6752
6714
|
}
|
|
6753
6715
|
_createSnackbar() {
|
|
6754
|
-
let snackbar = this.options.snackbarId ?
|
|
6716
|
+
let snackbar = this.options.snackbarId ? Utils.getElementById(this.options.root ?? document.body, this.options.snackbarId) : document.createElement("div");
|
|
6755
6717
|
if (snackbar instanceof HTMLTemplateElement) {
|
|
6756
6718
|
const node = snackbar.content.cloneNode(true);
|
|
6757
6719
|
snackbar = node.firstElementChild;
|
|
@@ -6873,13 +6835,15 @@ var Expressive = (() => {
|
|
|
6873
6835
|
}, this.options.outDuration);
|
|
6874
6836
|
}
|
|
6875
6837
|
};
|
|
6838
|
+
/** Which pointer owns the drag in flight; a second finger is ignored. */
|
|
6839
|
+
_Snackbar._dragPointerId = null;
|
|
6876
6840
|
_Snackbar._snackbars = [];
|
|
6877
6841
|
_Snackbar._container = null;
|
|
6878
6842
|
_Snackbar._draggedSnackbar = null;
|
|
6879
6843
|
var Snackbar = _Snackbar;
|
|
6880
6844
|
|
|
6881
6845
|
// src/ts/components/tooltip.ts
|
|
6882
|
-
var
|
|
6846
|
+
var _defaults20 = {
|
|
6883
6847
|
exitDelay: 200,
|
|
6884
6848
|
enterDelay: 0,
|
|
6885
6849
|
text: "",
|
|
@@ -6924,8 +6888,10 @@ var Expressive = (() => {
|
|
|
6924
6888
|
this.isFocused = false;
|
|
6925
6889
|
this.close();
|
|
6926
6890
|
};
|
|
6891
|
+
// Focus opens the tooltip only when it arrived by keyboard: a pointer press
|
|
6892
|
+
// on the trigger also focuses it, and _handleMouseEnter already covers that.
|
|
6927
6893
|
this._handleFocus = () => {
|
|
6928
|
-
if (
|
|
6894
|
+
if (this.el.matches(":focus-visible")) {
|
|
6929
6895
|
this.isFocused = true;
|
|
6930
6896
|
this.open(false);
|
|
6931
6897
|
}
|
|
@@ -6947,7 +6913,7 @@ var Expressive = (() => {
|
|
|
6947
6913
|
this._setupEventHandlers();
|
|
6948
6914
|
}
|
|
6949
6915
|
static get defaults() {
|
|
6950
|
-
return
|
|
6916
|
+
return _defaults20;
|
|
6951
6917
|
}
|
|
6952
6918
|
/**
|
|
6953
6919
|
* Initializes instances of Tooltip.
|
|
@@ -6974,7 +6940,7 @@ var Expressive = (() => {
|
|
|
6974
6940
|
this.tooltipEl.id = `tooltip-${Utils.guid()}`;
|
|
6975
6941
|
this.tooltipEl.setAttribute("role", "tooltip");
|
|
6976
6942
|
this.el.setAttribute("aria-describedby", this.tooltipEl.id);
|
|
6977
|
-
const tooltipContentEl = this.options.tooltipId ?
|
|
6943
|
+
const tooltipContentEl = this.options.tooltipId ? Utils.getElementById(this.el, this.options.tooltipId) : document.createElement("div");
|
|
6978
6944
|
if (this.options.tooltipId) {
|
|
6979
6945
|
this.tooltipEl.classList.add("rich");
|
|
6980
6946
|
}
|
|
@@ -6982,7 +6948,7 @@ var Expressive = (() => {
|
|
|
6982
6948
|
tooltipContentEl.classList.add("tooltip-content");
|
|
6983
6949
|
this._setTooltipContent(tooltipContentEl);
|
|
6984
6950
|
this.tooltipEl.appendChild(tooltipContentEl);
|
|
6985
|
-
|
|
6951
|
+
Utils.portalRoot(this.el).appendChild(this.tooltipEl);
|
|
6986
6952
|
}
|
|
6987
6953
|
_setTooltipContent(tooltipContentEl) {
|
|
6988
6954
|
if (this.options.tooltipId) return;
|
|
@@ -7121,26 +7087,44 @@ var Expressive = (() => {
|
|
|
7121
7087
|
|
|
7122
7088
|
// src/ts/components/registry.ts
|
|
7123
7089
|
var AUTO_INIT_COMPONENTS = {
|
|
7124
|
-
Autocomplete: {
|
|
7090
|
+
Autocomplete: {
|
|
7091
|
+
component: Autocomplete,
|
|
7092
|
+
selector: ".autocomplete"
|
|
7093
|
+
},
|
|
7125
7094
|
// Shared with Cards.Init() - see CARDS_SELECTOR. This entry used to read
|
|
7126
7095
|
// '.cards', which no card markup uses.
|
|
7127
7096
|
Cards: { component: Cards, selector: CARDS_SELECTOR },
|
|
7097
|
+
ExpandingCard: {
|
|
7098
|
+
component: ExpandingCard,
|
|
7099
|
+
selector: EXPANDING_CARD_SELECTOR
|
|
7100
|
+
},
|
|
7128
7101
|
Carousel: { component: Carousel, selector: ".carousel" },
|
|
7129
7102
|
Chips: { component: Chips, selector: ".chips" },
|
|
7130
|
-
Datepicker: {
|
|
7103
|
+
Datepicker: {
|
|
7104
|
+
component: Datepicker,
|
|
7105
|
+
selector: ".datepicker, .date-picker"
|
|
7106
|
+
},
|
|
7131
7107
|
Menu: { component: Menu, selector: ".menu-trigger" },
|
|
7132
7108
|
Lightbox: { component: Lightbox, selector: ".lightboxed" },
|
|
7133
|
-
Parallax: { component: Parallax, selector: ".parallax" },
|
|
7134
7109
|
ScrollSpy: { component: ScrollSpy, selector: ".scrollspy" },
|
|
7135
7110
|
FormSelect: { component: FormSelect, selector: "select" },
|
|
7136
|
-
|
|
7137
|
-
|
|
7111
|
+
NavigationDrawer: {
|
|
7112
|
+
component: NavigationDrawer,
|
|
7113
|
+
selector: ".sidenav, .navigation-drawer"
|
|
7114
|
+
},
|
|
7115
|
+
NavigationRail: {
|
|
7116
|
+
component: NavigationRail,
|
|
7117
|
+
selector: ".navigation-rail"
|
|
7118
|
+
},
|
|
7138
7119
|
Tabs: { component: Tabs, selector: ".tabs" },
|
|
7139
|
-
Timepicker: {
|
|
7120
|
+
Timepicker: {
|
|
7121
|
+
component: Timepicker,
|
|
7122
|
+
selector: ".timepicker, .time-picker"
|
|
7123
|
+
},
|
|
7140
7124
|
Tooltip: { component: Tooltip, selector: ".tooltipped" },
|
|
7141
7125
|
FloatingActionButton: {
|
|
7142
7126
|
component: FloatingActionButton,
|
|
7143
|
-
selector: ".fixed-action-btn"
|
|
7127
|
+
selector: ".fab, .fixed-action-btn, .fab-menu"
|
|
7144
7128
|
}
|
|
7145
7129
|
};
|
|
7146
7130
|
function AutoInit(context = document.body, options) {
|
|
@@ -7152,18 +7136,12 @@ var Expressive = (() => {
|
|
|
7152
7136
|
}
|
|
7153
7137
|
|
|
7154
7138
|
// src/ts/index.ts
|
|
7155
|
-
var version = "0.
|
|
7156
|
-
if (typeof document !== "undefined") {
|
|
7157
|
-
document.addEventListener("keydown", Utils.docHandleKeydown, true);
|
|
7158
|
-
document.addEventListener("keyup", Utils.docHandleKeyup, true);
|
|
7159
|
-
document.addEventListener("focus", Utils.docHandleFocus, true);
|
|
7160
|
-
document.addEventListener("blur", Utils.docHandleBlur, true);
|
|
7161
|
-
}
|
|
7139
|
+
var version = "0.8.0";
|
|
7162
7140
|
Forms.Init();
|
|
7163
7141
|
Chips.Init();
|
|
7164
|
-
|
|
7165
|
-
Range.Init();
|
|
7142
|
+
Slider.Init();
|
|
7166
7143
|
Cards.Init();
|
|
7144
|
+
ExpandingCard.Init();
|
|
7167
7145
|
Dialogs.Init();
|
|
7168
7146
|
BottomSheets.Init();
|
|
7169
7147
|
SideSheets.Init();
|