@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.mjs
CHANGED
|
@@ -1425,7 +1425,7 @@ var _defaults4 = {
|
|
|
1425
1425
|
data: [],
|
|
1426
1426
|
placeholder: "",
|
|
1427
1427
|
secondaryPlaceholder: "",
|
|
1428
|
-
closeIconClass: "material-
|
|
1428
|
+
closeIconClass: "material-symbols",
|
|
1429
1429
|
autocompleteOptions: {},
|
|
1430
1430
|
autocompleteOnly: false,
|
|
1431
1431
|
limit: Infinity,
|
|
@@ -2064,83 +2064,76 @@ var _defaults6 = {
|
|
|
2064
2064
|
var FloatingActionButton = class _FloatingActionButton extends Component {
|
|
2065
2065
|
constructor(el, options) {
|
|
2066
2066
|
super(el, options, _FloatingActionButton);
|
|
2067
|
-
/** Toolbar-mode backdrop, kept so closing can take it back out. */
|
|
2068
|
-
this._backdrop = null;
|
|
2069
|
-
this._handleFABClick = () => {
|
|
2070
|
-
this._handleFABToggle();
|
|
2071
|
-
};
|
|
2072
|
-
this._handleFABKeyPress = (e) => {
|
|
2073
|
-
if (Utils.keys.ENTER.includes(e.key)) {
|
|
2074
|
-
this._handleFABToggle();
|
|
2075
|
-
}
|
|
2076
|
-
};
|
|
2077
|
-
this._handleFABToggle = () => {
|
|
2078
|
-
if (this.isOpen) {
|
|
2079
|
-
this.close();
|
|
2080
|
-
} else {
|
|
2081
|
-
this.open();
|
|
2082
|
-
}
|
|
2083
|
-
};
|
|
2084
|
-
this._handleDocumentClick = (e) => {
|
|
2085
|
-
const elem = e.target;
|
|
2086
|
-
if (elem !== this._menu) this.close();
|
|
2087
|
-
};
|
|
2088
2067
|
/**
|
|
2089
2068
|
* Open FAB.
|
|
2090
2069
|
*/
|
|
2091
2070
|
this.open = () => {
|
|
2092
2071
|
if (this.isOpen) return;
|
|
2093
|
-
if (this.options.toolbarEnabled) this._animateInToolbar();
|
|
2094
|
-
else this._animateInFAB();
|
|
2095
2072
|
this.isOpen = true;
|
|
2073
|
+
this.el.classList.add("active");
|
|
2074
|
+
this._anchor?.setAttribute("aria-expanded", "true");
|
|
2075
|
+
document.addEventListener("click", this._handleDocumentClick);
|
|
2076
|
+
document.addEventListener("keydown", this._handleDocumentKeydown);
|
|
2096
2077
|
};
|
|
2097
2078
|
/**
|
|
2098
2079
|
* Close FAB.
|
|
2099
2080
|
*/
|
|
2100
2081
|
this.close = () => {
|
|
2101
2082
|
if (!this.isOpen) return;
|
|
2102
|
-
if (this.options.toolbarEnabled) {
|
|
2103
|
-
window.removeEventListener("scroll", this.close, true);
|
|
2104
|
-
document.body.removeEventListener("click", this._handleDocumentClick, true);
|
|
2105
|
-
this._animateOutToolbar();
|
|
2106
|
-
} else {
|
|
2107
|
-
this._animateOutFAB();
|
|
2108
|
-
}
|
|
2109
2083
|
this.isOpen = false;
|
|
2084
|
+
this.el.classList.remove("active");
|
|
2085
|
+
this._anchor?.setAttribute("aria-expanded", "false");
|
|
2086
|
+
document.removeEventListener("click", this._handleDocumentClick);
|
|
2087
|
+
document.removeEventListener("keydown", this._handleDocumentKeydown);
|
|
2088
|
+
};
|
|
2089
|
+
this._handleFABClick = (e) => {
|
|
2090
|
+
e.stopPropagation();
|
|
2091
|
+
this._toggle();
|
|
2092
|
+
};
|
|
2093
|
+
this._handleAnchorKeydown = (e) => {
|
|
2094
|
+
if (Utils.keys.ENTER.includes(e.key) || e.key === " ") {
|
|
2095
|
+
e.preventDefault();
|
|
2096
|
+
this._toggle();
|
|
2097
|
+
}
|
|
2098
|
+
};
|
|
2099
|
+
this._handleDocumentKeydown = (e) => {
|
|
2100
|
+
if (Utils.keys.ESC.includes(e.key)) this.close();
|
|
2101
|
+
};
|
|
2102
|
+
this._handleDocumentClick = (e) => {
|
|
2103
|
+
const target = e.target;
|
|
2104
|
+
if (!(target instanceof Node) || this.el.contains(target)) return;
|
|
2105
|
+
this.close();
|
|
2110
2106
|
};
|
|
2111
2107
|
this.el["Expressive_FloatingActionButton"] = this;
|
|
2108
|
+
const fromMarkup = this._directionFromClass();
|
|
2109
|
+
const toolbar = el.classList.contains("toolbar") || options.toolbarEnabled === true;
|
|
2110
|
+
const clickToToggle = el.classList.contains("click-to-toggle") || options.hoverEnabled === false;
|
|
2112
2111
|
this.options = {
|
|
2113
2112
|
..._FloatingActionButton.defaults,
|
|
2114
|
-
...options
|
|
2113
|
+
...options,
|
|
2114
|
+
direction: options.direction ?? fromMarkup ?? _FloatingActionButton.defaults.direction,
|
|
2115
|
+
hoverEnabled: !clickToToggle,
|
|
2116
|
+
toolbarEnabled: toolbar
|
|
2115
2117
|
};
|
|
2116
2118
|
this.isOpen = false;
|
|
2117
|
-
this._anchor = this.el.querySelector("a, button");
|
|
2118
|
-
this._menu = this.el.querySelector("ul");
|
|
2119
|
-
this._floatingBtns = Array.from(this.el.querySelectorAll("ul .btn-floating"));
|
|
2120
|
-
this._floatingBtnsReverse = this._floatingBtns.reverse();
|
|
2121
|
-
this.offsetY = 0;
|
|
2122
|
-
this.offsetX = 0;
|
|
2119
|
+
this._anchor = this.el.querySelector(":scope > a, :scope > button");
|
|
2120
|
+
this._menu = this.el.querySelector("ul, menu");
|
|
2123
2121
|
this.el.classList.add(`direction-${this.options.direction}`);
|
|
2124
|
-
if (
|
|
2125
|
-
if (
|
|
2126
|
-
if (this.
|
|
2127
|
-
this.
|
|
2128
|
-
|
|
2129
|
-
this.
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2122
|
+
if (clickToToggle) this.el.classList.add("click-to-toggle");
|
|
2123
|
+
if (toolbar) this.el.classList.add("toolbar");
|
|
2124
|
+
if (this._anchor) {
|
|
2125
|
+
this._anchor.setAttribute("aria-haspopup", "menu");
|
|
2126
|
+
this._anchor.setAttribute("aria-expanded", "false");
|
|
2127
|
+
if (this._anchor instanceof HTMLAnchorElement && !this._anchor.hasAttribute("href") && this._anchor.tabIndex < 0) {
|
|
2128
|
+
this._anchor.tabIndex = 0;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
if (this._menu) this._menu.setAttribute("role", "menu");
|
|
2134
2132
|
this._setupEventHandlers();
|
|
2135
2133
|
}
|
|
2136
2134
|
static get defaults() {
|
|
2137
2135
|
return _defaults6;
|
|
2138
2136
|
}
|
|
2139
|
-
/**
|
|
2140
|
-
* Initializes instances of FloatingActionButton.
|
|
2141
|
-
* @param els HTML elements.
|
|
2142
|
-
* @param options Component options.
|
|
2143
|
-
*/
|
|
2144
2137
|
static init(els, options = {}) {
|
|
2145
2138
|
return super.init(els, options, _FloatingActionButton);
|
|
2146
2139
|
}
|
|
@@ -2148,229 +2141,109 @@ var FloatingActionButton = class _FloatingActionButton extends Component {
|
|
|
2148
2141
|
return el["Expressive_FloatingActionButton"];
|
|
2149
2142
|
}
|
|
2150
2143
|
destroy() {
|
|
2151
|
-
this._removeEventHandlers();
|
|
2152
2144
|
this.close();
|
|
2145
|
+
this._removeEventHandlers();
|
|
2153
2146
|
this.el["Expressive_FloatingActionButton"] = void 0;
|
|
2154
2147
|
}
|
|
2148
|
+
_directionFromClass() {
|
|
2149
|
+
const match = [...this.el.classList].find((c) => c.startsWith("direction-"));
|
|
2150
|
+
const value = match?.slice("direction-".length);
|
|
2151
|
+
if (value === "top" || value === "right" || value === "bottom" || value === "left") {
|
|
2152
|
+
return value;
|
|
2153
|
+
}
|
|
2154
|
+
return null;
|
|
2155
|
+
}
|
|
2155
2156
|
_setupEventHandlers() {
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
this.
|
|
2159
|
-
} else {
|
|
2160
|
-
this.el.addEventListener("click", this._handleFABClick);
|
|
2157
|
+
this.el.addEventListener("click", this._handleFABClick);
|
|
2158
|
+
if (this._anchor instanceof HTMLAnchorElement && !this._anchor.hasAttribute("href")) {
|
|
2159
|
+
this._anchor.addEventListener("keydown", this._handleAnchorKeydown);
|
|
2161
2160
|
}
|
|
2162
|
-
this.el.addEventListener("keypress", this._handleFABKeyPress);
|
|
2163
2161
|
}
|
|
2164
2162
|
_removeEventHandlers() {
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
this.el.removeEventListener("mouseleave", this.close);
|
|
2168
|
-
} else {
|
|
2169
|
-
this.el.removeEventListener("click", this._handleFABClick);
|
|
2170
|
-
}
|
|
2171
|
-
this.el.removeEventListener("keypress", this._handleFABKeyPress);
|
|
2172
|
-
}
|
|
2173
|
-
_animateInFAB() {
|
|
2174
|
-
this.el.classList.add("active");
|
|
2175
|
-
if (this._menu) this._menu.ariaExpanded = "true";
|
|
2176
|
-
const delayIncrement = 40;
|
|
2177
|
-
const duration = 275;
|
|
2178
|
-
this._floatingBtnsReverse.forEach((el, index) => {
|
|
2179
|
-
const delay = delayIncrement * index;
|
|
2180
|
-
el.style.transition = "none";
|
|
2181
|
-
el.style.opacity = "0";
|
|
2182
|
-
el.style.transform = `translate(${this.offsetX}px, ${this.offsetY}px) scale(0.4)`;
|
|
2183
|
-
setTimeout(() => {
|
|
2184
|
-
el.style.opacity = "0.4";
|
|
2185
|
-
setTimeout(() => {
|
|
2186
|
-
el.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
|
|
2187
|
-
el.style.opacity = "1";
|
|
2188
|
-
el.style.transform = "translate(0, 0) scale(1)";
|
|
2189
|
-
el.tabIndex = 0;
|
|
2190
|
-
}, 1);
|
|
2191
|
-
}, delay);
|
|
2192
|
-
});
|
|
2193
|
-
}
|
|
2194
|
-
_animateOutFAB() {
|
|
2195
|
-
const duration = 175;
|
|
2196
|
-
setTimeout(() => {
|
|
2197
|
-
this.el.classList.remove("active");
|
|
2198
|
-
if (this._menu) this._menu.ariaExpanded = "false";
|
|
2199
|
-
}, duration);
|
|
2200
|
-
this._floatingBtnsReverse.forEach((el) => {
|
|
2201
|
-
el.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
|
|
2202
|
-
el.style.opacity = "0";
|
|
2203
|
-
el.style.transform = `translate(${this.offsetX}px, ${this.offsetY}px) scale(0.4)`;
|
|
2204
|
-
el.tabIndex = -1;
|
|
2205
|
-
});
|
|
2206
|
-
}
|
|
2207
|
-
_animateInToolbar() {
|
|
2208
|
-
const windowWidth = window.innerWidth;
|
|
2209
|
-
const windowHeight = window.innerHeight;
|
|
2210
|
-
const btnRect = this.el.getBoundingClientRect();
|
|
2211
|
-
const fabColor = getComputedStyle(this._anchor).backgroundColor;
|
|
2212
|
-
const backdrop = document.createElement("div");
|
|
2213
|
-
backdrop.classList.add("fab-backdrop");
|
|
2214
|
-
backdrop.style.backgroundColor = fabColor;
|
|
2215
|
-
this._anchor.append(backdrop);
|
|
2216
|
-
this._backdrop = backdrop;
|
|
2217
|
-
const backdropWidth = backdrop.clientWidth;
|
|
2218
|
-
const scaleFactor = backdropWidth > 0 ? windowWidth / backdropWidth : 1;
|
|
2219
|
-
this.offsetX = btnRect.left - windowWidth / 2 + btnRect.width / 2;
|
|
2220
|
-
this.offsetY = windowHeight - btnRect.bottom;
|
|
2221
|
-
this.btnBottom = btnRect.bottom;
|
|
2222
|
-
this.btnLeft = btnRect.left;
|
|
2223
|
-
this.btnWidth = btnRect.width;
|
|
2224
|
-
this.el.classList.add("active");
|
|
2225
|
-
this.el.style.textAlign = "center";
|
|
2226
|
-
this.el.style.width = "100%";
|
|
2227
|
-
this.el.style.bottom = "0";
|
|
2228
|
-
this.el.style.left = "0";
|
|
2229
|
-
this.el.style.transform = "translateX(" + this.offsetX + "px)";
|
|
2230
|
-
this.el.style.transition = "none";
|
|
2231
|
-
if (this._menu) this._menu.ariaExpanded = "true";
|
|
2232
|
-
this._anchor.style.transform = `translateY(${this.offsetY}px)`;
|
|
2233
|
-
this._anchor.style.transition = "none";
|
|
2234
|
-
setTimeout(() => {
|
|
2235
|
-
this.el.style.transform = "";
|
|
2236
|
-
this.el.style.transition = "transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s";
|
|
2237
|
-
this._anchor.style.overflow = "visible";
|
|
2238
|
-
this._anchor.style.transform = "";
|
|
2239
|
-
this._anchor.style.transition = "transform .2s";
|
|
2240
|
-
setTimeout(() => {
|
|
2241
|
-
this.el.style.overflow = "hidden";
|
|
2242
|
-
this.el.style.backgroundColor = fabColor;
|
|
2243
|
-
backdrop.style.transform = "scale(" + scaleFactor + ")";
|
|
2244
|
-
backdrop.style.transition = "transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)";
|
|
2245
|
-
this._menu.querySelectorAll("li > a").forEach((a) => {
|
|
2246
|
-
a.style.opacity = "1";
|
|
2247
|
-
a.tabIndex = 0;
|
|
2248
|
-
});
|
|
2249
|
-
window.addEventListener("scroll", this.close, true);
|
|
2250
|
-
document.body.addEventListener("click", this._handleDocumentClick, true);
|
|
2251
|
-
}, 100);
|
|
2252
|
-
}, 0);
|
|
2163
|
+
this.el.removeEventListener("click", this._handleFABClick);
|
|
2164
|
+
this._anchor?.removeEventListener("keydown", this._handleAnchorKeydown);
|
|
2253
2165
|
}
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
* Closing used to only unbind the listeners, leaving the FAB stretched
|
|
2258
|
-
* across the viewport with its backdrop still in the DOM - and a fresh
|
|
2259
|
-
* backdrop appended on every subsequent open.
|
|
2260
|
-
*/
|
|
2261
|
-
_animateOutToolbar() {
|
|
2262
|
-
const backdrop = this._backdrop;
|
|
2263
|
-
this._backdrop = null;
|
|
2264
|
-
this._menu?.querySelectorAll("li > a").forEach((a) => {
|
|
2265
|
-
a.style.opacity = "";
|
|
2266
|
-
a.tabIndex = -1;
|
|
2267
|
-
});
|
|
2268
|
-
if (backdrop) {
|
|
2269
|
-
backdrop.style.transition = "transform .2s";
|
|
2270
|
-
backdrop.style.transform = "scale(0)";
|
|
2271
|
-
}
|
|
2272
|
-
this.el.style.overflow = "";
|
|
2273
|
-
this.el.style.backgroundColor = "";
|
|
2274
|
-
this.el.style.transition = "transform .2s";
|
|
2275
|
-
this.el.style.transform = `translateX(${this.offsetX}px)`;
|
|
2276
|
-
this._anchor.style.transition = "transform .2s";
|
|
2277
|
-
this._anchor.style.transform = `translateY(${this.offsetY}px)`;
|
|
2278
|
-
setTimeout(() => {
|
|
2279
|
-
backdrop?.remove();
|
|
2280
|
-
this.el.classList.remove("active");
|
|
2281
|
-
if (this._menu) this._menu.ariaExpanded = "false";
|
|
2282
|
-
this.el.style.textAlign = "";
|
|
2283
|
-
this.el.style.width = "";
|
|
2284
|
-
this.el.style.bottom = "";
|
|
2285
|
-
this.el.style.left = "";
|
|
2286
|
-
this.el.style.transform = "";
|
|
2287
|
-
this.el.style.transition = "";
|
|
2288
|
-
this._anchor.style.overflow = "";
|
|
2289
|
-
this._anchor.style.transform = "";
|
|
2290
|
-
this._anchor.style.transition = "";
|
|
2291
|
-
}, 200);
|
|
2166
|
+
_toggle() {
|
|
2167
|
+
if (this.isOpen) this.close();
|
|
2168
|
+
else this.open();
|
|
2292
2169
|
}
|
|
2293
2170
|
};
|
|
2294
2171
|
|
|
2295
2172
|
// src/ts/components/carousel.ts
|
|
2296
2173
|
var _defaults7 = {
|
|
2297
2174
|
duration: 200,
|
|
2298
|
-
// ms
|
|
2299
2175
|
dist: -100,
|
|
2300
|
-
// zoom scale TODO: make this more intuitive as an option
|
|
2301
2176
|
shift: 0,
|
|
2302
|
-
// spacing for center image
|
|
2303
2177
|
padding: 0,
|
|
2304
|
-
// Padding between non center items
|
|
2305
2178
|
numVisible: 5,
|
|
2306
|
-
// Number of visible items in carousel
|
|
2307
2179
|
fullWidth: false,
|
|
2308
|
-
// Change to full width styles
|
|
2309
2180
|
indicators: false,
|
|
2310
|
-
// Toggle indicators
|
|
2311
2181
|
noWrap: false,
|
|
2312
|
-
// Don't wrap around and cycle through items.
|
|
2313
2182
|
onCycleTo: null
|
|
2314
|
-
// Callback for when a new slide is cycled to.
|
|
2315
2183
|
};
|
|
2316
|
-
var
|
|
2184
|
+
var _Carousel = class _Carousel extends Component {
|
|
2317
2185
|
constructor(el, options) {
|
|
2318
2186
|
super(el, options, _Carousel);
|
|
2319
|
-
/** The index of the center carousel item. */
|
|
2320
2187
|
this.center = 0;
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2188
|
+
this._ownIndicators = false;
|
|
2189
|
+
this._trackEl = null;
|
|
2190
|
+
this._ignoreScroll = false;
|
|
2191
|
+
this._trackRaf = null;
|
|
2192
|
+
this._started = false;
|
|
2324
2193
|
this._handleThrottledResize = Utils.throttle(() => this._handleResize(), 200);
|
|
2325
2194
|
this._handleCarouselTap = (e) => {
|
|
2326
|
-
if (e.
|
|
2195
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
2196
|
+
if (e.target instanceof HTMLElement && e.target.tagName === "IMG") {
|
|
2327
2197
|
e.preventDefault();
|
|
2328
2198
|
}
|
|
2329
2199
|
this.pressed = true;
|
|
2330
2200
|
this.dragged = false;
|
|
2331
2201
|
this.verticalDragged = false;
|
|
2332
|
-
this.reference =
|
|
2333
|
-
this.referenceY =
|
|
2202
|
+
this.reference = e.clientX;
|
|
2203
|
+
this.referenceY = e.clientY;
|
|
2334
2204
|
this.velocity = this.amplitude = 0;
|
|
2335
2205
|
this.frame = this.offset;
|
|
2336
2206
|
this.timestamp = Date.now();
|
|
2337
|
-
|
|
2338
|
-
|
|
2207
|
+
try {
|
|
2208
|
+
this.el.setPointerCapture(e.pointerId);
|
|
2209
|
+
} catch {
|
|
2210
|
+
}
|
|
2211
|
+
if (this._trackRaf !== null) cancelAnimationFrame(this._trackRaf);
|
|
2212
|
+
const loop = () => {
|
|
2213
|
+
this._track();
|
|
2214
|
+
if (this.pressed) this._trackRaf = requestAnimationFrame(loop);
|
|
2215
|
+
else this._trackRaf = null;
|
|
2216
|
+
};
|
|
2217
|
+
this._trackRaf = requestAnimationFrame(loop);
|
|
2339
2218
|
};
|
|
2340
2219
|
this._handleCarouselDrag = (e) => {
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
delta
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
this.dragged = true;
|
|
2350
|
-
this.reference = x;
|
|
2351
|
-
this._scroll(this.offset + delta);
|
|
2352
|
-
}
|
|
2353
|
-
} else if (this.dragged) {
|
|
2354
|
-
e.preventDefault();
|
|
2355
|
-
e.stopPropagation();
|
|
2356
|
-
return false;
|
|
2357
|
-
} else {
|
|
2358
|
-
this.verticalDragged = true;
|
|
2220
|
+
if (!this.pressed) return;
|
|
2221
|
+
const delta = this.reference - e.clientX;
|
|
2222
|
+
const deltaY = Math.abs(this.referenceY - e.clientY);
|
|
2223
|
+
if (deltaY < 30 && !this.verticalDragged) {
|
|
2224
|
+
if (delta > 2 || delta < -2) {
|
|
2225
|
+
this.dragged = true;
|
|
2226
|
+
this.reference = e.clientX;
|
|
2227
|
+
this._scroll(this.offset + delta);
|
|
2359
2228
|
}
|
|
2360
|
-
}
|
|
2361
|
-
if (this.dragged) {
|
|
2229
|
+
} else if (this.dragged) {
|
|
2362
2230
|
e.preventDefault();
|
|
2363
|
-
|
|
2364
|
-
|
|
2231
|
+
} else {
|
|
2232
|
+
this.verticalDragged = true;
|
|
2365
2233
|
}
|
|
2234
|
+
if (this.dragged) e.preventDefault();
|
|
2366
2235
|
};
|
|
2367
2236
|
this._handleCarouselRelease = (e) => {
|
|
2368
|
-
if (this.pressed)
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2237
|
+
if (!this.pressed) return;
|
|
2238
|
+
this.pressed = false;
|
|
2239
|
+
if (this._trackRaf !== null) {
|
|
2240
|
+
cancelAnimationFrame(this._trackRaf);
|
|
2241
|
+
this._trackRaf = null;
|
|
2242
|
+
}
|
|
2243
|
+
try {
|
|
2244
|
+
this.el.releasePointerCapture(e.pointerId);
|
|
2245
|
+
} catch {
|
|
2372
2246
|
}
|
|
2373
|
-
clearInterval(this.ticker);
|
|
2374
2247
|
this.target = this.offset;
|
|
2375
2248
|
if (this.velocity > 10 || this.velocity < -10) {
|
|
2376
2249
|
this.amplitude = 0.9 * this.velocity;
|
|
@@ -2387,86 +2260,91 @@ var Carousel = class _Carousel extends Component {
|
|
|
2387
2260
|
this.amplitude = this.target - this.offset;
|
|
2388
2261
|
this.timestamp = Date.now();
|
|
2389
2262
|
requestAnimationFrame(this._autoScroll);
|
|
2263
|
+
if (this.dragged) e.preventDefault();
|
|
2264
|
+
};
|
|
2265
|
+
this._handleCarouselClick = (e) => {
|
|
2390
2266
|
if (this.dragged) {
|
|
2391
2267
|
e.preventDefault();
|
|
2392
2268
|
e.stopPropagation();
|
|
2269
|
+
return;
|
|
2393
2270
|
}
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2271
|
+
const clickedElem = e.target.closest(".carousel-item");
|
|
2272
|
+
if (!clickedElem || !this.el.contains(clickedElem)) return;
|
|
2273
|
+
const clickedIndex = this.images.indexOf(clickedElem);
|
|
2274
|
+
const diff = this._wrap(this.center) - clickedIndex;
|
|
2275
|
+
if (diff !== 0) {
|
|
2398
2276
|
e.preventDefault();
|
|
2399
2277
|
e.stopPropagation();
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
const clickedIndex = [...clickedElem.parentNode.children].indexOf(clickedElem);
|
|
2405
|
-
const diff = this._wrap(this.center) - clickedIndex;
|
|
2406
|
-
if (diff !== 0) {
|
|
2407
|
-
e.preventDefault();
|
|
2408
|
-
e.stopPropagation();
|
|
2409
|
-
}
|
|
2410
|
-
if (clickedIndex < 0) {
|
|
2411
|
-
if (e.clientX - e.target.getBoundingClientRect().left > this.el.clientWidth / 2) {
|
|
2412
|
-
this.next();
|
|
2413
|
-
} else {
|
|
2414
|
-
this.prev();
|
|
2415
|
-
}
|
|
2278
|
+
}
|
|
2279
|
+
if (clickedIndex < 0) {
|
|
2280
|
+
if (e.clientX - e.target.getBoundingClientRect().left > this.el.clientWidth / 2) {
|
|
2281
|
+
this.next();
|
|
2416
2282
|
} else {
|
|
2417
|
-
this.
|
|
2283
|
+
this.prev();
|
|
2418
2284
|
}
|
|
2285
|
+
} else {
|
|
2286
|
+
this._cycleTo(clickedIndex);
|
|
2419
2287
|
}
|
|
2420
2288
|
};
|
|
2421
2289
|
this._handleIndicatorClick = (e) => {
|
|
2422
2290
|
e.stopPropagation();
|
|
2423
|
-
|
|
2291
|
+
const indicator = e.target.closest(".indicator-item");
|
|
2292
|
+
if (!indicator || !this._indicators.contains(indicator)) return;
|
|
2293
|
+
const index = [...this._indicators.children].indexOf(indicator);
|
|
2294
|
+
if (index < 0) return;
|
|
2295
|
+
this._cycleTo(index);
|
|
2424
2296
|
};
|
|
2425
|
-
this.
|
|
2426
|
-
e.
|
|
2427
|
-
if (
|
|
2428
|
-
|
|
2297
|
+
this._handleKeydown = (e) => {
|
|
2298
|
+
const target = e.target;
|
|
2299
|
+
if (target.closest('input, textarea, select, [contenteditable="true"]')) return;
|
|
2300
|
+
if (Utils.keys.ARROW_RIGHT.includes(e.key)) {
|
|
2301
|
+
e.preventDefault();
|
|
2302
|
+
this.next();
|
|
2303
|
+
} else if (Utils.keys.ARROW_LEFT.includes(e.key)) {
|
|
2304
|
+
e.preventDefault();
|
|
2305
|
+
this.prev();
|
|
2429
2306
|
}
|
|
2430
2307
|
};
|
|
2431
|
-
this.
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
this._cycleTo(index);
|
|
2436
|
-
}
|
|
2308
|
+
this._handleFlatScroll = () => {
|
|
2309
|
+
if (this._ignoreScroll) return;
|
|
2310
|
+
const index = this._nearestIndex();
|
|
2311
|
+
if (index !== this.center) this._syncActive(index, this.dragged);
|
|
2437
2312
|
};
|
|
2438
2313
|
this._handleResize = () => {
|
|
2314
|
+
if (!this.images.length) return;
|
|
2315
|
+
if (this._flat) {
|
|
2316
|
+
this._scrollToIndex(this.center, false);
|
|
2317
|
+
return;
|
|
2318
|
+
}
|
|
2439
2319
|
if (this.options.fullWidth) {
|
|
2440
|
-
const firstItem = this.
|
|
2441
|
-
|
|
2442
|
-
if (!firstItem || !activeItem) return;
|
|
2320
|
+
const firstItem = this.images[0];
|
|
2321
|
+
if (!firstItem) return;
|
|
2443
2322
|
this.itemWidth = firstItem.clientWidth;
|
|
2444
|
-
this.imageHeight = activeItem.clientHeight;
|
|
2445
2323
|
this.dim = this.itemWidth * 2 + this.options.padding;
|
|
2446
2324
|
this.offset = this.center * 2 * this.itemWidth;
|
|
2447
2325
|
this.target = this.offset;
|
|
2448
|
-
this._setCarouselHeight(true);
|
|
2449
2326
|
} else {
|
|
2450
2327
|
this._scroll();
|
|
2451
2328
|
}
|
|
2452
2329
|
};
|
|
2453
2330
|
this._track = () => {
|
|
2454
|
-
const now = Date.now()
|
|
2331
|
+
const now = Date.now();
|
|
2332
|
+
const elapsed = now - this.timestamp;
|
|
2333
|
+
const delta = this.offset - this.frame;
|
|
2334
|
+
const v = 1e3 * delta / (1 + elapsed);
|
|
2455
2335
|
this.timestamp = now;
|
|
2456
2336
|
this.frame = this.offset;
|
|
2457
2337
|
this.velocity = 0.8 * v + 0.2 * this.velocity;
|
|
2458
2338
|
};
|
|
2459
2339
|
this._autoScroll = () => {
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
this._scroll(this.target);
|
|
2469
|
-
}
|
|
2340
|
+
if (!this.amplitude) return;
|
|
2341
|
+
const elapsed = Date.now() - this.timestamp;
|
|
2342
|
+
const delta = this.amplitude * Math.exp(-elapsed / this.options.duration);
|
|
2343
|
+
if (delta > 2 || delta < -2) {
|
|
2344
|
+
this._scroll(this.target - delta);
|
|
2345
|
+
requestAnimationFrame(this._autoScroll);
|
|
2346
|
+
} else {
|
|
2347
|
+
this._scroll(this.target);
|
|
2470
2348
|
}
|
|
2471
2349
|
};
|
|
2472
2350
|
this.el["Expressive_Carousel"] = this;
|
|
@@ -2474,56 +2352,58 @@ var Carousel = class _Carousel extends Component {
|
|
|
2474
2352
|
..._Carousel.defaults,
|
|
2475
2353
|
...options
|
|
2476
2354
|
};
|
|
2477
|
-
this.
|
|
2478
|
-
|
|
2479
|
-
|
|
2355
|
+
this._flat = this.options.fullWidth || this.el.classList.contains("flat") || this.el.classList.contains("carousel-slider");
|
|
2356
|
+
if (this._flat) {
|
|
2357
|
+
this.el.classList.add("flat");
|
|
2358
|
+
this.options.fullWidth = true;
|
|
2359
|
+
this.options.dist = 0;
|
|
2360
|
+
}
|
|
2361
|
+
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
2362
|
+
this.options.duration = 1;
|
|
2363
|
+
if (!this._flat) this.options.dist = 0;
|
|
2364
|
+
}
|
|
2480
2365
|
this.pressed = false;
|
|
2481
2366
|
this.dragged = false;
|
|
2482
2367
|
this.offset = this.target = 0;
|
|
2483
|
-
this.images =
|
|
2484
|
-
|
|
2485
|
-
if (!firstItem) {
|
|
2368
|
+
this.images = this._collectItems();
|
|
2369
|
+
if (!this.images.length) {
|
|
2486
2370
|
console.error("Carousel: no .carousel-item elements to show");
|
|
2487
2371
|
return;
|
|
2488
2372
|
}
|
|
2489
|
-
this.
|
|
2490
|
-
this.
|
|
2491
|
-
this.
|
|
2492
|
-
if (this.options.fullWidth) {
|
|
2493
|
-
this.options.dist = 0;
|
|
2494
|
-
this._setCarouselHeight();
|
|
2495
|
-
if (this.showIndicators) {
|
|
2496
|
-
this.el.querySelector(".carousel-fixed-item")?.classList.add("with-indicators");
|
|
2497
|
-
}
|
|
2498
|
-
}
|
|
2499
|
-
this._indicators = document.createElement("ul");
|
|
2500
|
-
this._indicators.classList.add("indicators");
|
|
2501
|
-
this.el.querySelectorAll(".carousel-item").forEach((item, i) => {
|
|
2502
|
-
this.images.push(item);
|
|
2503
|
-
if (this.showIndicators) {
|
|
2504
|
-
const indicator = document.createElement("li");
|
|
2505
|
-
indicator.classList.add("indicator-item");
|
|
2506
|
-
indicator.tabIndex = 0;
|
|
2507
|
-
if (i === 0) {
|
|
2508
|
-
indicator.classList.add("active");
|
|
2509
|
-
}
|
|
2510
|
-
this._indicators.appendChild(indicator);
|
|
2511
|
-
}
|
|
2512
|
-
});
|
|
2513
|
-
if (this.showIndicators) this.el.appendChild(this._indicators);
|
|
2373
|
+
this.hasMultipleSlides = this.images.length > 1;
|
|
2374
|
+
this.showIndicators = this.options.indicators && this.hasMultipleSlides;
|
|
2375
|
+
this.noWrap = this.options.noWrap || !this.hasMultipleSlides || this._flat;
|
|
2514
2376
|
this.count = this.images.length;
|
|
2515
2377
|
this.options.numVisible = Math.min(this.count, this.options.numVisible);
|
|
2378
|
+
this.images.forEach((item) => item.classList.add("carousel-item"));
|
|
2379
|
+
if (this._flat) this._wrapTrack();
|
|
2380
|
+
const firstItem = this.images[0];
|
|
2381
|
+
this.itemWidth = firstItem.clientWidth || this.el.clientWidth || 1;
|
|
2382
|
+
this.itemHeight = firstItem.clientHeight || this.el.clientHeight || 1;
|
|
2383
|
+
this.dim = this.itemWidth * 2 + this.options.padding || 1;
|
|
2384
|
+
if (this.showIndicators) this._setupIndicators();
|
|
2385
|
+
this.el.tabIndex = this.el.tabIndex >= 0 ? this.el.tabIndex : 0;
|
|
2386
|
+
this.el.setAttribute("aria-roledescription", "carousel");
|
|
2516
2387
|
this._setupEventHandlers();
|
|
2517
|
-
this.
|
|
2388
|
+
this._started = true;
|
|
2389
|
+
if (this._flat) {
|
|
2390
|
+
const start = Math.max(
|
|
2391
|
+
0,
|
|
2392
|
+
this.images.findIndex((el2) => el2.classList.contains("active"))
|
|
2393
|
+
);
|
|
2394
|
+
this.center = start;
|
|
2395
|
+
this._syncActive(start, false);
|
|
2396
|
+
this._scrollToIndex(start, false);
|
|
2397
|
+
} else {
|
|
2398
|
+
this._scroll(this.offset);
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
get _scroller() {
|
|
2402
|
+
return this._trackEl ?? this.el;
|
|
2518
2403
|
}
|
|
2519
2404
|
static get defaults() {
|
|
2520
2405
|
return _defaults7;
|
|
2521
2406
|
}
|
|
2522
|
-
/**
|
|
2523
|
-
* Initializes instances of Carousel.
|
|
2524
|
-
* @param els HTML elements.
|
|
2525
|
-
* @param options Component options.
|
|
2526
|
-
*/
|
|
2527
2407
|
static init(els, options = {}) {
|
|
2528
2408
|
return super.init(els, options, _Carousel);
|
|
2529
2409
|
}
|
|
@@ -2531,81 +2411,104 @@ var Carousel = class _Carousel extends Component {
|
|
|
2531
2411
|
return el["Expressive_Carousel"];
|
|
2532
2412
|
}
|
|
2533
2413
|
destroy() {
|
|
2534
|
-
this.
|
|
2414
|
+
if (this._started) this._teardown();
|
|
2535
2415
|
this.el["Expressive_Carousel"] = void 0;
|
|
2536
2416
|
}
|
|
2417
|
+
_collectItems() {
|
|
2418
|
+
const explicit = Array.from(this.el.children).filter(
|
|
2419
|
+
(el) => el instanceof HTMLElement && el.classList.contains("carousel-item")
|
|
2420
|
+
);
|
|
2421
|
+
if (explicit.length) return explicit;
|
|
2422
|
+
return Array.from(this.el.children).filter((el) => {
|
|
2423
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
2424
|
+
if (el.classList.contains("indicators") || el.classList.contains("carousel-fixed-item")) {
|
|
2425
|
+
return false;
|
|
2426
|
+
}
|
|
2427
|
+
return el.tagName !== "NAV";
|
|
2428
|
+
});
|
|
2429
|
+
}
|
|
2430
|
+
_setupIndicators() {
|
|
2431
|
+
const existing = Array.from(this.el.children).find(
|
|
2432
|
+
(el) => el instanceof HTMLElement && el.classList.contains("indicators")
|
|
2433
|
+
);
|
|
2434
|
+
this._indicators = existing ?? document.createElement("nav");
|
|
2435
|
+
this._ownIndicators = !existing;
|
|
2436
|
+
this._indicators.classList.add("indicators");
|
|
2437
|
+
this._indicators.setAttribute("aria-label", "Slides");
|
|
2438
|
+
this._indicators.replaceChildren();
|
|
2439
|
+
this.images.forEach((_, i) => {
|
|
2440
|
+
const button = document.createElement("button");
|
|
2441
|
+
button.type = "button";
|
|
2442
|
+
button.classList.add("indicator-item");
|
|
2443
|
+
if (i === 0) {
|
|
2444
|
+
button.classList.add("active");
|
|
2445
|
+
button.setAttribute("aria-current", "true");
|
|
2446
|
+
}
|
|
2447
|
+
button.setAttribute("aria-label", `Slide ${i + 1}`);
|
|
2448
|
+
this._indicators.appendChild(button);
|
|
2449
|
+
});
|
|
2450
|
+
if (this._ownIndicators) this.el.appendChild(this._indicators);
|
|
2451
|
+
if (this._flat) {
|
|
2452
|
+
this.el.querySelector(".carousel-fixed-item")?.classList.add("with-indicators");
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2537
2455
|
_setupEventHandlers() {
|
|
2538
|
-
|
|
2539
|
-
this.el.addEventListener("touchstart", this._handleCarouselTap);
|
|
2540
|
-
this.el.addEventListener("touchmove", this._handleCarouselDrag);
|
|
2541
|
-
this.el.addEventListener("touchend", this._handleCarouselRelease);
|
|
2542
|
-
}
|
|
2543
|
-
this.el.addEventListener("mousedown", this._handleCarouselTap);
|
|
2544
|
-
this.el.addEventListener("mousemove", this._handleCarouselDrag);
|
|
2545
|
-
this.el.addEventListener("mouseup", this._handleCarouselRelease);
|
|
2546
|
-
this.el.addEventListener("mouseleave", this._handleCarouselRelease);
|
|
2547
|
-
this.el.addEventListener("click", this._handleCarouselClick);
|
|
2456
|
+
this.el.addEventListener("keydown", this._handleKeydown);
|
|
2548
2457
|
if (this.showIndicators && this._indicators) {
|
|
2549
|
-
this._indicators.
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2458
|
+
this._indicators.addEventListener("click", this._handleIndicatorClick);
|
|
2459
|
+
}
|
|
2460
|
+
_Carousel._live.add(this);
|
|
2461
|
+
if (!_Carousel._resizeListening) {
|
|
2462
|
+
window.addEventListener("resize", _Carousel._onResize, { passive: true });
|
|
2463
|
+
_Carousel._resizeListening = true;
|
|
2464
|
+
}
|
|
2465
|
+
if (this._flat) {
|
|
2466
|
+
this._scroller.addEventListener("scroll", this._handleFlatScroll, { passive: true });
|
|
2467
|
+
return;
|
|
2553
2468
|
}
|
|
2554
|
-
|
|
2469
|
+
this.el.addEventListener("pointerdown", this._handleCarouselTap);
|
|
2470
|
+
this.el.addEventListener("pointermove", this._handleCarouselDrag);
|
|
2471
|
+
this.el.addEventListener("pointerup", this._handleCarouselRelease);
|
|
2472
|
+
this.el.addEventListener("pointercancel", this._handleCarouselRelease);
|
|
2473
|
+
this.el.addEventListener("click", this._handleCarouselClick);
|
|
2555
2474
|
}
|
|
2556
2475
|
_removeEventHandlers() {
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
this.
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
this.el.removeEventListener("
|
|
2563
|
-
this.el.removeEventListener("
|
|
2564
|
-
this.el.removeEventListener("
|
|
2565
|
-
this.el.removeEventListener("
|
|
2476
|
+
this.el.removeEventListener("keydown", this._handleKeydown);
|
|
2477
|
+
if (this._indicators) {
|
|
2478
|
+
this._indicators.removeEventListener("click", this._handleIndicatorClick);
|
|
2479
|
+
}
|
|
2480
|
+
this._scroller.removeEventListener("scroll", this._handleFlatScroll);
|
|
2481
|
+
this.el.removeEventListener("pointerdown", this._handleCarouselTap);
|
|
2482
|
+
this.el.removeEventListener("pointermove", this._handleCarouselDrag);
|
|
2483
|
+
this.el.removeEventListener("pointerup", this._handleCarouselRelease);
|
|
2484
|
+
this.el.removeEventListener("pointercancel", this._handleCarouselRelease);
|
|
2566
2485
|
this.el.removeEventListener("click", this._handleCarouselClick);
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2486
|
+
_Carousel._live.delete(this);
|
|
2487
|
+
if (_Carousel._live.size === 0 && _Carousel._resizeListening) {
|
|
2488
|
+
window.removeEventListener("resize", _Carousel._onResize);
|
|
2489
|
+
_Carousel._resizeListening = false;
|
|
2571
2490
|
}
|
|
2572
|
-
window.removeEventListener("resize", this._handleThrottledResize);
|
|
2573
2491
|
}
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
this.el.style.height = adjustedHeight + "px";
|
|
2587
|
-
}
|
|
2588
|
-
} else {
|
|
2589
|
-
firstImage.addEventListener("load", () => {
|
|
2590
|
-
this.el.style.height = firstImage.offsetHeight + "px";
|
|
2591
|
-
});
|
|
2592
|
-
}
|
|
2593
|
-
} else if (!imageOnly) {
|
|
2594
|
-
const slideHeight = firstSlide.clientHeight;
|
|
2595
|
-
this.el.style.height = slideHeight + "px";
|
|
2596
|
-
}
|
|
2492
|
+
_teardown() {
|
|
2493
|
+
this._removeEventHandlers();
|
|
2494
|
+
if (this._trackRaf !== null) cancelAnimationFrame(this._trackRaf);
|
|
2495
|
+
window.clearTimeout(this.scrollingTimeout);
|
|
2496
|
+
if (this._ownIndicators) this._indicators?.remove();
|
|
2497
|
+
this._unwrapTrack();
|
|
2498
|
+
this.images.forEach((el) => {
|
|
2499
|
+
el.style.transform = "";
|
|
2500
|
+
el.style.zIndex = "";
|
|
2501
|
+
el.style.opacity = "";
|
|
2502
|
+
el.style.visibility = "";
|
|
2503
|
+
});
|
|
2597
2504
|
}
|
|
2598
2505
|
_xpos(e) {
|
|
2599
|
-
if (
|
|
2600
|
-
|
|
2601
|
-
}
|
|
2602
|
-
return e.clientX;
|
|
2506
|
+
if ("clientX" in e) return e.clientX;
|
|
2507
|
+
return 0;
|
|
2603
2508
|
}
|
|
2604
2509
|
_ypos(e) {
|
|
2605
|
-
if (
|
|
2606
|
-
|
|
2607
|
-
}
|
|
2608
|
-
return e.clientY;
|
|
2510
|
+
if ("clientY" in e) return e.clientY;
|
|
2511
|
+
return 0;
|
|
2609
2512
|
}
|
|
2610
2513
|
_wrap(x) {
|
|
2611
2514
|
return x >= this.count ? x % this.count : x < 0 ? this._wrap(this.count + x % this.count) : x;
|
|
@@ -2614,18 +2517,20 @@ var Carousel = class _Carousel extends Component {
|
|
|
2614
2517
|
if (!this.el.classList.contains("scrolling")) {
|
|
2615
2518
|
this.el.classList.add("scrolling");
|
|
2616
2519
|
}
|
|
2617
|
-
|
|
2618
|
-
clearTimeout(this.scrollingTimeout);
|
|
2619
|
-
}
|
|
2520
|
+
window.clearTimeout(this.scrollingTimeout);
|
|
2620
2521
|
this.scrollingTimeout = setTimeout(() => {
|
|
2621
2522
|
this.el.classList.remove("scrolling");
|
|
2622
2523
|
}, this.options.duration);
|
|
2623
2524
|
this.offset = typeof x === "number" ? x : this.offset;
|
|
2624
2525
|
this.center = Math.floor((this.offset + this.dim / 2) / this.dim);
|
|
2625
|
-
const half = this.count >> 1
|
|
2626
|
-
|
|
2526
|
+
const half = this.count >> 1;
|
|
2527
|
+
const delta = this.offset - this.center * this.dim;
|
|
2528
|
+
const dir = delta < 0 ? 1 : -1;
|
|
2529
|
+
const tween = -dir * delta * 2 / this.dim;
|
|
2627
2530
|
const lastCenter = this.center;
|
|
2628
2531
|
const numVisibleOffset = 1 / this.options.numVisible;
|
|
2532
|
+
let alignment;
|
|
2533
|
+
let centerTweenedOpacity;
|
|
2629
2534
|
if (this.options.fullWidth) {
|
|
2630
2535
|
alignment = "translateX(0)";
|
|
2631
2536
|
centerTweenedOpacity = 1;
|
|
@@ -2634,26 +2539,17 @@ var Carousel = class _Carousel extends Component {
|
|
|
2634
2539
|
alignment += "translateY(" + (this.el.clientHeight - this.itemHeight) / 2 + "px)";
|
|
2635
2540
|
centerTweenedOpacity = 1 - numVisibleOffset * tween;
|
|
2636
2541
|
}
|
|
2637
|
-
|
|
2638
|
-
const diff = this.center % this.count;
|
|
2639
|
-
const activeIndicator = this._indicators.querySelector(".indicator-item.active");
|
|
2640
|
-
const activeIndicatorIndex = [...activeIndicator.parentNode.children].indexOf(
|
|
2641
|
-
activeIndicator
|
|
2642
|
-
);
|
|
2643
|
-
if (activeIndicatorIndex !== diff) {
|
|
2644
|
-
activeIndicator.classList.remove("active");
|
|
2645
|
-
const pos = diff < 0 ? this.count + diff : diff;
|
|
2646
|
-
this._indicators.querySelectorAll(".indicator-item")[pos].classList.add("active");
|
|
2647
|
-
}
|
|
2648
|
-
}
|
|
2542
|
+
this._paintIndicators(this.center);
|
|
2649
2543
|
if (!this.noWrap || this.center >= 0 && this.center < this.count) {
|
|
2650
|
-
el = this.images[this._wrap(this.center)];
|
|
2651
|
-
if (!el.classList.contains("active")) {
|
|
2544
|
+
const el = this.images[this._wrap(this.center)];
|
|
2545
|
+
if (el && !el.classList.contains("active")) {
|
|
2652
2546
|
this.el.querySelector(".carousel-item.active")?.classList.remove("active");
|
|
2653
2547
|
el.classList.add("active");
|
|
2654
2548
|
}
|
|
2655
2549
|
}
|
|
2656
|
-
for (i = 1; i <= half; ++i) {
|
|
2550
|
+
for (let i = 1; i <= half; ++i) {
|
|
2551
|
+
let zTranslation;
|
|
2552
|
+
let tweenedOpacity;
|
|
2657
2553
|
if (this.options.fullWidth) {
|
|
2658
2554
|
zTranslation = this.options.dist;
|
|
2659
2555
|
tweenedOpacity = i === half && delta < 0 ? 1 - tween : 1;
|
|
@@ -2662,7 +2558,7 @@ var Carousel = class _Carousel extends Component {
|
|
|
2662
2558
|
tweenedOpacity = 1 - numVisibleOffset * (i * 2 + tween * dir);
|
|
2663
2559
|
}
|
|
2664
2560
|
if (!this.noWrap || this.center + i < this.count) {
|
|
2665
|
-
el = this.images[this._wrap(this.center + i)];
|
|
2561
|
+
const el = this.images[this._wrap(this.center + i)];
|
|
2666
2562
|
const transformString = `${alignment} translateX(${this.options.shift + (this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
2667
2563
|
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
2668
2564
|
}
|
|
@@ -2674,32 +2570,113 @@ var Carousel = class _Carousel extends Component {
|
|
|
2674
2570
|
tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
|
|
2675
2571
|
}
|
|
2676
2572
|
if (!this.noWrap || this.center - i >= 0) {
|
|
2677
|
-
el = this.images[this._wrap(this.center - i)];
|
|
2573
|
+
const el = this.images[this._wrap(this.center - i)];
|
|
2678
2574
|
const transformString = `${alignment} translateX(${-this.options.shift + (-this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
2679
2575
|
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
2680
2576
|
}
|
|
2681
2577
|
}
|
|
2682
2578
|
if (!this.noWrap || this.center >= 0 && this.center < this.count) {
|
|
2683
|
-
el = this.images[this._wrap(this.center)];
|
|
2579
|
+
const el = this.images[this._wrap(this.center)];
|
|
2684
2580
|
const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir * this.options.shift * tween}px) translateZ(${this.options.dist * tween}px)`;
|
|
2685
2581
|
this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
|
|
2686
2582
|
}
|
|
2687
|
-
const
|
|
2583
|
+
const currItem = this.images[this._wrap(this.center)];
|
|
2584
|
+
this._syncA11y(this._wrap(this.center));
|
|
2688
2585
|
if (lastCenter !== this.center && typeof this.options.onCycleTo === "function") {
|
|
2689
|
-
this.options.onCycleTo.call(this,
|
|
2586
|
+
this.options.onCycleTo.call(this, currItem, this.dragged);
|
|
2690
2587
|
}
|
|
2691
2588
|
if (typeof this.oneTimeCallback === "function") {
|
|
2692
|
-
this.oneTimeCallback.call(this,
|
|
2589
|
+
this.oneTimeCallback.call(this, currItem, this.dragged);
|
|
2693
2590
|
this.oneTimeCallback = null;
|
|
2694
2591
|
}
|
|
2695
2592
|
}
|
|
2696
2593
|
_updateItemStyle(el, opacity, zIndex, transform) {
|
|
2594
|
+
if (!el) return;
|
|
2697
2595
|
el.style.transform = transform;
|
|
2698
2596
|
el.style.zIndex = zIndex.toString();
|
|
2699
2597
|
el.style.opacity = opacity.toString();
|
|
2700
2598
|
el.style.visibility = "visible";
|
|
2701
2599
|
}
|
|
2600
|
+
_paintIndicators(center) {
|
|
2601
|
+
if (!this.showIndicators || !this._indicators) return;
|
|
2602
|
+
const pos = (center % this.count + this.count) % this.count;
|
|
2603
|
+
this._indicators.querySelectorAll(".indicator-item").forEach((el, i) => {
|
|
2604
|
+
const on = i === pos;
|
|
2605
|
+
el.classList.toggle("active", on);
|
|
2606
|
+
if (on) el.setAttribute("aria-current", "true");
|
|
2607
|
+
else el.removeAttribute("aria-current");
|
|
2608
|
+
});
|
|
2609
|
+
}
|
|
2610
|
+
_syncA11y(index) {
|
|
2611
|
+
this.images.forEach((el, i) => {
|
|
2612
|
+
if (i === index) el.removeAttribute("aria-hidden");
|
|
2613
|
+
else el.setAttribute("aria-hidden", "true");
|
|
2614
|
+
});
|
|
2615
|
+
}
|
|
2616
|
+
_syncActive(index, dragged) {
|
|
2617
|
+
const prev = this.center;
|
|
2618
|
+
this.center = index;
|
|
2619
|
+
this.images.forEach((el, i) => el.classList.toggle("active", i === index));
|
|
2620
|
+
this._paintIndicators(index);
|
|
2621
|
+
this._syncA11y(index);
|
|
2622
|
+
const curr = this.images[index];
|
|
2623
|
+
if (prev !== index && typeof this.options.onCycleTo === "function") {
|
|
2624
|
+
this.options.onCycleTo.call(this, curr, dragged);
|
|
2625
|
+
}
|
|
2626
|
+
if (typeof this.oneTimeCallback === "function") {
|
|
2627
|
+
this.oneTimeCallback.call(this, curr, dragged);
|
|
2628
|
+
this.oneTimeCallback = null;
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
_wrapTrack() {
|
|
2632
|
+
const track = document.createElement("div");
|
|
2633
|
+
track.className = "carousel-track";
|
|
2634
|
+
this.images[0].before(track);
|
|
2635
|
+
this.images.forEach((el) => track.appendChild(el));
|
|
2636
|
+
this._trackEl = track;
|
|
2637
|
+
}
|
|
2638
|
+
_unwrapTrack() {
|
|
2639
|
+
if (!this._trackEl) return;
|
|
2640
|
+
this.images.forEach((el) => this.el.insertBefore(el, this._trackEl));
|
|
2641
|
+
this._trackEl.remove();
|
|
2642
|
+
this._trackEl = null;
|
|
2643
|
+
}
|
|
2644
|
+
_nearestIndex() {
|
|
2645
|
+
const left = this._scroller.scrollLeft;
|
|
2646
|
+
let best = 0;
|
|
2647
|
+
let bestDist = Infinity;
|
|
2648
|
+
this.images.forEach((el, i) => {
|
|
2649
|
+
const dist = Math.abs(el.offsetLeft - left);
|
|
2650
|
+
if (dist < bestDist) {
|
|
2651
|
+
bestDist = dist;
|
|
2652
|
+
best = i;
|
|
2653
|
+
}
|
|
2654
|
+
});
|
|
2655
|
+
return best;
|
|
2656
|
+
}
|
|
2657
|
+
_scrollToIndex(n, smooth = true) {
|
|
2658
|
+
const el = this.images[n];
|
|
2659
|
+
if (!el) return;
|
|
2660
|
+
const left = el.offsetLeft;
|
|
2661
|
+
if (Math.abs(this._scroller.scrollLeft - left) < 1) {
|
|
2662
|
+
this._syncActive(n, false);
|
|
2663
|
+
return;
|
|
2664
|
+
}
|
|
2665
|
+
this._ignoreScroll = true;
|
|
2666
|
+
this._scroller.scrollTo({ left, behavior: smooth ? "smooth" : "auto" });
|
|
2667
|
+
const done = () => {
|
|
2668
|
+
this._ignoreScroll = false;
|
|
2669
|
+
};
|
|
2670
|
+
this._scroller.addEventListener("scrollend", done, { once: true });
|
|
2671
|
+
window.setTimeout(done, this.options.duration + 350);
|
|
2672
|
+
}
|
|
2702
2673
|
_cycleTo(n, callback = null) {
|
|
2674
|
+
if (this._flat) {
|
|
2675
|
+
if (typeof callback === "function") this.oneTimeCallback = callback;
|
|
2676
|
+
this._syncActive(n, false);
|
|
2677
|
+
this._scrollToIndex(n);
|
|
2678
|
+
return;
|
|
2679
|
+
}
|
|
2703
2680
|
let diff = this.center % this.count - n;
|
|
2704
2681
|
if (!this.noWrap) {
|
|
2705
2682
|
if (diff < 0) {
|
|
@@ -2727,14 +2704,8 @@ var Carousel = class _Carousel extends Component {
|
|
|
2727
2704
|
requestAnimationFrame(this._autoScroll);
|
|
2728
2705
|
}
|
|
2729
2706
|
}
|
|
2730
|
-
/**
|
|
2731
|
-
* Move carousel to next slide or go forward a given amount of slides.
|
|
2732
|
-
* @param n How many times the carousel slides.
|
|
2733
|
-
*/
|
|
2734
2707
|
next(n = 1) {
|
|
2735
|
-
if (n === void 0 || isNaN(n))
|
|
2736
|
-
n = 1;
|
|
2737
|
-
}
|
|
2708
|
+
if (n === void 0 || isNaN(n)) n = 1;
|
|
2738
2709
|
let index = this.center + n;
|
|
2739
2710
|
if (index >= this.count || index < 0) {
|
|
2740
2711
|
if (this.noWrap) return;
|
|
@@ -2742,14 +2713,8 @@ var Carousel = class _Carousel extends Component {
|
|
|
2742
2713
|
}
|
|
2743
2714
|
this._cycleTo(index);
|
|
2744
2715
|
}
|
|
2745
|
-
/**
|
|
2746
|
-
* Move carousel to previous slide or go back a given amount of slides.
|
|
2747
|
-
* @param n How many times the carousel slides.
|
|
2748
|
-
*/
|
|
2749
2716
|
prev(n = 1) {
|
|
2750
|
-
if (n === void 0 || isNaN(n))
|
|
2751
|
-
n = 1;
|
|
2752
|
-
}
|
|
2717
|
+
if (n === void 0 || isNaN(n)) n = 1;
|
|
2753
2718
|
let index = this.center - n;
|
|
2754
2719
|
if (index >= this.count || index < 0) {
|
|
2755
2720
|
if (this.noWrap) return;
|
|
@@ -2757,15 +2722,8 @@ var Carousel = class _Carousel extends Component {
|
|
|
2757
2722
|
}
|
|
2758
2723
|
this._cycleTo(index);
|
|
2759
2724
|
}
|
|
2760
|
-
/**
|
|
2761
|
-
* Move carousel to nth slide.
|
|
2762
|
-
* @param n Index of slide.
|
|
2763
|
-
* @param callback "onCycleTo" optional callback.
|
|
2764
|
-
*/
|
|
2765
2725
|
set(n, callback) {
|
|
2766
|
-
if (n === void 0 || isNaN(n))
|
|
2767
|
-
n = 0;
|
|
2768
|
-
}
|
|
2726
|
+
if (n === void 0 || isNaN(n)) n = 0;
|
|
2769
2727
|
if (n > this.count || n < 0) {
|
|
2770
2728
|
if (this.noWrap) return;
|
|
2771
2729
|
n = this._wrap(n);
|
|
@@ -2773,6 +2731,12 @@ var Carousel = class _Carousel extends Component {
|
|
|
2773
2731
|
this._cycleTo(n, callback);
|
|
2774
2732
|
}
|
|
2775
2733
|
};
|
|
2734
|
+
_Carousel._live = /* @__PURE__ */ new Set();
|
|
2735
|
+
_Carousel._resizeListening = false;
|
|
2736
|
+
_Carousel._onResize = Utils.throttle(() => {
|
|
2737
|
+
_Carousel._live.forEach((c) => c._handleResize());
|
|
2738
|
+
}, 200);
|
|
2739
|
+
var Carousel = _Carousel;
|
|
2776
2740
|
|
|
2777
2741
|
// src/ts/components/characterCounter.ts
|
|
2778
2742
|
var _defaults8 = Object.freeze({});
|
|
@@ -2862,77 +2826,75 @@ var _defaults9 = {
|
|
|
2862
2826
|
var Collapsible = class _Collapsible extends Component {
|
|
2863
2827
|
constructor(el, options) {
|
|
2864
2828
|
super(el, options, _Collapsible);
|
|
2865
|
-
this.
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
const collapsible = header.closest(".collapsible");
|
|
2869
|
-
if (collapsible !== this.el) return;
|
|
2870
|
-
const li = header.closest("li");
|
|
2871
|
-
const isActive = li.classList.contains("active");
|
|
2872
|
-
const index = [...li.parentNode.children].indexOf(li);
|
|
2873
|
-
if (isActive) this.close(index);
|
|
2874
|
-
else this.open(index);
|
|
2875
|
-
}
|
|
2876
|
-
};
|
|
2877
|
-
this._handleCollapsibleKeydown = (e) => {
|
|
2878
|
-
if (Utils.keys.ENTER.includes(e.key)) {
|
|
2879
|
-
this._handleCollapsibleClick(e);
|
|
2880
|
-
}
|
|
2881
|
-
};
|
|
2829
|
+
this._items = [];
|
|
2830
|
+
this._endTimers = [];
|
|
2831
|
+
this._wrappedBodies = [];
|
|
2882
2832
|
/**
|
|
2883
2833
|
* Open collapsible section.
|
|
2884
|
-
* @param
|
|
2834
|
+
* @param index 0-based index of the section to open.
|
|
2885
2835
|
*/
|
|
2886
2836
|
this.open = (index) => {
|
|
2887
|
-
const
|
|
2888
|
-
|
|
2889
|
-
if (
|
|
2890
|
-
|
|
2891
|
-
this.
|
|
2892
|
-
}
|
|
2893
|
-
if (this.options.accordion) {
|
|
2894
|
-
const activeLis = listItems.filter((li2) => li2.classList.contains("active"));
|
|
2895
|
-
activeLis.forEach((activeLi) => {
|
|
2896
|
-
const index2 = listItems.indexOf(activeLi);
|
|
2897
|
-
this.close(index2);
|
|
2898
|
-
});
|
|
2899
|
-
}
|
|
2900
|
-
li.classList.add("active");
|
|
2901
|
-
this._animateIn(index);
|
|
2837
|
+
const item = this._items[index];
|
|
2838
|
+
if (!item || this._isOpen(item)) return;
|
|
2839
|
+
if (this.options.accordion) {
|
|
2840
|
+
this._items.forEach((other, i) => {
|
|
2841
|
+
if (i !== index && this._isOpen(other)) this.close(i);
|
|
2842
|
+
});
|
|
2902
2843
|
}
|
|
2844
|
+
this._setOpen(item, true);
|
|
2903
2845
|
};
|
|
2904
2846
|
/**
|
|
2905
2847
|
* Close collapsible section.
|
|
2906
|
-
* @param
|
|
2848
|
+
* @param index 0-based index of the section to close.
|
|
2907
2849
|
*/
|
|
2908
2850
|
this.close = (index) => {
|
|
2909
|
-
const
|
|
2910
|
-
if (
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2851
|
+
const item = this._items[index];
|
|
2852
|
+
if (!item || !this._isOpen(item)) return;
|
|
2853
|
+
this._setOpen(item, false);
|
|
2854
|
+
};
|
|
2855
|
+
this._handleClick = (e) => {
|
|
2856
|
+
const header = e.target.closest(".collapsible-header");
|
|
2857
|
+
if (!header || header.closest(".collapsible") !== this.el) return;
|
|
2858
|
+
if (header.closest("details")) return;
|
|
2859
|
+
const item = header.closest("li");
|
|
2860
|
+
if (!item) return;
|
|
2861
|
+
const index = this._items.indexOf(item);
|
|
2862
|
+
if (index < 0) return;
|
|
2863
|
+
if (this._isOpen(item)) this.close(index);
|
|
2864
|
+
else this.open(index);
|
|
2865
|
+
};
|
|
2866
|
+
this._handleKeydown = (e) => {
|
|
2867
|
+
if (!Utils.keys.ENTER.includes(e.key) && e.key !== " ") return;
|
|
2868
|
+
const header = e.target.closest(".collapsible-header");
|
|
2869
|
+
if (!header || header.closest(".collapsible") !== this.el) return;
|
|
2870
|
+
if (header.closest("details")) return;
|
|
2871
|
+
if (header.matches("a, button")) return;
|
|
2872
|
+
e.preventDefault();
|
|
2873
|
+
const item = header.closest("li");
|
|
2874
|
+
if (!item) return;
|
|
2875
|
+
const index = this._items.indexOf(item);
|
|
2876
|
+
if (index < 0) return;
|
|
2877
|
+
if (this._isOpen(item)) this.close(index);
|
|
2878
|
+
else this.open(index);
|
|
2879
|
+
};
|
|
2880
|
+
this._handleToggle = (e) => {
|
|
2881
|
+
const item = e.target;
|
|
2882
|
+
if (!(item instanceof HTMLDetailsElement)) return;
|
|
2883
|
+
if (!this._items.includes(item)) return;
|
|
2884
|
+
this._notify(item, item.open);
|
|
2917
2885
|
};
|
|
2918
2886
|
this.el["Expressive_Collapsible"] = this;
|
|
2887
|
+
const accordion = options.accordion !== void 0 ? options.accordion : !el.classList.contains("expandable");
|
|
2919
2888
|
this.options = {
|
|
2920
2889
|
..._Collapsible.defaults,
|
|
2921
|
-
...options
|
|
2890
|
+
...options,
|
|
2891
|
+
accordion
|
|
2922
2892
|
};
|
|
2923
|
-
this.
|
|
2924
|
-
this.
|
|
2893
|
+
this._groupName = el.id ? `collapsible-${el.id}` : `collapsible-${Utils.guid()}`;
|
|
2894
|
+
this._items = this._collectItems();
|
|
2895
|
+
this._wrapDetailsBodies();
|
|
2896
|
+
this._setupItems();
|
|
2925
2897
|
this._setupEventHandlers();
|
|
2926
|
-
const activeBodies = Array.from(
|
|
2927
|
-
this.el.querySelectorAll("li.active > .collapsible-body")
|
|
2928
|
-
);
|
|
2929
|
-
if (this.options.accordion) {
|
|
2930
|
-
if (activeBodies.length > 0) {
|
|
2931
|
-
this._setExpanded(activeBodies[0]);
|
|
2932
|
-
}
|
|
2933
|
-
} else {
|
|
2934
|
-
activeBodies.forEach((el2) => this._setExpanded(el2));
|
|
2935
|
-
}
|
|
2936
2898
|
}
|
|
2937
2899
|
static get defaults() {
|
|
2938
2900
|
return _defaults9;
|
|
@@ -2950,48 +2912,130 @@ var Collapsible = class _Collapsible extends Component {
|
|
|
2950
2912
|
}
|
|
2951
2913
|
destroy() {
|
|
2952
2914
|
this._removeEventHandlers();
|
|
2915
|
+
this._endTimers.forEach((id) => clearTimeout(id));
|
|
2916
|
+
this._endTimers = [];
|
|
2917
|
+
this._unwrapDetailsBodies();
|
|
2953
2918
|
this.el["Expressive_Collapsible"] = void 0;
|
|
2954
2919
|
}
|
|
2955
|
-
|
|
2956
|
-
this.el.
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
);
|
|
2920
|
+
_collectItems() {
|
|
2921
|
+
const details = Array.from(this.el.querySelectorAll(":scope > details"));
|
|
2922
|
+
if (details.length) return details;
|
|
2923
|
+
return Array.from(this.el.children).filter((c) => c.tagName === "LI");
|
|
2960
2924
|
}
|
|
2961
|
-
|
|
2962
|
-
this.
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2925
|
+
_setupItems() {
|
|
2926
|
+
if (this.options.accordion) {
|
|
2927
|
+
this._items.forEach((item) => {
|
|
2928
|
+
if (item instanceof HTMLDetailsElement && !item.getAttribute("name")) {
|
|
2929
|
+
item.setAttribute("name", this._groupName);
|
|
2930
|
+
}
|
|
2931
|
+
});
|
|
2932
|
+
}
|
|
2933
|
+
const opened = this._items.filter((item) => this._isOpen(item));
|
|
2934
|
+
if (this.options.accordion && opened.length > 1) {
|
|
2935
|
+
opened.slice(1).forEach((item) => {
|
|
2936
|
+
if (item instanceof HTMLDetailsElement) item.open = false;
|
|
2937
|
+
else item.classList.remove("active");
|
|
2938
|
+
});
|
|
2939
|
+
}
|
|
2940
|
+
this._items.forEach((item) => this._syncAria(item));
|
|
2966
2941
|
}
|
|
2967
|
-
|
|
2968
|
-
|
|
2942
|
+
_isOpen(item) {
|
|
2943
|
+
if (item instanceof HTMLDetailsElement) return item.open;
|
|
2944
|
+
return item.classList.contains("active");
|
|
2969
2945
|
}
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
this.
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2946
|
+
_setOpen(item, open) {
|
|
2947
|
+
if (item instanceof HTMLDetailsElement) {
|
|
2948
|
+
item.open = open;
|
|
2949
|
+
return;
|
|
2950
|
+
}
|
|
2951
|
+
item.classList.toggle("active", open);
|
|
2952
|
+
this._syncAria(item);
|
|
2953
|
+
this._notify(item, open);
|
|
2954
|
+
}
|
|
2955
|
+
_headerOf(item) {
|
|
2956
|
+
if (item instanceof HTMLDetailsElement) {
|
|
2957
|
+
return item.querySelector(":scope > summary");
|
|
2958
|
+
}
|
|
2959
|
+
return item.querySelector(":scope > .collapsible-header");
|
|
2960
|
+
}
|
|
2961
|
+
_wrapDetailsBodies() {
|
|
2962
|
+
this._items.forEach((item) => {
|
|
2963
|
+
if (!(item instanceof HTMLDetailsElement)) return;
|
|
2964
|
+
if (item.querySelector(":scope > .collapsible-body")) return;
|
|
2965
|
+
const body = document.createElement("div");
|
|
2966
|
+
body.className = "collapsible-body";
|
|
2967
|
+
Array.from(item.childNodes).forEach((node) => {
|
|
2968
|
+
if (node instanceof HTMLElement && node.tagName === "SUMMARY") return;
|
|
2969
|
+
body.appendChild(node);
|
|
2970
|
+
});
|
|
2971
|
+
item.appendChild(body);
|
|
2972
|
+
this._wrappedBodies.push(body);
|
|
2973
|
+
});
|
|
2982
2974
|
}
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2975
|
+
_unwrapDetailsBodies() {
|
|
2976
|
+
this._wrappedBodies.forEach((body) => {
|
|
2977
|
+
const parent = body.parentNode;
|
|
2978
|
+
if (!parent) return;
|
|
2979
|
+
while (body.firstChild) parent.insertBefore(body.firstChild, body);
|
|
2980
|
+
body.remove();
|
|
2981
|
+
});
|
|
2982
|
+
this._wrappedBodies = [];
|
|
2983
|
+
}
|
|
2984
|
+
_bodyOf(item) {
|
|
2985
|
+
return item.querySelector(":scope > .collapsible-body");
|
|
2986
|
+
}
|
|
2987
|
+
_syncAria(item) {
|
|
2988
|
+
if (item instanceof HTMLDetailsElement) return;
|
|
2989
|
+
const header = this._headerOf(item);
|
|
2990
|
+
const body = this._bodyOf(item);
|
|
2991
|
+
if (!header) return;
|
|
2992
|
+
header.setAttribute("aria-expanded", String(this._isOpen(item)));
|
|
2993
|
+
if (body) {
|
|
2994
|
+
if (!body.id) body.id = `collapsible-body-${Utils.guid()}`;
|
|
2995
|
+
header.setAttribute("aria-controls", body.id);
|
|
2996
|
+
}
|
|
2997
|
+
if (!header.matches("a, button, summary")) {
|
|
2998
|
+
header.setAttribute("role", "button");
|
|
2999
|
+
if (header.tabIndex < 0) header.tabIndex = 0;
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
_setupEventHandlers() {
|
|
3003
|
+
this.el.addEventListener("click", this._handleClick);
|
|
3004
|
+
this.el.addEventListener("keydown", this._handleKeydown);
|
|
3005
|
+
this.el.addEventListener("toggle", this._handleToggle, true);
|
|
3006
|
+
}
|
|
3007
|
+
_removeEventHandlers() {
|
|
3008
|
+
this.el.removeEventListener("click", this._handleClick);
|
|
3009
|
+
this.el.removeEventListener("keydown", this._handleKeydown);
|
|
3010
|
+
this.el.removeEventListener("toggle", this._handleToggle, true);
|
|
3011
|
+
}
|
|
3012
|
+
_notify(item, opening) {
|
|
3013
|
+
const start = opening ? this.options.onOpenStart : this.options.onCloseStart;
|
|
3014
|
+
if (typeof start === "function") start.call(this, item);
|
|
3015
|
+
const end = opening ? this.options.onOpenEnd : this.options.onCloseEnd;
|
|
3016
|
+
if (typeof end !== "function") return;
|
|
3017
|
+
const target = this._bodyOf(item) ?? item;
|
|
3018
|
+
let done = false;
|
|
3019
|
+
const finish = () => {
|
|
3020
|
+
if (done) return;
|
|
3021
|
+
done = true;
|
|
3022
|
+
target.removeEventListener("transitionend", onEnd);
|
|
3023
|
+
end.call(this, item);
|
|
3024
|
+
};
|
|
3025
|
+
const onEnd = (ev) => {
|
|
3026
|
+
if (ev.target !== target) return;
|
|
3027
|
+
finish();
|
|
3028
|
+
};
|
|
3029
|
+
target.addEventListener("transitionend", onEnd);
|
|
3030
|
+
this._endTimers.push(window.setTimeout(finish, this._durationMs() + 50));
|
|
3031
|
+
}
|
|
3032
|
+
_durationMs() {
|
|
3033
|
+
const raw = getComputedStyle(this.el).getPropertyValue("--md-comp-collapsible-duration").trim();
|
|
3034
|
+
if (!raw) return 500;
|
|
3035
|
+
if (raw.endsWith("ms")) return parseFloat(raw);
|
|
3036
|
+
if (raw.endsWith("s")) return parseFloat(raw) * 1e3;
|
|
3037
|
+
const n = parseFloat(raw);
|
|
3038
|
+
return Number.isFinite(n) ? n : 500;
|
|
2995
3039
|
}
|
|
2996
3040
|
};
|
|
2997
3041
|
|
|
@@ -4791,38 +4835,22 @@ var Modal = _Modal;
|
|
|
4791
4835
|
// src/ts/components/parallax.ts
|
|
4792
4836
|
var _defaults15 = {
|
|
4793
4837
|
responsiveThreshold: 0
|
|
4794
|
-
// breakpoint for swipeable
|
|
4795
4838
|
};
|
|
4796
|
-
var
|
|
4839
|
+
var Parallax = class _Parallax extends Component {
|
|
4797
4840
|
constructor(el, options) {
|
|
4798
4841
|
super(el, options, _Parallax);
|
|
4799
|
-
this._handleImageLoad = () => {
|
|
4800
|
-
this._updateParallax();
|
|
4801
|
-
};
|
|
4802
4842
|
this.el["Expressive_Parallax"] = this;
|
|
4803
4843
|
this.options = {
|
|
4804
4844
|
..._Parallax.defaults,
|
|
4805
4845
|
...options
|
|
4806
4846
|
};
|
|
4807
|
-
this.
|
|
4808
|
-
|
|
4809
|
-
if (!this._img) {
|
|
4810
|
-
console.error("Parallax: no <img> to move inside the .parallax element");
|
|
4811
|
-
return;
|
|
4847
|
+
if (!this.el.querySelector("img, video")) {
|
|
4848
|
+
console.error("Parallax: no <img> or <video> to move inside the .parallax element");
|
|
4812
4849
|
}
|
|
4813
|
-
this._updateParallax();
|
|
4814
|
-
this._setupEventHandlers();
|
|
4815
|
-
this._setupStyles();
|
|
4816
|
-
_Parallax._parallaxes.push(this);
|
|
4817
4850
|
}
|
|
4818
4851
|
static get defaults() {
|
|
4819
4852
|
return _defaults15;
|
|
4820
4853
|
}
|
|
4821
|
-
/**
|
|
4822
|
-
* Initializes instances of Parallax.
|
|
4823
|
-
* @param els HTML elements.
|
|
4824
|
-
* @param options Component options.
|
|
4825
|
-
*/
|
|
4826
4854
|
static init(els, options = {}) {
|
|
4827
4855
|
return super.init(els, options, _Parallax);
|
|
4828
4856
|
}
|
|
@@ -4830,84 +4858,9 @@ var _Parallax = class _Parallax extends Component {
|
|
|
4830
4858
|
return el["Expressive_Parallax"];
|
|
4831
4859
|
}
|
|
4832
4860
|
destroy() {
|
|
4833
|
-
const index = _Parallax._parallaxes.indexOf(this);
|
|
4834
|
-
if (index >= 0) _Parallax._parallaxes.splice(index, 1);
|
|
4835
|
-
if (this._img) this._img.style.transform = "";
|
|
4836
|
-
this._removeEventHandlers();
|
|
4837
4861
|
this.el["Expressive_Parallax"] = void 0;
|
|
4838
4862
|
}
|
|
4839
|
-
static _handleScroll() {
|
|
4840
|
-
for (let i = 0; i < _Parallax._parallaxes.length; i++) {
|
|
4841
|
-
const parallaxInstance = _Parallax._parallaxes[i];
|
|
4842
|
-
parallaxInstance._updateParallax.call(parallaxInstance);
|
|
4843
|
-
}
|
|
4844
|
-
}
|
|
4845
|
-
static _handleWindowResize() {
|
|
4846
|
-
for (let i = 0; i < _Parallax._parallaxes.length; i++) {
|
|
4847
|
-
const parallaxInstance = _Parallax._parallaxes[i];
|
|
4848
|
-
parallaxInstance._enabled = window.innerWidth > parallaxInstance.options.responsiveThreshold;
|
|
4849
|
-
}
|
|
4850
|
-
}
|
|
4851
|
-
_setupEventHandlers() {
|
|
4852
|
-
this._img?.addEventListener("load", this._handleImageLoad);
|
|
4853
|
-
if (_Parallax._parallaxes.length === 0) {
|
|
4854
|
-
if (!_Parallax._handleWindowResizeThrottled) {
|
|
4855
|
-
_Parallax._handleWindowResizeThrottled = Utils.throttle(_Parallax._handleWindowResize, 100);
|
|
4856
|
-
}
|
|
4857
|
-
window.addEventListener("scroll", _Parallax._requestScrollUpdate, { passive: true });
|
|
4858
|
-
window.addEventListener("resize", _Parallax._handleWindowResizeThrottled, { passive: true });
|
|
4859
|
-
}
|
|
4860
|
-
}
|
|
4861
|
-
_removeEventHandlers() {
|
|
4862
|
-
this._img?.removeEventListener("load", this._handleImageLoad);
|
|
4863
|
-
if (_Parallax._parallaxes.length === 0) {
|
|
4864
|
-
window.removeEventListener("scroll", _Parallax._requestScrollUpdate);
|
|
4865
|
-
window.removeEventListener("resize", _Parallax._handleWindowResizeThrottled);
|
|
4866
|
-
if (_Parallax._scrollFrame !== null) {
|
|
4867
|
-
cancelAnimationFrame(_Parallax._scrollFrame);
|
|
4868
|
-
_Parallax._scrollFrame = null;
|
|
4869
|
-
}
|
|
4870
|
-
}
|
|
4871
|
-
}
|
|
4872
|
-
_setupStyles() {
|
|
4873
|
-
if (this._img) this._img.style.opacity = "1";
|
|
4874
|
-
}
|
|
4875
|
-
_updateParallax() {
|
|
4876
|
-
const rect = this.el.getBoundingClientRect();
|
|
4877
|
-
const containerHeight = rect.height > 0 ? this.el.parentElement.offsetHeight : 500;
|
|
4878
|
-
const imgHeight = this._img.offsetHeight;
|
|
4879
|
-
const parallaxDist = imgHeight - containerHeight;
|
|
4880
|
-
const top = rect.top + window.scrollY - document.documentElement.clientTop;
|
|
4881
|
-
const bottom = top + containerHeight;
|
|
4882
|
-
const scrollTop = Utils.getDocumentScrollTop();
|
|
4883
|
-
const windowHeight = window.innerHeight;
|
|
4884
|
-
const windowBottom = scrollTop + windowHeight;
|
|
4885
|
-
const percentScrolled = (windowBottom - top) / (containerHeight + windowHeight);
|
|
4886
|
-
const parallax = parallaxDist * percentScrolled;
|
|
4887
|
-
if (!this._enabled) {
|
|
4888
|
-
this._img.style.transform = "";
|
|
4889
|
-
} else if (bottom > scrollTop && top < scrollTop + windowHeight) {
|
|
4890
|
-
this._img.style.transform = `translate3D(-50%, ${parallax}px, 0)`;
|
|
4891
|
-
}
|
|
4892
|
-
}
|
|
4893
|
-
};
|
|
4894
|
-
_Parallax._parallaxes = [];
|
|
4895
|
-
_Parallax._scrollFrame = null;
|
|
4896
|
-
/**
|
|
4897
|
-
* Coalesce scroll events onto animation frames.
|
|
4898
|
-
*
|
|
4899
|
-
* The handler reads layout and then writes a transform, so running it more
|
|
4900
|
-
* than once per frame is wasted work - and the 5ms throttle it replaces was
|
|
4901
|
-
* short enough to let several run per frame anyway.
|
|
4902
|
-
*/
|
|
4903
|
-
_Parallax._requestScrollUpdate = () => {
|
|
4904
|
-
if (_Parallax._scrollFrame !== null) return;
|
|
4905
|
-
_Parallax._scrollFrame = requestAnimationFrame(() => {
|
|
4906
|
-
_Parallax._scrollFrame = null;
|
|
4907
|
-
_Parallax._handleScroll();
|
|
4908
|
-
});
|
|
4909
4863
|
};
|
|
4910
|
-
var Parallax = _Parallax;
|
|
4911
4864
|
|
|
4912
4865
|
// src/ts/components/pushpin.ts
|
|
4913
4866
|
var _defaults16 = {
|
|
@@ -6147,60 +6100,96 @@ var _defaults21 = {
|
|
|
6147
6100
|
var _TapTarget = class _TapTarget extends Component {
|
|
6148
6101
|
constructor(el, options) {
|
|
6149
6102
|
super(el, options, _TapTarget);
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
this.
|
|
6153
|
-
this.
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
this._handleTargetToggle = () => {
|
|
6159
|
-
if (!this.isOpen) this.open();
|
|
6160
|
-
else this.close();
|
|
6161
|
-
};
|
|
6162
|
-
/*_handleOriginClick = () => {
|
|
6163
|
-
this.close();
|
|
6164
|
-
}*/
|
|
6165
|
-
this._handleResize = () => {
|
|
6166
|
-
this._calculatePositioning();
|
|
6167
|
-
};
|
|
6168
|
-
this._handleDocumentClick = (e) => {
|
|
6169
|
-
const target = e.target;
|
|
6170
|
-
if (!(target instanceof Element)) return;
|
|
6171
|
-
if (!this.originEl.contains(target) && !target.closest(".tap-target-wrapper")) {
|
|
6172
|
-
this.close();
|
|
6173
|
-
}
|
|
6174
|
-
};
|
|
6103
|
+
this.wrapper = null;
|
|
6104
|
+
this.waveEl = null;
|
|
6105
|
+
this.contentEl = null;
|
|
6106
|
+
this._createdWrapper = false;
|
|
6107
|
+
this._createdWave = false;
|
|
6108
|
+
this._usePopover = false;
|
|
6109
|
+
this._liftedStatic = false;
|
|
6110
|
+
this._opening = false;
|
|
6175
6111
|
/**
|
|
6176
6112
|
* Open Tap Target.
|
|
6177
6113
|
*/
|
|
6178
6114
|
this.open = () => {
|
|
6179
|
-
if (this.isOpen) return;
|
|
6115
|
+
if (this.isOpen || !this.originEl || !this.wrapper) return;
|
|
6116
|
+
_TapTarget._taptargets.forEach((other) => {
|
|
6117
|
+
if (other !== this) other.close();
|
|
6118
|
+
});
|
|
6119
|
+
this._calculatePositioning();
|
|
6180
6120
|
if (typeof this.options.onOpen === "function") {
|
|
6181
6121
|
this.options.onOpen.call(this, this.originEl);
|
|
6182
6122
|
}
|
|
6183
6123
|
this.isOpen = true;
|
|
6184
6124
|
this.wrapper.classList.add("open");
|
|
6185
|
-
this.
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6125
|
+
this.originEl.setAttribute("aria-expanded", "true");
|
|
6126
|
+
if (!this._usePopover) {
|
|
6127
|
+
this.originEl.classList.add("tap-target-origin");
|
|
6128
|
+
if (getComputedStyle(this.originEl).position === "static") {
|
|
6129
|
+
this.originEl.style.position = "relative";
|
|
6130
|
+
this._liftedStatic = true;
|
|
6131
|
+
}
|
|
6132
|
+
}
|
|
6133
|
+
if (this._usePopover) {
|
|
6134
|
+
this._opening = true;
|
|
6135
|
+
try {
|
|
6136
|
+
this.wrapper.showPopover();
|
|
6137
|
+
} catch {
|
|
6138
|
+
}
|
|
6139
|
+
requestAnimationFrame(() => {
|
|
6140
|
+
this._opening = false;
|
|
6141
|
+
});
|
|
6142
|
+
}
|
|
6189
6143
|
};
|
|
6190
6144
|
/**
|
|
6191
6145
|
* Close Tap Target.
|
|
6192
6146
|
*/
|
|
6193
6147
|
this.close = () => {
|
|
6194
6148
|
if (!this.isOpen) return;
|
|
6195
|
-
if (typeof this.options.onClose === "function") {
|
|
6149
|
+
if (typeof this.options.onClose === "function" && this.originEl) {
|
|
6196
6150
|
this.options.onClose.call(this, this.originEl);
|
|
6197
6151
|
}
|
|
6198
6152
|
this.isOpen = false;
|
|
6199
|
-
this.wrapper
|
|
6200
|
-
this.
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6153
|
+
this.wrapper?.classList.remove("open");
|
|
6154
|
+
this.originEl?.setAttribute("aria-expanded", "false");
|
|
6155
|
+
this.originEl?.classList.remove("tap-target-origin");
|
|
6156
|
+
if (this._liftedStatic && this.originEl) {
|
|
6157
|
+
this.originEl.style.position = "";
|
|
6158
|
+
this._liftedStatic = false;
|
|
6159
|
+
}
|
|
6160
|
+
if (this._usePopover && this.wrapper) {
|
|
6161
|
+
try {
|
|
6162
|
+
this.wrapper.hidePopover();
|
|
6163
|
+
} catch {
|
|
6164
|
+
}
|
|
6165
|
+
}
|
|
6166
|
+
};
|
|
6167
|
+
// Built once per instance; a fresh throttle per event never fires.
|
|
6168
|
+
this._handleThrottledResize = Utils.throttle(() => this._handleResize(), 200);
|
|
6169
|
+
this._handleOriginKeydown = (e) => {
|
|
6170
|
+
if (Utils.keys.ENTER.includes(e.key) || e.key === " ") {
|
|
6171
|
+
e.preventDefault();
|
|
6172
|
+
this._handleTargetToggle();
|
|
6173
|
+
}
|
|
6174
|
+
};
|
|
6175
|
+
this._handleTargetToggle = () => {
|
|
6176
|
+
if (!this.isOpen) this.open();
|
|
6177
|
+
else this.close();
|
|
6178
|
+
};
|
|
6179
|
+
this._handleResize = () => {
|
|
6180
|
+
if (this.isOpen) this._calculatePositioning();
|
|
6181
|
+
};
|
|
6182
|
+
this._handlePopoverToggle = (e) => {
|
|
6183
|
+
const state = "newState" in e ? String(e.newState) : "";
|
|
6184
|
+
if (state === "open") return;
|
|
6185
|
+
if (this._opening) {
|
|
6186
|
+
try {
|
|
6187
|
+
this.wrapper?.showPopover();
|
|
6188
|
+
} catch {
|
|
6189
|
+
}
|
|
6190
|
+
return;
|
|
6191
|
+
}
|
|
6192
|
+
if (this.isOpen) this.close();
|
|
6204
6193
|
};
|
|
6205
6194
|
this.el["Expressive_TapTarget"] = this;
|
|
6206
6195
|
this.options = {
|
|
@@ -6213,7 +6202,6 @@ var _TapTarget = class _TapTarget extends Component {
|
|
|
6213
6202
|
console.error(`TapTarget: no element with id "${el.dataset.target ?? ""}" to attach to`);
|
|
6214
6203
|
return;
|
|
6215
6204
|
}
|
|
6216
|
-
this.originEl.tabIndex = 0;
|
|
6217
6205
|
this._setup();
|
|
6218
6206
|
this._calculatePositioning();
|
|
6219
6207
|
this._setupEventHandlers();
|
|
@@ -6222,11 +6210,6 @@ var _TapTarget = class _TapTarget extends Component {
|
|
|
6222
6210
|
static get defaults() {
|
|
6223
6211
|
return _defaults21;
|
|
6224
6212
|
}
|
|
6225
|
-
/**
|
|
6226
|
-
* Initializes instances of TapTarget.
|
|
6227
|
-
* @param els HTML elements.
|
|
6228
|
-
* @param options Component options.
|
|
6229
|
-
*/
|
|
6230
6213
|
static init(els, options = {}) {
|
|
6231
6214
|
return super.init(els, options, _TapTarget);
|
|
6232
6215
|
}
|
|
@@ -6236,116 +6219,95 @@ var _TapTarget = class _TapTarget extends Component {
|
|
|
6236
6219
|
destroy() {
|
|
6237
6220
|
this.close();
|
|
6238
6221
|
this._removeEventHandlers();
|
|
6222
|
+
this._teardownDom();
|
|
6239
6223
|
this.el["Expressive_TapTarget"] = void 0;
|
|
6240
6224
|
const index = _TapTarget._taptargets.indexOf(this);
|
|
6241
|
-
if (index >= 0)
|
|
6242
|
-
_TapTarget._taptargets.splice(index, 1);
|
|
6243
|
-
}
|
|
6244
|
-
}
|
|
6245
|
-
_setupEventHandlers() {
|
|
6246
|
-
if (!this.originEl) return;
|
|
6247
|
-
this.originEl.addEventListener("click", this._handleTargetToggle);
|
|
6248
|
-
this.originEl.addEventListener("keypress", this._handleKeyboardInteraction, true);
|
|
6249
|
-
window.addEventListener("resize", this._handleThrottledResize);
|
|
6250
|
-
}
|
|
6251
|
-
_removeEventHandlers() {
|
|
6252
|
-
if (!this.originEl) return;
|
|
6253
|
-
this.originEl.removeEventListener("click", this._handleTargetToggle);
|
|
6254
|
-
this.originEl.removeEventListener("keypress", this._handleKeyboardInteraction, true);
|
|
6255
|
-
window.removeEventListener("resize", this._handleThrottledResize);
|
|
6225
|
+
if (index >= 0) _TapTarget._taptargets.splice(index, 1);
|
|
6256
6226
|
}
|
|
6257
6227
|
_setup() {
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
this.contentEl = this.el.querySelector(".tap-target-content");
|
|
6263
|
-
if (!this.wrapper.classList.contains(".tap-target-wrapper")) {
|
|
6228
|
+
const parent = this.el.parentElement;
|
|
6229
|
+
if (parent?.classList.contains("tap-target-wrapper")) {
|
|
6230
|
+
this.wrapper = parent;
|
|
6231
|
+
} else {
|
|
6264
6232
|
this.wrapper = document.createElement("div");
|
|
6265
6233
|
this.wrapper.classList.add("tap-target-wrapper");
|
|
6266
6234
|
this.el.before(this.wrapper);
|
|
6267
6235
|
this.wrapper.append(this.el);
|
|
6236
|
+
this._createdWrapper = true;
|
|
6268
6237
|
}
|
|
6238
|
+
this.contentEl = this.el.querySelector(".tap-target-content");
|
|
6269
6239
|
if (!this.contentEl) {
|
|
6270
6240
|
this.contentEl = document.createElement("div");
|
|
6271
|
-
this.contentEl.
|
|
6241
|
+
this.contentEl.className = "tap-target-content";
|
|
6242
|
+
while (this.el.firstChild) this.contentEl.append(this.el.firstChild);
|
|
6272
6243
|
this.el.append(this.contentEl);
|
|
6273
6244
|
}
|
|
6245
|
+
this.waveEl = this.el.querySelector(".tap-target-wave") ?? this.wrapper.querySelector(".tap-target-wave");
|
|
6274
6246
|
if (!this.waveEl) {
|
|
6275
6247
|
this.waveEl = document.createElement("div");
|
|
6276
|
-
this.waveEl.
|
|
6277
|
-
this.
|
|
6248
|
+
this.waveEl.className = "tap-target-wave";
|
|
6249
|
+
this._createdWave = true;
|
|
6250
|
+
}
|
|
6251
|
+
this.el.prepend(this.waveEl);
|
|
6252
|
+
this.el.setAttribute("role", "dialog");
|
|
6253
|
+
this._labelFromHeading();
|
|
6254
|
+
const origin = this.originEl;
|
|
6255
|
+
origin.setAttribute("aria-expanded", "false");
|
|
6256
|
+
origin.setAttribute("aria-controls", this.el.id || this._ensureId());
|
|
6257
|
+
this._usePopover = typeof this.wrapper.showPopover === "function";
|
|
6258
|
+
if (this._usePopover) {
|
|
6259
|
+
this.wrapper.setAttribute("popover", "auto");
|
|
6260
|
+
}
|
|
6261
|
+
}
|
|
6262
|
+
_ensureId() {
|
|
6263
|
+
if (!this.el.id) this.el.id = `tap-target-${Utils.guid()}`;
|
|
6264
|
+
return this.el.id;
|
|
6265
|
+
}
|
|
6266
|
+
_labelFromHeading() {
|
|
6267
|
+
const heading = this.contentEl?.querySelector("h1, h2, h3, h4, h5, h6");
|
|
6268
|
+
if (!heading) return;
|
|
6269
|
+
if (!heading.id) heading.id = `tap-target-title-${Utils.guid()}`;
|
|
6270
|
+
this.el.setAttribute("aria-labelledby", heading.id);
|
|
6271
|
+
}
|
|
6272
|
+
_teardownDom() {
|
|
6273
|
+
if (this._createdWave) this.waveEl?.remove();
|
|
6274
|
+
if (this._createdWrapper && this.wrapper) {
|
|
6275
|
+
this.wrapper.before(this.el);
|
|
6276
|
+
this.wrapper.remove();
|
|
6277
|
+
}
|
|
6278
|
+
this.wrapper = null;
|
|
6279
|
+
this.waveEl = null;
|
|
6280
|
+
}
|
|
6281
|
+
_setupEventHandlers() {
|
|
6282
|
+
if (!this.originEl) return;
|
|
6283
|
+
this.originEl.addEventListener("click", this._handleTargetToggle);
|
|
6284
|
+
if (!this.originEl.matches('button, a, [tabindex], .btn, [role="button"]')) {
|
|
6285
|
+
this.originEl.tabIndex = 0;
|
|
6286
|
+
this.originEl.addEventListener("keydown", this._handleOriginKeydown);
|
|
6278
6287
|
}
|
|
6288
|
+
this.wrapper?.addEventListener("toggle", this._handlePopoverToggle);
|
|
6289
|
+
window.addEventListener("resize", this._handleThrottledResize, { passive: true });
|
|
6279
6290
|
}
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
};
|
|
6291
|
+
_removeEventHandlers() {
|
|
6292
|
+
if (!this.originEl) return;
|
|
6293
|
+
this.originEl.removeEventListener("click", this._handleTargetToggle);
|
|
6294
|
+
this.originEl.removeEventListener("keydown", this._handleOriginKeydown);
|
|
6295
|
+
this.wrapper?.removeEventListener("toggle", this._handlePopoverToggle);
|
|
6296
|
+
window.removeEventListener("resize", this._handleThrottledResize);
|
|
6287
6297
|
}
|
|
6288
6298
|
_calculatePositioning() {
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
const originHeight = this.originEl.offsetHeight;
|
|
6302
|
-
const originOffset = this._offset(this.originEl);
|
|
6303
|
-
const originTop = isFixed ? originOffset.top - Utils.getDocumentScrollTop() : originOffset.top;
|
|
6304
|
-
const originLeft = isFixed ? originOffset.left - Utils.getDocumentScrollLeft() : originOffset.left;
|
|
6305
|
-
const windowWidth = window.innerWidth;
|
|
6306
|
-
const windowHeight = window.innerHeight;
|
|
6307
|
-
const scrollBarWidth = windowWidth - document.documentElement.clientWidth;
|
|
6308
|
-
const centerX = windowWidth / 2;
|
|
6309
|
-
const centerY = windowHeight / 2;
|
|
6310
|
-
const isLeft = originLeft <= centerX;
|
|
6311
|
-
const isRight = originLeft > centerX;
|
|
6312
|
-
const isTop = originTop <= centerY;
|
|
6313
|
-
const isBottom = originTop > centerY;
|
|
6314
|
-
const isCenterX = originLeft >= windowWidth * 0.25 && originLeft <= windowWidth * 0.75;
|
|
6315
|
-
const tapTargetWidth = this.el.offsetWidth;
|
|
6316
|
-
const tapTargetHeight = this.el.offsetHeight;
|
|
6317
|
-
const tapTargetTop = originTop + originHeight / 2 - tapTargetHeight / 2;
|
|
6318
|
-
const tapTargetLeft = originLeft + originWidth / 2 - tapTargetWidth / 2;
|
|
6319
|
-
const tapTargetPosition = isFixed ? "fixed" : "absolute";
|
|
6320
|
-
const tapTargetTextWidth = isCenterX ? tapTargetWidth : tapTargetWidth / 2 + originWidth;
|
|
6321
|
-
const tapTargetTextHeight = tapTargetHeight / 2;
|
|
6322
|
-
const tapTargetTextTop = isTop ? tapTargetHeight / 2 : 0;
|
|
6323
|
-
const tapTargetTextBottom = 0;
|
|
6324
|
-
const tapTargetTextLeft = isLeft && !isCenterX ? tapTargetWidth / 2 - originWidth : 0;
|
|
6325
|
-
const tapTargetTextRight = 0;
|
|
6326
|
-
const tapTargetTextPadding = originWidth;
|
|
6327
|
-
const tapTargetTextAlign = isBottom ? "bottom" : "top";
|
|
6328
|
-
const tapTargetWaveWidth = originWidth > originHeight ? originWidth * 2 : originWidth * 2;
|
|
6329
|
-
const tapTargetWaveHeight = tapTargetWaveWidth;
|
|
6330
|
-
const tapTargetWaveTop = tapTargetHeight / 2 - tapTargetWaveHeight / 2;
|
|
6331
|
-
const tapTargetWaveLeft = tapTargetWidth / 2 - tapTargetWaveWidth / 2;
|
|
6332
|
-
this.wrapper.style.top = isTop ? tapTargetTop + "px" : "";
|
|
6333
|
-
this.wrapper.style.right = isRight ? windowWidth - tapTargetLeft - tapTargetWidth - scrollBarWidth + "px" : "";
|
|
6334
|
-
this.wrapper.style.bottom = isBottom ? windowHeight - tapTargetTop - tapTargetHeight + "px" : "";
|
|
6335
|
-
this.wrapper.style.left = isLeft ? tapTargetLeft + "px" : "";
|
|
6336
|
-
this.wrapper.style.position = tapTargetPosition;
|
|
6337
|
-
this.contentEl.style.width = tapTargetTextWidth + "px";
|
|
6338
|
-
this.contentEl.style.height = tapTargetTextHeight + "px";
|
|
6339
|
-
this.contentEl.style.top = tapTargetTextTop + "px";
|
|
6340
|
-
this.contentEl.style.right = tapTargetTextRight + "px";
|
|
6341
|
-
this.contentEl.style.bottom = tapTargetTextBottom + "px";
|
|
6342
|
-
this.contentEl.style.left = tapTargetTextLeft + "px";
|
|
6343
|
-
this.contentEl.style.padding = tapTargetTextPadding + "px";
|
|
6344
|
-
this.contentEl.style.verticalAlign = tapTargetTextAlign;
|
|
6345
|
-
this.waveEl.style.top = tapTargetWaveTop + "px";
|
|
6346
|
-
this.waveEl.style.left = tapTargetWaveLeft + "px";
|
|
6347
|
-
this.waveEl.style.width = tapTargetWaveWidth + "px";
|
|
6348
|
-
this.waveEl.style.height = tapTargetWaveHeight + "px";
|
|
6299
|
+
if (!this.originEl || !this.wrapper) return;
|
|
6300
|
+
const rect = this.originEl.getBoundingClientRect();
|
|
6301
|
+
const x = rect.left + rect.width / 2;
|
|
6302
|
+
const y = rect.top + rect.height / 2;
|
|
6303
|
+
const size = Math.max(rect.width, rect.height, 1);
|
|
6304
|
+
this.wrapper.style.setProperty("--md-comp-tap-target-x", `${x}px`);
|
|
6305
|
+
this.wrapper.style.setProperty("--md-comp-tap-target-y", `${y}px`);
|
|
6306
|
+
this.wrapper.style.setProperty("--md-comp-tap-target-origin-size", `${size}px`);
|
|
6307
|
+
const vertical = y <= window.innerHeight / 2 ? "top" : "bottom";
|
|
6308
|
+
const onCenter = x >= window.innerWidth * 0.25 && x <= window.innerWidth * 0.75;
|
|
6309
|
+
const horizontal = onCenter ? "center" : x <= window.innerWidth / 2 ? "left" : "right";
|
|
6310
|
+
this.wrapper.dataset.edge = `${vertical}-${horizontal}`;
|
|
6349
6311
|
}
|
|
6350
6312
|
};
|
|
6351
6313
|
_TapTarget._taptargets = [];
|
|
@@ -7089,7 +7051,7 @@ var _Toast = class _Toast {
|
|
|
7089
7051
|
close.className = "circle";
|
|
7090
7052
|
close.setAttribute("aria-label", "Dismiss");
|
|
7091
7053
|
const icon = document.createElement("i");
|
|
7092
|
-
icon.className = "material-
|
|
7054
|
+
icon.className = "material-symbols";
|
|
7093
7055
|
icon.setAttribute("aria-hidden", "true");
|
|
7094
7056
|
icon.textContent = "close";
|
|
7095
7057
|
close.appendChild(icon);
|
|
@@ -7454,7 +7416,7 @@ function AutoInit(context = document.body, options) {
|
|
|
7454
7416
|
}
|
|
7455
7417
|
|
|
7456
7418
|
// src/ts/index.ts
|
|
7457
|
-
var version = "0.
|
|
7419
|
+
var version = "0.3.0";
|
|
7458
7420
|
if (typeof document !== "undefined") {
|
|
7459
7421
|
document.addEventListener("keydown", Utils.docHandleKeydown, true);
|
|
7460
7422
|
document.addEventListener("keyup", Utils.docHandleKeyup, true);
|