@expressivecss/expressive 0.1.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 +1088 -356
- 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 +778 -746
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +778 -746
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +10 -10
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +778 -746
- package/dist/js/expressive.mjs.map +4 -4
- package/dist/types/behaviors/dialogs.d.ts +25 -0
- 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 +2 -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/_modal.scss +67 -3
- 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/src/sass/utilities/_helpers.scss +10 -0
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,
|
|
@@ -1842,6 +1842,74 @@ var Range = class _Range extends Component {
|
|
|
1842
1842
|
}
|
|
1843
1843
|
};
|
|
1844
1844
|
|
|
1845
|
+
// src/ts/behaviors/dialogs.ts
|
|
1846
|
+
var _Dialogs = class _Dialogs {
|
|
1847
|
+
static Init() {
|
|
1848
|
+
Utils.onDocumentReady(() => {
|
|
1849
|
+
document.addEventListener("pointerdown", _Dialogs._onPointerDown, { passive: true });
|
|
1850
|
+
document.addEventListener("pointerup", _Dialogs._onPointerUp, { passive: true });
|
|
1851
|
+
document.addEventListener("pointercancel", _Dialogs._onPointerCancel, { passive: true });
|
|
1852
|
+
});
|
|
1853
|
+
}
|
|
1854
|
+
static _onPointerDown(event) {
|
|
1855
|
+
if (!_Dialogs._isPrimaryPress(event)) {
|
|
1856
|
+
_Dialogs._down = null;
|
|
1857
|
+
return;
|
|
1858
|
+
}
|
|
1859
|
+
const dialog = _Dialogs._backdropDialog(event);
|
|
1860
|
+
if (!dialog || !_Dialogs._lightDismissible(dialog) || !_Dialogs._outside(event, dialog)) {
|
|
1861
|
+
_Dialogs._down = null;
|
|
1862
|
+
return;
|
|
1863
|
+
}
|
|
1864
|
+
_Dialogs._down = { dialog, pointerId: event.pointerId };
|
|
1865
|
+
}
|
|
1866
|
+
static _onPointerUp(event) {
|
|
1867
|
+
const started = _Dialogs._down;
|
|
1868
|
+
_Dialogs._down = null;
|
|
1869
|
+
if (!started || started.pointerId !== event.pointerId) return;
|
|
1870
|
+
if (!event.isPrimary) return;
|
|
1871
|
+
if (!started.dialog.isConnected || !started.dialog.open) return;
|
|
1872
|
+
if (!_Dialogs._lightDismissible(started.dialog)) return;
|
|
1873
|
+
if (_Dialogs._backdropDialog(event) !== started.dialog) return;
|
|
1874
|
+
if (_Dialogs._outside(event, started.dialog)) {
|
|
1875
|
+
started.dialog.close();
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
static _onPointerCancel() {
|
|
1879
|
+
_Dialogs._down = null;
|
|
1880
|
+
}
|
|
1881
|
+
/** Backdrop hits retarget to the dialog itself, never a child. */
|
|
1882
|
+
static _backdropDialog(event) {
|
|
1883
|
+
const target = event.target;
|
|
1884
|
+
if (!(target instanceof HTMLDialogElement) || !target.open) return null;
|
|
1885
|
+
return target;
|
|
1886
|
+
}
|
|
1887
|
+
static _outside(event, dialog) {
|
|
1888
|
+
const rect = dialog.getBoundingClientRect();
|
|
1889
|
+
return event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom;
|
|
1890
|
+
}
|
|
1891
|
+
static _isPrimaryPress(event) {
|
|
1892
|
+
if (!event.isPrimary) return false;
|
|
1893
|
+
return event.pointerType !== "mouse" || event.button === 0;
|
|
1894
|
+
}
|
|
1895
|
+
static _lightDismissible(dialog) {
|
|
1896
|
+
const value = _Dialogs._closedBy(dialog);
|
|
1897
|
+
if (value === "none" || value === "closerequest") return false;
|
|
1898
|
+
if (value === "any" && "closedBy" in HTMLDialogElement.prototype) return false;
|
|
1899
|
+
return true;
|
|
1900
|
+
}
|
|
1901
|
+
// Read the attribute only. The IDL default for an unset closedby is
|
|
1902
|
+
// "closerequest" (Escape, no light dismiss) — treating that as an
|
|
1903
|
+
// author opt-out made every dialog undismissable from the scrim.
|
|
1904
|
+
static _closedBy(dialog) {
|
|
1905
|
+
const attr = dialog.getAttribute("closedby");
|
|
1906
|
+
if (attr === "any" || attr === "closerequest" || attr === "none") return attr;
|
|
1907
|
+
return null;
|
|
1908
|
+
}
|
|
1909
|
+
};
|
|
1910
|
+
_Dialogs._down = null;
|
|
1911
|
+
var Dialogs = _Dialogs;
|
|
1912
|
+
|
|
1845
1913
|
// src/ts/behaviors/forms.ts
|
|
1846
1914
|
var Forms = class _Forms {
|
|
1847
1915
|
/**
|
|
@@ -1996,83 +2064,76 @@ var _defaults6 = {
|
|
|
1996
2064
|
var FloatingActionButton = class _FloatingActionButton extends Component {
|
|
1997
2065
|
constructor(el, options) {
|
|
1998
2066
|
super(el, options, _FloatingActionButton);
|
|
1999
|
-
/** Toolbar-mode backdrop, kept so closing can take it back out. */
|
|
2000
|
-
this._backdrop = null;
|
|
2001
|
-
this._handleFABClick = () => {
|
|
2002
|
-
this._handleFABToggle();
|
|
2003
|
-
};
|
|
2004
|
-
this._handleFABKeyPress = (e) => {
|
|
2005
|
-
if (Utils.keys.ENTER.includes(e.key)) {
|
|
2006
|
-
this._handleFABToggle();
|
|
2007
|
-
}
|
|
2008
|
-
};
|
|
2009
|
-
this._handleFABToggle = () => {
|
|
2010
|
-
if (this.isOpen) {
|
|
2011
|
-
this.close();
|
|
2012
|
-
} else {
|
|
2013
|
-
this.open();
|
|
2014
|
-
}
|
|
2015
|
-
};
|
|
2016
|
-
this._handleDocumentClick = (e) => {
|
|
2017
|
-
const elem = e.target;
|
|
2018
|
-
if (elem !== this._menu) this.close();
|
|
2019
|
-
};
|
|
2020
2067
|
/**
|
|
2021
2068
|
* Open FAB.
|
|
2022
2069
|
*/
|
|
2023
2070
|
this.open = () => {
|
|
2024
2071
|
if (this.isOpen) return;
|
|
2025
|
-
if (this.options.toolbarEnabled) this._animateInToolbar();
|
|
2026
|
-
else this._animateInFAB();
|
|
2027
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);
|
|
2028
2077
|
};
|
|
2029
2078
|
/**
|
|
2030
2079
|
* Close FAB.
|
|
2031
2080
|
*/
|
|
2032
2081
|
this.close = () => {
|
|
2033
2082
|
if (!this.isOpen) return;
|
|
2034
|
-
if (this.options.toolbarEnabled) {
|
|
2035
|
-
window.removeEventListener("scroll", this.close, true);
|
|
2036
|
-
document.body.removeEventListener("click", this._handleDocumentClick, true);
|
|
2037
|
-
this._animateOutToolbar();
|
|
2038
|
-
} else {
|
|
2039
|
-
this._animateOutFAB();
|
|
2040
|
-
}
|
|
2041
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();
|
|
2042
2106
|
};
|
|
2043
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;
|
|
2044
2111
|
this.options = {
|
|
2045
2112
|
..._FloatingActionButton.defaults,
|
|
2046
|
-
...options
|
|
2113
|
+
...options,
|
|
2114
|
+
direction: options.direction ?? fromMarkup ?? _FloatingActionButton.defaults.direction,
|
|
2115
|
+
hoverEnabled: !clickToToggle,
|
|
2116
|
+
toolbarEnabled: toolbar
|
|
2047
2117
|
};
|
|
2048
2118
|
this.isOpen = false;
|
|
2049
|
-
this._anchor = this.el.querySelector("a, button");
|
|
2050
|
-
this._menu = this.el.querySelector("ul");
|
|
2051
|
-
this._floatingBtns = Array.from(this.el.querySelectorAll("ul .btn-floating"));
|
|
2052
|
-
this._floatingBtnsReverse = this._floatingBtns.reverse();
|
|
2053
|
-
this.offsetY = 0;
|
|
2054
|
-
this.offsetX = 0;
|
|
2119
|
+
this._anchor = this.el.querySelector(":scope > a, :scope > button");
|
|
2120
|
+
this._menu = this.el.querySelector("ul, menu");
|
|
2055
2121
|
this.el.classList.add(`direction-${this.options.direction}`);
|
|
2056
|
-
if (
|
|
2057
|
-
if (
|
|
2058
|
-
if (this.
|
|
2059
|
-
this.
|
|
2060
|
-
|
|
2061
|
-
this.
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
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");
|
|
2066
2132
|
this._setupEventHandlers();
|
|
2067
2133
|
}
|
|
2068
2134
|
static get defaults() {
|
|
2069
2135
|
return _defaults6;
|
|
2070
2136
|
}
|
|
2071
|
-
/**
|
|
2072
|
-
* Initializes instances of FloatingActionButton.
|
|
2073
|
-
* @param els HTML elements.
|
|
2074
|
-
* @param options Component options.
|
|
2075
|
-
*/
|
|
2076
2137
|
static init(els, options = {}) {
|
|
2077
2138
|
return super.init(els, options, _FloatingActionButton);
|
|
2078
2139
|
}
|
|
@@ -2080,229 +2141,109 @@ var FloatingActionButton = class _FloatingActionButton extends Component {
|
|
|
2080
2141
|
return el["Expressive_FloatingActionButton"];
|
|
2081
2142
|
}
|
|
2082
2143
|
destroy() {
|
|
2083
|
-
this._removeEventHandlers();
|
|
2084
2144
|
this.close();
|
|
2145
|
+
this._removeEventHandlers();
|
|
2085
2146
|
this.el["Expressive_FloatingActionButton"] = void 0;
|
|
2086
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
|
+
}
|
|
2087
2156
|
_setupEventHandlers() {
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
this.
|
|
2091
|
-
} else {
|
|
2092
|
-
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);
|
|
2093
2160
|
}
|
|
2094
|
-
this.el.addEventListener("keypress", this._handleFABKeyPress);
|
|
2095
2161
|
}
|
|
2096
2162
|
_removeEventHandlers() {
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
this.el.removeEventListener("mouseleave", this.close);
|
|
2100
|
-
} else {
|
|
2101
|
-
this.el.removeEventListener("click", this._handleFABClick);
|
|
2102
|
-
}
|
|
2103
|
-
this.el.removeEventListener("keypress", this._handleFABKeyPress);
|
|
2104
|
-
}
|
|
2105
|
-
_animateInFAB() {
|
|
2106
|
-
this.el.classList.add("active");
|
|
2107
|
-
if (this._menu) this._menu.ariaExpanded = "true";
|
|
2108
|
-
const delayIncrement = 40;
|
|
2109
|
-
const duration = 275;
|
|
2110
|
-
this._floatingBtnsReverse.forEach((el, index) => {
|
|
2111
|
-
const delay = delayIncrement * index;
|
|
2112
|
-
el.style.transition = "none";
|
|
2113
|
-
el.style.opacity = "0";
|
|
2114
|
-
el.style.transform = `translate(${this.offsetX}px, ${this.offsetY}px) scale(0.4)`;
|
|
2115
|
-
setTimeout(() => {
|
|
2116
|
-
el.style.opacity = "0.4";
|
|
2117
|
-
setTimeout(() => {
|
|
2118
|
-
el.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
|
|
2119
|
-
el.style.opacity = "1";
|
|
2120
|
-
el.style.transform = "translate(0, 0) scale(1)";
|
|
2121
|
-
el.tabIndex = 0;
|
|
2122
|
-
}, 1);
|
|
2123
|
-
}, delay);
|
|
2124
|
-
});
|
|
2125
|
-
}
|
|
2126
|
-
_animateOutFAB() {
|
|
2127
|
-
const duration = 175;
|
|
2128
|
-
setTimeout(() => {
|
|
2129
|
-
this.el.classList.remove("active");
|
|
2130
|
-
if (this._menu) this._menu.ariaExpanded = "false";
|
|
2131
|
-
}, duration);
|
|
2132
|
-
this._floatingBtnsReverse.forEach((el) => {
|
|
2133
|
-
el.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
|
|
2134
|
-
el.style.opacity = "0";
|
|
2135
|
-
el.style.transform = `translate(${this.offsetX}px, ${this.offsetY}px) scale(0.4)`;
|
|
2136
|
-
el.tabIndex = -1;
|
|
2137
|
-
});
|
|
2138
|
-
}
|
|
2139
|
-
_animateInToolbar() {
|
|
2140
|
-
const windowWidth = window.innerWidth;
|
|
2141
|
-
const windowHeight = window.innerHeight;
|
|
2142
|
-
const btnRect = this.el.getBoundingClientRect();
|
|
2143
|
-
const fabColor = getComputedStyle(this._anchor).backgroundColor;
|
|
2144
|
-
const backdrop = document.createElement("div");
|
|
2145
|
-
backdrop.classList.add("fab-backdrop");
|
|
2146
|
-
backdrop.style.backgroundColor = fabColor;
|
|
2147
|
-
this._anchor.append(backdrop);
|
|
2148
|
-
this._backdrop = backdrop;
|
|
2149
|
-
const backdropWidth = backdrop.clientWidth;
|
|
2150
|
-
const scaleFactor = backdropWidth > 0 ? windowWidth / backdropWidth : 1;
|
|
2151
|
-
this.offsetX = btnRect.left - windowWidth / 2 + btnRect.width / 2;
|
|
2152
|
-
this.offsetY = windowHeight - btnRect.bottom;
|
|
2153
|
-
this.btnBottom = btnRect.bottom;
|
|
2154
|
-
this.btnLeft = btnRect.left;
|
|
2155
|
-
this.btnWidth = btnRect.width;
|
|
2156
|
-
this.el.classList.add("active");
|
|
2157
|
-
this.el.style.textAlign = "center";
|
|
2158
|
-
this.el.style.width = "100%";
|
|
2159
|
-
this.el.style.bottom = "0";
|
|
2160
|
-
this.el.style.left = "0";
|
|
2161
|
-
this.el.style.transform = "translateX(" + this.offsetX + "px)";
|
|
2162
|
-
this.el.style.transition = "none";
|
|
2163
|
-
if (this._menu) this._menu.ariaExpanded = "true";
|
|
2164
|
-
this._anchor.style.transform = `translateY(${this.offsetY}px)`;
|
|
2165
|
-
this._anchor.style.transition = "none";
|
|
2166
|
-
setTimeout(() => {
|
|
2167
|
-
this.el.style.transform = "";
|
|
2168
|
-
this.el.style.transition = "transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s";
|
|
2169
|
-
this._anchor.style.overflow = "visible";
|
|
2170
|
-
this._anchor.style.transform = "";
|
|
2171
|
-
this._anchor.style.transition = "transform .2s";
|
|
2172
|
-
setTimeout(() => {
|
|
2173
|
-
this.el.style.overflow = "hidden";
|
|
2174
|
-
this.el.style.backgroundColor = fabColor;
|
|
2175
|
-
backdrop.style.transform = "scale(" + scaleFactor + ")";
|
|
2176
|
-
backdrop.style.transition = "transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)";
|
|
2177
|
-
this._menu.querySelectorAll("li > a").forEach((a) => {
|
|
2178
|
-
a.style.opacity = "1";
|
|
2179
|
-
a.tabIndex = 0;
|
|
2180
|
-
});
|
|
2181
|
-
window.addEventListener("scroll", this.close, true);
|
|
2182
|
-
document.body.addEventListener("click", this._handleDocumentClick, true);
|
|
2183
|
-
}, 100);
|
|
2184
|
-
}, 0);
|
|
2163
|
+
this.el.removeEventListener("click", this._handleFABClick);
|
|
2164
|
+
this._anchor?.removeEventListener("keydown", this._handleAnchorKeydown);
|
|
2185
2165
|
}
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
* Closing used to only unbind the listeners, leaving the FAB stretched
|
|
2190
|
-
* across the viewport with its backdrop still in the DOM - and a fresh
|
|
2191
|
-
* backdrop appended on every subsequent open.
|
|
2192
|
-
*/
|
|
2193
|
-
_animateOutToolbar() {
|
|
2194
|
-
const backdrop = this._backdrop;
|
|
2195
|
-
this._backdrop = null;
|
|
2196
|
-
this._menu?.querySelectorAll("li > a").forEach((a) => {
|
|
2197
|
-
a.style.opacity = "";
|
|
2198
|
-
a.tabIndex = -1;
|
|
2199
|
-
});
|
|
2200
|
-
if (backdrop) {
|
|
2201
|
-
backdrop.style.transition = "transform .2s";
|
|
2202
|
-
backdrop.style.transform = "scale(0)";
|
|
2203
|
-
}
|
|
2204
|
-
this.el.style.overflow = "";
|
|
2205
|
-
this.el.style.backgroundColor = "";
|
|
2206
|
-
this.el.style.transition = "transform .2s";
|
|
2207
|
-
this.el.style.transform = `translateX(${this.offsetX}px)`;
|
|
2208
|
-
this._anchor.style.transition = "transform .2s";
|
|
2209
|
-
this._anchor.style.transform = `translateY(${this.offsetY}px)`;
|
|
2210
|
-
setTimeout(() => {
|
|
2211
|
-
backdrop?.remove();
|
|
2212
|
-
this.el.classList.remove("active");
|
|
2213
|
-
if (this._menu) this._menu.ariaExpanded = "false";
|
|
2214
|
-
this.el.style.textAlign = "";
|
|
2215
|
-
this.el.style.width = "";
|
|
2216
|
-
this.el.style.bottom = "";
|
|
2217
|
-
this.el.style.left = "";
|
|
2218
|
-
this.el.style.transform = "";
|
|
2219
|
-
this.el.style.transition = "";
|
|
2220
|
-
this._anchor.style.overflow = "";
|
|
2221
|
-
this._anchor.style.transform = "";
|
|
2222
|
-
this._anchor.style.transition = "";
|
|
2223
|
-
}, 200);
|
|
2166
|
+
_toggle() {
|
|
2167
|
+
if (this.isOpen) this.close();
|
|
2168
|
+
else this.open();
|
|
2224
2169
|
}
|
|
2225
2170
|
};
|
|
2226
2171
|
|
|
2227
2172
|
// src/ts/components/carousel.ts
|
|
2228
2173
|
var _defaults7 = {
|
|
2229
2174
|
duration: 200,
|
|
2230
|
-
// ms
|
|
2231
2175
|
dist: -100,
|
|
2232
|
-
// zoom scale TODO: make this more intuitive as an option
|
|
2233
2176
|
shift: 0,
|
|
2234
|
-
// spacing for center image
|
|
2235
2177
|
padding: 0,
|
|
2236
|
-
// Padding between non center items
|
|
2237
2178
|
numVisible: 5,
|
|
2238
|
-
// Number of visible items in carousel
|
|
2239
2179
|
fullWidth: false,
|
|
2240
|
-
// Change to full width styles
|
|
2241
2180
|
indicators: false,
|
|
2242
|
-
// Toggle indicators
|
|
2243
2181
|
noWrap: false,
|
|
2244
|
-
// Don't wrap around and cycle through items.
|
|
2245
2182
|
onCycleTo: null
|
|
2246
|
-
// Callback for when a new slide is cycled to.
|
|
2247
2183
|
};
|
|
2248
|
-
var
|
|
2184
|
+
var _Carousel = class _Carousel extends Component {
|
|
2249
2185
|
constructor(el, options) {
|
|
2250
2186
|
super(el, options, _Carousel);
|
|
2251
|
-
/** The index of the center carousel item. */
|
|
2252
2187
|
this.center = 0;
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2188
|
+
this._ownIndicators = false;
|
|
2189
|
+
this._trackEl = null;
|
|
2190
|
+
this._ignoreScroll = false;
|
|
2191
|
+
this._trackRaf = null;
|
|
2192
|
+
this._started = false;
|
|
2256
2193
|
this._handleThrottledResize = Utils.throttle(() => this._handleResize(), 200);
|
|
2257
2194
|
this._handleCarouselTap = (e) => {
|
|
2258
|
-
if (e.
|
|
2195
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
2196
|
+
if (e.target instanceof HTMLElement && e.target.tagName === "IMG") {
|
|
2259
2197
|
e.preventDefault();
|
|
2260
2198
|
}
|
|
2261
2199
|
this.pressed = true;
|
|
2262
2200
|
this.dragged = false;
|
|
2263
2201
|
this.verticalDragged = false;
|
|
2264
|
-
this.reference =
|
|
2265
|
-
this.referenceY =
|
|
2202
|
+
this.reference = e.clientX;
|
|
2203
|
+
this.referenceY = e.clientY;
|
|
2266
2204
|
this.velocity = this.amplitude = 0;
|
|
2267
2205
|
this.frame = this.offset;
|
|
2268
2206
|
this.timestamp = Date.now();
|
|
2269
|
-
|
|
2270
|
-
|
|
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);
|
|
2271
2218
|
};
|
|
2272
2219
|
this._handleCarouselDrag = (e) => {
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
delta
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
this.dragged = true;
|
|
2282
|
-
this.reference = x;
|
|
2283
|
-
this._scroll(this.offset + delta);
|
|
2284
|
-
}
|
|
2285
|
-
} else if (this.dragged) {
|
|
2286
|
-
e.preventDefault();
|
|
2287
|
-
e.stopPropagation();
|
|
2288
|
-
return false;
|
|
2289
|
-
} else {
|
|
2290
|
-
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);
|
|
2291
2228
|
}
|
|
2292
|
-
}
|
|
2293
|
-
if (this.dragged) {
|
|
2229
|
+
} else if (this.dragged) {
|
|
2294
2230
|
e.preventDefault();
|
|
2295
|
-
|
|
2296
|
-
|
|
2231
|
+
} else {
|
|
2232
|
+
this.verticalDragged = true;
|
|
2297
2233
|
}
|
|
2234
|
+
if (this.dragged) e.preventDefault();
|
|
2298
2235
|
};
|
|
2299
2236
|
this._handleCarouselRelease = (e) => {
|
|
2300
|
-
if (this.pressed)
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
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 {
|
|
2304
2246
|
}
|
|
2305
|
-
clearInterval(this.ticker);
|
|
2306
2247
|
this.target = this.offset;
|
|
2307
2248
|
if (this.velocity > 10 || this.velocity < -10) {
|
|
2308
2249
|
this.amplitude = 0.9 * this.velocity;
|
|
@@ -2319,86 +2260,91 @@ var Carousel = class _Carousel extends Component {
|
|
|
2319
2260
|
this.amplitude = this.target - this.offset;
|
|
2320
2261
|
this.timestamp = Date.now();
|
|
2321
2262
|
requestAnimationFrame(this._autoScroll);
|
|
2263
|
+
if (this.dragged) e.preventDefault();
|
|
2264
|
+
};
|
|
2265
|
+
this._handleCarouselClick = (e) => {
|
|
2322
2266
|
if (this.dragged) {
|
|
2323
2267
|
e.preventDefault();
|
|
2324
2268
|
e.stopPropagation();
|
|
2269
|
+
return;
|
|
2325
2270
|
}
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
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) {
|
|
2330
2276
|
e.preventDefault();
|
|
2331
2277
|
e.stopPropagation();
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
const clickedIndex = [...clickedElem.parentNode.children].indexOf(clickedElem);
|
|
2337
|
-
const diff = this._wrap(this.center) - clickedIndex;
|
|
2338
|
-
if (diff !== 0) {
|
|
2339
|
-
e.preventDefault();
|
|
2340
|
-
e.stopPropagation();
|
|
2341
|
-
}
|
|
2342
|
-
if (clickedIndex < 0) {
|
|
2343
|
-
if (e.clientX - e.target.getBoundingClientRect().left > this.el.clientWidth / 2) {
|
|
2344
|
-
this.next();
|
|
2345
|
-
} else {
|
|
2346
|
-
this.prev();
|
|
2347
|
-
}
|
|
2278
|
+
}
|
|
2279
|
+
if (clickedIndex < 0) {
|
|
2280
|
+
if (e.clientX - e.target.getBoundingClientRect().left > this.el.clientWidth / 2) {
|
|
2281
|
+
this.next();
|
|
2348
2282
|
} else {
|
|
2349
|
-
this.
|
|
2283
|
+
this.prev();
|
|
2350
2284
|
}
|
|
2285
|
+
} else {
|
|
2286
|
+
this._cycleTo(clickedIndex);
|
|
2351
2287
|
}
|
|
2352
2288
|
};
|
|
2353
2289
|
this._handleIndicatorClick = (e) => {
|
|
2354
2290
|
e.stopPropagation();
|
|
2355
|
-
|
|
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);
|
|
2356
2296
|
};
|
|
2357
|
-
this.
|
|
2358
|
-
e.
|
|
2359
|
-
if (
|
|
2360
|
-
|
|
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();
|
|
2361
2306
|
}
|
|
2362
2307
|
};
|
|
2363
|
-
this.
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
this._cycleTo(index);
|
|
2368
|
-
}
|
|
2308
|
+
this._handleFlatScroll = () => {
|
|
2309
|
+
if (this._ignoreScroll) return;
|
|
2310
|
+
const index = this._nearestIndex();
|
|
2311
|
+
if (index !== this.center) this._syncActive(index, this.dragged);
|
|
2369
2312
|
};
|
|
2370
2313
|
this._handleResize = () => {
|
|
2314
|
+
if (!this.images.length) return;
|
|
2315
|
+
if (this._flat) {
|
|
2316
|
+
this._scrollToIndex(this.center, false);
|
|
2317
|
+
return;
|
|
2318
|
+
}
|
|
2371
2319
|
if (this.options.fullWidth) {
|
|
2372
|
-
const firstItem = this.
|
|
2373
|
-
|
|
2374
|
-
if (!firstItem || !activeItem) return;
|
|
2320
|
+
const firstItem = this.images[0];
|
|
2321
|
+
if (!firstItem) return;
|
|
2375
2322
|
this.itemWidth = firstItem.clientWidth;
|
|
2376
|
-
this.imageHeight = activeItem.clientHeight;
|
|
2377
2323
|
this.dim = this.itemWidth * 2 + this.options.padding;
|
|
2378
2324
|
this.offset = this.center * 2 * this.itemWidth;
|
|
2379
2325
|
this.target = this.offset;
|
|
2380
|
-
this._setCarouselHeight(true);
|
|
2381
2326
|
} else {
|
|
2382
2327
|
this._scroll();
|
|
2383
2328
|
}
|
|
2384
2329
|
};
|
|
2385
2330
|
this._track = () => {
|
|
2386
|
-
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);
|
|
2387
2335
|
this.timestamp = now;
|
|
2388
2336
|
this.frame = this.offset;
|
|
2389
2337
|
this.velocity = 0.8 * v + 0.2 * this.velocity;
|
|
2390
2338
|
};
|
|
2391
2339
|
this._autoScroll = () => {
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
this._scroll(this.target);
|
|
2401
|
-
}
|
|
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);
|
|
2402
2348
|
}
|
|
2403
2349
|
};
|
|
2404
2350
|
this.el["Expressive_Carousel"] = this;
|
|
@@ -2406,56 +2352,58 @@ var Carousel = class _Carousel extends Component {
|
|
|
2406
2352
|
..._Carousel.defaults,
|
|
2407
2353
|
...options
|
|
2408
2354
|
};
|
|
2409
|
-
this.
|
|
2410
|
-
|
|
2411
|
-
|
|
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
|
+
}
|
|
2412
2365
|
this.pressed = false;
|
|
2413
2366
|
this.dragged = false;
|
|
2414
2367
|
this.offset = this.target = 0;
|
|
2415
|
-
this.images =
|
|
2416
|
-
|
|
2417
|
-
if (!firstItem) {
|
|
2368
|
+
this.images = this._collectItems();
|
|
2369
|
+
if (!this.images.length) {
|
|
2418
2370
|
console.error("Carousel: no .carousel-item elements to show");
|
|
2419
2371
|
return;
|
|
2420
2372
|
}
|
|
2421
|
-
this.
|
|
2422
|
-
this.
|
|
2423
|
-
this.
|
|
2424
|
-
if (this.options.fullWidth) {
|
|
2425
|
-
this.options.dist = 0;
|
|
2426
|
-
this._setCarouselHeight();
|
|
2427
|
-
if (this.showIndicators) {
|
|
2428
|
-
this.el.querySelector(".carousel-fixed-item")?.classList.add("with-indicators");
|
|
2429
|
-
}
|
|
2430
|
-
}
|
|
2431
|
-
this._indicators = document.createElement("ul");
|
|
2432
|
-
this._indicators.classList.add("indicators");
|
|
2433
|
-
this.el.querySelectorAll(".carousel-item").forEach((item, i) => {
|
|
2434
|
-
this.images.push(item);
|
|
2435
|
-
if (this.showIndicators) {
|
|
2436
|
-
const indicator = document.createElement("li");
|
|
2437
|
-
indicator.classList.add("indicator-item");
|
|
2438
|
-
indicator.tabIndex = 0;
|
|
2439
|
-
if (i === 0) {
|
|
2440
|
-
indicator.classList.add("active");
|
|
2441
|
-
}
|
|
2442
|
-
this._indicators.appendChild(indicator);
|
|
2443
|
-
}
|
|
2444
|
-
});
|
|
2445
|
-
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;
|
|
2446
2376
|
this.count = this.images.length;
|
|
2447
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");
|
|
2448
2387
|
this._setupEventHandlers();
|
|
2449
|
-
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;
|
|
2450
2403
|
}
|
|
2451
2404
|
static get defaults() {
|
|
2452
2405
|
return _defaults7;
|
|
2453
2406
|
}
|
|
2454
|
-
/**
|
|
2455
|
-
* Initializes instances of Carousel.
|
|
2456
|
-
* @param els HTML elements.
|
|
2457
|
-
* @param options Component options.
|
|
2458
|
-
*/
|
|
2459
2407
|
static init(els, options = {}) {
|
|
2460
2408
|
return super.init(els, options, _Carousel);
|
|
2461
2409
|
}
|
|
@@ -2463,81 +2411,104 @@ var Carousel = class _Carousel extends Component {
|
|
|
2463
2411
|
return el["Expressive_Carousel"];
|
|
2464
2412
|
}
|
|
2465
2413
|
destroy() {
|
|
2466
|
-
this.
|
|
2414
|
+
if (this._started) this._teardown();
|
|
2467
2415
|
this.el["Expressive_Carousel"] = void 0;
|
|
2468
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
|
+
}
|
|
2469
2455
|
_setupEventHandlers() {
|
|
2470
|
-
|
|
2471
|
-
this.el.addEventListener("touchstart", this._handleCarouselTap);
|
|
2472
|
-
this.el.addEventListener("touchmove", this._handleCarouselDrag);
|
|
2473
|
-
this.el.addEventListener("touchend", this._handleCarouselRelease);
|
|
2474
|
-
}
|
|
2475
|
-
this.el.addEventListener("mousedown", this._handleCarouselTap);
|
|
2476
|
-
this.el.addEventListener("mousemove", this._handleCarouselDrag);
|
|
2477
|
-
this.el.addEventListener("mouseup", this._handleCarouselRelease);
|
|
2478
|
-
this.el.addEventListener("mouseleave", this._handleCarouselRelease);
|
|
2479
|
-
this.el.addEventListener("click", this._handleCarouselClick);
|
|
2456
|
+
this.el.addEventListener("keydown", this._handleKeydown);
|
|
2480
2457
|
if (this.showIndicators && this._indicators) {
|
|
2481
|
-
this._indicators.
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
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;
|
|
2485
2464
|
}
|
|
2486
|
-
|
|
2465
|
+
if (this._flat) {
|
|
2466
|
+
this._scroller.addEventListener("scroll", this._handleFlatScroll, { passive: true });
|
|
2467
|
+
return;
|
|
2468
|
+
}
|
|
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);
|
|
2487
2474
|
}
|
|
2488
2475
|
_removeEventHandlers() {
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
this.
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
this.el.removeEventListener("
|
|
2495
|
-
this.el.removeEventListener("
|
|
2496
|
-
this.el.removeEventListener("
|
|
2497
|
-
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);
|
|
2498
2485
|
this.el.removeEventListener("click", this._handleCarouselClick);
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2486
|
+
_Carousel._live.delete(this);
|
|
2487
|
+
if (_Carousel._live.size === 0 && _Carousel._resizeListening) {
|
|
2488
|
+
window.removeEventListener("resize", _Carousel._onResize);
|
|
2489
|
+
_Carousel._resizeListening = false;
|
|
2503
2490
|
}
|
|
2504
|
-
window.removeEventListener("resize", this._handleThrottledResize);
|
|
2505
2491
|
}
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
this.el.style.height = adjustedHeight + "px";
|
|
2519
|
-
}
|
|
2520
|
-
} else {
|
|
2521
|
-
firstImage.addEventListener("load", () => {
|
|
2522
|
-
this.el.style.height = firstImage.offsetHeight + "px";
|
|
2523
|
-
});
|
|
2524
|
-
}
|
|
2525
|
-
} else if (!imageOnly) {
|
|
2526
|
-
const slideHeight = firstSlide.clientHeight;
|
|
2527
|
-
this.el.style.height = slideHeight + "px";
|
|
2528
|
-
}
|
|
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
|
+
});
|
|
2529
2504
|
}
|
|
2530
2505
|
_xpos(e) {
|
|
2531
|
-
if (
|
|
2532
|
-
|
|
2533
|
-
}
|
|
2534
|
-
return e.clientX;
|
|
2506
|
+
if ("clientX" in e) return e.clientX;
|
|
2507
|
+
return 0;
|
|
2535
2508
|
}
|
|
2536
2509
|
_ypos(e) {
|
|
2537
|
-
if (
|
|
2538
|
-
|
|
2539
|
-
}
|
|
2540
|
-
return e.clientY;
|
|
2510
|
+
if ("clientY" in e) return e.clientY;
|
|
2511
|
+
return 0;
|
|
2541
2512
|
}
|
|
2542
2513
|
_wrap(x) {
|
|
2543
2514
|
return x >= this.count ? x % this.count : x < 0 ? this._wrap(this.count + x % this.count) : x;
|
|
@@ -2546,18 +2517,20 @@ var Carousel = class _Carousel extends Component {
|
|
|
2546
2517
|
if (!this.el.classList.contains("scrolling")) {
|
|
2547
2518
|
this.el.classList.add("scrolling");
|
|
2548
2519
|
}
|
|
2549
|
-
|
|
2550
|
-
clearTimeout(this.scrollingTimeout);
|
|
2551
|
-
}
|
|
2520
|
+
window.clearTimeout(this.scrollingTimeout);
|
|
2552
2521
|
this.scrollingTimeout = setTimeout(() => {
|
|
2553
2522
|
this.el.classList.remove("scrolling");
|
|
2554
2523
|
}, this.options.duration);
|
|
2555
2524
|
this.offset = typeof x === "number" ? x : this.offset;
|
|
2556
2525
|
this.center = Math.floor((this.offset + this.dim / 2) / this.dim);
|
|
2557
|
-
const half = this.count >> 1
|
|
2558
|
-
|
|
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;
|
|
2559
2530
|
const lastCenter = this.center;
|
|
2560
2531
|
const numVisibleOffset = 1 / this.options.numVisible;
|
|
2532
|
+
let alignment;
|
|
2533
|
+
let centerTweenedOpacity;
|
|
2561
2534
|
if (this.options.fullWidth) {
|
|
2562
2535
|
alignment = "translateX(0)";
|
|
2563
2536
|
centerTweenedOpacity = 1;
|
|
@@ -2566,26 +2539,17 @@ var Carousel = class _Carousel extends Component {
|
|
|
2566
2539
|
alignment += "translateY(" + (this.el.clientHeight - this.itemHeight) / 2 + "px)";
|
|
2567
2540
|
centerTweenedOpacity = 1 - numVisibleOffset * tween;
|
|
2568
2541
|
}
|
|
2569
|
-
|
|
2570
|
-
const diff = this.center % this.count;
|
|
2571
|
-
const activeIndicator = this._indicators.querySelector(".indicator-item.active");
|
|
2572
|
-
const activeIndicatorIndex = [...activeIndicator.parentNode.children].indexOf(
|
|
2573
|
-
activeIndicator
|
|
2574
|
-
);
|
|
2575
|
-
if (activeIndicatorIndex !== diff) {
|
|
2576
|
-
activeIndicator.classList.remove("active");
|
|
2577
|
-
const pos = diff < 0 ? this.count + diff : diff;
|
|
2578
|
-
this._indicators.querySelectorAll(".indicator-item")[pos].classList.add("active");
|
|
2579
|
-
}
|
|
2580
|
-
}
|
|
2542
|
+
this._paintIndicators(this.center);
|
|
2581
2543
|
if (!this.noWrap || this.center >= 0 && this.center < this.count) {
|
|
2582
|
-
el = this.images[this._wrap(this.center)];
|
|
2583
|
-
if (!el.classList.contains("active")) {
|
|
2544
|
+
const el = this.images[this._wrap(this.center)];
|
|
2545
|
+
if (el && !el.classList.contains("active")) {
|
|
2584
2546
|
this.el.querySelector(".carousel-item.active")?.classList.remove("active");
|
|
2585
2547
|
el.classList.add("active");
|
|
2586
2548
|
}
|
|
2587
2549
|
}
|
|
2588
|
-
for (i = 1; i <= half; ++i) {
|
|
2550
|
+
for (let i = 1; i <= half; ++i) {
|
|
2551
|
+
let zTranslation;
|
|
2552
|
+
let tweenedOpacity;
|
|
2589
2553
|
if (this.options.fullWidth) {
|
|
2590
2554
|
zTranslation = this.options.dist;
|
|
2591
2555
|
tweenedOpacity = i === half && delta < 0 ? 1 - tween : 1;
|
|
@@ -2594,7 +2558,7 @@ var Carousel = class _Carousel extends Component {
|
|
|
2594
2558
|
tweenedOpacity = 1 - numVisibleOffset * (i * 2 + tween * dir);
|
|
2595
2559
|
}
|
|
2596
2560
|
if (!this.noWrap || this.center + i < this.count) {
|
|
2597
|
-
el = this.images[this._wrap(this.center + i)];
|
|
2561
|
+
const el = this.images[this._wrap(this.center + i)];
|
|
2598
2562
|
const transformString = `${alignment} translateX(${this.options.shift + (this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
2599
2563
|
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
2600
2564
|
}
|
|
@@ -2606,32 +2570,113 @@ var Carousel = class _Carousel extends Component {
|
|
|
2606
2570
|
tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
|
|
2607
2571
|
}
|
|
2608
2572
|
if (!this.noWrap || this.center - i >= 0) {
|
|
2609
|
-
el = this.images[this._wrap(this.center - i)];
|
|
2573
|
+
const el = this.images[this._wrap(this.center - i)];
|
|
2610
2574
|
const transformString = `${alignment} translateX(${-this.options.shift + (-this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
|
|
2611
2575
|
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
|
|
2612
2576
|
}
|
|
2613
2577
|
}
|
|
2614
2578
|
if (!this.noWrap || this.center >= 0 && this.center < this.count) {
|
|
2615
|
-
el = this.images[this._wrap(this.center)];
|
|
2579
|
+
const el = this.images[this._wrap(this.center)];
|
|
2616
2580
|
const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir * this.options.shift * tween}px) translateZ(${this.options.dist * tween}px)`;
|
|
2617
2581
|
this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
|
|
2618
2582
|
}
|
|
2619
|
-
const
|
|
2583
|
+
const currItem = this.images[this._wrap(this.center)];
|
|
2584
|
+
this._syncA11y(this._wrap(this.center));
|
|
2620
2585
|
if (lastCenter !== this.center && typeof this.options.onCycleTo === "function") {
|
|
2621
|
-
this.options.onCycleTo.call(this,
|
|
2586
|
+
this.options.onCycleTo.call(this, currItem, this.dragged);
|
|
2622
2587
|
}
|
|
2623
2588
|
if (typeof this.oneTimeCallback === "function") {
|
|
2624
|
-
this.oneTimeCallback.call(this,
|
|
2589
|
+
this.oneTimeCallback.call(this, currItem, this.dragged);
|
|
2625
2590
|
this.oneTimeCallback = null;
|
|
2626
2591
|
}
|
|
2627
2592
|
}
|
|
2628
2593
|
_updateItemStyle(el, opacity, zIndex, transform) {
|
|
2594
|
+
if (!el) return;
|
|
2629
2595
|
el.style.transform = transform;
|
|
2630
2596
|
el.style.zIndex = zIndex.toString();
|
|
2631
2597
|
el.style.opacity = opacity.toString();
|
|
2632
2598
|
el.style.visibility = "visible";
|
|
2633
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
|
+
}
|
|
2634
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
|
+
}
|
|
2635
2680
|
let diff = this.center % this.count - n;
|
|
2636
2681
|
if (!this.noWrap) {
|
|
2637
2682
|
if (diff < 0) {
|
|
@@ -2659,14 +2704,8 @@ var Carousel = class _Carousel extends Component {
|
|
|
2659
2704
|
requestAnimationFrame(this._autoScroll);
|
|
2660
2705
|
}
|
|
2661
2706
|
}
|
|
2662
|
-
/**
|
|
2663
|
-
* Move carousel to next slide or go forward a given amount of slides.
|
|
2664
|
-
* @param n How many times the carousel slides.
|
|
2665
|
-
*/
|
|
2666
2707
|
next(n = 1) {
|
|
2667
|
-
if (n === void 0 || isNaN(n))
|
|
2668
|
-
n = 1;
|
|
2669
|
-
}
|
|
2708
|
+
if (n === void 0 || isNaN(n)) n = 1;
|
|
2670
2709
|
let index = this.center + n;
|
|
2671
2710
|
if (index >= this.count || index < 0) {
|
|
2672
2711
|
if (this.noWrap) return;
|
|
@@ -2674,14 +2713,8 @@ var Carousel = class _Carousel extends Component {
|
|
|
2674
2713
|
}
|
|
2675
2714
|
this._cycleTo(index);
|
|
2676
2715
|
}
|
|
2677
|
-
/**
|
|
2678
|
-
* Move carousel to previous slide or go back a given amount of slides.
|
|
2679
|
-
* @param n How many times the carousel slides.
|
|
2680
|
-
*/
|
|
2681
2716
|
prev(n = 1) {
|
|
2682
|
-
if (n === void 0 || isNaN(n))
|
|
2683
|
-
n = 1;
|
|
2684
|
-
}
|
|
2717
|
+
if (n === void 0 || isNaN(n)) n = 1;
|
|
2685
2718
|
let index = this.center - n;
|
|
2686
2719
|
if (index >= this.count || index < 0) {
|
|
2687
2720
|
if (this.noWrap) return;
|
|
@@ -2689,15 +2722,8 @@ var Carousel = class _Carousel extends Component {
|
|
|
2689
2722
|
}
|
|
2690
2723
|
this._cycleTo(index);
|
|
2691
2724
|
}
|
|
2692
|
-
/**
|
|
2693
|
-
* Move carousel to nth slide.
|
|
2694
|
-
* @param n Index of slide.
|
|
2695
|
-
* @param callback "onCycleTo" optional callback.
|
|
2696
|
-
*/
|
|
2697
2725
|
set(n, callback) {
|
|
2698
|
-
if (n === void 0 || isNaN(n))
|
|
2699
|
-
n = 0;
|
|
2700
|
-
}
|
|
2726
|
+
if (n === void 0 || isNaN(n)) n = 0;
|
|
2701
2727
|
if (n > this.count || n < 0) {
|
|
2702
2728
|
if (this.noWrap) return;
|
|
2703
2729
|
n = this._wrap(n);
|
|
@@ -2705,6 +2731,12 @@ var Carousel = class _Carousel extends Component {
|
|
|
2705
2731
|
this._cycleTo(n, callback);
|
|
2706
2732
|
}
|
|
2707
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;
|
|
2708
2740
|
|
|
2709
2741
|
// src/ts/components/characterCounter.ts
|
|
2710
2742
|
var _defaults8 = Object.freeze({});
|
|
@@ -2794,77 +2826,75 @@ var _defaults9 = {
|
|
|
2794
2826
|
var Collapsible = class _Collapsible extends Component {
|
|
2795
2827
|
constructor(el, options) {
|
|
2796
2828
|
super(el, options, _Collapsible);
|
|
2797
|
-
this.
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
const collapsible = header.closest(".collapsible");
|
|
2801
|
-
if (collapsible !== this.el) return;
|
|
2802
|
-
const li = header.closest("li");
|
|
2803
|
-
const isActive = li.classList.contains("active");
|
|
2804
|
-
const index = [...li.parentNode.children].indexOf(li);
|
|
2805
|
-
if (isActive) this.close(index);
|
|
2806
|
-
else this.open(index);
|
|
2807
|
-
}
|
|
2808
|
-
};
|
|
2809
|
-
this._handleCollapsibleKeydown = (e) => {
|
|
2810
|
-
if (Utils.keys.ENTER.includes(e.key)) {
|
|
2811
|
-
this._handleCollapsibleClick(e);
|
|
2812
|
-
}
|
|
2813
|
-
};
|
|
2829
|
+
this._items = [];
|
|
2830
|
+
this._endTimers = [];
|
|
2831
|
+
this._wrappedBodies = [];
|
|
2814
2832
|
/**
|
|
2815
2833
|
* Open collapsible section.
|
|
2816
|
-
* @param
|
|
2834
|
+
* @param index 0-based index of the section to open.
|
|
2817
2835
|
*/
|
|
2818
2836
|
this.open = (index) => {
|
|
2819
|
-
const
|
|
2820
|
-
|
|
2821
|
-
if (
|
|
2822
|
-
|
|
2823
|
-
this.
|
|
2824
|
-
}
|
|
2825
|
-
if (this.options.accordion) {
|
|
2826
|
-
const activeLis = listItems.filter((li2) => li2.classList.contains("active"));
|
|
2827
|
-
activeLis.forEach((activeLi) => {
|
|
2828
|
-
const index2 = listItems.indexOf(activeLi);
|
|
2829
|
-
this.close(index2);
|
|
2830
|
-
});
|
|
2831
|
-
}
|
|
2832
|
-
li.classList.add("active");
|
|
2833
|
-
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
|
+
});
|
|
2834
2843
|
}
|
|
2844
|
+
this._setOpen(item, true);
|
|
2835
2845
|
};
|
|
2836
2846
|
/**
|
|
2837
2847
|
* Close collapsible section.
|
|
2838
|
-
* @param
|
|
2848
|
+
* @param index 0-based index of the section to close.
|
|
2839
2849
|
*/
|
|
2840
2850
|
this.close = (index) => {
|
|
2841
|
-
const
|
|
2842
|
-
if (
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
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);
|
|
2849
2885
|
};
|
|
2850
2886
|
this.el["Expressive_Collapsible"] = this;
|
|
2887
|
+
const accordion = options.accordion !== void 0 ? options.accordion : !el.classList.contains("expandable");
|
|
2851
2888
|
this.options = {
|
|
2852
2889
|
..._Collapsible.defaults,
|
|
2853
|
-
...options
|
|
2890
|
+
...options,
|
|
2891
|
+
accordion
|
|
2854
2892
|
};
|
|
2855
|
-
this.
|
|
2856
|
-
this.
|
|
2893
|
+
this._groupName = el.id ? `collapsible-${el.id}` : `collapsible-${Utils.guid()}`;
|
|
2894
|
+
this._items = this._collectItems();
|
|
2895
|
+
this._wrapDetailsBodies();
|
|
2896
|
+
this._setupItems();
|
|
2857
2897
|
this._setupEventHandlers();
|
|
2858
|
-
const activeBodies = Array.from(
|
|
2859
|
-
this.el.querySelectorAll("li.active > .collapsible-body")
|
|
2860
|
-
);
|
|
2861
|
-
if (this.options.accordion) {
|
|
2862
|
-
if (activeBodies.length > 0) {
|
|
2863
|
-
this._setExpanded(activeBodies[0]);
|
|
2864
|
-
}
|
|
2865
|
-
} else {
|
|
2866
|
-
activeBodies.forEach((el2) => this._setExpanded(el2));
|
|
2867
|
-
}
|
|
2868
2898
|
}
|
|
2869
2899
|
static get defaults() {
|
|
2870
2900
|
return _defaults9;
|
|
@@ -2882,48 +2912,130 @@ var Collapsible = class _Collapsible extends Component {
|
|
|
2882
2912
|
}
|
|
2883
2913
|
destroy() {
|
|
2884
2914
|
this._removeEventHandlers();
|
|
2915
|
+
this._endTimers.forEach((id) => clearTimeout(id));
|
|
2916
|
+
this._endTimers = [];
|
|
2917
|
+
this._unwrapDetailsBodies();
|
|
2885
2918
|
this.el["Expressive_Collapsible"] = void 0;
|
|
2886
2919
|
}
|
|
2887
|
-
|
|
2888
|
-
this.el.
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
);
|
|
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");
|
|
2892
2924
|
}
|
|
2893
|
-
|
|
2894
|
-
this.
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
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));
|
|
2898
2941
|
}
|
|
2899
|
-
|
|
2900
|
-
|
|
2942
|
+
_isOpen(item) {
|
|
2943
|
+
if (item instanceof HTMLDetailsElement) return item.open;
|
|
2944
|
+
return item.classList.contains("active");
|
|
2901
2945
|
}
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
this.
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
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
|
+
});
|
|
2914
2974
|
}
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
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;
|
|
2927
3039
|
}
|
|
2928
3040
|
};
|
|
2929
3041
|
|
|
@@ -4723,38 +4835,22 @@ var Modal = _Modal;
|
|
|
4723
4835
|
// src/ts/components/parallax.ts
|
|
4724
4836
|
var _defaults15 = {
|
|
4725
4837
|
responsiveThreshold: 0
|
|
4726
|
-
// breakpoint for swipeable
|
|
4727
4838
|
};
|
|
4728
|
-
var
|
|
4839
|
+
var Parallax = class _Parallax extends Component {
|
|
4729
4840
|
constructor(el, options) {
|
|
4730
4841
|
super(el, options, _Parallax);
|
|
4731
|
-
this._handleImageLoad = () => {
|
|
4732
|
-
this._updateParallax();
|
|
4733
|
-
};
|
|
4734
4842
|
this.el["Expressive_Parallax"] = this;
|
|
4735
4843
|
this.options = {
|
|
4736
4844
|
..._Parallax.defaults,
|
|
4737
4845
|
...options
|
|
4738
4846
|
};
|
|
4739
|
-
this.
|
|
4740
|
-
|
|
4741
|
-
if (!this._img) {
|
|
4742
|
-
console.error("Parallax: no <img> to move inside the .parallax element");
|
|
4743
|
-
return;
|
|
4847
|
+
if (!this.el.querySelector("img, video")) {
|
|
4848
|
+
console.error("Parallax: no <img> or <video> to move inside the .parallax element");
|
|
4744
4849
|
}
|
|
4745
|
-
this._updateParallax();
|
|
4746
|
-
this._setupEventHandlers();
|
|
4747
|
-
this._setupStyles();
|
|
4748
|
-
_Parallax._parallaxes.push(this);
|
|
4749
4850
|
}
|
|
4750
4851
|
static get defaults() {
|
|
4751
4852
|
return _defaults15;
|
|
4752
4853
|
}
|
|
4753
|
-
/**
|
|
4754
|
-
* Initializes instances of Parallax.
|
|
4755
|
-
* @param els HTML elements.
|
|
4756
|
-
* @param options Component options.
|
|
4757
|
-
*/
|
|
4758
4854
|
static init(els, options = {}) {
|
|
4759
4855
|
return super.init(els, options, _Parallax);
|
|
4760
4856
|
}
|
|
@@ -4762,84 +4858,9 @@ var _Parallax = class _Parallax extends Component {
|
|
|
4762
4858
|
return el["Expressive_Parallax"];
|
|
4763
4859
|
}
|
|
4764
4860
|
destroy() {
|
|
4765
|
-
const index = _Parallax._parallaxes.indexOf(this);
|
|
4766
|
-
if (index >= 0) _Parallax._parallaxes.splice(index, 1);
|
|
4767
|
-
if (this._img) this._img.style.transform = "";
|
|
4768
|
-
this._removeEventHandlers();
|
|
4769
4861
|
this.el["Expressive_Parallax"] = void 0;
|
|
4770
4862
|
}
|
|
4771
|
-
static _handleScroll() {
|
|
4772
|
-
for (let i = 0; i < _Parallax._parallaxes.length; i++) {
|
|
4773
|
-
const parallaxInstance = _Parallax._parallaxes[i];
|
|
4774
|
-
parallaxInstance._updateParallax.call(parallaxInstance);
|
|
4775
|
-
}
|
|
4776
|
-
}
|
|
4777
|
-
static _handleWindowResize() {
|
|
4778
|
-
for (let i = 0; i < _Parallax._parallaxes.length; i++) {
|
|
4779
|
-
const parallaxInstance = _Parallax._parallaxes[i];
|
|
4780
|
-
parallaxInstance._enabled = window.innerWidth > parallaxInstance.options.responsiveThreshold;
|
|
4781
|
-
}
|
|
4782
|
-
}
|
|
4783
|
-
_setupEventHandlers() {
|
|
4784
|
-
this._img?.addEventListener("load", this._handleImageLoad);
|
|
4785
|
-
if (_Parallax._parallaxes.length === 0) {
|
|
4786
|
-
if (!_Parallax._handleWindowResizeThrottled) {
|
|
4787
|
-
_Parallax._handleWindowResizeThrottled = Utils.throttle(_Parallax._handleWindowResize, 100);
|
|
4788
|
-
}
|
|
4789
|
-
window.addEventListener("scroll", _Parallax._requestScrollUpdate, { passive: true });
|
|
4790
|
-
window.addEventListener("resize", _Parallax._handleWindowResizeThrottled, { passive: true });
|
|
4791
|
-
}
|
|
4792
|
-
}
|
|
4793
|
-
_removeEventHandlers() {
|
|
4794
|
-
this._img?.removeEventListener("load", this._handleImageLoad);
|
|
4795
|
-
if (_Parallax._parallaxes.length === 0) {
|
|
4796
|
-
window.removeEventListener("scroll", _Parallax._requestScrollUpdate);
|
|
4797
|
-
window.removeEventListener("resize", _Parallax._handleWindowResizeThrottled);
|
|
4798
|
-
if (_Parallax._scrollFrame !== null) {
|
|
4799
|
-
cancelAnimationFrame(_Parallax._scrollFrame);
|
|
4800
|
-
_Parallax._scrollFrame = null;
|
|
4801
|
-
}
|
|
4802
|
-
}
|
|
4803
|
-
}
|
|
4804
|
-
_setupStyles() {
|
|
4805
|
-
if (this._img) this._img.style.opacity = "1";
|
|
4806
|
-
}
|
|
4807
|
-
_updateParallax() {
|
|
4808
|
-
const rect = this.el.getBoundingClientRect();
|
|
4809
|
-
const containerHeight = rect.height > 0 ? this.el.parentElement.offsetHeight : 500;
|
|
4810
|
-
const imgHeight = this._img.offsetHeight;
|
|
4811
|
-
const parallaxDist = imgHeight - containerHeight;
|
|
4812
|
-
const top = rect.top + window.scrollY - document.documentElement.clientTop;
|
|
4813
|
-
const bottom = top + containerHeight;
|
|
4814
|
-
const scrollTop = Utils.getDocumentScrollTop();
|
|
4815
|
-
const windowHeight = window.innerHeight;
|
|
4816
|
-
const windowBottom = scrollTop + windowHeight;
|
|
4817
|
-
const percentScrolled = (windowBottom - top) / (containerHeight + windowHeight);
|
|
4818
|
-
const parallax = parallaxDist * percentScrolled;
|
|
4819
|
-
if (!this._enabled) {
|
|
4820
|
-
this._img.style.transform = "";
|
|
4821
|
-
} else if (bottom > scrollTop && top < scrollTop + windowHeight) {
|
|
4822
|
-
this._img.style.transform = `translate3D(-50%, ${parallax}px, 0)`;
|
|
4823
|
-
}
|
|
4824
|
-
}
|
|
4825
4863
|
};
|
|
4826
|
-
_Parallax._parallaxes = [];
|
|
4827
|
-
_Parallax._scrollFrame = null;
|
|
4828
|
-
/**
|
|
4829
|
-
* Coalesce scroll events onto animation frames.
|
|
4830
|
-
*
|
|
4831
|
-
* The handler reads layout and then writes a transform, so running it more
|
|
4832
|
-
* than once per frame is wasted work - and the 5ms throttle it replaces was
|
|
4833
|
-
* short enough to let several run per frame anyway.
|
|
4834
|
-
*/
|
|
4835
|
-
_Parallax._requestScrollUpdate = () => {
|
|
4836
|
-
if (_Parallax._scrollFrame !== null) return;
|
|
4837
|
-
_Parallax._scrollFrame = requestAnimationFrame(() => {
|
|
4838
|
-
_Parallax._scrollFrame = null;
|
|
4839
|
-
_Parallax._handleScroll();
|
|
4840
|
-
});
|
|
4841
|
-
};
|
|
4842
|
-
var Parallax = _Parallax;
|
|
4843
4864
|
|
|
4844
4865
|
// src/ts/components/pushpin.ts
|
|
4845
4866
|
var _defaults16 = {
|
|
@@ -6079,60 +6100,96 @@ var _defaults21 = {
|
|
|
6079
6100
|
var _TapTarget = class _TapTarget extends Component {
|
|
6080
6101
|
constructor(el, options) {
|
|
6081
6102
|
super(el, options, _TapTarget);
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
this.
|
|
6085
|
-
this.
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
this._handleTargetToggle = () => {
|
|
6091
|
-
if (!this.isOpen) this.open();
|
|
6092
|
-
else this.close();
|
|
6093
|
-
};
|
|
6094
|
-
/*_handleOriginClick = () => {
|
|
6095
|
-
this.close();
|
|
6096
|
-
}*/
|
|
6097
|
-
this._handleResize = () => {
|
|
6098
|
-
this._calculatePositioning();
|
|
6099
|
-
};
|
|
6100
|
-
this._handleDocumentClick = (e) => {
|
|
6101
|
-
const target = e.target;
|
|
6102
|
-
if (!(target instanceof Element)) return;
|
|
6103
|
-
if (!this.originEl.contains(target) && !target.closest(".tap-target-wrapper")) {
|
|
6104
|
-
this.close();
|
|
6105
|
-
}
|
|
6106
|
-
};
|
|
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;
|
|
6107
6111
|
/**
|
|
6108
6112
|
* Open Tap Target.
|
|
6109
6113
|
*/
|
|
6110
6114
|
this.open = () => {
|
|
6111
|
-
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();
|
|
6112
6120
|
if (typeof this.options.onOpen === "function") {
|
|
6113
6121
|
this.options.onOpen.call(this, this.originEl);
|
|
6114
6122
|
}
|
|
6115
6123
|
this.isOpen = true;
|
|
6116
6124
|
this.wrapper.classList.add("open");
|
|
6117
|
-
this.
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
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
|
+
}
|
|
6121
6143
|
};
|
|
6122
6144
|
/**
|
|
6123
6145
|
* Close Tap Target.
|
|
6124
6146
|
*/
|
|
6125
6147
|
this.close = () => {
|
|
6126
6148
|
if (!this.isOpen) return;
|
|
6127
|
-
if (typeof this.options.onClose === "function") {
|
|
6149
|
+
if (typeof this.options.onClose === "function" && this.originEl) {
|
|
6128
6150
|
this.options.onClose.call(this, this.originEl);
|
|
6129
6151
|
}
|
|
6130
6152
|
this.isOpen = false;
|
|
6131
|
-
this.wrapper
|
|
6132
|
-
this.
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
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();
|
|
6136
6193
|
};
|
|
6137
6194
|
this.el["Expressive_TapTarget"] = this;
|
|
6138
6195
|
this.options = {
|
|
@@ -6145,7 +6202,6 @@ var _TapTarget = class _TapTarget extends Component {
|
|
|
6145
6202
|
console.error(`TapTarget: no element with id "${el.dataset.target ?? ""}" to attach to`);
|
|
6146
6203
|
return;
|
|
6147
6204
|
}
|
|
6148
|
-
this.originEl.tabIndex = 0;
|
|
6149
6205
|
this._setup();
|
|
6150
6206
|
this._calculatePositioning();
|
|
6151
6207
|
this._setupEventHandlers();
|
|
@@ -6154,11 +6210,6 @@ var _TapTarget = class _TapTarget extends Component {
|
|
|
6154
6210
|
static get defaults() {
|
|
6155
6211
|
return _defaults21;
|
|
6156
6212
|
}
|
|
6157
|
-
/**
|
|
6158
|
-
* Initializes instances of TapTarget.
|
|
6159
|
-
* @param els HTML elements.
|
|
6160
|
-
* @param options Component options.
|
|
6161
|
-
*/
|
|
6162
6213
|
static init(els, options = {}) {
|
|
6163
6214
|
return super.init(els, options, _TapTarget);
|
|
6164
6215
|
}
|
|
@@ -6168,116 +6219,95 @@ var _TapTarget = class _TapTarget extends Component {
|
|
|
6168
6219
|
destroy() {
|
|
6169
6220
|
this.close();
|
|
6170
6221
|
this._removeEventHandlers();
|
|
6222
|
+
this._teardownDom();
|
|
6171
6223
|
this.el["Expressive_TapTarget"] = void 0;
|
|
6172
6224
|
const index = _TapTarget._taptargets.indexOf(this);
|
|
6173
|
-
if (index >= 0)
|
|
6174
|
-
_TapTarget._taptargets.splice(index, 1);
|
|
6175
|
-
}
|
|
6176
|
-
}
|
|
6177
|
-
_setupEventHandlers() {
|
|
6178
|
-
if (!this.originEl) return;
|
|
6179
|
-
this.originEl.addEventListener("click", this._handleTargetToggle);
|
|
6180
|
-
this.originEl.addEventListener("keypress", this._handleKeyboardInteraction, true);
|
|
6181
|
-
window.addEventListener("resize", this._handleThrottledResize);
|
|
6182
|
-
}
|
|
6183
|
-
_removeEventHandlers() {
|
|
6184
|
-
if (!this.originEl) return;
|
|
6185
|
-
this.originEl.removeEventListener("click", this._handleTargetToggle);
|
|
6186
|
-
this.originEl.removeEventListener("keypress", this._handleKeyboardInteraction, true);
|
|
6187
|
-
window.removeEventListener("resize", this._handleThrottledResize);
|
|
6225
|
+
if (index >= 0) _TapTarget._taptargets.splice(index, 1);
|
|
6188
6226
|
}
|
|
6189
6227
|
_setup() {
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
this.contentEl = this.el.querySelector(".tap-target-content");
|
|
6195
|
-
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 {
|
|
6196
6232
|
this.wrapper = document.createElement("div");
|
|
6197
6233
|
this.wrapper.classList.add("tap-target-wrapper");
|
|
6198
6234
|
this.el.before(this.wrapper);
|
|
6199
6235
|
this.wrapper.append(this.el);
|
|
6236
|
+
this._createdWrapper = true;
|
|
6200
6237
|
}
|
|
6238
|
+
this.contentEl = this.el.querySelector(".tap-target-content");
|
|
6201
6239
|
if (!this.contentEl) {
|
|
6202
6240
|
this.contentEl = document.createElement("div");
|
|
6203
|
-
this.contentEl.
|
|
6241
|
+
this.contentEl.className = "tap-target-content";
|
|
6242
|
+
while (this.el.firstChild) this.contentEl.append(this.el.firstChild);
|
|
6204
6243
|
this.el.append(this.contentEl);
|
|
6205
6244
|
}
|
|
6245
|
+
this.waveEl = this.el.querySelector(".tap-target-wave") ?? this.wrapper.querySelector(".tap-target-wave");
|
|
6206
6246
|
if (!this.waveEl) {
|
|
6207
6247
|
this.waveEl = document.createElement("div");
|
|
6208
|
-
this.waveEl.
|
|
6209
|
-
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);
|
|
6210
6287
|
}
|
|
6288
|
+
this.wrapper?.addEventListener("toggle", this._handlePopoverToggle);
|
|
6289
|
+
window.addEventListener("resize", this._handleThrottledResize, { passive: true });
|
|
6211
6290
|
}
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
};
|
|
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);
|
|
6219
6297
|
}
|
|
6220
6298
|
_calculatePositioning() {
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
const originHeight = this.originEl.offsetHeight;
|
|
6234
|
-
const originOffset = this._offset(this.originEl);
|
|
6235
|
-
const originTop = isFixed ? originOffset.top - Utils.getDocumentScrollTop() : originOffset.top;
|
|
6236
|
-
const originLeft = isFixed ? originOffset.left - Utils.getDocumentScrollLeft() : originOffset.left;
|
|
6237
|
-
const windowWidth = window.innerWidth;
|
|
6238
|
-
const windowHeight = window.innerHeight;
|
|
6239
|
-
const scrollBarWidth = windowWidth - document.documentElement.clientWidth;
|
|
6240
|
-
const centerX = windowWidth / 2;
|
|
6241
|
-
const centerY = windowHeight / 2;
|
|
6242
|
-
const isLeft = originLeft <= centerX;
|
|
6243
|
-
const isRight = originLeft > centerX;
|
|
6244
|
-
const isTop = originTop <= centerY;
|
|
6245
|
-
const isBottom = originTop > centerY;
|
|
6246
|
-
const isCenterX = originLeft >= windowWidth * 0.25 && originLeft <= windowWidth * 0.75;
|
|
6247
|
-
const tapTargetWidth = this.el.offsetWidth;
|
|
6248
|
-
const tapTargetHeight = this.el.offsetHeight;
|
|
6249
|
-
const tapTargetTop = originTop + originHeight / 2 - tapTargetHeight / 2;
|
|
6250
|
-
const tapTargetLeft = originLeft + originWidth / 2 - tapTargetWidth / 2;
|
|
6251
|
-
const tapTargetPosition = isFixed ? "fixed" : "absolute";
|
|
6252
|
-
const tapTargetTextWidth = isCenterX ? tapTargetWidth : tapTargetWidth / 2 + originWidth;
|
|
6253
|
-
const tapTargetTextHeight = tapTargetHeight / 2;
|
|
6254
|
-
const tapTargetTextTop = isTop ? tapTargetHeight / 2 : 0;
|
|
6255
|
-
const tapTargetTextBottom = 0;
|
|
6256
|
-
const tapTargetTextLeft = isLeft && !isCenterX ? tapTargetWidth / 2 - originWidth : 0;
|
|
6257
|
-
const tapTargetTextRight = 0;
|
|
6258
|
-
const tapTargetTextPadding = originWidth;
|
|
6259
|
-
const tapTargetTextAlign = isBottom ? "bottom" : "top";
|
|
6260
|
-
const tapTargetWaveWidth = originWidth > originHeight ? originWidth * 2 : originWidth * 2;
|
|
6261
|
-
const tapTargetWaveHeight = tapTargetWaveWidth;
|
|
6262
|
-
const tapTargetWaveTop = tapTargetHeight / 2 - tapTargetWaveHeight / 2;
|
|
6263
|
-
const tapTargetWaveLeft = tapTargetWidth / 2 - tapTargetWaveWidth / 2;
|
|
6264
|
-
this.wrapper.style.top = isTop ? tapTargetTop + "px" : "";
|
|
6265
|
-
this.wrapper.style.right = isRight ? windowWidth - tapTargetLeft - tapTargetWidth - scrollBarWidth + "px" : "";
|
|
6266
|
-
this.wrapper.style.bottom = isBottom ? windowHeight - tapTargetTop - tapTargetHeight + "px" : "";
|
|
6267
|
-
this.wrapper.style.left = isLeft ? tapTargetLeft + "px" : "";
|
|
6268
|
-
this.wrapper.style.position = tapTargetPosition;
|
|
6269
|
-
this.contentEl.style.width = tapTargetTextWidth + "px";
|
|
6270
|
-
this.contentEl.style.height = tapTargetTextHeight + "px";
|
|
6271
|
-
this.contentEl.style.top = tapTargetTextTop + "px";
|
|
6272
|
-
this.contentEl.style.right = tapTargetTextRight + "px";
|
|
6273
|
-
this.contentEl.style.bottom = tapTargetTextBottom + "px";
|
|
6274
|
-
this.contentEl.style.left = tapTargetTextLeft + "px";
|
|
6275
|
-
this.contentEl.style.padding = tapTargetTextPadding + "px";
|
|
6276
|
-
this.contentEl.style.verticalAlign = tapTargetTextAlign;
|
|
6277
|
-
this.waveEl.style.top = tapTargetWaveTop + "px";
|
|
6278
|
-
this.waveEl.style.left = tapTargetWaveLeft + "px";
|
|
6279
|
-
this.waveEl.style.width = tapTargetWaveWidth + "px";
|
|
6280
|
-
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}`;
|
|
6281
6311
|
}
|
|
6282
6312
|
};
|
|
6283
6313
|
_TapTarget._taptargets = [];
|
|
@@ -7021,7 +7051,7 @@ var _Toast = class _Toast {
|
|
|
7021
7051
|
close.className = "circle";
|
|
7022
7052
|
close.setAttribute("aria-label", "Dismiss");
|
|
7023
7053
|
const icon = document.createElement("i");
|
|
7024
|
-
icon.className = "material-
|
|
7054
|
+
icon.className = "material-symbols";
|
|
7025
7055
|
icon.setAttribute("aria-hidden", "true");
|
|
7026
7056
|
icon.textContent = "close";
|
|
7027
7057
|
close.appendChild(icon);
|
|
@@ -7386,7 +7416,7 @@ function AutoInit(context = document.body, options) {
|
|
|
7386
7416
|
}
|
|
7387
7417
|
|
|
7388
7418
|
// src/ts/index.ts
|
|
7389
|
-
var version = "0.
|
|
7419
|
+
var version = "0.3.0";
|
|
7390
7420
|
if (typeof document !== "undefined") {
|
|
7391
7421
|
document.addEventListener("keydown", Utils.docHandleKeydown, true);
|
|
7392
7422
|
document.addEventListener("keyup", Utils.docHandleKeyup, true);
|
|
@@ -7398,6 +7428,7 @@ Chips.Init();
|
|
|
7398
7428
|
Waves.Init();
|
|
7399
7429
|
Range.Init();
|
|
7400
7430
|
Cards.Init();
|
|
7431
|
+
Dialogs.Init();
|
|
7401
7432
|
export {
|
|
7402
7433
|
AutoInit,
|
|
7403
7434
|
Autocomplete,
|
|
@@ -7407,6 +7438,7 @@ export {
|
|
|
7407
7438
|
Chips,
|
|
7408
7439
|
Collapsible,
|
|
7409
7440
|
Datepicker,
|
|
7441
|
+
Dialogs,
|
|
7410
7442
|
Dropdown,
|
|
7411
7443
|
FloatingActionButton,
|
|
7412
7444
|
FormSelect,
|