@expressivecss/expressive 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/dist/css/expressive.css +1038 -361
- 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 +708 -746
- package/dist/js/expressive.cjs.map +3 -3
- package/dist/js/expressive.js +708 -746
- package/dist/js/expressive.js.map +3 -3
- package/dist/js/expressive.min.js +10 -10
- package/dist/js/expressive.min.js.map +3 -3
- package/dist/js/expressive.mjs +708 -746
- package/dist/js/expressive.mjs.map +3 -3
- package/dist/types/components/buttons.d.ts +17 -41
- package/dist/types/components/carousel.d.ts +40 -46
- package/dist/types/components/chips.d.ts +2 -2
- package/dist/types/components/collapsible.d.ts +35 -13
- package/dist/types/components/parallax.d.ts +7 -31
- package/dist/types/components/tapTarget.d.ts +23 -24
- package/dist/types/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/sass/README.md +4 -3
- package/src/sass/components/_badges.scss +5 -4
- package/src/sass/components/_breadcrumb.scss +93 -16
- package/src/sass/components/_buttons.scss +195 -96
- package/src/sass/components/_carousel.scss +130 -63
- package/src/sass/components/_chips.scss +1 -1
- package/src/sass/components/_collapsible.scss +160 -60
- package/src/sass/components/_collection.scss +161 -77
- package/src/sass/components/_icons-material-design.scss +77 -4
- package/src/sass/components/_lightbox.scss +4 -0
- package/src/sass/components/_navbar.scss +15 -0
- package/src/sass/components/_pagination.scss +131 -25
- package/src/sass/components/_parallax.scss +116 -20
- package/src/sass/components/_sidenav.scss +10 -5
- package/src/sass/components/_slider.scss +8 -0
- package/src/sass/components/_tapTarget.scss +134 -47
package/dist/js/expressive.js
CHANGED
|
@@ -1476,7 +1476,7 @@ var Expressive = (() => {
|
|
|
1476
1476
|
data: [],
|
|
1477
1477
|
placeholder: "",
|
|
1478
1478
|
secondaryPlaceholder: "",
|
|
1479
|
-
closeIconClass: "material-
|
|
1479
|
+
closeIconClass: "material-symbols",
|
|
1480
1480
|
autocompleteOptions: {},
|
|
1481
1481
|
autocompleteOnly: false,
|
|
1482
1482
|
limit: Infinity,
|
|
@@ -2115,83 +2115,76 @@ var Expressive = (() => {
|
|
|
2115
2115
|
var FloatingActionButton = class _FloatingActionButton extends Component {
|
|
2116
2116
|
constructor(el, options) {
|
|
2117
2117
|
super(el, options, _FloatingActionButton);
|
|
2118
|
-
/** Toolbar-mode backdrop, kept so closing can take it back out. */
|
|
2119
|
-
this._backdrop = null;
|
|
2120
|
-
this._handleFABClick = () => {
|
|
2121
|
-
this._handleFABToggle();
|
|
2122
|
-
};
|
|
2123
|
-
this._handleFABKeyPress = (e) => {
|
|
2124
|
-
if (Utils.keys.ENTER.includes(e.key)) {
|
|
2125
|
-
this._handleFABToggle();
|
|
2126
|
-
}
|
|
2127
|
-
};
|
|
2128
|
-
this._handleFABToggle = () => {
|
|
2129
|
-
if (this.isOpen) {
|
|
2130
|
-
this.close();
|
|
2131
|
-
} else {
|
|
2132
|
-
this.open();
|
|
2133
|
-
}
|
|
2134
|
-
};
|
|
2135
|
-
this._handleDocumentClick = (e) => {
|
|
2136
|
-
const elem = e.target;
|
|
2137
|
-
if (elem !== this._menu) this.close();
|
|
2138
|
-
};
|
|
2139
2118
|
/**
|
|
2140
2119
|
* Open FAB.
|
|
2141
2120
|
*/
|
|
2142
2121
|
this.open = () => {
|
|
2143
2122
|
if (this.isOpen) return;
|
|
2144
|
-
if (this.options.toolbarEnabled) this._animateInToolbar();
|
|
2145
|
-
else this._animateInFAB();
|
|
2146
2123
|
this.isOpen = true;
|
|
2124
|
+
this.el.classList.add("active");
|
|
2125
|
+
this._anchor?.setAttribute("aria-expanded", "true");
|
|
2126
|
+
document.addEventListener("click", this._handleDocumentClick);
|
|
2127
|
+
document.addEventListener("keydown", this._handleDocumentKeydown);
|
|
2147
2128
|
};
|
|
2148
2129
|
/**
|
|
2149
2130
|
* Close FAB.
|
|
2150
2131
|
*/
|
|
2151
2132
|
this.close = () => {
|
|
2152
2133
|
if (!this.isOpen) return;
|
|
2153
|
-
if (this.options.toolbarEnabled) {
|
|
2154
|
-
window.removeEventListener("scroll", this.close, true);
|
|
2155
|
-
document.body.removeEventListener("click", this._handleDocumentClick, true);
|
|
2156
|
-
this._animateOutToolbar();
|
|
2157
|
-
} else {
|
|
2158
|
-
this._animateOutFAB();
|
|
2159
|
-
}
|
|
2160
2134
|
this.isOpen = false;
|
|
2135
|
+
this.el.classList.remove("active");
|
|
2136
|
+
this._anchor?.setAttribute("aria-expanded", "false");
|
|
2137
|
+
document.removeEventListener("click", this._handleDocumentClick);
|
|
2138
|
+
document.removeEventListener("keydown", this._handleDocumentKeydown);
|
|
2139
|
+
};
|
|
2140
|
+
this._handleFABClick = (e) => {
|
|
2141
|
+
e.stopPropagation();
|
|
2142
|
+
this._toggle();
|
|
2143
|
+
};
|
|
2144
|
+
this._handleAnchorKeydown = (e) => {
|
|
2145
|
+
if (Utils.keys.ENTER.includes(e.key) || e.key === " ") {
|
|
2146
|
+
e.preventDefault();
|
|
2147
|
+
this._toggle();
|
|
2148
|
+
}
|
|
2149
|
+
};
|
|
2150
|
+
this._handleDocumentKeydown = (e) => {
|
|
2151
|
+
if (Utils.keys.ESC.includes(e.key)) this.close();
|
|
2152
|
+
};
|
|
2153
|
+
this._handleDocumentClick = (e) => {
|
|
2154
|
+
const target = e.target;
|
|
2155
|
+
if (!(target instanceof Node) || this.el.contains(target)) return;
|
|
2156
|
+
this.close();
|
|
2161
2157
|
};
|
|
2162
2158
|
this.el["Expressive_FloatingActionButton"] = this;
|
|
2159
|
+
const fromMarkup = this._directionFromClass();
|
|
2160
|
+
const toolbar = el.classList.contains("toolbar") || options.toolbarEnabled === true;
|
|
2161
|
+
const clickToToggle = el.classList.contains("click-to-toggle") || options.hoverEnabled === false;
|
|
2163
2162
|
this.options = {
|
|
2164
2163
|
..._FloatingActionButton.defaults,
|
|
2165
|
-
...options
|
|
2164
|
+
...options,
|
|
2165
|
+
direction: options.direction ?? fromMarkup ?? _FloatingActionButton.defaults.direction,
|
|
2166
|
+
hoverEnabled: !clickToToggle,
|
|
2167
|
+
toolbarEnabled: toolbar
|
|
2166
2168
|
};
|
|
2167
2169
|
this.isOpen = false;
|
|
2168
|
-
this._anchor = this.el.querySelector("a, button");
|
|
2169
|
-
this._menu = this.el.querySelector("ul");
|
|
2170
|
-
this._floatingBtns = Array.from(this.el.querySelectorAll("ul .btn-floating"));
|
|
2171
|
-
this._floatingBtnsReverse = this._floatingBtns.reverse();
|
|
2172
|
-
this.offsetY = 0;
|
|
2173
|
-
this.offsetX = 0;
|
|
2170
|
+
this._anchor = this.el.querySelector(":scope > a, :scope > button");
|
|
2171
|
+
this._menu = this.el.querySelector("ul, menu");
|
|
2174
2172
|
this.el.classList.add(`direction-${this.options.direction}`);
|
|
2175
|
-
if (
|
|
2176
|
-
if (
|
|
2177
|
-
if (this.
|
|
2178
|
-
this.
|
|
2179
|
-
|
|
2180
|
-
this.
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2173
|
+
if (clickToToggle) this.el.classList.add("click-to-toggle");
|
|
2174
|
+
if (toolbar) this.el.classList.add("toolbar");
|
|
2175
|
+
if (this._anchor) {
|
|
2176
|
+
this._anchor.setAttribute("aria-haspopup", "menu");
|
|
2177
|
+
this._anchor.setAttribute("aria-expanded", "false");
|
|
2178
|
+
if (this._anchor instanceof HTMLAnchorElement && !this._anchor.hasAttribute("href") && this._anchor.tabIndex < 0) {
|
|
2179
|
+
this._anchor.tabIndex = 0;
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
if (this._menu) this._menu.setAttribute("role", "menu");
|
|
2185
2183
|
this._setupEventHandlers();
|
|
2186
2184
|
}
|
|
2187
2185
|
static get defaults() {
|
|
2188
2186
|
return _defaults6;
|
|
2189
2187
|
}
|
|
2190
|
-
/**
|
|
2191
|
-
* Initializes instances of FloatingActionButton.
|
|
2192
|
-
* @param els HTML elements.
|
|
2193
|
-
* @param options Component options.
|
|
2194
|
-
*/
|
|
2195
2188
|
static init(els, options = {}) {
|
|
2196
2189
|
return super.init(els, options, _FloatingActionButton);
|
|
2197
2190
|
}
|
|
@@ -2199,229 +2192,109 @@ var Expressive = (() => {
|
|
|
2199
2192
|
return el["Expressive_FloatingActionButton"];
|
|
2200
2193
|
}
|
|
2201
2194
|
destroy() {
|
|
2202
|
-
this._removeEventHandlers();
|
|
2203
2195
|
this.close();
|
|
2196
|
+
this._removeEventHandlers();
|
|
2204
2197
|
this.el["Expressive_FloatingActionButton"] = void 0;
|
|
2205
2198
|
}
|
|
2199
|
+
_directionFromClass() {
|
|
2200
|
+
const match = [...this.el.classList].find((c) => c.startsWith("direction-"));
|
|
2201
|
+
const value = match?.slice("direction-".length);
|
|
2202
|
+
if (value === "top" || value === "right" || value === "bottom" || value === "left") {
|
|
2203
|
+
return value;
|
|
2204
|
+
}
|
|
2205
|
+
return null;
|
|
2206
|
+
}
|
|
2206
2207
|
_setupEventHandlers() {
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
this.
|
|
2210
|
-
} else {
|
|
2211
|
-
this.el.addEventListener("click", this._handleFABClick);
|
|
2208
|
+
this.el.addEventListener("click", this._handleFABClick);
|
|
2209
|
+
if (this._anchor instanceof HTMLAnchorElement && !this._anchor.hasAttribute("href")) {
|
|
2210
|
+
this._anchor.addEventListener("keydown", this._handleAnchorKeydown);
|
|
2212
2211
|
}
|
|
2213
|
-
this.el.addEventListener("keypress", this._handleFABKeyPress);
|
|
2214
2212
|
}
|
|
2215
2213
|
_removeEventHandlers() {
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
this.el.removeEventListener("mouseleave", this.close);
|
|
2219
|
-
} else {
|
|
2220
|
-
this.el.removeEventListener("click", this._handleFABClick);
|
|
2221
|
-
}
|
|
2222
|
-
this.el.removeEventListener("keypress", this._handleFABKeyPress);
|
|
2223
|
-
}
|
|
2224
|
-
_animateInFAB() {
|
|
2225
|
-
this.el.classList.add("active");
|
|
2226
|
-
if (this._menu) this._menu.ariaExpanded = "true";
|
|
2227
|
-
const delayIncrement = 40;
|
|
2228
|
-
const duration = 275;
|
|
2229
|
-
this._floatingBtnsReverse.forEach((el, index) => {
|
|
2230
|
-
const delay = delayIncrement * index;
|
|
2231
|
-
el.style.transition = "none";
|
|
2232
|
-
el.style.opacity = "0";
|
|
2233
|
-
el.style.transform = `translate(${this.offsetX}px, ${this.offsetY}px) scale(0.4)`;
|
|
2234
|
-
setTimeout(() => {
|
|
2235
|
-
el.style.opacity = "0.4";
|
|
2236
|
-
setTimeout(() => {
|
|
2237
|
-
el.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
|
|
2238
|
-
el.style.opacity = "1";
|
|
2239
|
-
el.style.transform = "translate(0, 0) scale(1)";
|
|
2240
|
-
el.tabIndex = 0;
|
|
2241
|
-
}, 1);
|
|
2242
|
-
}, delay);
|
|
2243
|
-
});
|
|
2244
|
-
}
|
|
2245
|
-
_animateOutFAB() {
|
|
2246
|
-
const duration = 175;
|
|
2247
|
-
setTimeout(() => {
|
|
2248
|
-
this.el.classList.remove("active");
|
|
2249
|
-
if (this._menu) this._menu.ariaExpanded = "false";
|
|
2250
|
-
}, duration);
|
|
2251
|
-
this._floatingBtnsReverse.forEach((el) => {
|
|
2252
|
-
el.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
|
|
2253
|
-
el.style.opacity = "0";
|
|
2254
|
-
el.style.transform = `translate(${this.offsetX}px, ${this.offsetY}px) scale(0.4)`;
|
|
2255
|
-
el.tabIndex = -1;
|
|
2256
|
-
});
|
|
2257
|
-
}
|
|
2258
|
-
_animateInToolbar() {
|
|
2259
|
-
const windowWidth = window.innerWidth;
|
|
2260
|
-
const windowHeight = window.innerHeight;
|
|
2261
|
-
const btnRect = this.el.getBoundingClientRect();
|
|
2262
|
-
const fabColor = getComputedStyle(this._anchor).backgroundColor;
|
|
2263
|
-
const backdrop = document.createElement("div");
|
|
2264
|
-
backdrop.classList.add("fab-backdrop");
|
|
2265
|
-
backdrop.style.backgroundColor = fabColor;
|
|
2266
|
-
this._anchor.append(backdrop);
|
|
2267
|
-
this._backdrop = backdrop;
|
|
2268
|
-
const backdropWidth = backdrop.clientWidth;
|
|
2269
|
-
const scaleFactor = backdropWidth > 0 ? windowWidth / backdropWidth : 1;
|
|
2270
|
-
this.offsetX = btnRect.left - windowWidth / 2 + btnRect.width / 2;
|
|
2271
|
-
this.offsetY = windowHeight - btnRect.bottom;
|
|
2272
|
-
this.btnBottom = btnRect.bottom;
|
|
2273
|
-
this.btnLeft = btnRect.left;
|
|
2274
|
-
this.btnWidth = btnRect.width;
|
|
2275
|
-
this.el.classList.add("active");
|
|
2276
|
-
this.el.style.textAlign = "center";
|
|
2277
|
-
this.el.style.width = "100%";
|
|
2278
|
-
this.el.style.bottom = "0";
|
|
2279
|
-
this.el.style.left = "0";
|
|
2280
|
-
this.el.style.transform = "translateX(" + this.offsetX + "px)";
|
|
2281
|
-
this.el.style.transition = "none";
|
|
2282
|
-
if (this._menu) this._menu.ariaExpanded = "true";
|
|
2283
|
-
this._anchor.style.transform = `translateY(${this.offsetY}px)`;
|
|
2284
|
-
this._anchor.style.transition = "none";
|
|
2285
|
-
setTimeout(() => {
|
|
2286
|
-
this.el.style.transform = "";
|
|
2287
|
-
this.el.style.transition = "transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s";
|
|
2288
|
-
this._anchor.style.overflow = "visible";
|
|
2289
|
-
this._anchor.style.transform = "";
|
|
2290
|
-
this._anchor.style.transition = "transform .2s";
|
|
2291
|
-
setTimeout(() => {
|
|
2292
|
-
this.el.style.overflow = "hidden";
|
|
2293
|
-
this.el.style.backgroundColor = fabColor;
|
|
2294
|
-
backdrop.style.transform = "scale(" + scaleFactor + ")";
|
|
2295
|
-
backdrop.style.transition = "transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)";
|
|
2296
|
-
this._menu.querySelectorAll("li > a").forEach((a) => {
|
|
2297
|
-
a.style.opacity = "1";
|
|
2298
|
-
a.tabIndex = 0;
|
|
2299
|
-
});
|
|
2300
|
-
window.addEventListener("scroll", this.close, true);
|
|
2301
|
-
document.body.addEventListener("click", this._handleDocumentClick, true);
|
|
2302
|
-
}, 100);
|
|
2303
|
-
}, 0);
|
|
2214
|
+
this.el.removeEventListener("click", this._handleFABClick);
|
|
2215
|
+
this._anchor?.removeEventListener("keydown", this._handleAnchorKeydown);
|
|
2304
2216
|
}
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
* Closing used to only unbind the listeners, leaving the FAB stretched
|
|
2309
|
-
* across the viewport with its backdrop still in the DOM - and a fresh
|
|
2310
|
-
* backdrop appended on every subsequent open.
|
|
2311
|
-
*/
|
|
2312
|
-
_animateOutToolbar() {
|
|
2313
|
-
const backdrop = this._backdrop;
|
|
2314
|
-
this._backdrop = null;
|
|
2315
|
-
this._menu?.querySelectorAll("li > a").forEach((a) => {
|
|
2316
|
-
a.style.opacity = "";
|
|
2317
|
-
a.tabIndex = -1;
|
|
2318
|
-
});
|
|
2319
|
-
if (backdrop) {
|
|
2320
|
-
backdrop.style.transition = "transform .2s";
|
|
2321
|
-
backdrop.style.transform = "scale(0)";
|
|
2322
|
-
}
|
|
2323
|
-
this.el.style.overflow = "";
|
|
2324
|
-
this.el.style.backgroundColor = "";
|
|
2325
|
-
this.el.style.transition = "transform .2s";
|
|
2326
|
-
this.el.style.transform = `translateX(${this.offsetX}px)`;
|
|
2327
|
-
this._anchor.style.transition = "transform .2s";
|
|
2328
|
-
this._anchor.style.transform = `translateY(${this.offsetY}px)`;
|
|
2329
|
-
setTimeout(() => {
|
|
2330
|
-
backdrop?.remove();
|
|
2331
|
-
this.el.classList.remove("active");
|
|
2332
|
-
if (this._menu) this._menu.ariaExpanded = "false";
|
|
2333
|
-
this.el.style.textAlign = "";
|
|
2334
|
-
this.el.style.width = "";
|
|
2335
|
-
this.el.style.bottom = "";
|
|
2336
|
-
this.el.style.left = "";
|
|
2337
|
-
this.el.style.transform = "";
|
|
2338
|
-
this.el.style.transition = "";
|
|
2339
|
-
this._anchor.style.overflow = "";
|
|
2340
|
-
this._anchor.style.transform = "";
|
|
2341
|
-
this._anchor.style.transition = "";
|
|
2342
|
-
}, 200);
|
|
2217
|
+
_toggle() {
|
|
2218
|
+
if (this.isOpen) this.close();
|
|
2219
|
+
else this.open();
|
|
2343
2220
|
}
|
|
2344
2221
|
};
|
|
2345
2222
|
|
|
2346
2223
|
// src/ts/components/carousel.ts
|
|
2347
2224
|
var _defaults7 = {
|
|
2348
2225
|
duration: 200,
|
|
2349
|
-
// ms
|
|
2350
2226
|
dist: -100,
|
|
2351
|
-
// zoom scale TODO: make this more intuitive as an option
|
|
2352
2227
|
shift: 0,
|
|
2353
|
-
// spacing for center image
|
|
2354
2228
|
padding: 0,
|
|
2355
|
-
// Padding between non center items
|
|
2356
2229
|
numVisible: 5,
|
|
2357
|
-
// Number of visible items in carousel
|
|
2358
2230
|
fullWidth: false,
|
|
2359
|
-
// Change to full width styles
|
|
2360
2231
|
indicators: false,
|
|
2361
|
-
// Toggle indicators
|
|
2362
2232
|
noWrap: false,
|
|
2363
|
-
// Don't wrap around and cycle through items.
|
|
2364
2233
|
onCycleTo: null
|
|
2365
|
-
// Callback for when a new slide is cycled to.
|
|
2366
2234
|
};
|
|
2367
|
-
var
|
|
2235
|
+
var _Carousel = class _Carousel extends Component {
|
|
2368
2236
|
constructor(el, options) {
|
|
2369
2237
|
super(el, options, _Carousel);
|
|
2370
|
-
/** The index of the center carousel item. */
|
|
2371
2238
|
this.center = 0;
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2239
|
+
this._ownIndicators = false;
|
|
2240
|
+
this._trackEl = null;
|
|
2241
|
+
this._ignoreScroll = false;
|
|
2242
|
+
this._trackRaf = null;
|
|
2243
|
+
this._started = false;
|
|
2375
2244
|
this._handleThrottledResize = Utils.throttle(() => this._handleResize(), 200);
|
|
2376
2245
|
this._handleCarouselTap = (e) => {
|
|
2377
|
-
if (e.
|
|
2246
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
2247
|
+
if (e.target instanceof HTMLElement && e.target.tagName === "IMG") {
|
|
2378
2248
|
e.preventDefault();
|
|
2379
2249
|
}
|
|
2380
2250
|
this.pressed = true;
|
|
2381
2251
|
this.dragged = false;
|
|
2382
2252
|
this.verticalDragged = false;
|
|
2383
|
-
this.reference =
|
|
2384
|
-
this.referenceY =
|
|
2253
|
+
this.reference = e.clientX;
|
|
2254
|
+
this.referenceY = e.clientY;
|
|
2385
2255
|
this.velocity = this.amplitude = 0;
|
|
2386
2256
|
this.frame = this.offset;
|
|
2387
2257
|
this.timestamp = Date.now();
|
|
2388
|
-
|
|
2389
|
-
|
|
2258
|
+
try {
|
|
2259
|
+
this.el.setPointerCapture(e.pointerId);
|
|
2260
|
+
} catch {
|
|
2261
|
+
}
|
|
2262
|
+
if (this._trackRaf !== null) cancelAnimationFrame(this._trackRaf);
|
|
2263
|
+
const loop = () => {
|
|
2264
|
+
this._track();
|
|
2265
|
+
if (this.pressed) this._trackRaf = requestAnimationFrame(loop);
|
|
2266
|
+
else this._trackRaf = null;
|
|
2267
|
+
};
|
|
2268
|
+
this._trackRaf = requestAnimationFrame(loop);
|
|
2390
2269
|
};
|
|
2391
2270
|
this._handleCarouselDrag = (e) => {
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
delta
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
this.dragged = true;
|
|
2401
|
-
this.reference = x;
|
|
2402
|
-
this._scroll(this.offset + delta);
|
|
2403
|
-
}
|
|
2404
|
-
} else if (this.dragged) {
|
|
2405
|
-
e.preventDefault();
|
|
2406
|
-
e.stopPropagation();
|
|
2407
|
-
return false;
|
|
2408
|
-
} else {
|
|
2409
|
-
this.verticalDragged = true;
|
|
2271
|
+
if (!this.pressed) return;
|
|
2272
|
+
const delta = this.reference - e.clientX;
|
|
2273
|
+
const deltaY = Math.abs(this.referenceY - e.clientY);
|
|
2274
|
+
if (deltaY < 30 && !this.verticalDragged) {
|
|
2275
|
+
if (delta > 2 || delta < -2) {
|
|
2276
|
+
this.dragged = true;
|
|
2277
|
+
this.reference = e.clientX;
|
|
2278
|
+
this._scroll(this.offset + delta);
|
|
2410
2279
|
}
|
|
2411
|
-
}
|
|
2412
|
-
if (this.dragged) {
|
|
2280
|
+
} else if (this.dragged) {
|
|
2413
2281
|
e.preventDefault();
|
|
2414
|
-
|
|
2415
|
-
|
|
2282
|
+
} else {
|
|
2283
|
+
this.verticalDragged = true;
|
|
2416
2284
|
}
|
|
2285
|
+
if (this.dragged) e.preventDefault();
|
|
2417
2286
|
};
|
|
2418
2287
|
this._handleCarouselRelease = (e) => {
|
|
2419
|
-
if (this.pressed)
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2288
|
+
if (!this.pressed) return;
|
|
2289
|
+
this.pressed = false;
|
|
2290
|
+
if (this._trackRaf !== null) {
|
|
2291
|
+
cancelAnimationFrame(this._trackRaf);
|
|
2292
|
+
this._trackRaf = null;
|
|
2293
|
+
}
|
|
2294
|
+
try {
|
|
2295
|
+
this.el.releasePointerCapture(e.pointerId);
|
|
2296
|
+
} catch {
|
|
2423
2297
|
}
|
|
2424
|
-
clearInterval(this.ticker);
|
|
2425
2298
|
this.target = this.offset;
|
|
2426
2299
|
if (this.velocity > 10 || this.velocity < -10) {
|
|
2427
2300
|
this.amplitude = 0.9 * this.velocity;
|
|
@@ -2438,86 +2311,91 @@ var Expressive = (() => {
|
|
|
2438
2311
|
this.amplitude = this.target - this.offset;
|
|
2439
2312
|
this.timestamp = Date.now();
|
|
2440
2313
|
requestAnimationFrame(this._autoScroll);
|
|
2314
|
+
if (this.dragged) e.preventDefault();
|
|
2315
|
+
};
|
|
2316
|
+
this._handleCarouselClick = (e) => {
|
|
2441
2317
|
if (this.dragged) {
|
|
2442
2318
|
e.preventDefault();
|
|
2443
2319
|
e.stopPropagation();
|
|
2320
|
+
return;
|
|
2444
2321
|
}
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2322
|
+
const clickedElem = e.target.closest(".carousel-item");
|
|
2323
|
+
if (!clickedElem || !this.el.contains(clickedElem)) return;
|
|
2324
|
+
const clickedIndex = this.images.indexOf(clickedElem);
|
|
2325
|
+
const diff = this._wrap(this.center) - clickedIndex;
|
|
2326
|
+
if (diff !== 0) {
|
|
2449
2327
|
e.preventDefault();
|
|
2450
2328
|
e.stopPropagation();
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
const clickedIndex = [...clickedElem.parentNode.children].indexOf(clickedElem);
|
|
2456
|
-
const diff = this._wrap(this.center) - clickedIndex;
|
|
2457
|
-
if (diff !== 0) {
|
|
2458
|
-
e.preventDefault();
|
|
2459
|
-
e.stopPropagation();
|
|
2460
|
-
}
|
|
2461
|
-
if (clickedIndex < 0) {
|
|
2462
|
-
if (e.clientX - e.target.getBoundingClientRect().left > this.el.clientWidth / 2) {
|
|
2463
|
-
this.next();
|
|
2464
|
-
} else {
|
|
2465
|
-
this.prev();
|
|
2466
|
-
}
|
|
2329
|
+
}
|
|
2330
|
+
if (clickedIndex < 0) {
|
|
2331
|
+
if (e.clientX - e.target.getBoundingClientRect().left > this.el.clientWidth / 2) {
|
|
2332
|
+
this.next();
|
|
2467
2333
|
} else {
|
|
2468
|
-
this.
|
|
2334
|
+
this.prev();
|
|
2469
2335
|
}
|
|
2336
|
+
} else {
|
|
2337
|
+
this._cycleTo(clickedIndex);
|
|
2470
2338
|
}
|
|
2471
2339
|
};
|
|
2472
2340
|
this._handleIndicatorClick = (e) => {
|
|
2473
2341
|
e.stopPropagation();
|
|
2474
|
-
|
|
2342
|
+
const indicator = e.target.closest(".indicator-item");
|
|
2343
|
+
if (!indicator || !this._indicators.contains(indicator)) return;
|
|
2344
|
+
const index = [...this._indicators.children].indexOf(indicator);
|
|
2345
|
+
if (index < 0) return;
|
|
2346
|
+
this._cycleTo(index);
|
|
2475
2347
|
};
|
|
2476
|
-
this.
|
|
2477
|
-
e.
|
|
2478
|
-
if (
|
|
2479
|
-
|
|
2348
|
+
this._handleKeydown = (e) => {
|
|
2349
|
+
const target = e.target;
|
|
2350
|
+
if (target.closest('input, textarea, select, [contenteditable="true"]')) return;
|
|
2351
|
+
if (Utils.keys.ARROW_RIGHT.includes(e.key)) {
|
|
2352
|
+
e.preventDefault();
|
|
2353
|
+
this.next();
|
|
2354
|
+
} else if (Utils.keys.ARROW_LEFT.includes(e.key)) {
|
|
2355
|
+
e.preventDefault();
|
|
2356
|
+
this.prev();
|
|
2480
2357
|
}
|
|
2481
2358
|
};
|
|
2482
|
-
this.
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
this._cycleTo(index);
|
|
2487
|
-
}
|
|
2359
|
+
this._handleFlatScroll = () => {
|
|
2360
|
+
if (this._ignoreScroll) return;
|
|
2361
|
+
const index = this._nearestIndex();
|
|
2362
|
+
if (index !== this.center) this._syncActive(index, this.dragged);
|
|
2488
2363
|
};
|
|
2489
2364
|
this._handleResize = () => {
|
|
2365
|
+
if (!this.images.length) return;
|
|
2366
|
+
if (this._flat) {
|
|
2367
|
+
this._scrollToIndex(this.center, false);
|
|
2368
|
+
return;
|
|
2369
|
+
}
|
|
2490
2370
|
if (this.options.fullWidth) {
|
|
2491
|
-
const firstItem = this.
|
|
2492
|
-
|
|
2493
|
-
if (!firstItem || !activeItem) return;
|
|
2371
|
+
const firstItem = this.images[0];
|
|
2372
|
+
if (!firstItem) return;
|
|
2494
2373
|
this.itemWidth = firstItem.clientWidth;
|
|
2495
|
-
this.imageHeight = activeItem.clientHeight;
|
|
2496
2374
|
this.dim = this.itemWidth * 2 + this.options.padding;
|
|
2497
2375
|
this.offset = this.center * 2 * this.itemWidth;
|
|
2498
2376
|
this.target = this.offset;
|
|
2499
|
-
this._setCarouselHeight(true);
|
|
2500
2377
|
} else {
|
|
2501
2378
|
this._scroll();
|
|
2502
2379
|
}
|
|
2503
2380
|
};
|
|
2504
2381
|
this._track = () => {
|
|
2505
|
-
const now = Date.now()
|
|
2382
|
+
const now = Date.now();
|
|
2383
|
+
const elapsed = now - this.timestamp;
|
|
2384
|
+
const delta = this.offset - this.frame;
|
|
2385
|
+
const v = 1e3 * delta / (1 + elapsed);
|
|
2506
2386
|
this.timestamp = now;
|
|
2507
2387
|
this.frame = this.offset;
|
|
2508
2388
|
this.velocity = 0.8 * v + 0.2 * this.velocity;
|
|
2509
2389
|
};
|
|
2510
2390
|
this._autoScroll = () => {
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
this._scroll(this.target);
|
|
2520
|
-
}
|
|
2391
|
+
if (!this.amplitude) return;
|
|
2392
|
+
const elapsed = Date.now() - this.timestamp;
|
|
2393
|
+
const delta = this.amplitude * Math.exp(-elapsed / this.options.duration);
|
|
2394
|
+
if (delta > 2 || delta < -2) {
|
|
2395
|
+
this._scroll(this.target - delta);
|
|
2396
|
+
requestAnimationFrame(this._autoScroll);
|
|
2397
|
+
} else {
|
|
2398
|
+
this._scroll(this.target);
|
|
2521
2399
|
}
|
|
2522
2400
|
};
|
|
2523
2401
|
this.el["Expressive_Carousel"] = this;
|
|
@@ -2525,56 +2403,58 @@ var Expressive = (() => {
|
|
|
2525
2403
|
..._Carousel.defaults,
|
|
2526
2404
|
...options
|
|
2527
2405
|
};
|
|
2528
|
-
this.
|
|
2529
|
-
|
|
2530
|
-
|
|
2406
|
+
this._flat = this.options.fullWidth || this.el.classList.contains("flat") || this.el.classList.contains("carousel-slider");
|
|
2407
|
+
if (this._flat) {
|
|
2408
|
+
this.el.classList.add("flat");
|
|
2409
|
+
this.options.fullWidth = true;
|
|
2410
|
+
this.options.dist = 0;
|
|
2411
|
+
}
|
|
2412
|
+
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
2413
|
+
this.options.duration = 1;
|
|
2414
|
+
if (!this._flat) this.options.dist = 0;
|
|
2415
|
+
}
|
|
2531
2416
|
this.pressed = false;
|
|
2532
2417
|
this.dragged = false;
|
|
2533
2418
|
this.offset = this.target = 0;
|
|
2534
|
-
this.images =
|
|
2535
|
-
|
|
2536
|
-
if (!firstItem) {
|
|
2419
|
+
this.images = this._collectItems();
|
|
2420
|
+
if (!this.images.length) {
|
|
2537
2421
|
console.error("Carousel: no .carousel-item elements to show");
|
|
2538
2422
|
return;
|
|
2539
2423
|
}
|
|
2540
|
-
this.
|
|
2541
|
-
this.
|
|
2542
|
-
this.
|
|
2543
|
-
if (this.options.fullWidth) {
|
|
2544
|
-
this.options.dist = 0;
|
|
2545
|
-
this._setCarouselHeight();
|
|
2546
|
-
if (this.showIndicators) {
|
|
2547
|
-
this.el.querySelector(".carousel-fixed-item")?.classList.add("with-indicators");
|
|
2548
|
-
}
|
|
2549
|
-
}
|
|
2550
|
-
this._indicators = document.createElement("ul");
|
|
2551
|
-
this._indicators.classList.add("indicators");
|
|
2552
|
-
this.el.querySelectorAll(".carousel-item").forEach((item, i) => {
|
|
2553
|
-
this.images.push(item);
|
|
2554
|
-
if (this.showIndicators) {
|
|
2555
|
-
const indicator = document.createElement("li");
|
|
2556
|
-
indicator.classList.add("indicator-item");
|
|
2557
|
-
indicator.tabIndex = 0;
|
|
2558
|
-
if (i === 0) {
|
|
2559
|
-
indicator.classList.add("active");
|
|
2560
|
-
}
|
|
2561
|
-
this._indicators.appendChild(indicator);
|
|
2562
|
-
}
|
|
2563
|
-
});
|
|
2564
|
-
if (this.showIndicators) this.el.appendChild(this._indicators);
|
|
2424
|
+
this.hasMultipleSlides = this.images.length > 1;
|
|
2425
|
+
this.showIndicators = this.options.indicators && this.hasMultipleSlides;
|
|
2426
|
+
this.noWrap = this.options.noWrap || !this.hasMultipleSlides || this._flat;
|
|
2565
2427
|
this.count = this.images.length;
|
|
2566
2428
|
this.options.numVisible = Math.min(this.count, this.options.numVisible);
|
|
2429
|
+
this.images.forEach((item) => item.classList.add("carousel-item"));
|
|
2430
|
+
if (this._flat) this._wrapTrack();
|
|
2431
|
+
const firstItem = this.images[0];
|
|
2432
|
+
this.itemWidth = firstItem.clientWidth || this.el.clientWidth || 1;
|
|
2433
|
+
this.itemHeight = firstItem.clientHeight || this.el.clientHeight || 1;
|
|
2434
|
+
this.dim = this.itemWidth * 2 + this.options.padding || 1;
|
|
2435
|
+
if (this.showIndicators) this._setupIndicators();
|
|
2436
|
+
this.el.tabIndex = this.el.tabIndex >= 0 ? this.el.tabIndex : 0;
|
|
2437
|
+
this.el.setAttribute("aria-roledescription", "carousel");
|
|
2567
2438
|
this._setupEventHandlers();
|
|
2568
|
-
this.
|
|
2439
|
+
this._started = true;
|
|
2440
|
+
if (this._flat) {
|
|
2441
|
+
const start = Math.max(
|
|
2442
|
+
0,
|
|
2443
|
+
this.images.findIndex((el2) => el2.classList.contains("active"))
|
|
2444
|
+
);
|
|
2445
|
+
this.center = start;
|
|
2446
|
+
this._syncActive(start, false);
|
|
2447
|
+
this._scrollToIndex(start, false);
|
|
2448
|
+
} else {
|
|
2449
|
+
this._scroll(this.offset);
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
get _scroller() {
|
|
2453
|
+
return this._trackEl ?? this.el;
|
|
2569
2454
|
}
|
|
2570
2455
|
static get defaults() {
|
|
2571
2456
|
return _defaults7;
|
|
2572
2457
|
}
|
|
2573
|
-
/**
|
|
2574
|
-
* Initializes instances of Carousel.
|
|
2575
|
-
* @param els HTML elements.
|
|
2576
|
-
* @param options Component options.
|
|
2577
|
-
*/
|
|
2578
2458
|
static init(els, options = {}) {
|
|
2579
2459
|
return super.init(els, options, _Carousel);
|
|
2580
2460
|
}
|
|
@@ -2582,81 +2462,104 @@ var Expressive = (() => {
|
|
|
2582
2462
|
return el["Expressive_Carousel"];
|
|
2583
2463
|
}
|
|
2584
2464
|
destroy() {
|
|
2585
|
-
this.
|
|
2465
|
+
if (this._started) this._teardown();
|
|
2586
2466
|
this.el["Expressive_Carousel"] = void 0;
|
|
2587
2467
|
}
|
|
2468
|
+
_collectItems() {
|
|
2469
|
+
const explicit = Array.from(this.el.children).filter(
|
|
2470
|
+
(el) => el instanceof HTMLElement && el.classList.contains("carousel-item")
|
|
2471
|
+
);
|
|
2472
|
+
if (explicit.length) return explicit;
|
|
2473
|
+
return Array.from(this.el.children).filter((el) => {
|
|
2474
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
2475
|
+
if (el.classList.contains("indicators") || el.classList.contains("carousel-fixed-item")) {
|
|
2476
|
+
return false;
|
|
2477
|
+
}
|
|
2478
|
+
return el.tagName !== "NAV";
|
|
2479
|
+
});
|
|
2480
|
+
}
|
|
2481
|
+
_setupIndicators() {
|
|
2482
|
+
const existing = Array.from(this.el.children).find(
|
|
2483
|
+
(el) => el instanceof HTMLElement && el.classList.contains("indicators")
|
|
2484
|
+
);
|
|
2485
|
+
this._indicators = existing ?? document.createElement("nav");
|
|
2486
|
+
this._ownIndicators = !existing;
|
|
2487
|
+
this._indicators.classList.add("indicators");
|
|
2488
|
+
this._indicators.setAttribute("aria-label", "Slides");
|
|
2489
|
+
this._indicators.replaceChildren();
|
|
2490
|
+
this.images.forEach((_, i) => {
|
|
2491
|
+
const button = document.createElement("button");
|
|
2492
|
+
button.type = "button";
|
|
2493
|
+
button.classList.add("indicator-item");
|
|
2494
|
+
if (i === 0) {
|
|
2495
|
+
button.classList.add("active");
|
|
2496
|
+
button.setAttribute("aria-current", "true");
|
|
2497
|
+
}
|
|
2498
|
+
button.setAttribute("aria-label", `Slide ${i + 1}`);
|
|
2499
|
+
this._indicators.appendChild(button);
|
|
2500
|
+
});
|
|
2501
|
+
if (this._ownIndicators) this.el.appendChild(this._indicators);
|
|
2502
|
+
if (this._flat) {
|
|
2503
|
+
this.el.querySelector(".carousel-fixed-item")?.classList.add("with-indicators");
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2588
2506
|
_setupEventHandlers() {
|
|
2589
|
-
|
|
2590
|
-
this.el.addEventListener("touchstart", this._handleCarouselTap);
|
|
2591
|
-
this.el.addEventListener("touchmove", this._handleCarouselDrag);
|
|
2592
|
-
this.el.addEventListener("touchend", this._handleCarouselRelease);
|
|
2593
|
-
}
|
|
2594
|
-
this.el.addEventListener("mousedown", this._handleCarouselTap);
|
|
2595
|
-
this.el.addEventListener("mousemove", this._handleCarouselDrag);
|
|
2596
|
-
this.el.addEventListener("mouseup", this._handleCarouselRelease);
|
|
2597
|
-
this.el.addEventListener("mouseleave", this._handleCarouselRelease);
|
|
2598
|
-
this.el.addEventListener("click", this._handleCarouselClick);
|
|
2507
|
+
this.el.addEventListener("keydown", this._handleKeydown);
|
|
2599
2508
|
if (this.showIndicators && this._indicators) {
|
|
2600
|
-
this._indicators.
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2509
|
+
this._indicators.addEventListener("click", this._handleIndicatorClick);
|
|
2510
|
+
}
|
|
2511
|
+
_Carousel._live.add(this);
|
|
2512
|
+
if (!_Carousel._resizeListening) {
|
|
2513
|
+
window.addEventListener("resize", _Carousel._onResize, { passive: true });
|
|
2514
|
+
_Carousel._resizeListening = true;
|
|
2515
|
+
}
|
|
2516
|
+
if (this._flat) {
|
|
2517
|
+
this._scroller.addEventListener("scroll", this._handleFlatScroll, { passive: true });
|
|
2518
|
+
return;
|
|
2604
2519
|
}
|
|
2605
|
-
|
|
2520
|
+
this.el.addEventListener("pointerdown", this._handleCarouselTap);
|
|
2521
|
+
this.el.addEventListener("pointermove", this._handleCarouselDrag);
|
|
2522
|
+
this.el.addEventListener("pointerup", this._handleCarouselRelease);
|
|
2523
|
+
this.el.addEventListener("pointercancel", this._handleCarouselRelease);
|
|
2524
|
+
this.el.addEventListener("click", this._handleCarouselClick);
|
|
2606
2525
|
}
|
|
2607
2526
|
_removeEventHandlers() {
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
this.
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
this.el.removeEventListener("
|
|
2614
|
-
this.el.removeEventListener("
|
|
2615
|
-
this.el.removeEventListener("
|
|
2616
|
-
this.el.removeEventListener("
|
|
2527
|
+
this.el.removeEventListener("keydown", this._handleKeydown);
|
|
2528
|
+
if (this._indicators) {
|
|
2529
|
+
this._indicators.removeEventListener("click", this._handleIndicatorClick);
|
|
2530
|
+
}
|
|
2531
|
+
this._scroller.removeEventListener("scroll", this._handleFlatScroll);
|
|
2532
|
+
this.el.removeEventListener("pointerdown", this._handleCarouselTap);
|
|
2533
|
+
this.el.removeEventListener("pointermove", this._handleCarouselDrag);
|
|
2534
|
+
this.el.removeEventListener("pointerup", this._handleCarouselRelease);
|
|
2535
|
+
this.el.removeEventListener("pointercancel", this._handleCarouselRelease);
|
|
2617
2536
|
this.el.removeEventListener("click", this._handleCarouselClick);
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2537
|
+
_Carousel._live.delete(this);
|
|
2538
|
+
if (_Carousel._live.size === 0 && _Carousel._resizeListening) {
|
|
2539
|
+
window.removeEventListener("resize", _Carousel._onResize);
|
|
2540
|
+
_Carousel._resizeListening = false;
|
|
2622
2541
|
}
|
|
2623
|
-
window.removeEventListener("resize", this._handleThrottledResize);
|
|
2624
2542
|
}
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
this.el.style.height = adjustedHeight + "px";
|
|
2638
|
-
}
|
|
2639
|
-
} else {
|
|
2640
|
-
firstImage.addEventListener("load", () => {
|
|
2641
|
-
this.el.style.height = firstImage.offsetHeight + "px";
|
|
2642
|
-
});
|
|
2643
|
-
}
|
|
2644
|
-
} else if (!imageOnly) {
|
|
2645
|
-
const slideHeight = firstSlide.clientHeight;
|
|
2646
|
-
this.el.style.height = slideHeight + "px";
|
|
2647
|
-
}
|
|
2543
|
+
_teardown() {
|
|
2544
|
+
this._removeEventHandlers();
|
|
2545
|
+
if (this._trackRaf !== null) cancelAnimationFrame(this._trackRaf);
|
|
2546
|
+
window.clearTimeout(this.scrollingTimeout);
|
|
2547
|
+
if (this._ownIndicators) this._indicators?.remove();
|
|
2548
|
+
this._unwrapTrack();
|
|
2549
|
+
this.images.forEach((el) => {
|
|
2550
|
+
el.style.transform = "";
|
|
2551
|
+
el.style.zIndex = "";
|
|
2552
|
+
el.style.opacity = "";
|
|
2553
|
+
el.style.visibility = "";
|
|
2554
|
+
});
|
|
2648
2555
|
}
|
|
2649
2556
|
_xpos(e) {
|
|
2650
|
-
if (
|
|
2651
|
-
|
|
2652
|
-
}
|
|
2653
|
-
return e.clientX;
|
|
2557
|
+
if ("clientX" in e) return e.clientX;
|
|
2558
|
+
return 0;
|
|
2654
2559
|
}
|
|
2655
2560
|
_ypos(e) {
|
|
2656
|
-
if (
|
|
2657
|
-
|
|
2658
|
-
}
|
|
2659
|
-
return e.clientY;
|
|
2561
|
+
if ("clientY" in e) return e.clientY;
|
|
2562
|
+
return 0;
|
|
2660
2563
|
}
|
|
2661
2564
|
_wrap(x) {
|
|
2662
2565
|
return x >= this.count ? x % this.count : x < 0 ? this._wrap(this.count + x % this.count) : x;
|
|
@@ -2665,18 +2568,20 @@ var Expressive = (() => {
|
|
|
2665
2568
|
if (!this.el.classList.contains("scrolling")) {
|
|
2666
2569
|
this.el.classList.add("scrolling");
|
|
2667
2570
|
}
|
|
2668
|
-
|
|
2669
|
-
clearTimeout(this.scrollingTimeout);
|
|
2670
|
-
}
|
|
2571
|
+
window.clearTimeout(this.scrollingTimeout);
|
|
2671
2572
|
this.scrollingTimeout = setTimeout(() => {
|
|
2672
2573
|
this.el.classList.remove("scrolling");
|
|
2673
2574
|
}, this.options.duration);
|
|
2674
2575
|
this.offset = typeof x === "number" ? x : this.offset;
|
|
2675
2576
|
this.center = Math.floor((this.offset + this.dim / 2) / this.dim);
|
|
2676
|
-
const half = this.count >> 1
|
|
2677
|
-
|
|
2577
|
+
const half = this.count >> 1;
|
|
2578
|
+
const delta = this.offset - this.center * this.dim;
|
|
2579
|
+
const dir = delta < 0 ? 1 : -1;
|
|
2580
|
+
const tween = -dir * delta * 2 / this.dim;
|
|
2678
2581
|
const lastCenter = this.center;
|
|
2679
2582
|
const numVisibleOffset = 1 / this.options.numVisible;
|
|
2583
|
+
let alignment;
|
|
2584
|
+
let centerTweenedOpacity;
|
|
2680
2585
|
if (this.options.fullWidth) {
|
|
2681
2586
|
alignment = "translateX(0)";
|
|
2682
2587
|
centerTweenedOpacity = 1;
|
|
@@ -2685,26 +2590,17 @@ var Expressive = (() => {
|
|
|
2685
2590
|
alignment += "translateY(" + (this.el.clientHeight - this.itemHeight) / 2 + "px)";
|
|
2686
2591
|
centerTweenedOpacity = 1 - numVisibleOffset * tween;
|
|
2687
2592
|
}
|
|
2688
|
-
|
|
2689
|
-
const diff = this.center % this.count;
|
|
2690
|
-
const activeIndicator = this._indicators.querySelector(".indicator-item.active");
|
|
2691
|
-
const activeIndicatorIndex = [...activeIndicator.parentNode.children].indexOf(
|
|
2692
|
-
activeIndicator
|
|
2693
|
-
);
|
|
2694
|
-
if (activeIndicatorIndex !== diff) {
|
|
2695
|
-
activeIndicator.classList.remove("active");
|
|
2696
|
-
const pos = diff < 0 ? this.count + diff : diff;
|
|
2697
|
-
this._indicators.querySelectorAll(".indicator-item")[pos].classList.add("active");
|
|
2698
|
-
}
|
|
2699
|
-
}
|
|
2593
|
+
this._paintIndicators(this.center);
|
|
2700
2594
|
if (!this.noWrap || this.center >= 0 && this.center < this.count) {
|
|
2701
|
-
el = this.images[this._wrap(this.center)];
|
|
2702
|
-
if (!el.classList.contains("active")) {
|
|
2595
|
+
const el = this.images[this._wrap(this.center)];
|
|
2596
|
+
if (el && !el.classList.contains("active")) {
|
|
2703
2597
|
this.el.querySelector(".carousel-item.active")?.classList.remove("active");
|
|
2704
2598
|
el.classList.add("active");
|
|
2705
2599
|
}
|
|
2706
2600
|
}
|
|
2707
|
-
for (i = 1; i <= half; ++i) {
|
|
2601
|
+
for (let i = 1; i <= half; ++i) {
|
|
2602
|
+
let zTranslation;
|
|
2603
|
+
let tweenedOpacity;
|
|
2708
2604
|
if (this.options.fullWidth) {
|
|
2709
2605
|
zTranslation = this.options.dist;
|
|
2710
2606
|
tweenedOpacity = i === half && delta < 0 ? 1 - tween : 1;
|
|
@@ -2713,7 +2609,7 @@ var Expressive = (() => {
|
|
|
2713
2609
|
tweenedOpacity = 1 - numVisibleOffset * (i * 2 + tween * dir);
|
|
2714
2610
|
}
|
|
2715
2611
|
if (!this.noWrap || this.center + i < this.count) {
|
|
2716
|
-
el = this.images[this._wrap(this.center + i)];
|
|
2612
|
+
const el = this.images[this._wrap(this.center + i)];
|
|
2717
2613
|
const transformString = `${alignment} translateX(${this.options.shift + (this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
2718
2614
|
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
2719
2615
|
}
|
|
@@ -2725,32 +2621,113 @@ var Expressive = (() => {
|
|
|
2725
2621
|
tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
|
|
2726
2622
|
}
|
|
2727
2623
|
if (!this.noWrap || this.center - i >= 0) {
|
|
2728
|
-
el = this.images[this._wrap(this.center - i)];
|
|
2624
|
+
const el = this.images[this._wrap(this.center - i)];
|
|
2729
2625
|
const transformString = `${alignment} translateX(${-this.options.shift + (-this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
2730
2626
|
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
2731
2627
|
}
|
|
2732
2628
|
}
|
|
2733
2629
|
if (!this.noWrap || this.center >= 0 && this.center < this.count) {
|
|
2734
|
-
el = this.images[this._wrap(this.center)];
|
|
2630
|
+
const el = this.images[this._wrap(this.center)];
|
|
2735
2631
|
const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir * this.options.shift * tween}px) translateZ(${this.options.dist * tween}px)`;
|
|
2736
2632
|
this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
|
|
2737
2633
|
}
|
|
2738
|
-
const
|
|
2634
|
+
const currItem = this.images[this._wrap(this.center)];
|
|
2635
|
+
this._syncA11y(this._wrap(this.center));
|
|
2739
2636
|
if (lastCenter !== this.center && typeof this.options.onCycleTo === "function") {
|
|
2740
|
-
this.options.onCycleTo.call(this,
|
|
2637
|
+
this.options.onCycleTo.call(this, currItem, this.dragged);
|
|
2741
2638
|
}
|
|
2742
2639
|
if (typeof this.oneTimeCallback === "function") {
|
|
2743
|
-
this.oneTimeCallback.call(this,
|
|
2640
|
+
this.oneTimeCallback.call(this, currItem, this.dragged);
|
|
2744
2641
|
this.oneTimeCallback = null;
|
|
2745
2642
|
}
|
|
2746
2643
|
}
|
|
2747
2644
|
_updateItemStyle(el, opacity, zIndex, transform) {
|
|
2645
|
+
if (!el) return;
|
|
2748
2646
|
el.style.transform = transform;
|
|
2749
2647
|
el.style.zIndex = zIndex.toString();
|
|
2750
2648
|
el.style.opacity = opacity.toString();
|
|
2751
2649
|
el.style.visibility = "visible";
|
|
2752
2650
|
}
|
|
2651
|
+
_paintIndicators(center) {
|
|
2652
|
+
if (!this.showIndicators || !this._indicators) return;
|
|
2653
|
+
const pos = (center % this.count + this.count) % this.count;
|
|
2654
|
+
this._indicators.querySelectorAll(".indicator-item").forEach((el, i) => {
|
|
2655
|
+
const on = i === pos;
|
|
2656
|
+
el.classList.toggle("active", on);
|
|
2657
|
+
if (on) el.setAttribute("aria-current", "true");
|
|
2658
|
+
else el.removeAttribute("aria-current");
|
|
2659
|
+
});
|
|
2660
|
+
}
|
|
2661
|
+
_syncA11y(index) {
|
|
2662
|
+
this.images.forEach((el, i) => {
|
|
2663
|
+
if (i === index) el.removeAttribute("aria-hidden");
|
|
2664
|
+
else el.setAttribute("aria-hidden", "true");
|
|
2665
|
+
});
|
|
2666
|
+
}
|
|
2667
|
+
_syncActive(index, dragged) {
|
|
2668
|
+
const prev = this.center;
|
|
2669
|
+
this.center = index;
|
|
2670
|
+
this.images.forEach((el, i) => el.classList.toggle("active", i === index));
|
|
2671
|
+
this._paintIndicators(index);
|
|
2672
|
+
this._syncA11y(index);
|
|
2673
|
+
const curr = this.images[index];
|
|
2674
|
+
if (prev !== index && typeof this.options.onCycleTo === "function") {
|
|
2675
|
+
this.options.onCycleTo.call(this, curr, dragged);
|
|
2676
|
+
}
|
|
2677
|
+
if (typeof this.oneTimeCallback === "function") {
|
|
2678
|
+
this.oneTimeCallback.call(this, curr, dragged);
|
|
2679
|
+
this.oneTimeCallback = null;
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
_wrapTrack() {
|
|
2683
|
+
const track = document.createElement("div");
|
|
2684
|
+
track.className = "carousel-track";
|
|
2685
|
+
this.images[0].before(track);
|
|
2686
|
+
this.images.forEach((el) => track.appendChild(el));
|
|
2687
|
+
this._trackEl = track;
|
|
2688
|
+
}
|
|
2689
|
+
_unwrapTrack() {
|
|
2690
|
+
if (!this._trackEl) return;
|
|
2691
|
+
this.images.forEach((el) => this.el.insertBefore(el, this._trackEl));
|
|
2692
|
+
this._trackEl.remove();
|
|
2693
|
+
this._trackEl = null;
|
|
2694
|
+
}
|
|
2695
|
+
_nearestIndex() {
|
|
2696
|
+
const left = this._scroller.scrollLeft;
|
|
2697
|
+
let best = 0;
|
|
2698
|
+
let bestDist = Infinity;
|
|
2699
|
+
this.images.forEach((el, i) => {
|
|
2700
|
+
const dist = Math.abs(el.offsetLeft - left);
|
|
2701
|
+
if (dist < bestDist) {
|
|
2702
|
+
bestDist = dist;
|
|
2703
|
+
best = i;
|
|
2704
|
+
}
|
|
2705
|
+
});
|
|
2706
|
+
return best;
|
|
2707
|
+
}
|
|
2708
|
+
_scrollToIndex(n, smooth = true) {
|
|
2709
|
+
const el = this.images[n];
|
|
2710
|
+
if (!el) return;
|
|
2711
|
+
const left = el.offsetLeft;
|
|
2712
|
+
if (Math.abs(this._scroller.scrollLeft - left) < 1) {
|
|
2713
|
+
this._syncActive(n, false);
|
|
2714
|
+
return;
|
|
2715
|
+
}
|
|
2716
|
+
this._ignoreScroll = true;
|
|
2717
|
+
this._scroller.scrollTo({ left, behavior: smooth ? "smooth" : "auto" });
|
|
2718
|
+
const done = () => {
|
|
2719
|
+
this._ignoreScroll = false;
|
|
2720
|
+
};
|
|
2721
|
+
this._scroller.addEventListener("scrollend", done, { once: true });
|
|
2722
|
+
window.setTimeout(done, this.options.duration + 350);
|
|
2723
|
+
}
|
|
2753
2724
|
_cycleTo(n, callback = null) {
|
|
2725
|
+
if (this._flat) {
|
|
2726
|
+
if (typeof callback === "function") this.oneTimeCallback = callback;
|
|
2727
|
+
this._syncActive(n, false);
|
|
2728
|
+
this._scrollToIndex(n);
|
|
2729
|
+
return;
|
|
2730
|
+
}
|
|
2754
2731
|
let diff = this.center % this.count - n;
|
|
2755
2732
|
if (!this.noWrap) {
|
|
2756
2733
|
if (diff < 0) {
|
|
@@ -2778,14 +2755,8 @@ var Expressive = (() => {
|
|
|
2778
2755
|
requestAnimationFrame(this._autoScroll);
|
|
2779
2756
|
}
|
|
2780
2757
|
}
|
|
2781
|
-
/**
|
|
2782
|
-
* Move carousel to next slide or go forward a given amount of slides.
|
|
2783
|
-
* @param n How many times the carousel slides.
|
|
2784
|
-
*/
|
|
2785
2758
|
next(n = 1) {
|
|
2786
|
-
if (n === void 0 || isNaN(n))
|
|
2787
|
-
n = 1;
|
|
2788
|
-
}
|
|
2759
|
+
if (n === void 0 || isNaN(n)) n = 1;
|
|
2789
2760
|
let index = this.center + n;
|
|
2790
2761
|
if (index >= this.count || index < 0) {
|
|
2791
2762
|
if (this.noWrap) return;
|
|
@@ -2793,14 +2764,8 @@ var Expressive = (() => {
|
|
|
2793
2764
|
}
|
|
2794
2765
|
this._cycleTo(index);
|
|
2795
2766
|
}
|
|
2796
|
-
/**
|
|
2797
|
-
* Move carousel to previous slide or go back a given amount of slides.
|
|
2798
|
-
* @param n How many times the carousel slides.
|
|
2799
|
-
*/
|
|
2800
2767
|
prev(n = 1) {
|
|
2801
|
-
if (n === void 0 || isNaN(n))
|
|
2802
|
-
n = 1;
|
|
2803
|
-
}
|
|
2768
|
+
if (n === void 0 || isNaN(n)) n = 1;
|
|
2804
2769
|
let index = this.center - n;
|
|
2805
2770
|
if (index >= this.count || index < 0) {
|
|
2806
2771
|
if (this.noWrap) return;
|
|
@@ -2808,15 +2773,8 @@ var Expressive = (() => {
|
|
|
2808
2773
|
}
|
|
2809
2774
|
this._cycleTo(index);
|
|
2810
2775
|
}
|
|
2811
|
-
/**
|
|
2812
|
-
* Move carousel to nth slide.
|
|
2813
|
-
* @param n Index of slide.
|
|
2814
|
-
* @param callback "onCycleTo" optional callback.
|
|
2815
|
-
*/
|
|
2816
2776
|
set(n, callback) {
|
|
2817
|
-
if (n === void 0 || isNaN(n))
|
|
2818
|
-
n = 0;
|
|
2819
|
-
}
|
|
2777
|
+
if (n === void 0 || isNaN(n)) n = 0;
|
|
2820
2778
|
if (n > this.count || n < 0) {
|
|
2821
2779
|
if (this.noWrap) return;
|
|
2822
2780
|
n = this._wrap(n);
|
|
@@ -2824,6 +2782,12 @@ var Expressive = (() => {
|
|
|
2824
2782
|
this._cycleTo(n, callback);
|
|
2825
2783
|
}
|
|
2826
2784
|
};
|
|
2785
|
+
_Carousel._live = /* @__PURE__ */ new Set();
|
|
2786
|
+
_Carousel._resizeListening = false;
|
|
2787
|
+
_Carousel._onResize = Utils.throttle(() => {
|
|
2788
|
+
_Carousel._live.forEach((c) => c._handleResize());
|
|
2789
|
+
}, 200);
|
|
2790
|
+
var Carousel = _Carousel;
|
|
2827
2791
|
|
|
2828
2792
|
// src/ts/components/characterCounter.ts
|
|
2829
2793
|
var _defaults8 = Object.freeze({});
|
|
@@ -2913,77 +2877,75 @@ var Expressive = (() => {
|
|
|
2913
2877
|
var Collapsible = class _Collapsible extends Component {
|
|
2914
2878
|
constructor(el, options) {
|
|
2915
2879
|
super(el, options, _Collapsible);
|
|
2916
|
-
this.
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
const collapsible = header.closest(".collapsible");
|
|
2920
|
-
if (collapsible !== this.el) return;
|
|
2921
|
-
const li = header.closest("li");
|
|
2922
|
-
const isActive = li.classList.contains("active");
|
|
2923
|
-
const index = [...li.parentNode.children].indexOf(li);
|
|
2924
|
-
if (isActive) this.close(index);
|
|
2925
|
-
else this.open(index);
|
|
2926
|
-
}
|
|
2927
|
-
};
|
|
2928
|
-
this._handleCollapsibleKeydown = (e) => {
|
|
2929
|
-
if (Utils.keys.ENTER.includes(e.key)) {
|
|
2930
|
-
this._handleCollapsibleClick(e);
|
|
2931
|
-
}
|
|
2932
|
-
};
|
|
2880
|
+
this._items = [];
|
|
2881
|
+
this._endTimers = [];
|
|
2882
|
+
this._wrappedBodies = [];
|
|
2933
2883
|
/**
|
|
2934
2884
|
* Open collapsible section.
|
|
2935
|
-
* @param
|
|
2885
|
+
* @param index 0-based index of the section to open.
|
|
2936
2886
|
*/
|
|
2937
2887
|
this.open = (index) => {
|
|
2938
|
-
const
|
|
2939
|
-
|
|
2940
|
-
if (
|
|
2941
|
-
|
|
2942
|
-
this.
|
|
2943
|
-
}
|
|
2944
|
-
if (this.options.accordion) {
|
|
2945
|
-
const activeLis = listItems.filter((li2) => li2.classList.contains("active"));
|
|
2946
|
-
activeLis.forEach((activeLi) => {
|
|
2947
|
-
const index2 = listItems.indexOf(activeLi);
|
|
2948
|
-
this.close(index2);
|
|
2949
|
-
});
|
|
2950
|
-
}
|
|
2951
|
-
li.classList.add("active");
|
|
2952
|
-
this._animateIn(index);
|
|
2888
|
+
const item = this._items[index];
|
|
2889
|
+
if (!item || this._isOpen(item)) return;
|
|
2890
|
+
if (this.options.accordion) {
|
|
2891
|
+
this._items.forEach((other, i) => {
|
|
2892
|
+
if (i !== index && this._isOpen(other)) this.close(i);
|
|
2893
|
+
});
|
|
2953
2894
|
}
|
|
2895
|
+
this._setOpen(item, true);
|
|
2954
2896
|
};
|
|
2955
2897
|
/**
|
|
2956
2898
|
* Close collapsible section.
|
|
2957
|
-
* @param
|
|
2899
|
+
* @param index 0-based index of the section to close.
|
|
2958
2900
|
*/
|
|
2959
2901
|
this.close = (index) => {
|
|
2960
|
-
const
|
|
2961
|
-
if (
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2902
|
+
const item = this._items[index];
|
|
2903
|
+
if (!item || !this._isOpen(item)) return;
|
|
2904
|
+
this._setOpen(item, false);
|
|
2905
|
+
};
|
|
2906
|
+
this._handleClick = (e) => {
|
|
2907
|
+
const header = e.target.closest(".collapsible-header");
|
|
2908
|
+
if (!header || header.closest(".collapsible") !== this.el) return;
|
|
2909
|
+
if (header.closest("details")) return;
|
|
2910
|
+
const item = header.closest("li");
|
|
2911
|
+
if (!item) return;
|
|
2912
|
+
const index = this._items.indexOf(item);
|
|
2913
|
+
if (index < 0) return;
|
|
2914
|
+
if (this._isOpen(item)) this.close(index);
|
|
2915
|
+
else this.open(index);
|
|
2916
|
+
};
|
|
2917
|
+
this._handleKeydown = (e) => {
|
|
2918
|
+
if (!Utils.keys.ENTER.includes(e.key) && e.key !== " ") return;
|
|
2919
|
+
const header = e.target.closest(".collapsible-header");
|
|
2920
|
+
if (!header || header.closest(".collapsible") !== this.el) return;
|
|
2921
|
+
if (header.closest("details")) return;
|
|
2922
|
+
if (header.matches("a, button")) return;
|
|
2923
|
+
e.preventDefault();
|
|
2924
|
+
const item = header.closest("li");
|
|
2925
|
+
if (!item) return;
|
|
2926
|
+
const index = this._items.indexOf(item);
|
|
2927
|
+
if (index < 0) return;
|
|
2928
|
+
if (this._isOpen(item)) this.close(index);
|
|
2929
|
+
else this.open(index);
|
|
2930
|
+
};
|
|
2931
|
+
this._handleToggle = (e) => {
|
|
2932
|
+
const item = e.target;
|
|
2933
|
+
if (!(item instanceof HTMLDetailsElement)) return;
|
|
2934
|
+
if (!this._items.includes(item)) return;
|
|
2935
|
+
this._notify(item, item.open);
|
|
2968
2936
|
};
|
|
2969
2937
|
this.el["Expressive_Collapsible"] = this;
|
|
2938
|
+
const accordion = options.accordion !== void 0 ? options.accordion : !el.classList.contains("expandable");
|
|
2970
2939
|
this.options = {
|
|
2971
2940
|
..._Collapsible.defaults,
|
|
2972
|
-
...options
|
|
2941
|
+
...options,
|
|
2942
|
+
accordion
|
|
2973
2943
|
};
|
|
2974
|
-
this.
|
|
2975
|
-
this.
|
|
2944
|
+
this._groupName = el.id ? `collapsible-${el.id}` : `collapsible-${Utils.guid()}`;
|
|
2945
|
+
this._items = this._collectItems();
|
|
2946
|
+
this._wrapDetailsBodies();
|
|
2947
|
+
this._setupItems();
|
|
2976
2948
|
this._setupEventHandlers();
|
|
2977
|
-
const activeBodies = Array.from(
|
|
2978
|
-
this.el.querySelectorAll("li.active > .collapsible-body")
|
|
2979
|
-
);
|
|
2980
|
-
if (this.options.accordion) {
|
|
2981
|
-
if (activeBodies.length > 0) {
|
|
2982
|
-
this._setExpanded(activeBodies[0]);
|
|
2983
|
-
}
|
|
2984
|
-
} else {
|
|
2985
|
-
activeBodies.forEach((el2) => this._setExpanded(el2));
|
|
2986
|
-
}
|
|
2987
2949
|
}
|
|
2988
2950
|
static get defaults() {
|
|
2989
2951
|
return _defaults9;
|
|
@@ -3001,48 +2963,130 @@ var Expressive = (() => {
|
|
|
3001
2963
|
}
|
|
3002
2964
|
destroy() {
|
|
3003
2965
|
this._removeEventHandlers();
|
|
2966
|
+
this._endTimers.forEach((id) => clearTimeout(id));
|
|
2967
|
+
this._endTimers = [];
|
|
2968
|
+
this._unwrapDetailsBodies();
|
|
3004
2969
|
this.el["Expressive_Collapsible"] = void 0;
|
|
3005
2970
|
}
|
|
3006
|
-
|
|
3007
|
-
this.el.
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
);
|
|
2971
|
+
_collectItems() {
|
|
2972
|
+
const details = Array.from(this.el.querySelectorAll(":scope > details"));
|
|
2973
|
+
if (details.length) return details;
|
|
2974
|
+
return Array.from(this.el.children).filter((c) => c.tagName === "LI");
|
|
3011
2975
|
}
|
|
3012
|
-
|
|
3013
|
-
this.
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
2976
|
+
_setupItems() {
|
|
2977
|
+
if (this.options.accordion) {
|
|
2978
|
+
this._items.forEach((item) => {
|
|
2979
|
+
if (item instanceof HTMLDetailsElement && !item.getAttribute("name")) {
|
|
2980
|
+
item.setAttribute("name", this._groupName);
|
|
2981
|
+
}
|
|
2982
|
+
});
|
|
2983
|
+
}
|
|
2984
|
+
const opened = this._items.filter((item) => this._isOpen(item));
|
|
2985
|
+
if (this.options.accordion && opened.length > 1) {
|
|
2986
|
+
opened.slice(1).forEach((item) => {
|
|
2987
|
+
if (item instanceof HTMLDetailsElement) item.open = false;
|
|
2988
|
+
else item.classList.remove("active");
|
|
2989
|
+
});
|
|
2990
|
+
}
|
|
2991
|
+
this._items.forEach((item) => this._syncAria(item));
|
|
3017
2992
|
}
|
|
3018
|
-
|
|
3019
|
-
|
|
2993
|
+
_isOpen(item) {
|
|
2994
|
+
if (item instanceof HTMLDetailsElement) return item.open;
|
|
2995
|
+
return item.classList.contains("active");
|
|
3020
2996
|
}
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
this.
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
2997
|
+
_setOpen(item, open) {
|
|
2998
|
+
if (item instanceof HTMLDetailsElement) {
|
|
2999
|
+
item.open = open;
|
|
3000
|
+
return;
|
|
3001
|
+
}
|
|
3002
|
+
item.classList.toggle("active", open);
|
|
3003
|
+
this._syncAria(item);
|
|
3004
|
+
this._notify(item, open);
|
|
3005
|
+
}
|
|
3006
|
+
_headerOf(item) {
|
|
3007
|
+
if (item instanceof HTMLDetailsElement) {
|
|
3008
|
+
return item.querySelector(":scope > summary");
|
|
3009
|
+
}
|
|
3010
|
+
return item.querySelector(":scope > .collapsible-header");
|
|
3011
|
+
}
|
|
3012
|
+
_wrapDetailsBodies() {
|
|
3013
|
+
this._items.forEach((item) => {
|
|
3014
|
+
if (!(item instanceof HTMLDetailsElement)) return;
|
|
3015
|
+
if (item.querySelector(":scope > .collapsible-body")) return;
|
|
3016
|
+
const body = document.createElement("div");
|
|
3017
|
+
body.className = "collapsible-body";
|
|
3018
|
+
Array.from(item.childNodes).forEach((node) => {
|
|
3019
|
+
if (node instanceof HTMLElement && node.tagName === "SUMMARY") return;
|
|
3020
|
+
body.appendChild(node);
|
|
3021
|
+
});
|
|
3022
|
+
item.appendChild(body);
|
|
3023
|
+
this._wrappedBodies.push(body);
|
|
3024
|
+
});
|
|
3033
3025
|
}
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3026
|
+
_unwrapDetailsBodies() {
|
|
3027
|
+
this._wrappedBodies.forEach((body) => {
|
|
3028
|
+
const parent = body.parentNode;
|
|
3029
|
+
if (!parent) return;
|
|
3030
|
+
while (body.firstChild) parent.insertBefore(body.firstChild, body);
|
|
3031
|
+
body.remove();
|
|
3032
|
+
});
|
|
3033
|
+
this._wrappedBodies = [];
|
|
3034
|
+
}
|
|
3035
|
+
_bodyOf(item) {
|
|
3036
|
+
return item.querySelector(":scope > .collapsible-body");
|
|
3037
|
+
}
|
|
3038
|
+
_syncAria(item) {
|
|
3039
|
+
if (item instanceof HTMLDetailsElement) return;
|
|
3040
|
+
const header = this._headerOf(item);
|
|
3041
|
+
const body = this._bodyOf(item);
|
|
3042
|
+
if (!header) return;
|
|
3043
|
+
header.setAttribute("aria-expanded", String(this._isOpen(item)));
|
|
3044
|
+
if (body) {
|
|
3045
|
+
if (!body.id) body.id = `collapsible-body-${Utils.guid()}`;
|
|
3046
|
+
header.setAttribute("aria-controls", body.id);
|
|
3047
|
+
}
|
|
3048
|
+
if (!header.matches("a, button, summary")) {
|
|
3049
|
+
header.setAttribute("role", "button");
|
|
3050
|
+
if (header.tabIndex < 0) header.tabIndex = 0;
|
|
3051
|
+
}
|
|
3052
|
+
}
|
|
3053
|
+
_setupEventHandlers() {
|
|
3054
|
+
this.el.addEventListener("click", this._handleClick);
|
|
3055
|
+
this.el.addEventListener("keydown", this._handleKeydown);
|
|
3056
|
+
this.el.addEventListener("toggle", this._handleToggle, true);
|
|
3057
|
+
}
|
|
3058
|
+
_removeEventHandlers() {
|
|
3059
|
+
this.el.removeEventListener("click", this._handleClick);
|
|
3060
|
+
this.el.removeEventListener("keydown", this._handleKeydown);
|
|
3061
|
+
this.el.removeEventListener("toggle", this._handleToggle, true);
|
|
3062
|
+
}
|
|
3063
|
+
_notify(item, opening) {
|
|
3064
|
+
const start = opening ? this.options.onOpenStart : this.options.onCloseStart;
|
|
3065
|
+
if (typeof start === "function") start.call(this, item);
|
|
3066
|
+
const end = opening ? this.options.onOpenEnd : this.options.onCloseEnd;
|
|
3067
|
+
if (typeof end !== "function") return;
|
|
3068
|
+
const target = this._bodyOf(item) ?? item;
|
|
3069
|
+
let done = false;
|
|
3070
|
+
const finish = () => {
|
|
3071
|
+
if (done) return;
|
|
3072
|
+
done = true;
|
|
3073
|
+
target.removeEventListener("transitionend", onEnd);
|
|
3074
|
+
end.call(this, item);
|
|
3075
|
+
};
|
|
3076
|
+
const onEnd = (ev) => {
|
|
3077
|
+
if (ev.target !== target) return;
|
|
3078
|
+
finish();
|
|
3079
|
+
};
|
|
3080
|
+
target.addEventListener("transitionend", onEnd);
|
|
3081
|
+
this._endTimers.push(window.setTimeout(finish, this._durationMs() + 50));
|
|
3082
|
+
}
|
|
3083
|
+
_durationMs() {
|
|
3084
|
+
const raw = getComputedStyle(this.el).getPropertyValue("--md-comp-collapsible-duration").trim();
|
|
3085
|
+
if (!raw) return 500;
|
|
3086
|
+
if (raw.endsWith("ms")) return parseFloat(raw);
|
|
3087
|
+
if (raw.endsWith("s")) return parseFloat(raw) * 1e3;
|
|
3088
|
+
const n = parseFloat(raw);
|
|
3089
|
+
return Number.isFinite(n) ? n : 500;
|
|
3046
3090
|
}
|
|
3047
3091
|
};
|
|
3048
3092
|
|
|
@@ -4842,38 +4886,22 @@ var Expressive = (() => {
|
|
|
4842
4886
|
// src/ts/components/parallax.ts
|
|
4843
4887
|
var _defaults15 = {
|
|
4844
4888
|
responsiveThreshold: 0
|
|
4845
|
-
// breakpoint for swipeable
|
|
4846
4889
|
};
|
|
4847
|
-
var
|
|
4890
|
+
var Parallax = class _Parallax extends Component {
|
|
4848
4891
|
constructor(el, options) {
|
|
4849
4892
|
super(el, options, _Parallax);
|
|
4850
|
-
this._handleImageLoad = () => {
|
|
4851
|
-
this._updateParallax();
|
|
4852
|
-
};
|
|
4853
4893
|
this.el["Expressive_Parallax"] = this;
|
|
4854
4894
|
this.options = {
|
|
4855
4895
|
..._Parallax.defaults,
|
|
4856
4896
|
...options
|
|
4857
4897
|
};
|
|
4858
|
-
this.
|
|
4859
|
-
|
|
4860
|
-
if (!this._img) {
|
|
4861
|
-
console.error("Parallax: no <img> to move inside the .parallax element");
|
|
4862
|
-
return;
|
|
4898
|
+
if (!this.el.querySelector("img, video")) {
|
|
4899
|
+
console.error("Parallax: no <img> or <video> to move inside the .parallax element");
|
|
4863
4900
|
}
|
|
4864
|
-
this._updateParallax();
|
|
4865
|
-
this._setupEventHandlers();
|
|
4866
|
-
this._setupStyles();
|
|
4867
|
-
_Parallax._parallaxes.push(this);
|
|
4868
4901
|
}
|
|
4869
4902
|
static get defaults() {
|
|
4870
4903
|
return _defaults15;
|
|
4871
4904
|
}
|
|
4872
|
-
/**
|
|
4873
|
-
* Initializes instances of Parallax.
|
|
4874
|
-
* @param els HTML elements.
|
|
4875
|
-
* @param options Component options.
|
|
4876
|
-
*/
|
|
4877
4905
|
static init(els, options = {}) {
|
|
4878
4906
|
return super.init(els, options, _Parallax);
|
|
4879
4907
|
}
|
|
@@ -4881,84 +4909,9 @@ var Expressive = (() => {
|
|
|
4881
4909
|
return el["Expressive_Parallax"];
|
|
4882
4910
|
}
|
|
4883
4911
|
destroy() {
|
|
4884
|
-
const index = _Parallax._parallaxes.indexOf(this);
|
|
4885
|
-
if (index >= 0) _Parallax._parallaxes.splice(index, 1);
|
|
4886
|
-
if (this._img) this._img.style.transform = "";
|
|
4887
|
-
this._removeEventHandlers();
|
|
4888
4912
|
this.el["Expressive_Parallax"] = void 0;
|
|
4889
4913
|
}
|
|
4890
|
-
static _handleScroll() {
|
|
4891
|
-
for (let i = 0; i < _Parallax._parallaxes.length; i++) {
|
|
4892
|
-
const parallaxInstance = _Parallax._parallaxes[i];
|
|
4893
|
-
parallaxInstance._updateParallax.call(parallaxInstance);
|
|
4894
|
-
}
|
|
4895
|
-
}
|
|
4896
|
-
static _handleWindowResize() {
|
|
4897
|
-
for (let i = 0; i < _Parallax._parallaxes.length; i++) {
|
|
4898
|
-
const parallaxInstance = _Parallax._parallaxes[i];
|
|
4899
|
-
parallaxInstance._enabled = window.innerWidth > parallaxInstance.options.responsiveThreshold;
|
|
4900
|
-
}
|
|
4901
|
-
}
|
|
4902
|
-
_setupEventHandlers() {
|
|
4903
|
-
this._img?.addEventListener("load", this._handleImageLoad);
|
|
4904
|
-
if (_Parallax._parallaxes.length === 0) {
|
|
4905
|
-
if (!_Parallax._handleWindowResizeThrottled) {
|
|
4906
|
-
_Parallax._handleWindowResizeThrottled = Utils.throttle(_Parallax._handleWindowResize, 100);
|
|
4907
|
-
}
|
|
4908
|
-
window.addEventListener("scroll", _Parallax._requestScrollUpdate, { passive: true });
|
|
4909
|
-
window.addEventListener("resize", _Parallax._handleWindowResizeThrottled, { passive: true });
|
|
4910
|
-
}
|
|
4911
|
-
}
|
|
4912
|
-
_removeEventHandlers() {
|
|
4913
|
-
this._img?.removeEventListener("load", this._handleImageLoad);
|
|
4914
|
-
if (_Parallax._parallaxes.length === 0) {
|
|
4915
|
-
window.removeEventListener("scroll", _Parallax._requestScrollUpdate);
|
|
4916
|
-
window.removeEventListener("resize", _Parallax._handleWindowResizeThrottled);
|
|
4917
|
-
if (_Parallax._scrollFrame !== null) {
|
|
4918
|
-
cancelAnimationFrame(_Parallax._scrollFrame);
|
|
4919
|
-
_Parallax._scrollFrame = null;
|
|
4920
|
-
}
|
|
4921
|
-
}
|
|
4922
|
-
}
|
|
4923
|
-
_setupStyles() {
|
|
4924
|
-
if (this._img) this._img.style.opacity = "1";
|
|
4925
|
-
}
|
|
4926
|
-
_updateParallax() {
|
|
4927
|
-
const rect = this.el.getBoundingClientRect();
|
|
4928
|
-
const containerHeight = rect.height > 0 ? this.el.parentElement.offsetHeight : 500;
|
|
4929
|
-
const imgHeight = this._img.offsetHeight;
|
|
4930
|
-
const parallaxDist = imgHeight - containerHeight;
|
|
4931
|
-
const top = rect.top + window.scrollY - document.documentElement.clientTop;
|
|
4932
|
-
const bottom = top + containerHeight;
|
|
4933
|
-
const scrollTop = Utils.getDocumentScrollTop();
|
|
4934
|
-
const windowHeight = window.innerHeight;
|
|
4935
|
-
const windowBottom = scrollTop + windowHeight;
|
|
4936
|
-
const percentScrolled = (windowBottom - top) / (containerHeight + windowHeight);
|
|
4937
|
-
const parallax = parallaxDist * percentScrolled;
|
|
4938
|
-
if (!this._enabled) {
|
|
4939
|
-
this._img.style.transform = "";
|
|
4940
|
-
} else if (bottom > scrollTop && top < scrollTop + windowHeight) {
|
|
4941
|
-
this._img.style.transform = `translate3D(-50%, ${parallax}px, 0)`;
|
|
4942
|
-
}
|
|
4943
|
-
}
|
|
4944
|
-
};
|
|
4945
|
-
_Parallax._parallaxes = [];
|
|
4946
|
-
_Parallax._scrollFrame = null;
|
|
4947
|
-
/**
|
|
4948
|
-
* Coalesce scroll events onto animation frames.
|
|
4949
|
-
*
|
|
4950
|
-
* The handler reads layout and then writes a transform, so running it more
|
|
4951
|
-
* than once per frame is wasted work - and the 5ms throttle it replaces was
|
|
4952
|
-
* short enough to let several run per frame anyway.
|
|
4953
|
-
*/
|
|
4954
|
-
_Parallax._requestScrollUpdate = () => {
|
|
4955
|
-
if (_Parallax._scrollFrame !== null) return;
|
|
4956
|
-
_Parallax._scrollFrame = requestAnimationFrame(() => {
|
|
4957
|
-
_Parallax._scrollFrame = null;
|
|
4958
|
-
_Parallax._handleScroll();
|
|
4959
|
-
});
|
|
4960
4914
|
};
|
|
4961
|
-
var Parallax = _Parallax;
|
|
4962
4915
|
|
|
4963
4916
|
// src/ts/components/pushpin.ts
|
|
4964
4917
|
var _defaults16 = {
|
|
@@ -6198,60 +6151,96 @@ var Expressive = (() => {
|
|
|
6198
6151
|
var _TapTarget = class _TapTarget extends Component {
|
|
6199
6152
|
constructor(el, options) {
|
|
6200
6153
|
super(el, options, _TapTarget);
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
this.
|
|
6204
|
-
this.
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
this._handleTargetToggle = () => {
|
|
6210
|
-
if (!this.isOpen) this.open();
|
|
6211
|
-
else this.close();
|
|
6212
|
-
};
|
|
6213
|
-
/*_handleOriginClick = () => {
|
|
6214
|
-
this.close();
|
|
6215
|
-
}*/
|
|
6216
|
-
this._handleResize = () => {
|
|
6217
|
-
this._calculatePositioning();
|
|
6218
|
-
};
|
|
6219
|
-
this._handleDocumentClick = (e) => {
|
|
6220
|
-
const target = e.target;
|
|
6221
|
-
if (!(target instanceof Element)) return;
|
|
6222
|
-
if (!this.originEl.contains(target) && !target.closest(".tap-target-wrapper")) {
|
|
6223
|
-
this.close();
|
|
6224
|
-
}
|
|
6225
|
-
};
|
|
6154
|
+
this.wrapper = null;
|
|
6155
|
+
this.waveEl = null;
|
|
6156
|
+
this.contentEl = null;
|
|
6157
|
+
this._createdWrapper = false;
|
|
6158
|
+
this._createdWave = false;
|
|
6159
|
+
this._usePopover = false;
|
|
6160
|
+
this._liftedStatic = false;
|
|
6161
|
+
this._opening = false;
|
|
6226
6162
|
/**
|
|
6227
6163
|
* Open Tap Target.
|
|
6228
6164
|
*/
|
|
6229
6165
|
this.open = () => {
|
|
6230
|
-
if (this.isOpen) return;
|
|
6166
|
+
if (this.isOpen || !this.originEl || !this.wrapper) return;
|
|
6167
|
+
_TapTarget._taptargets.forEach((other) => {
|
|
6168
|
+
if (other !== this) other.close();
|
|
6169
|
+
});
|
|
6170
|
+
this._calculatePositioning();
|
|
6231
6171
|
if (typeof this.options.onOpen === "function") {
|
|
6232
6172
|
this.options.onOpen.call(this, this.originEl);
|
|
6233
6173
|
}
|
|
6234
6174
|
this.isOpen = true;
|
|
6235
6175
|
this.wrapper.classList.add("open");
|
|
6236
|
-
this.
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6176
|
+
this.originEl.setAttribute("aria-expanded", "true");
|
|
6177
|
+
if (!this._usePopover) {
|
|
6178
|
+
this.originEl.classList.add("tap-target-origin");
|
|
6179
|
+
if (getComputedStyle(this.originEl).position === "static") {
|
|
6180
|
+
this.originEl.style.position = "relative";
|
|
6181
|
+
this._liftedStatic = true;
|
|
6182
|
+
}
|
|
6183
|
+
}
|
|
6184
|
+
if (this._usePopover) {
|
|
6185
|
+
this._opening = true;
|
|
6186
|
+
try {
|
|
6187
|
+
this.wrapper.showPopover();
|
|
6188
|
+
} catch {
|
|
6189
|
+
}
|
|
6190
|
+
requestAnimationFrame(() => {
|
|
6191
|
+
this._opening = false;
|
|
6192
|
+
});
|
|
6193
|
+
}
|
|
6240
6194
|
};
|
|
6241
6195
|
/**
|
|
6242
6196
|
* Close Tap Target.
|
|
6243
6197
|
*/
|
|
6244
6198
|
this.close = () => {
|
|
6245
6199
|
if (!this.isOpen) return;
|
|
6246
|
-
if (typeof this.options.onClose === "function") {
|
|
6200
|
+
if (typeof this.options.onClose === "function" && this.originEl) {
|
|
6247
6201
|
this.options.onClose.call(this, this.originEl);
|
|
6248
6202
|
}
|
|
6249
6203
|
this.isOpen = false;
|
|
6250
|
-
this.wrapper
|
|
6251
|
-
this.
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6204
|
+
this.wrapper?.classList.remove("open");
|
|
6205
|
+
this.originEl?.setAttribute("aria-expanded", "false");
|
|
6206
|
+
this.originEl?.classList.remove("tap-target-origin");
|
|
6207
|
+
if (this._liftedStatic && this.originEl) {
|
|
6208
|
+
this.originEl.style.position = "";
|
|
6209
|
+
this._liftedStatic = false;
|
|
6210
|
+
}
|
|
6211
|
+
if (this._usePopover && this.wrapper) {
|
|
6212
|
+
try {
|
|
6213
|
+
this.wrapper.hidePopover();
|
|
6214
|
+
} catch {
|
|
6215
|
+
}
|
|
6216
|
+
}
|
|
6217
|
+
};
|
|
6218
|
+
// Built once per instance; a fresh throttle per event never fires.
|
|
6219
|
+
this._handleThrottledResize = Utils.throttle(() => this._handleResize(), 200);
|
|
6220
|
+
this._handleOriginKeydown = (e) => {
|
|
6221
|
+
if (Utils.keys.ENTER.includes(e.key) || e.key === " ") {
|
|
6222
|
+
e.preventDefault();
|
|
6223
|
+
this._handleTargetToggle();
|
|
6224
|
+
}
|
|
6225
|
+
};
|
|
6226
|
+
this._handleTargetToggle = () => {
|
|
6227
|
+
if (!this.isOpen) this.open();
|
|
6228
|
+
else this.close();
|
|
6229
|
+
};
|
|
6230
|
+
this._handleResize = () => {
|
|
6231
|
+
if (this.isOpen) this._calculatePositioning();
|
|
6232
|
+
};
|
|
6233
|
+
this._handlePopoverToggle = (e) => {
|
|
6234
|
+
const state = "newState" in e ? String(e.newState) : "";
|
|
6235
|
+
if (state === "open") return;
|
|
6236
|
+
if (this._opening) {
|
|
6237
|
+
try {
|
|
6238
|
+
this.wrapper?.showPopover();
|
|
6239
|
+
} catch {
|
|
6240
|
+
}
|
|
6241
|
+
return;
|
|
6242
|
+
}
|
|
6243
|
+
if (this.isOpen) this.close();
|
|
6255
6244
|
};
|
|
6256
6245
|
this.el["Expressive_TapTarget"] = this;
|
|
6257
6246
|
this.options = {
|
|
@@ -6264,7 +6253,6 @@ var Expressive = (() => {
|
|
|
6264
6253
|
console.error(`TapTarget: no element with id "${el.dataset.target ?? ""}" to attach to`);
|
|
6265
6254
|
return;
|
|
6266
6255
|
}
|
|
6267
|
-
this.originEl.tabIndex = 0;
|
|
6268
6256
|
this._setup();
|
|
6269
6257
|
this._calculatePositioning();
|
|
6270
6258
|
this._setupEventHandlers();
|
|
@@ -6273,11 +6261,6 @@ var Expressive = (() => {
|
|
|
6273
6261
|
static get defaults() {
|
|
6274
6262
|
return _defaults21;
|
|
6275
6263
|
}
|
|
6276
|
-
/**
|
|
6277
|
-
* Initializes instances of TapTarget.
|
|
6278
|
-
* @param els HTML elements.
|
|
6279
|
-
* @param options Component options.
|
|
6280
|
-
*/
|
|
6281
6264
|
static init(els, options = {}) {
|
|
6282
6265
|
return super.init(els, options, _TapTarget);
|
|
6283
6266
|
}
|
|
@@ -6287,116 +6270,95 @@ var Expressive = (() => {
|
|
|
6287
6270
|
destroy() {
|
|
6288
6271
|
this.close();
|
|
6289
6272
|
this._removeEventHandlers();
|
|
6273
|
+
this._teardownDom();
|
|
6290
6274
|
this.el["Expressive_TapTarget"] = void 0;
|
|
6291
6275
|
const index = _TapTarget._taptargets.indexOf(this);
|
|
6292
|
-
if (index >= 0)
|
|
6293
|
-
_TapTarget._taptargets.splice(index, 1);
|
|
6294
|
-
}
|
|
6295
|
-
}
|
|
6296
|
-
_setupEventHandlers() {
|
|
6297
|
-
if (!this.originEl) return;
|
|
6298
|
-
this.originEl.addEventListener("click", this._handleTargetToggle);
|
|
6299
|
-
this.originEl.addEventListener("keypress", this._handleKeyboardInteraction, true);
|
|
6300
|
-
window.addEventListener("resize", this._handleThrottledResize);
|
|
6301
|
-
}
|
|
6302
|
-
_removeEventHandlers() {
|
|
6303
|
-
if (!this.originEl) return;
|
|
6304
|
-
this.originEl.removeEventListener("click", this._handleTargetToggle);
|
|
6305
|
-
this.originEl.removeEventListener("keypress", this._handleKeyboardInteraction, true);
|
|
6306
|
-
window.removeEventListener("resize", this._handleThrottledResize);
|
|
6276
|
+
if (index >= 0) _TapTarget._taptargets.splice(index, 1);
|
|
6307
6277
|
}
|
|
6308
6278
|
_setup() {
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
this.contentEl = this.el.querySelector(".tap-target-content");
|
|
6314
|
-
if (!this.wrapper.classList.contains(".tap-target-wrapper")) {
|
|
6279
|
+
const parent = this.el.parentElement;
|
|
6280
|
+
if (parent?.classList.contains("tap-target-wrapper")) {
|
|
6281
|
+
this.wrapper = parent;
|
|
6282
|
+
} else {
|
|
6315
6283
|
this.wrapper = document.createElement("div");
|
|
6316
6284
|
this.wrapper.classList.add("tap-target-wrapper");
|
|
6317
6285
|
this.el.before(this.wrapper);
|
|
6318
6286
|
this.wrapper.append(this.el);
|
|
6287
|
+
this._createdWrapper = true;
|
|
6319
6288
|
}
|
|
6289
|
+
this.contentEl = this.el.querySelector(".tap-target-content");
|
|
6320
6290
|
if (!this.contentEl) {
|
|
6321
6291
|
this.contentEl = document.createElement("div");
|
|
6322
|
-
this.contentEl.
|
|
6292
|
+
this.contentEl.className = "tap-target-content";
|
|
6293
|
+
while (this.el.firstChild) this.contentEl.append(this.el.firstChild);
|
|
6323
6294
|
this.el.append(this.contentEl);
|
|
6324
6295
|
}
|
|
6296
|
+
this.waveEl = this.el.querySelector(".tap-target-wave") ?? this.wrapper.querySelector(".tap-target-wave");
|
|
6325
6297
|
if (!this.waveEl) {
|
|
6326
6298
|
this.waveEl = document.createElement("div");
|
|
6327
|
-
this.waveEl.
|
|
6328
|
-
this.
|
|
6299
|
+
this.waveEl.className = "tap-target-wave";
|
|
6300
|
+
this._createdWave = true;
|
|
6301
|
+
}
|
|
6302
|
+
this.el.prepend(this.waveEl);
|
|
6303
|
+
this.el.setAttribute("role", "dialog");
|
|
6304
|
+
this._labelFromHeading();
|
|
6305
|
+
const origin = this.originEl;
|
|
6306
|
+
origin.setAttribute("aria-expanded", "false");
|
|
6307
|
+
origin.setAttribute("aria-controls", this.el.id || this._ensureId());
|
|
6308
|
+
this._usePopover = typeof this.wrapper.showPopover === "function";
|
|
6309
|
+
if (this._usePopover) {
|
|
6310
|
+
this.wrapper.setAttribute("popover", "auto");
|
|
6311
|
+
}
|
|
6312
|
+
}
|
|
6313
|
+
_ensureId() {
|
|
6314
|
+
if (!this.el.id) this.el.id = `tap-target-${Utils.guid()}`;
|
|
6315
|
+
return this.el.id;
|
|
6316
|
+
}
|
|
6317
|
+
_labelFromHeading() {
|
|
6318
|
+
const heading = this.contentEl?.querySelector("h1, h2, h3, h4, h5, h6");
|
|
6319
|
+
if (!heading) return;
|
|
6320
|
+
if (!heading.id) heading.id = `tap-target-title-${Utils.guid()}`;
|
|
6321
|
+
this.el.setAttribute("aria-labelledby", heading.id);
|
|
6322
|
+
}
|
|
6323
|
+
_teardownDom() {
|
|
6324
|
+
if (this._createdWave) this.waveEl?.remove();
|
|
6325
|
+
if (this._createdWrapper && this.wrapper) {
|
|
6326
|
+
this.wrapper.before(this.el);
|
|
6327
|
+
this.wrapper.remove();
|
|
6328
|
+
}
|
|
6329
|
+
this.wrapper = null;
|
|
6330
|
+
this.waveEl = null;
|
|
6331
|
+
}
|
|
6332
|
+
_setupEventHandlers() {
|
|
6333
|
+
if (!this.originEl) return;
|
|
6334
|
+
this.originEl.addEventListener("click", this._handleTargetToggle);
|
|
6335
|
+
if (!this.originEl.matches('button, a, [tabindex], .btn, [role="button"]')) {
|
|
6336
|
+
this.originEl.tabIndex = 0;
|
|
6337
|
+
this.originEl.addEventListener("keydown", this._handleOriginKeydown);
|
|
6329
6338
|
}
|
|
6339
|
+
this.wrapper?.addEventListener("toggle", this._handlePopoverToggle);
|
|
6340
|
+
window.addEventListener("resize", this._handleThrottledResize, { passive: true });
|
|
6330
6341
|
}
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
};
|
|
6342
|
+
_removeEventHandlers() {
|
|
6343
|
+
if (!this.originEl) return;
|
|
6344
|
+
this.originEl.removeEventListener("click", this._handleTargetToggle);
|
|
6345
|
+
this.originEl.removeEventListener("keydown", this._handleOriginKeydown);
|
|
6346
|
+
this.wrapper?.removeEventListener("toggle", this._handlePopoverToggle);
|
|
6347
|
+
window.removeEventListener("resize", this._handleThrottledResize);
|
|
6338
6348
|
}
|
|
6339
6349
|
_calculatePositioning() {
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
const originHeight = this.originEl.offsetHeight;
|
|
6353
|
-
const originOffset = this._offset(this.originEl);
|
|
6354
|
-
const originTop = isFixed ? originOffset.top - Utils.getDocumentScrollTop() : originOffset.top;
|
|
6355
|
-
const originLeft = isFixed ? originOffset.left - Utils.getDocumentScrollLeft() : originOffset.left;
|
|
6356
|
-
const windowWidth = window.innerWidth;
|
|
6357
|
-
const windowHeight = window.innerHeight;
|
|
6358
|
-
const scrollBarWidth = windowWidth - document.documentElement.clientWidth;
|
|
6359
|
-
const centerX = windowWidth / 2;
|
|
6360
|
-
const centerY = windowHeight / 2;
|
|
6361
|
-
const isLeft = originLeft <= centerX;
|
|
6362
|
-
const isRight = originLeft > centerX;
|
|
6363
|
-
const isTop = originTop <= centerY;
|
|
6364
|
-
const isBottom = originTop > centerY;
|
|
6365
|
-
const isCenterX = originLeft >= windowWidth * 0.25 && originLeft <= windowWidth * 0.75;
|
|
6366
|
-
const tapTargetWidth = this.el.offsetWidth;
|
|
6367
|
-
const tapTargetHeight = this.el.offsetHeight;
|
|
6368
|
-
const tapTargetTop = originTop + originHeight / 2 - tapTargetHeight / 2;
|
|
6369
|
-
const tapTargetLeft = originLeft + originWidth / 2 - tapTargetWidth / 2;
|
|
6370
|
-
const tapTargetPosition = isFixed ? "fixed" : "absolute";
|
|
6371
|
-
const tapTargetTextWidth = isCenterX ? tapTargetWidth : tapTargetWidth / 2 + originWidth;
|
|
6372
|
-
const tapTargetTextHeight = tapTargetHeight / 2;
|
|
6373
|
-
const tapTargetTextTop = isTop ? tapTargetHeight / 2 : 0;
|
|
6374
|
-
const tapTargetTextBottom = 0;
|
|
6375
|
-
const tapTargetTextLeft = isLeft && !isCenterX ? tapTargetWidth / 2 - originWidth : 0;
|
|
6376
|
-
const tapTargetTextRight = 0;
|
|
6377
|
-
const tapTargetTextPadding = originWidth;
|
|
6378
|
-
const tapTargetTextAlign = isBottom ? "bottom" : "top";
|
|
6379
|
-
const tapTargetWaveWidth = originWidth > originHeight ? originWidth * 2 : originWidth * 2;
|
|
6380
|
-
const tapTargetWaveHeight = tapTargetWaveWidth;
|
|
6381
|
-
const tapTargetWaveTop = tapTargetHeight / 2 - tapTargetWaveHeight / 2;
|
|
6382
|
-
const tapTargetWaveLeft = tapTargetWidth / 2 - tapTargetWaveWidth / 2;
|
|
6383
|
-
this.wrapper.style.top = isTop ? tapTargetTop + "px" : "";
|
|
6384
|
-
this.wrapper.style.right = isRight ? windowWidth - tapTargetLeft - tapTargetWidth - scrollBarWidth + "px" : "";
|
|
6385
|
-
this.wrapper.style.bottom = isBottom ? windowHeight - tapTargetTop - tapTargetHeight + "px" : "";
|
|
6386
|
-
this.wrapper.style.left = isLeft ? tapTargetLeft + "px" : "";
|
|
6387
|
-
this.wrapper.style.position = tapTargetPosition;
|
|
6388
|
-
this.contentEl.style.width = tapTargetTextWidth + "px";
|
|
6389
|
-
this.contentEl.style.height = tapTargetTextHeight + "px";
|
|
6390
|
-
this.contentEl.style.top = tapTargetTextTop + "px";
|
|
6391
|
-
this.contentEl.style.right = tapTargetTextRight + "px";
|
|
6392
|
-
this.contentEl.style.bottom = tapTargetTextBottom + "px";
|
|
6393
|
-
this.contentEl.style.left = tapTargetTextLeft + "px";
|
|
6394
|
-
this.contentEl.style.padding = tapTargetTextPadding + "px";
|
|
6395
|
-
this.contentEl.style.verticalAlign = tapTargetTextAlign;
|
|
6396
|
-
this.waveEl.style.top = tapTargetWaveTop + "px";
|
|
6397
|
-
this.waveEl.style.left = tapTargetWaveLeft + "px";
|
|
6398
|
-
this.waveEl.style.width = tapTargetWaveWidth + "px";
|
|
6399
|
-
this.waveEl.style.height = tapTargetWaveHeight + "px";
|
|
6350
|
+
if (!this.originEl || !this.wrapper) return;
|
|
6351
|
+
const rect = this.originEl.getBoundingClientRect();
|
|
6352
|
+
const x = rect.left + rect.width / 2;
|
|
6353
|
+
const y = rect.top + rect.height / 2;
|
|
6354
|
+
const size = Math.max(rect.width, rect.height, 1);
|
|
6355
|
+
this.wrapper.style.setProperty("--md-comp-tap-target-x", `${x}px`);
|
|
6356
|
+
this.wrapper.style.setProperty("--md-comp-tap-target-y", `${y}px`);
|
|
6357
|
+
this.wrapper.style.setProperty("--md-comp-tap-target-origin-size", `${size}px`);
|
|
6358
|
+
const vertical = y <= window.innerHeight / 2 ? "top" : "bottom";
|
|
6359
|
+
const onCenter = x >= window.innerWidth * 0.25 && x <= window.innerWidth * 0.75;
|
|
6360
|
+
const horizontal = onCenter ? "center" : x <= window.innerWidth / 2 ? "left" : "right";
|
|
6361
|
+
this.wrapper.dataset.edge = `${vertical}-${horizontal}`;
|
|
6400
6362
|
}
|
|
6401
6363
|
};
|
|
6402
6364
|
_TapTarget._taptargets = [];
|
|
@@ -7140,7 +7102,7 @@ var Expressive = (() => {
|
|
|
7140
7102
|
close.className = "circle";
|
|
7141
7103
|
close.setAttribute("aria-label", "Dismiss");
|
|
7142
7104
|
const icon = document.createElement("i");
|
|
7143
|
-
icon.className = "material-
|
|
7105
|
+
icon.className = "material-symbols";
|
|
7144
7106
|
icon.setAttribute("aria-hidden", "true");
|
|
7145
7107
|
icon.textContent = "close";
|
|
7146
7108
|
close.appendChild(icon);
|
|
@@ -7505,7 +7467,7 @@ var Expressive = (() => {
|
|
|
7505
7467
|
}
|
|
7506
7468
|
|
|
7507
7469
|
// src/ts/index.ts
|
|
7508
|
-
var version = "0.
|
|
7470
|
+
var version = "0.3.0";
|
|
7509
7471
|
if (typeof document !== "undefined") {
|
|
7510
7472
|
document.addEventListener("keydown", Utils.docHandleKeydown, true);
|
|
7511
7473
|
document.addEventListener("keyup", Utils.docHandleKeyup, true);
|