@expressivecss/expressive 0.14.1 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +88 -1
- package/README.md +1 -1
- package/dist/css/expressive.css +200 -241
- 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/chunks/{chunk-4KMNFIFZ.mjs → chunk-33QVDDGR.mjs} +3 -3
- package/dist/js/chunks/{chunk-SPETGK25.mjs → chunk-45FER6RI.mjs} +5 -5
- package/dist/js/chunks/chunk-45FER6RI.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GIW4K4SE.mjs → chunk-5CEAOLUA.mjs} +11 -10
- package/dist/js/chunks/{chunk-GIW4K4SE.mjs.map → chunk-5CEAOLUA.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-LRZMJZ3T.mjs → chunk-6VATUZC6.mjs} +10 -6
- package/dist/js/chunks/chunk-6VATUZC6.mjs.map +7 -0
- package/dist/js/chunks/{chunk-QDAL4IYN.mjs → chunk-74MXKKLN.mjs} +2 -2
- package/dist/js/chunks/{chunk-QDAL4IYN.mjs.map → chunk-74MXKKLN.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-CUQPB25U.mjs → chunk-AIURVCG6.mjs} +3 -3
- package/dist/js/chunks/{chunk-KHV6DZXX.mjs → chunk-BGZLF6JZ.mjs} +16 -16
- package/dist/js/chunks/chunk-BGZLF6JZ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-BG6ZRB5H.mjs → chunk-C6CHEWYP.mjs} +2 -2
- package/dist/js/chunks/{chunk-GVGT6MIU.mjs → chunk-CK2XCICY.mjs} +2 -2
- package/dist/js/chunks/{chunk-KY6U46SM.mjs → chunk-CXXM2L4F.mjs} +8 -9
- package/dist/js/chunks/chunk-CXXM2L4F.mjs.map +7 -0
- package/dist/js/chunks/{chunk-Z2NRKI7R.mjs → chunk-DXGRXYYL.mjs} +25 -37
- package/dist/js/chunks/chunk-DXGRXYYL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-MZ6Z24BX.mjs → chunk-FM5CZOUB.mjs} +3 -7
- package/dist/js/chunks/{chunk-MZ6Z24BX.mjs.map → chunk-FM5CZOUB.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-5HQSGDZ5.mjs → chunk-GJL6GCIU.mjs} +34 -55
- package/dist/js/chunks/chunk-GJL6GCIU.mjs.map +7 -0
- package/dist/js/chunks/chunk-K3HZMFMD.mjs +135 -0
- package/dist/js/chunks/chunk-K3HZMFMD.mjs.map +7 -0
- package/dist/js/chunks/{chunk-TBM3FT7G.mjs → chunk-KHXZ2A4K.mjs} +12 -15
- package/dist/js/chunks/{chunk-TBM3FT7G.mjs.map → chunk-KHXZ2A4K.mjs.map} +2 -2
- package/dist/js/chunks/chunk-KQACNQ22.mjs +7 -0
- package/dist/js/chunks/{chunk-KBNN3QDH.mjs.map → chunk-KQACNQ22.mjs.map} +1 -1
- package/dist/js/chunks/{chunk-UEXCIMJZ.mjs → chunk-KUFHW3DS.mjs} +2 -2
- package/dist/js/chunks/{chunk-A7ALMYUR.mjs → chunk-KVJAVDBC.mjs} +7 -15
- package/dist/js/chunks/chunk-KVJAVDBC.mjs.map +7 -0
- package/dist/js/chunks/{chunk-YDCS5S3J.mjs → chunk-L27Q6ZMI.mjs} +2 -2
- package/dist/js/chunks/{chunk-NS2UMNZV.mjs → chunk-LQWUDNHZ.mjs} +3 -3
- package/dist/js/chunks/{chunk-MNPROCZF.mjs → chunk-M372EDXD.mjs} +4 -10
- package/dist/js/chunks/chunk-M372EDXD.mjs.map +7 -0
- package/dist/js/chunks/{chunk-YMSXJON6.mjs → chunk-M3MURWMB.mjs} +15 -12
- package/dist/js/chunks/{chunk-YMSXJON6.mjs.map → chunk-M3MURWMB.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-JIDMQGK6.mjs → chunk-NUHMOAOY.mjs} +18 -33
- package/dist/js/chunks/chunk-NUHMOAOY.mjs.map +7 -0
- package/dist/js/chunks/{chunk-VGZSAFTX.mjs → chunk-OWG3LMUL.mjs} +7 -11
- package/dist/js/chunks/chunk-OWG3LMUL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-LTWPGFBR.mjs → chunk-PD6HYHAE.mjs} +4 -15
- package/dist/js/chunks/chunk-PD6HYHAE.mjs.map +7 -0
- package/dist/js/chunks/{chunk-ZAS25YFD.mjs → chunk-PDG64UHF.mjs} +3 -3
- package/dist/js/chunks/{chunk-QERLECVU.mjs → chunk-PO3AXVR3.mjs} +38 -64
- package/dist/js/chunks/chunk-PO3AXVR3.mjs.map +7 -0
- package/dist/js/chunks/{chunk-ILP3PDTL.mjs → chunk-QYGK36OG.mjs} +7 -13
- package/dist/js/chunks/chunk-QYGK36OG.mjs.map +7 -0
- package/dist/js/chunks/{chunk-S3XDFGSZ.mjs → chunk-SFI2U4YW.mjs} +28 -44
- package/dist/js/chunks/chunk-SFI2U4YW.mjs.map +7 -0
- package/dist/js/chunks/{chunk-FS7XY3HT.mjs → chunk-SMY7GJSS.mjs} +3 -3
- package/dist/js/chunks/{chunk-O5XPWXIQ.mjs → chunk-TCCA2HDG.mjs} +39 -31
- package/dist/js/chunks/chunk-TCCA2HDG.mjs.map +7 -0
- package/dist/js/chunks/{chunk-PM655FXL.mjs → chunk-TSZYSW7F.mjs} +4 -4
- package/dist/js/chunks/{chunk-PM655FXL.mjs.map → chunk-TSZYSW7F.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-UEZUJQ66.mjs → chunk-UAZSDUVP.mjs} +3 -4
- package/dist/js/chunks/{chunk-UEZUJQ66.mjs.map → chunk-UAZSDUVP.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-6N2XAEFK.mjs → chunk-UBRZZWRA.mjs} +10 -8
- package/dist/js/chunks/chunk-UBRZZWRA.mjs.map +7 -0
- package/dist/js/chunks/{chunk-5BKHWHYY.mjs → chunk-UCOE7ZDL.mjs} +41 -46
- package/dist/js/chunks/chunk-UCOE7ZDL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-4TKTLGEM.mjs → chunk-UETTGDLI.mjs} +3 -3
- package/dist/js/chunks/{chunk-RHRQKTTX.mjs → chunk-UNCRDLP6.mjs} +6 -9
- package/dist/js/chunks/chunk-UNCRDLP6.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GUB3TNO2.mjs → chunk-VGNYF6FB.mjs} +3 -6
- package/dist/js/chunks/{chunk-GUB3TNO2.mjs.map → chunk-VGNYF6FB.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-X7OCHZVF.mjs → chunk-VGPGBNGL.mjs} +4 -12
- package/dist/js/chunks/chunk-VGPGBNGL.mjs.map +7 -0
- package/dist/js/chunks/chunk-VKAUVTQY.mjs +1 -0
- package/dist/js/chunks/{chunk-HKT2S7VM.mjs → chunk-VM4FTS7L.mjs} +3 -3
- package/dist/js/chunks/{chunk-3GVFZ4XO.mjs → chunk-WDK4T63U.mjs} +8 -11
- package/dist/js/chunks/chunk-WDK4T63U.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GZKEFWPM.mjs → chunk-WOCCTVUF.mjs} +38 -34
- package/dist/js/chunks/chunk-WOCCTVUF.mjs.map +7 -0
- package/dist/js/chunks/{chunk-QJABDLSD.mjs → chunk-WQYN5L4E.mjs} +11 -16
- package/dist/js/chunks/chunk-WQYN5L4E.mjs.map +7 -0
- package/dist/js/chunks/{chunk-DAIU5SLG.mjs → chunk-X4ISMKE2.mjs} +2 -2
- package/dist/js/chunks/{chunk-3DHK5CZU.mjs → chunk-XAEAEHIX.mjs} +6 -8
- package/dist/js/chunks/chunk-XAEAEHIX.mjs.map +7 -0
- package/dist/js/chunks/{chunk-4HZMB7LI.mjs → chunk-ZX6M7SWO.mjs} +24 -24
- package/dist/js/chunks/chunk-ZX6M7SWO.mjs.map +7 -0
- package/dist/js/expressive.cjs +484 -507
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +484 -507
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +10 -13
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +54 -50
- package/dist/js/expressive.mjs.map +1 -1
- package/dist/js/internal/behaviors/bottomSheets.mjs +3 -3
- package/dist/js/internal/behaviors/dialogs.mjs +2 -2
- package/dist/js/internal/behaviors/forms.mjs +2 -2
- package/dist/js/internal/behaviors/sheetDrag.mjs +2 -2
- package/dist/js/internal/behaviors/sideSheets.mjs +3 -3
- package/dist/js/internal/components/appBar.mjs +2 -2
- package/dist/js/internal/components/autocomplete.mjs +4 -4
- package/dist/js/internal/components/barChart.mjs +4 -4
- package/dist/js/internal/components/buttonGroup.mjs +2 -2
- package/dist/js/internal/components/buttons.mjs +3 -3
- package/dist/js/internal/components/cards.mjs +3 -3
- package/dist/js/internal/components/carousel.mjs +3 -3
- package/dist/js/internal/components/characterCounter.mjs +2 -2
- package/dist/js/internal/components/chips.mjs +5 -5
- package/dist/js/internal/components/columnChart.mjs +3 -3
- package/dist/js/internal/components/commandPalette.mjs +3 -3
- package/dist/js/internal/components/confetti.mjs +2 -2
- package/dist/js/internal/components/datepicker.mjs +6 -6
- package/dist/js/internal/components/expandingCard.mjs +3 -3
- package/dist/js/internal/components/heatmapChart.mjs +3 -3
- package/dist/js/internal/components/index.mjs +47 -43
- package/dist/js/internal/components/keypad.mjs +9 -0
- package/dist/js/internal/components/keypad.mjs.map +7 -0
- package/dist/js/internal/components/lightbox.mjs +3 -3
- package/dist/js/internal/components/lineChart.mjs +6 -2
- package/dist/js/internal/components/mapView.mjs +3 -3
- package/dist/js/internal/components/menu.mjs +3 -3
- package/dist/js/internal/components/messageScroller.mjs +3 -3
- package/dist/js/internal/components/mixedChart.mjs +4 -4
- package/dist/js/internal/components/navigationRail.mjs +2 -2
- package/dist/js/internal/components/particles.mjs +2 -2
- package/dist/js/internal/components/pieChart.mjs +3 -3
- package/dist/js/internal/components/questionnaire.mjs +3 -3
- package/dist/js/internal/components/radarChart.mjs +3 -3
- package/dist/js/internal/components/radialChart.mjs +3 -3
- package/dist/js/internal/components/registry.mjs +41 -40
- package/dist/js/internal/components/richTextEditor.mjs +3 -3
- package/dist/js/internal/components/scrollspy.mjs +2 -2
- package/dist/js/internal/components/select.mjs +4 -4
- package/dist/js/internal/components/slider.mjs +3 -3
- package/dist/js/internal/components/snackbar.mjs +2 -2
- package/dist/js/internal/components/tabs.mjs +4 -4
- package/dist/js/internal/components/timepicker.mjs +4 -4
- package/dist/js/internal/components/tooltip.mjs +3 -3
- package/dist/js/internal/core/component.mjs +1 -1
- package/dist/js/internal/core/utils.mjs +1 -1
- package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +2 -2
- package/dist/js/modular.mjs +54 -50
- package/dist/types/components/autocomplete.d.ts +1 -0
- package/dist/types/components/datepicker.d.ts +3 -4
- package/dist/types/components/expandingCard.d.ts +2 -0
- package/dist/types/components/index.d.ts +1 -0
- package/dist/types/components/keypad.d.ts +34 -0
- package/dist/types/components/lightbox.d.ts +3 -5
- package/dist/types/components/lineChart.d.ts +4 -0
- package/dist/types/components/menu.d.ts +1 -0
- package/dist/types/components/radialChart.d.ts +0 -1
- package/dist/types/components/registry.d.ts +4 -0
- package/dist/types/components/slider.d.ts +2 -0
- package/dist/types/components/snackbar.d.ts +1 -0
- package/dist/types/components/tabs.d.ts +4 -0
- package/dist/types/components/timepicker.d.ts +2 -0
- package/dist/types/modular.d.ts +1 -1
- package/dist/types/plugins/dockedDisplayPlugin.d.ts +1 -0
- package/package.json +1 -1
- package/src/sass/abstracts/_breakpoints.scss +0 -1
- package/src/sass/abstracts/_elevation.scss +1 -1
- package/src/sass/abstracts/_mixins.scss +20 -60
- package/src/sass/abstracts/_variables.scss +10 -0
- package/src/sass/base/_global.scss +3 -12
- package/src/sass/base/_index.scss +1 -1
- package/src/sass/components/_badges.scss +1 -8
- package/src/sass/components/_bar-chart.scss +1 -1
- package/src/sass/components/_button-groups.scss +31 -66
- package/src/sass/components/_cards.scss +6 -25
- package/src/sass/components/_carousel.scss +16 -55
- package/src/sass/components/_chips.scss +0 -6
- package/src/sass/components/_column-chart.scss +1 -1
- package/src/sass/components/_data-table.scss +1 -3
- package/src/sass/components/_datepicker.scss +3 -22
- package/src/sass/components/_dialog.scss +1 -4
- package/src/sass/components/_heatmap-chart.scss +2 -2
- package/src/sass/components/_icon-buttons.scss +0 -1
- package/src/sass/components/_index.scss +1 -0
- package/src/sass/components/_keypad.scss +162 -0
- package/src/sass/components/_lightbox.scss +3 -8
- package/src/sass/components/_map.scss +2 -2
- package/src/sass/components/_menu.scss +31 -74
- package/src/sass/components/_mixed-chart.scss +1 -1
- package/src/sass/components/_navbar.scss +9 -45
- package/src/sass/components/_navigation-rail.scss +23 -32
- package/src/sass/components/_page-footer.scss +15 -12
- package/src/sass/components/_panes.scss +2 -6
- package/src/sass/components/_progress.scss +6 -4
- package/src/sass/components/_side-sheet.scss +1 -4
- package/src/sass/components/_stepper.scss +0 -4
- package/src/sass/components/_timepicker.scss +4 -36
- package/src/sass/components/_toolbar.scss +0 -4
- package/src/sass/components/forms/_checkboxes.scss +37 -65
- package/src/sass/components/forms/_fieldset.scss +3 -3
- package/src/sass/components/forms/_file-input.scss +0 -1
- package/src/sass/components/forms/_radio-buttons.scss +10 -36
- package/src/sass/components/forms/_select.scss +0 -3
- package/src/sass/components/forms/_slider.scss +72 -259
- package/src/sass/tokens/_state.scss +2 -2
- package/src/sass/tokens/_theme.scss +1 -1
- package/src/sass/utilities/_colors.scss +6 -1
- package/src/sass/utilities/_index.scss +1 -1
- package/dist/js/chunks/chunk-3DHK5CZU.mjs.map +0 -7
- package/dist/js/chunks/chunk-3GVFZ4XO.mjs.map +0 -7
- package/dist/js/chunks/chunk-4HZMB7LI.mjs.map +0 -7
- package/dist/js/chunks/chunk-5BKHWHYY.mjs.map +0 -7
- package/dist/js/chunks/chunk-5HQSGDZ5.mjs.map +0 -7
- package/dist/js/chunks/chunk-6N2XAEFK.mjs.map +0 -7
- package/dist/js/chunks/chunk-A7ALMYUR.mjs.map +0 -7
- package/dist/js/chunks/chunk-GZKEFWPM.mjs.map +0 -7
- package/dist/js/chunks/chunk-ILP3PDTL.mjs.map +0 -7
- package/dist/js/chunks/chunk-JIDMQGK6.mjs.map +0 -7
- package/dist/js/chunks/chunk-KBNN3QDH.mjs +0 -7
- package/dist/js/chunks/chunk-KHV6DZXX.mjs.map +0 -7
- package/dist/js/chunks/chunk-KY6U46SM.mjs.map +0 -7
- package/dist/js/chunks/chunk-LRZMJZ3T.mjs.map +0 -7
- package/dist/js/chunks/chunk-LTWPGFBR.mjs.map +0 -7
- package/dist/js/chunks/chunk-MNPROCZF.mjs.map +0 -7
- package/dist/js/chunks/chunk-O5XPWXIQ.mjs.map +0 -7
- package/dist/js/chunks/chunk-QERLECVU.mjs.map +0 -7
- package/dist/js/chunks/chunk-QJABDLSD.mjs.map +0 -7
- package/dist/js/chunks/chunk-RHRQKTTX.mjs.map +0 -7
- package/dist/js/chunks/chunk-S3XDFGSZ.mjs.map +0 -7
- package/dist/js/chunks/chunk-SPETGK25.mjs.map +0 -7
- package/dist/js/chunks/chunk-VGZSAFTX.mjs.map +0 -7
- package/dist/js/chunks/chunk-X7OCHZVF.mjs.map +0 -7
- package/dist/js/chunks/chunk-Z2NRKI7R.mjs.map +0 -7
- package/dist/js/chunks/chunk-ZKZKNSLC.mjs +0 -1
- /package/dist/js/chunks/{chunk-4KMNFIFZ.mjs.map → chunk-33QVDDGR.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-CUQPB25U.mjs.map → chunk-AIURVCG6.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-BG6ZRB5H.mjs.map → chunk-C6CHEWYP.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-GVGT6MIU.mjs.map → chunk-CK2XCICY.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-UEXCIMJZ.mjs.map → chunk-KUFHW3DS.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-YDCS5S3J.mjs.map → chunk-L27Q6ZMI.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-NS2UMNZV.mjs.map → chunk-LQWUDNHZ.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-ZAS25YFD.mjs.map → chunk-PDG64UHF.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-FS7XY3HT.mjs.map → chunk-SMY7GJSS.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-4TKTLGEM.mjs.map → chunk-UETTGDLI.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-ZKZKNSLC.mjs.map → chunk-VKAUVTQY.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-HKT2S7VM.mjs.map → chunk-VM4FTS7L.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-DAIU5SLG.mjs.map → chunk-X4ISMKE2.mjs.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Component
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PD6HYHAE.mjs";
|
|
4
4
|
|
|
5
5
|
// src/ts/components/lineChart.ts
|
|
6
6
|
var _defaults = {
|
|
@@ -14,13 +14,19 @@ function svgNode(name, attributes = {}) {
|
|
|
14
14
|
for (const key in attributes) element.setAttribute(key, attributes[key]);
|
|
15
15
|
return element;
|
|
16
16
|
}
|
|
17
|
+
function polarPoint(turn, r) {
|
|
18
|
+
const angle = turn * 2 * Math.PI;
|
|
19
|
+
return `${(r * Math.sin(angle)).toFixed(3)},${(-r * Math.cos(angle)).toFixed(3)}`;
|
|
20
|
+
}
|
|
21
|
+
var seriesColor = (i) => String(i % COLORS + 1);
|
|
17
22
|
var _gradientId = 0;
|
|
18
23
|
function cellValue(cell) {
|
|
19
24
|
if (!cell) return null;
|
|
20
25
|
const raw = cell.dataset.value ?? cell.textContent;
|
|
21
26
|
const text = raw.replace(/\u2212/g, "-").replace(/[\s%\p{Sc}]/gu, "");
|
|
22
|
-
if (!/^[+-]?(\d{1,3}(,\d{3})+|\d+)?(\.\d+)?(e[+-]?\d+)?$/i.test(text)
|
|
23
|
-
|
|
27
|
+
if (!/^[+-]?(\d{1,3}(,\d{3})+|\d+)?(\.\d+)?(e[+-]?\d+)?$/i.test(text)) return null;
|
|
28
|
+
const value = parseFloat(text.replace(/,/g, ""));
|
|
29
|
+
return Number.isFinite(value) ? value : null;
|
|
24
30
|
}
|
|
25
31
|
function monotonePath(points) {
|
|
26
32
|
const n = points.length;
|
|
@@ -161,7 +167,7 @@ var LineChart = class extends Component {
|
|
|
161
167
|
this.series.forEach((series, i) => {
|
|
162
168
|
const value = series.values[index];
|
|
163
169
|
if (value === null) return;
|
|
164
|
-
const color =
|
|
170
|
+
const color = seriesColor(i);
|
|
165
171
|
const top = series.tops[index];
|
|
166
172
|
if (top !== null && this._points) {
|
|
167
173
|
const dot = document.createElement("span");
|
|
@@ -313,7 +319,7 @@ var LineChart = class extends Component {
|
|
|
313
319
|
legend.setAttribute("aria-hidden", "true");
|
|
314
320
|
legend.append(...this.series.map((series, i) => {
|
|
315
321
|
const li = document.createElement("li");
|
|
316
|
-
li.dataset.series =
|
|
322
|
+
li.dataset.series = seriesColor(i);
|
|
317
323
|
li.textContent = series.name;
|
|
318
324
|
return li;
|
|
319
325
|
}));
|
|
@@ -321,15 +327,17 @@ var LineChart = class extends Component {
|
|
|
321
327
|
}
|
|
322
328
|
/** Draws the series, which fill the plot. */
|
|
323
329
|
_draw(drawn = this.series) {
|
|
324
|
-
const svg =
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
330
|
+
const svg = svgNode("svg", {
|
|
331
|
+
viewBox: "0 0 100 100",
|
|
332
|
+
preserveAspectRatio: "none",
|
|
333
|
+
"aria-hidden": "true",
|
|
334
|
+
focusable: "false"
|
|
335
|
+
});
|
|
329
336
|
for (const series of drawn) {
|
|
330
|
-
const group =
|
|
331
|
-
|
|
332
|
-
|
|
337
|
+
const group = svgNode("g", {
|
|
338
|
+
class: `${this._type}-series ${series.className}`.trim(),
|
|
339
|
+
"data-series": seriesColor(this.series.indexOf(series))
|
|
340
|
+
});
|
|
333
341
|
const runs = [[]];
|
|
334
342
|
series.tops.forEach((value, index) => {
|
|
335
343
|
if (value === null) runs.push([]);
|
|
@@ -339,23 +347,21 @@ var LineChart = class extends Component {
|
|
|
339
347
|
const points = (run, values) => run.map((index) => [this._x(index), series.y(values[index])]);
|
|
340
348
|
const tops = filled.map((run) => monotonePath(points(run, series.tops)));
|
|
341
349
|
const id = `line-chart-gradient-${++_gradientId}`;
|
|
342
|
-
const gradient =
|
|
343
|
-
gradient.
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
})
|
|
356
|
-
const line =
|
|
357
|
-
line.setAttribute("class", `${this._type}-line`);
|
|
358
|
-
line.setAttribute("d", tops.join(""));
|
|
350
|
+
const gradient = svgNode("linearGradient", { id, x2: "0", y2: "1" });
|
|
351
|
+
gradient.append(svgNode("stop"), svgNode("stop", { offset: "1" }));
|
|
352
|
+
const area = svgNode("path", {
|
|
353
|
+
class: `${this._type}-area`,
|
|
354
|
+
fill: `url(#${id})`,
|
|
355
|
+
// A stacked area runs back along the series below; the reversed curve
|
|
356
|
+
// is the same curve. Its base stops at the plot bottom when the y axis
|
|
357
|
+
// starts above zero.
|
|
358
|
+
d: filled.map((run, r) => {
|
|
359
|
+
if (!series.base) return `${tops[r]}V100H${this._x(run[0])}Z`;
|
|
360
|
+
const base = points(run, series.base).map(([x, y]) => [x, Math.min(100, y)]);
|
|
361
|
+
return `${tops[r]}L${monotonePath(base.reverse()).slice(1)}Z`;
|
|
362
|
+
}).join("")
|
|
363
|
+
});
|
|
364
|
+
const line = svgNode("path", { class: `${this._type}-line`, d: tops.join("") });
|
|
359
365
|
group.append(gradient, area, line);
|
|
360
366
|
svg.append(group);
|
|
361
367
|
}
|
|
@@ -401,6 +407,8 @@ var LineChart = class extends Component {
|
|
|
401
407
|
export {
|
|
402
408
|
COLORS,
|
|
403
409
|
svgNode,
|
|
410
|
+
polarPoint,
|
|
411
|
+
seriesColor,
|
|
404
412
|
LineChart
|
|
405
413
|
};
|
|
406
|
-
//# sourceMappingURL=chunk-
|
|
414
|
+
//# sourceMappingURL=chunk-TCCA2HDG.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ts/components/lineChart.ts"],
|
|
4
|
+
"sourcesContent": ["import { Component, BaseOptions, InitElements, InitElement } from '../core/component';\n\nexport interface LineChartOptions extends BaseOptions {\n /**\n * Lowest value on the y axis. Defaults to the data minimum less 10% of\n * the range; a stacked chart starts at zero or its lowest total, and a\n * column chart always includes zero. Overridden by `data-min` on the chart.\n */\n min: number | null;\n /**\n * Highest value on the y axis. Defaults to the data maximum plus 10% of\n * the range. Overridden by `data-max` on the chart.\n */\n max: number | null;\n}\n\nconst _defaults: LineChartOptions = {\n min: null,\n max: null\n};\n\nconst SVG = 'http://www.w3.org/2000/svg';\nexport const COLORS = 4;\n\n/** An SVG element with its attributes. */\nexport function svgNode(name: string, attributes: Record<string, string> = {}): SVGElement {\n const element = document.createElementNS(SVG, name);\n for (const key in attributes) element.setAttribute(key, attributes[key]);\n return element;\n}\n\n/** A point at a turn clockwise from the top and a distance from the middle, as \"x,y\". */\nexport function polarPoint(turn: number, r: number): string {\n const angle = turn * 2 * Math.PI;\n return `${(r * Math.sin(angle)).toFixed(3)},${(-r * Math.cos(angle)).toFixed(3)}`;\n}\n\n/** A series' color number, for its `data-series`. */\nexport const seriesColor = (i: number) => String((i % COLORS) + 1);\nlet _gradientId = 0;\n\nexport interface Series {\n name: string;\n /** Header cell classes, such as `dashed`. */\n className: string;\n /** Cell text, shown in the tooltip as the author formatted it. */\n text: string[];\n values: (number | null)[];\n /**\n * Where each value is drawn: the value, or in a stacked chart the running\n * total, which is unknown (null) above a gap.\n */\n tops: (number | null)[];\n /** In a stacked chart, the total of the series below, which this area fills down to. */\n base?: (number | null)[];\n /** The series' y scale: a value's distance down the plot, in percent. */\n y: (value: number) => number;\n}\n\n/**\n * Reads a cell as a number. `data-value` wins over the text, which may carry\n * currency or percent signs, grouping commas and a typographic minus around\n * one number. Anything else, such as \"(1,200)\" or \"3\u20135\", is a gap rather\n * than a guess.\n */\nfunction cellValue(cell: Element | undefined): number | null {\n if (!cell) return null;\n const raw = (cell as HTMLElement).dataset.value ?? cell.textContent;\n const text = raw.replace(/\\u2212/g, '-').replace(/[\\s%\\p{Sc}]/gu, '');\n if (!/^[+-]?(\\d{1,3}(,\\d{3})+|\\d+)?(\\.\\d+)?(e[+-]?\\d+)?$/i.test(text)) return null;\n // The pattern also lets through \"e5\" (NaN) and \"1e400\" (Infinity).\n const value = parseFloat(text.replace(/,/g, ''));\n return Number.isFinite(value) ? value : null;\n}\n\n/**\n * A monotone cubic through the points (Fritsch-Butland tangents), so the\n * curve never overshoots a data point. Bezier curves keep their shape under\n * the plot's non-uniform scaling, so this can be drawn in a 0-100 box.\n */\nfunction monotonePath(points: [number, number][]): string {\n const n = points.length;\n if (n === 0) return '';\n if (n === 1) return `M${points[0][0]},${points[0][1]}h0`;\n const slopes: number[] = [];\n for (let i = 0; i < n - 1; i++) {\n slopes.push((points[i + 1][1] - points[i][1]) / (points[i + 1][0] - points[i][0]));\n }\n const tangents = points.map((_, i) => {\n if (i === 0) return slopes[0];\n if (i === n - 1) return slopes[n - 2];\n const [a, b] = [slopes[i - 1], slopes[i]];\n return a * b <= 0 ? 0 : 2 / (1 / a + 1 / b);\n });\n let d = `M${points[0][0]},${points[0][1]}`;\n for (let i = 0; i < n - 1; i++) {\n const [[x0, y0], [x1, y1]] = [points[i], points[i + 1]];\n const h = (x1 - x0) / 3;\n d += `C${x0 + h},${y0 + tangents[i] * h} ${x1 - h},${y1 - tangents[i + 1] * h} ${x1},${y1}`;\n }\n return d;\n}\n\n/**\n * Line chart. The data is the chart's <table>; this class draws it as an SVG\n * with x labels, a legend for more than one series, and a cursor and tooltip\n * that follow the pointer or the arrow keys. Styling is CSS.\n *\n * Re-run `LineChart.init(el)` after changing the table.\n */\nexport class LineChart extends Component<LineChartOptions> {\n /** The values' x positions and series, read from the table. */\n labels: string[] = [];\n series: Series[] = [];\n /** The highlighted row, or -1. */\n activeIndex = -1;\n private _generated: Element[] = [];\n /** The table's header cells and body rows, as read. */\n protected _header: HTMLTableCellElement[] = [];\n protected _rows: HTMLTableRowElement[] = [];\n protected _plot: HTMLElement;\n protected _cursor: HTMLElement;\n protected _tooltip: HTMLElement;\n protected _y: (value: number) => number;\n /**\n * Whether the rows run right to left: a horizontal row axis in a\n * right-to-left context, like the labels. Bar chart rows keep their order.\n */\n protected _reversed = false;\n\n /** The class prefix of the generated parts; ColumnChart reuses this class. */\n protected get _type() {\n return 'line-chart';\n }\n\n /** Whether the y axis always includes zero, as columns grow from it. */\n protected get _fromZero() {\n return false;\n }\n\n /**\n * Whether the rows run down the plot and the values across it, as in a\n * bar chart. The rows then keep their order in a right-to-left context.\n */\n protected get _horizontal() {\n return false;\n }\n\n /**\n * Whether the rows go round a circle, as in a pie or radar chart. The\n * arrows then step round it, wrapping from the last row to the first.\n */\n protected get _circular() {\n return false;\n }\n\n /** Whether the cursor marks each series with a point. */\n protected get _points() {\n return true;\n }\n\n protected get _key() {\n return 'Expressive_LineChart';\n }\n\n constructor(el: HTMLElement, options: Partial<LineChartOptions>) {\n super(el, options, new.target);\n this.el[this._key] = this;\n\n this.options = {\n ...new.target.defaults,\n ...options\n };\n\n this._read();\n if (!this.labels.length || !this.series.length) return;\n this._reversed = !this._horizontal && getComputedStyle(this.el).direction === 'rtl';\n this._render();\n if (!this.el.classList.contains('sparkline')) {\n this._plot.tabIndex = 0;\n // A tap has no move before it, so the press picks the row too.\n this._plot.addEventListener('pointerdown', this._onPointerMove);\n this._plot.addEventListener('pointermove', this._onPointerMove);\n this._plot.addEventListener('pointerleave', this._onLeave);\n this._plot.addEventListener('pointercancel', this._onCancel);\n this._plot.addEventListener('keydown', this._onKeyDown);\n this._plot.addEventListener('focus', this._onFocus);\n this._plot.addEventListener('blur', this._onLeave);\n }\n }\n\n static get defaults(): LineChartOptions {\n return _defaults;\n }\n\n static init(el: HTMLElement, options?: Partial<LineChartOptions>): LineChart;\n static init(els: InitElements<InitElement>, options?: Partial<LineChartOptions>): LineChart[];\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<LineChartOptions> = {}\n ): LineChart | LineChart[] {\n return super.init(els, options, this);\n }\n\n static getInstance(el: HTMLElement): LineChart {\n return el['Expressive_LineChart'];\n }\n\n destroy() {\n // The listeners live on the plot, which goes with the generated nodes.\n this._generated.forEach((node) => node.remove());\n this._generated = [];\n this.el[this._key] = undefined;\n }\n\n /**\n * Highlights one row: moves the cursor and fills the tooltip.\n * Pass -1 to hide them. Does nothing for a chart without data.\n */\n show(index: number) {\n // Skipping a repeat also keeps the live tooltip from re-announcing.\n if (!this._tooltip || index === this.activeIndex) return;\n this.activeIndex = index;\n const hidden = index < 0 || index >= this.labels.length;\n this._cursor.hidden = this._tooltip.hidden = hidden;\n if (hidden) return;\n\n this._cursor.replaceChildren();\n const title = document.createElement('strong');\n title.textContent = this.labels[index];\n this._tooltip.replaceChildren(title);\n\n this.series.forEach((series, i) => {\n const value = series.values[index];\n if (value === null) return;\n const color = seriesColor(i);\n const top = series.tops[index];\n if (top !== null && this._points) {\n const dot = document.createElement('span');\n dot.className = series.className;\n dot.dataset.series = color;\n dot.style.top = `${series.y(top)}%`;\n this._cursor.append(dot);\n }\n const name = document.createElement('span');\n name.dataset.series = color;\n name.textContent = series.name;\n const text = document.createElement('span');\n text.textContent = series.text[index];\n this._tooltip.append(name, text);\n });\n this._place(index);\n }\n\n /**\n * Moves the filled cursor and tooltip to a row: beside its band, with the\n * tooltip opening back over the plot past the middle.\n */\n protected _place(index: number) {\n const x = this._x(index);\n const side = this._horizontal ? 'top' : 'left';\n this._cursor.style[side] = this._tooltip.style[side] = `${x}%`;\n this._tooltip.classList.toggle('end', x > 50);\n }\n\n private _read() {\n const table = this.el.querySelector<HTMLTableElement>(':scope > table');\n if (!table) return;\n // Without a <thead> the parser puts the header row in the first <tbody>.\n const headerRow = table.tHead?.rows[0] ?? table.rows[0];\n const header = Array.from(headerRow?.cells ?? []);\n const rows = Array.from(table.tBodies)\n .flatMap((body) => Array.from(body.rows))\n .filter((row) => row !== headerRow);\n [this._header, this._rows] = [header, rows];\n this.labels = rows.map((row) => row.cells[0]?.textContent.trim() ?? '');\n this.series = header.slice(1).map((cell, i) => {\n const values = rows.map((row) => cellValue(row.cells[i + 1]));\n return {\n name: cell.textContent.trim(),\n className: cell.className,\n text: rows.map((row) => row.cells[i + 1]?.textContent.trim() ?? ''),\n values,\n tops: values,\n y: undefined\n };\n });\n const stacked = this.el.classList.contains('stacked');\n if (stacked) {\n // A gap leaves the total unknown, so the series above break there too.\n // ponytail: negative values overlap the band below; diverging stacks if needed.\n const totals: (number | null)[] = this.labels.map(() => 0);\n for (const series of this.series) {\n series.base = [...totals];\n series.tops = series.values.map((value, i) =>\n (totals[i] = value === null || totals[i] === null ? null : totals[i] + value));\n }\n }\n\n if (this.series.every((series) => series.tops.every((value) => value === null))) this.series = [];\n const option = (name: 'min' | 'max') => this._number(name) ?? this.options[name];\n this._y = this._scale(this.series, option('min'), option('max'));\n }\n\n /** A number from one of the chart's data attributes, or null. */\n protected _number(name: string) {\n const value = parseFloat(this.el.dataset[name] ?? '');\n return Number.isFinite(value) ? value : null;\n }\n\n /**\n * Fits a y scale to the series' tops, between `min` and `max` where they\n * are set, and gives it to each series.\n */\n protected _scale(series: Series[], min: number | null, max: number | null, fromZero = this._fromZero) {\n const stacked = this.el.classList.contains('stacked');\n let [low, high] = [Infinity, -Infinity];\n for (const { tops } of series) {\n for (const value of tops) {\n if (value === null) continue;\n low = Math.min(low, value);\n high = Math.max(high, value);\n }\n }\n if (low > high) low = high = 0;\n if (fromZero) {\n // Zero is on the scale, with 10% of the span to spare on each side\n // that has data.\n const [bottom, top] = [Math.min(0, low), Math.max(0, high)];\n const room = (top - (min ?? bottom)) * 0.1 || 1;\n min ??= bottom < 0 ? bottom - room : 0;\n max ??= top + room;\n } else {\n const pad = (high - low) * 0.1 || 1;\n // Stacked areas are read against zero, with the headroom of that span.\n min ??= stacked ? Math.min(0, low) : low - pad;\n max ??= high + (stacked ? (high - min) * 0.1 || 1 : pad);\n }\n const y = (value: number) => 100 - ((value - min) / (max - min || 1)) * 100;\n for (const each of series) each.y = y;\n return y;\n }\n\n /** Each row sits in the middle of an equal band, beside its label. */\n private _x(index: number) {\n const x = ((index + 0.5) / this.labels.length) * 100;\n return this._reversed ? 100 - x : x;\n }\n\n private _render() {\n const type = this._type;\n this._plot = document.createElement('div');\n this._plot.className = `${type}-plot`;\n const caption = this.el.querySelector(':scope > figcaption')?.textContent.trim();\n this._plot.setAttribute('role', 'group');\n this._plot.setAttribute('aria-roledescription', type.replace(/-/g, ' '));\n if (caption) this._plot.setAttribute('aria-label', caption);\n\n this._cursor = document.createElement('div');\n this._cursor.className = `${type}-cursor`;\n this._cursor.hidden = true;\n this._tooltip = document.createElement('div');\n this._tooltip.className = `${type}-tooltip`;\n this._tooltip.hidden = true;\n this._tooltip.setAttribute('aria-live', 'polite');\n this._plot.append(this._draw(), this._cursor, this._tooltip);\n\n this._generated = [this._plot, ...this._guides()];\n this.el.append(...this._generated);\n }\n\n /**\n * The <tfoot> row as a total to show over the plot, its value over its\n * label, or null without one.\n */\n protected _total(className: string): HTMLElement | null {\n const footer = this.el.querySelector<HTMLTableElement>(':scope > table')?.tFoot?.rows[0];\n if (!footer) return null;\n const total = document.createElement('div');\n total.className = className;\n const [label, value] = [document.createElement('span'), document.createElement('strong')];\n label.textContent = footer.cells[0]?.textContent.trim() ?? '';\n value.textContent = footer.cells[1]?.textContent.trim() ?? '';\n total.append(value, label);\n return total;\n }\n\n /** The parts below the plot: the row labels and the legend. */\n protected _guides(): Element[] {\n const labels = document.createElement('ol');\n labels.className = `${this._type}-labels`;\n labels.setAttribute('aria-hidden', 'true');\n // A loop rather than a spread: a spread of every row overflows the stack.\n for (const text of this.labels) {\n const li = document.createElement('li');\n li.textContent = text;\n labels.append(li);\n }\n return [labels, ...this._legend()];\n }\n\n /** The series legend, for more than one series. */\n protected _legend(): Element[] {\n if (this.series.length < 2) return [];\n const legend = document.createElement('ul');\n legend.className = `${this._type}-legend`;\n legend.setAttribute('aria-hidden', 'true');\n legend.append(...this.series.map((series, i) => {\n const li = document.createElement('li');\n li.dataset.series = seriesColor(i);\n li.textContent = series.name;\n return li;\n }));\n return [legend];\n }\n\n /** Draws the series, which fill the plot. */\n protected _draw(drawn = this.series): Element {\n const svg = svgNode('svg', {\n viewBox: '0 0 100 100',\n preserveAspectRatio: 'none',\n 'aria-hidden': 'true',\n focusable: 'false'\n });\n\n for (const series of drawn) {\n const group = svgNode('g', {\n class: `${this._type}-series ${series.className}`.trim(),\n 'data-series': seriesColor(this.series.indexOf(series))\n });\n\n // A gap in the data breaks the line into runs of row indexes.\n const runs: number[][] = [[]];\n series.tops.forEach((value, index) => {\n if (value === null) runs.push([]);\n else runs[runs.length - 1].push(index);\n });\n const filled = runs.filter((run) => run.length);\n const points = (run: number[], values: (number | null)[]) =>\n run.map((index): [number, number] => [this._x(index), series.y(values[index]!)]);\n const tops = filled.map((run) => monotonePath(points(run, series.tops)));\n\n const id = `line-chart-gradient-${++_gradientId}`;\n const gradient = svgNode('linearGradient', { id, x2: '0', y2: '1' });\n gradient.append(svgNode('stop'), svgNode('stop', { offset: '1' }));\n\n const area = svgNode('path', {\n class: `${this._type}-area`,\n fill: `url(#${id})`,\n // A stacked area runs back along the series below; the reversed curve\n // is the same curve. Its base stops at the plot bottom when the y axis\n // starts above zero.\n d: filled\n .map((run, r) => {\n if (!series.base) return `${tops[r]}V100H${this._x(run[0])}Z`;\n const base = points(run, series.base).map(([x, y]): [number, number] => [x, Math.min(100, y)]);\n return `${tops[r]}L${monotonePath(base.reverse()).slice(1)}Z`;\n })\n .join('')\n });\n\n const line = svgNode('path', { class: `${this._type}-line`, d: tops.join('') });\n\n group.append(gradient, area, line);\n svg.append(group);\n }\n return svg;\n }\n\n private _onPointerMove = (e: PointerEvent) => {\n this.show(this._indexAt(e));\n };\n\n /** The row under the pointer, or -1. */\n protected _indexAt(e: PointerEvent) {\n const box = this._plot.getBoundingClientRect();\n const fraction = this._horizontal\n ? (e.clientY - box.top) / box.height\n : (e.clientX - box.left) / box.width;\n const index = Math.floor((this._reversed ? 1 - fraction : fraction) * this.labels.length);\n return Math.min(this.labels.length - 1, Math.max(0, index));\n }\n\n /**\n * For a circular chart, the pointer's position from the plot's middle: a\n * fraction of a turn clockwise from the top, and its distance as a share\n * of the plot's width.\n */\n protected _polarAt(e: PointerEvent): [turn: number, distance: number] {\n const box = this._plot.getBoundingClientRect();\n const [x, y] = [e.clientX - box.left - box.width / 2, e.clientY - box.top - box.height / 2];\n return [(Math.atan2(x, -y) / (2 * Math.PI) + 1) % 1, Math.hypot(x, y) / box.width];\n }\n\n /** The keys that move to the next row and to the one before. */\n protected get _arrows(): [string[], string[]] {\n // Round a circle both pairs work. The rows run clockwise in RTL too, so\n // right still moves the way the top row turns.\n if (this._circular) return [['ArrowRight', 'ArrowDown'], ['ArrowLeft', 'ArrowUp']];\n // Arrows move the cursor the way they point, so they swap in RTL.\n if (this._horizontal) return [['ArrowDown'], ['ArrowUp']];\n return this._reversed ? [['ArrowLeft'], ['ArrowRight']] : [['ArrowRight'], ['ArrowLeft']];\n }\n\n private _onFocus = () => {\n // Only keyboard focus picks the first row; a press off the marks, which\n // focuses the plot too, leaves the tooltip hidden.\n if (this.activeIndex < 0 && this._plot.matches(':focus-visible')) this.show(0);\n };\n\n private _onLeave = (e: Event) => {\n // A touch leaves as it lifts; the tapped row stays until the plot blurs.\n if ((e as PointerEvent).pointerType === 'touch' || this._plot.matches(':focus-visible')) return;\n this.show(-1);\n };\n\n /** The browser took the touch to scroll the page. */\n private _onCancel = () => {\n this.show(-1);\n };\n\n /** The index a key moves to, or undefined for a key the chart ignores. */\n protected _keyTarget(key: string): number | undefined {\n const last = this.labels.length - 1;\n const [forward, back] = this._arrows;\n const step = (by: number) => {\n if (!this._circular) return Math.min(last, Math.max(0, this.activeIndex + by));\n // Round a circle the ends meet; from no row, back starts at the last.\n if (this.activeIndex < 0) return by > 0 ? 0 : last;\n return (this.activeIndex + by + last + 1) % (last + 1);\n };\n // With nothing shown, Escape is left to a dialog or sheet around the chart.\n if (key === 'Escape') return this.activeIndex < 0 ? undefined : -1;\n return forward.includes(key) ? step(1)\n : back.includes(key) ? step(-1)\n : { Home: 0, End: last }[key];\n }\n\n private _onKeyDown = (e: KeyboardEvent) => {\n const next = this._keyTarget(e.key);\n if (next === undefined) return;\n e.preventDefault();\n this.show(next);\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Utils
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-M372EDXD.mjs";
|
|
4
4
|
import {
|
|
5
5
|
Component
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PD6HYHAE.mjs";
|
|
7
7
|
|
|
8
8
|
// src/ts/components/cards.ts
|
|
9
9
|
var _defaults = {
|
|
@@ -169,7 +169,7 @@ var Cards = class _Cards extends Component {
|
|
|
169
169
|
Utils.onDocumentReady(() => {
|
|
170
170
|
const cards = Array.from(document.querySelectorAll(CARDS_SELECTOR)).filter(isCardReveal);
|
|
171
171
|
cards.forEach((el) => {
|
|
172
|
-
if (el
|
|
172
|
+
if (el["Expressive_Cards"] == void 0) this.init(el);
|
|
173
173
|
});
|
|
174
174
|
});
|
|
175
175
|
}
|
|
@@ -180,4 +180,4 @@ export {
|
|
|
180
180
|
isCardReveal,
|
|
181
181
|
Cards
|
|
182
182
|
};
|
|
183
|
-
//# sourceMappingURL=chunk-
|
|
183
|
+
//# sourceMappingURL=chunk-TSZYSW7F.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ts/components/cards.ts"],
|
|
4
|
-
"sourcesContent": ["import { Utils } from '../core/utils';\nimport { Component, BaseOptions, InitElements, InitElement, Openable } from '../core/component';\n\nexport interface CardsOptions extends BaseOptions {\n onOpen: (el: Element) => void;\n onClose: (el: Element) => void;\n}\n\nconst _defaults: CardsOptions = {\n onOpen: null,\n onClose: null\n};\n\n/**\n * What counts as a card reveal.\n *\n * Shared with `components/registry.ts` so `Cards.Init()` and `AutoInit()` use\n * the same semantic selector.\n */\nexport const CARDS_SELECTOR =\n 'article:has(> aside[id]:not([id=\"\"])):not(:has(> aside ~ aside)):has(> button.card-reveal-trigger[type=\"button\"], > :not(aside) button.card-reveal-trigger[type=\"button\"])';\n\nconst REVEAL_INITIALIZED_CLASS = 'card-reveal-initialized';\n\nfunction hasAccessibleName(trigger: HTMLButtonElement) {\n const label = trigger.getAttribute('aria-label');\n if (label?.trim()) return true;\n\n const labelledBy = trigger.getAttribute('aria-labelledby');\n if (labelledBy) {\n const referencedText = labelledBy\n .trim()\n .split(/\\s+/)\n .map((id) => trigger.ownerDocument.getElementById(id)?.textContent ?? '')\n .join(' ')\n .trim();\n if (referencedText) return true;\n }\n\n const content = trigger.cloneNode(true) as HTMLButtonElement;\n content.querySelectorAll('[aria-hidden=\"true\"]').forEach((node) => node.remove());\n return Boolean(content.textContent?.trim());\n}\n\nfunction isUsableCardTrigger(\n trigger: HTMLButtonElement,\n card: Element,\n panel: HTMLElement\n) {\n return (\n trigger.closest('article') === card &&\n !panel.contains(trigger) &&\n !trigger.disabled &&\n trigger.getAttribute('aria-disabled') !== 'true' &&\n hasAccessibleName(trigger)\n );\n}\n\nexport function isCardReveal(el: Element): el is HTMLElement {\n if (el.tagName !== 'ARTICLE') return false;\n const panels = el.querySelectorAll<HTMLElement>(':scope > aside');\n if (panels.length !== 1 || !panels[0].id) return false;\n\n return Array.from(\n el.querySelectorAll<HTMLButtonElement>('button.card-reveal-trigger[type=\"button\"]')\n ).some((trigger) => isUsableCardTrigger(trigger, el, panels[0]));\n}\n\nexport class Cards extends Component<CardsOptions> implements Openable {\n isOpen: boolean = false;\n private readonly cardReveal: HTMLElement | null;\n private _activators: HTMLButtonElement[];\n private _ownsRevealInitializedClass = false;\n private _initialAriaControls = new Map<HTMLButtonElement, string | null>();\n private _lastActivator: HTMLButtonElement | null = null;\n\n constructor(el: HTMLElement, options: Partial<CardsOptions> = {}) {\n super(el, options, Cards);\n this.el['Expressive_Cards'] = this;\n\n this.options = {\n ...Cards.defaults,\n ...options\n };\n\n const cardReveals = this.el.querySelectorAll<HTMLElement>(':scope > aside');\n const cardReveal = cardReveals.length === 1 ? cardReveals[0] : null;\n const activators = cardReveal\n ? Array.from(\n this.el.querySelectorAll<HTMLButtonElement>(\n 'button.card-reveal-trigger[type=\"button\"]'\n )\n ).filter(\n (activator) => isUsableCardTrigger(activator, this.el, cardReveal)\n )\n : [];\n\n this.cardReveal = cardReveal?.id && activators.length > 0 ? cardReveal : null;\n this._activators = this.cardReveal ? activators : [];\n\n if (this.cardReveal) {\n this._ownsRevealInitializedClass = !this.el.classList.contains(REVEAL_INITIALIZED_CLASS);\n this.el.classList.add(REVEAL_INITIALIZED_CLASS);\n this._activators.forEach((activator) => {\n this._initialAriaControls.set(activator, activator.getAttribute('aria-controls'));\n activator.ariaExpanded = 'false';\n activator.setAttribute('aria-controls', this.cardReveal.id);\n });\n\n this.cardReveal.classList.remove('open');\n this.cardReveal.inert = true;\n this._setupEventHandlers();\n }\n }\n\n static get defaults(): CardsOptions {\n return _defaults;\n }\n\n /**\n * Initializes instance of Cards.\n * @param el HTML element.\n * @param options Component options.\n */\n static init(el: HTMLElement, options?: Partial<CardsOptions>): Cards;\n /**\n * Initializes instances of Cards.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(els: InitElements<InitElement>, options?: Partial<CardsOptions>): Cards[];\n /**\n * Initializes instances of Cards.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options?: Partial<CardsOptions>\n ): Cards | Cards[] {\n return super.init(els, options, Cards);\n }\n\n static getInstance(el: HTMLElement): Cards {\n return el['Expressive_Cards'];\n }\n\n /**\n * {@inheritDoc}\n */\n destroy() {\n this._removeEventHandlers();\n if (this.cardReveal) {\n this.cardReveal.classList.remove('open');\n this.cardReveal.inert = false;\n if (this._ownsRevealInitializedClass) this.el.classList.remove(REVEAL_INITIALIZED_CLASS);\n }\n this._activators.forEach((activator) => {\n activator.removeAttribute('aria-expanded');\n const initialAriaControls = this._initialAriaControls.get(activator);\n if (initialAriaControls === null) activator.removeAttribute('aria-controls');\n else if (initialAriaControls !== undefined) {\n activator.setAttribute('aria-controls', initialAriaControls);\n }\n });\n this.isOpen = false;\n this._activators = [];\n this._initialAriaControls.clear();\n this._lastActivator = null;\n this.el['Expressive_Cards'] = undefined;\n }\n\n _setupEventHandlers = () => {\n this._activators.forEach((activator) => {\n activator.addEventListener('click', this._handleClickInteraction);\n });\n this.el.addEventListener('keydown', this._handleKeydownEvent);\n };\n\n _removeEventHandlers = () => {\n this._activators.forEach((activator) => {\n activator.removeEventListener('click', this._handleClickInteraction);\n });\n this.el.removeEventListener('keydown', this._handleKeydownEvent);\n };\n\n _handleClickInteraction = (event: MouseEvent) => {\n this._lastActivator = event.currentTarget as HTMLButtonElement;\n this._handleRevealEvent();\n };\n\n _handleKeydownEvent = (event: KeyboardEvent) => {\n const target = event.target instanceof Element ? event.target.closest('article') : null;\n if (target !== this.el || event.key !== 'Escape' || !this.isOpen) return;\n event.preventDefault();\n this.close();\n };\n\n _handleRevealEvent = () => {\n if (this.isOpen) this.close();\n else this.open();\n };\n\n /**\n * Show card reveal.\n */\n open: () => void = () => {\n if (this.isOpen || !this.cardReveal) return;\n this.isOpen = true;\n this.cardReveal.classList.add('open');\n this.cardReveal.inert = false;\n this._activators.forEach((activator) => (activator.ariaExpanded = 'true'));\n if (typeof this.options.onOpen === 'function') {\n this.options.onOpen.call(this, this.el);\n }\n };\n\n /**\n * Hide card reveal.\n */\n close: () => void = () => {\n if (!this.isOpen || !this.cardReveal) return;\n\n const focusWasInside = this.cardReveal.contains(document.activeElement);\n this.isOpen = false;\n this.cardReveal.classList.remove('open');\n this.cardReveal.inert = true;\n this._activators.forEach((activator) => (activator.ariaExpanded = 'false'));\n if (typeof this.options.onClose === 'function') {\n this.options.onClose.call(this, this.el);\n }\n\n if (focusWasInside) {\n (this._lastActivator ?? this._activators[0])?.focus();\n }\n };\n\n static Init() {\n Utils.onDocumentReady(() => {\n const cards = Array.from(document.querySelectorAll(CARDS_SELECTOR)).filter(isCardReveal);\n cards.forEach((el) => {\n if (el
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { Utils } from '../core/utils';\nimport { Component, BaseOptions, InitElements, InitElement, Openable } from '../core/component';\n\nexport interface CardsOptions extends BaseOptions {\n onOpen: (el: Element) => void;\n onClose: (el: Element) => void;\n}\n\nconst _defaults: CardsOptions = {\n onOpen: null,\n onClose: null\n};\n\n/**\n * What counts as a card reveal.\n *\n * Shared with `components/registry.ts` so `Cards.Init()` and `AutoInit()` use\n * the same semantic selector.\n */\nexport const CARDS_SELECTOR =\n 'article:has(> aside[id]:not([id=\"\"])):not(:has(> aside ~ aside)):has(> button.card-reveal-trigger[type=\"button\"], > :not(aside) button.card-reveal-trigger[type=\"button\"])';\n\nconst REVEAL_INITIALIZED_CLASS = 'card-reveal-initialized';\n\nfunction hasAccessibleName(trigger: HTMLButtonElement) {\n const label = trigger.getAttribute('aria-label');\n if (label?.trim()) return true;\n\n const labelledBy = trigger.getAttribute('aria-labelledby');\n if (labelledBy) {\n const referencedText = labelledBy\n .trim()\n .split(/\\s+/)\n .map((id) => trigger.ownerDocument.getElementById(id)?.textContent ?? '')\n .join(' ')\n .trim();\n if (referencedText) return true;\n }\n\n const content = trigger.cloneNode(true) as HTMLButtonElement;\n content.querySelectorAll('[aria-hidden=\"true\"]').forEach((node) => node.remove());\n return Boolean(content.textContent?.trim());\n}\n\nfunction isUsableCardTrigger(\n trigger: HTMLButtonElement,\n card: Element,\n panel: HTMLElement\n) {\n return (\n trigger.closest('article') === card &&\n !panel.contains(trigger) &&\n !trigger.disabled &&\n trigger.getAttribute('aria-disabled') !== 'true' &&\n hasAccessibleName(trigger)\n );\n}\n\nexport function isCardReveal(el: Element): el is HTMLElement {\n if (el.tagName !== 'ARTICLE') return false;\n const panels = el.querySelectorAll<HTMLElement>(':scope > aside');\n if (panels.length !== 1 || !panels[0].id) return false;\n\n return Array.from(\n el.querySelectorAll<HTMLButtonElement>('button.card-reveal-trigger[type=\"button\"]')\n ).some((trigger) => isUsableCardTrigger(trigger, el, panels[0]));\n}\n\nexport class Cards extends Component<CardsOptions> implements Openable {\n isOpen: boolean = false;\n private readonly cardReveal: HTMLElement | null;\n private _activators: HTMLButtonElement[];\n private _ownsRevealInitializedClass = false;\n private _initialAriaControls = new Map<HTMLButtonElement, string | null>();\n private _lastActivator: HTMLButtonElement | null = null;\n\n constructor(el: HTMLElement, options: Partial<CardsOptions> = {}) {\n super(el, options, Cards);\n this.el['Expressive_Cards'] = this;\n\n this.options = {\n ...Cards.defaults,\n ...options\n };\n\n const cardReveals = this.el.querySelectorAll<HTMLElement>(':scope > aside');\n const cardReveal = cardReveals.length === 1 ? cardReveals[0] : null;\n const activators = cardReveal\n ? Array.from(\n this.el.querySelectorAll<HTMLButtonElement>(\n 'button.card-reveal-trigger[type=\"button\"]'\n )\n ).filter(\n (activator) => isUsableCardTrigger(activator, this.el, cardReveal)\n )\n : [];\n\n this.cardReveal = cardReveal?.id && activators.length > 0 ? cardReveal : null;\n this._activators = this.cardReveal ? activators : [];\n\n if (this.cardReveal) {\n this._ownsRevealInitializedClass = !this.el.classList.contains(REVEAL_INITIALIZED_CLASS);\n this.el.classList.add(REVEAL_INITIALIZED_CLASS);\n this._activators.forEach((activator) => {\n this._initialAriaControls.set(activator, activator.getAttribute('aria-controls'));\n activator.ariaExpanded = 'false';\n activator.setAttribute('aria-controls', this.cardReveal.id);\n });\n\n this.cardReveal.classList.remove('open');\n this.cardReveal.inert = true;\n this._setupEventHandlers();\n }\n }\n\n static get defaults(): CardsOptions {\n return _defaults;\n }\n\n /**\n * Initializes instance of Cards.\n * @param el HTML element.\n * @param options Component options.\n */\n static init(el: HTMLElement, options?: Partial<CardsOptions>): Cards;\n /**\n * Initializes instances of Cards.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(els: InitElements<InitElement>, options?: Partial<CardsOptions>): Cards[];\n /**\n * Initializes instances of Cards.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options?: Partial<CardsOptions>\n ): Cards | Cards[] {\n return super.init(els, options, Cards);\n }\n\n static getInstance(el: HTMLElement): Cards {\n return el['Expressive_Cards'];\n }\n\n /**\n * {@inheritDoc}\n */\n destroy() {\n this._removeEventHandlers();\n if (this.cardReveal) {\n this.cardReveal.classList.remove('open');\n this.cardReveal.inert = false;\n if (this._ownsRevealInitializedClass) this.el.classList.remove(REVEAL_INITIALIZED_CLASS);\n }\n this._activators.forEach((activator) => {\n activator.removeAttribute('aria-expanded');\n const initialAriaControls = this._initialAriaControls.get(activator);\n if (initialAriaControls === null) activator.removeAttribute('aria-controls');\n else if (initialAriaControls !== undefined) {\n activator.setAttribute('aria-controls', initialAriaControls);\n }\n });\n this.isOpen = false;\n this._activators = [];\n this._initialAriaControls.clear();\n this._lastActivator = null;\n this.el['Expressive_Cards'] = undefined;\n }\n\n _setupEventHandlers = () => {\n this._activators.forEach((activator) => {\n activator.addEventListener('click', this._handleClickInteraction);\n });\n this.el.addEventListener('keydown', this._handleKeydownEvent);\n };\n\n _removeEventHandlers = () => {\n this._activators.forEach((activator) => {\n activator.removeEventListener('click', this._handleClickInteraction);\n });\n this.el.removeEventListener('keydown', this._handleKeydownEvent);\n };\n\n _handleClickInteraction = (event: MouseEvent) => {\n this._lastActivator = event.currentTarget as HTMLButtonElement;\n this._handleRevealEvent();\n };\n\n _handleKeydownEvent = (event: KeyboardEvent) => {\n const target = event.target instanceof Element ? event.target.closest('article') : null;\n if (target !== this.el || event.key !== 'Escape' || !this.isOpen) return;\n event.preventDefault();\n this.close();\n };\n\n _handleRevealEvent = () => {\n if (this.isOpen) this.close();\n else this.open();\n };\n\n /**\n * Show card reveal.\n */\n open: () => void = () => {\n if (this.isOpen || !this.cardReveal) return;\n this.isOpen = true;\n this.cardReveal.classList.add('open');\n this.cardReveal.inert = false;\n this._activators.forEach((activator) => (activator.ariaExpanded = 'true'));\n if (typeof this.options.onOpen === 'function') {\n this.options.onOpen.call(this, this.el);\n }\n };\n\n /**\n * Hide card reveal.\n */\n close: () => void = () => {\n if (!this.isOpen || !this.cardReveal) return;\n\n const focusWasInside = this.cardReveal.contains(document.activeElement);\n this.isOpen = false;\n this.cardReveal.classList.remove('open');\n this.cardReveal.inert = true;\n this._activators.forEach((activator) => (activator.ariaExpanded = 'false'));\n if (typeof this.options.onClose === 'function') {\n this.options.onClose.call(this, this.el);\n }\n\n if (focusWasInside) {\n (this._lastActivator ?? this._activators[0])?.focus();\n }\n };\n\n static Init() {\n Utils.onDocumentReady(() => {\n const cards = Array.from(document.querySelectorAll(CARDS_SELECTOR)).filter(isCardReveal);\n cards.forEach((el) => {\n if (el['Expressive_Cards'] == undefined) this.init(el);\n });\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Component
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PD6HYHAE.mjs";
|
|
4
4
|
|
|
5
5
|
// src/ts/components/appBar.ts
|
|
6
6
|
var _defaults = {};
|
|
@@ -74,8 +74,7 @@ var AppBar = class _AppBar extends Component {
|
|
|
74
74
|
this._input = this.el.querySelector('input[type="search"]');
|
|
75
75
|
if (!this._input) return;
|
|
76
76
|
const id = this._input.getAttribute("aria-controls");
|
|
77
|
-
|
|
78
|
-
if (!this._view) this._view = this.el.querySelector(".search-view");
|
|
77
|
+
this._view = id && document.getElementById(id) || this.el.querySelector(".search-view");
|
|
79
78
|
if (!this._view) return;
|
|
80
79
|
this._input.addEventListener("focus", this._onSearchFocus);
|
|
81
80
|
this._input.addEventListener("click", this._onSearchFocus);
|
|
@@ -88,4 +87,4 @@ var AppBar = class _AppBar extends Component {
|
|
|
88
87
|
export {
|
|
89
88
|
AppBar
|
|
90
89
|
};
|
|
91
|
-
//# sourceMappingURL=chunk-
|
|
90
|
+
//# sourceMappingURL=chunk-UAZSDUVP.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ts/components/appBar.ts"],
|
|
4
|
-
"sourcesContent": ["import { Component, BaseOptions, InitElements, InitElement } from '../core/component';\n\nconst _defaults: BaseOptions = {};\n\n/**\n * Collapse medium/large flexible app bars on scroll, and open the related\n * search view when the search field in a search app bar is selected.\n *\n * Observation is IntersectionObserver on a sentinel after the header.\n * A scroll listener would re-enter layout on every tick; this does not.\n */\nexport class AppBar extends Component<BaseOptions> {\n private _observer: IntersectionObserver | null = null;\n private _sentinel: HTMLElement | null = null;\n private _input: HTMLInputElement | null = null;\n private _view: HTMLElement | null = null;\n private _searchOpen = false;\n\n constructor(el: HTMLElement, options: Partial<BaseOptions>) {\n super(el, options, AppBar);\n this.el['Expressive_AppBar'] = this;\n this.options = { ...AppBar.defaults, ...options };\n this._setupCollapse();\n this._setupSearch();\n }\n\n static get defaults(): BaseOptions {\n return _defaults;\n }\n\n static init(el: HTMLElement, options?: Partial<BaseOptions>): AppBar;\n static init(els: InitElements<InitElement>, options?: Partial<BaseOptions>): AppBar[];\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<BaseOptions> = {}\n ): AppBar | AppBar[] {\n return super.init(els, options, AppBar);\n }\n\n static getInstance(el: HTMLElement): AppBar {\n return el['Expressive_AppBar'];\n }\n\n destroy() {\n this._observer?.disconnect();\n this._observer = null;\n this._sentinel?.remove();\n this._sentinel = null;\n this._input?.removeEventListener('focus', this._onSearchFocus);\n this._input?.removeEventListener('click', this._onSearchFocus);\n this._view?.removeEventListener('close', this._onSearchViewClose);\n this.el.classList.remove('collapsed');\n this.el['Expressive_AppBar'] = undefined;\n }\n\n private _setupCollapse() {\n if (!this.el.classList.contains('medium') && !this.el.classList.contains('large')) {\n return;\n }\n if (typeof IntersectionObserver === 'undefined') return;\n\n // Collapsing shrinks the header, and scroll anchoring then scrolls the page\n // back by the height it lost. The sentinel follows the header, so it moves\n // with the page and that correction cannot bring it back into view. It sits\n // 64px, the small bar's height, above the header's bottom edge. An expanded\n // bar therefore collapses once the page has scrolled by the height that\n // collapsing removes, and a collapsed bar expands when the page is back at\n // its top. Zero height and no margins keep it out of the layout.\n this._sentinel = document.createElement('span');\n this._sentinel.setAttribute('aria-hidden', 'true');\n this._sentinel.style.cssText =\n 'display:block;height:0;position:relative;top:-64px;pointer-events:none;visibility:hidden';\n this.el.insertAdjacentElement('afterend', this._sentinel);\n this._observer = new IntersectionObserver(this._onIntersect);\n this._observer.observe(this._sentinel);\n }\n\n private _onIntersect = (entries: IntersectionObserverEntry[]) => {\n const entry = entries[0];\n if (!entry) return;\n // Collapse only when the sentinel has gone above the pinned header. A\n // sentinel below the viewport would move back into view as the bar shrank,\n // and the bar would switch sizes on every frame.\n this.el.classList.toggle(\n 'collapsed',\n !entry.isIntersecting && entry.boundingClientRect.top < this.el.getBoundingClientRect().top\n );\n };\n\n private _setupSearch() {\n this._input = this.el.querySelector('input[type=\"search\"]');\n if (!this._input) return;\n\n const id = this._input.getAttribute('aria-controls');\n
|
|
5
|
-
"mappings": ";;;;;AAEA,IAAM,YAAyB,CAAC;AASzB,IAAM,SAAN,MAAM,gBAAe,UAAuB;AAAA,EAOjD,YAAY,IAAiB,SAA+B;AAC1D,UAAM,IAAI,SAAS,OAAM;AAP3B,SAAQ,YAAyC;AACjD,SAAQ,YAAgC;AACxC,SAAQ,SAAkC;AAC1C,SAAQ,QAA4B;AACpC,SAAQ,cAAc;AA6DtB,SAAQ,eAAe,CAAC,YAAyC;AAC/D,YAAM,QAAQ,QAAQ,CAAC;AACvB,UAAI,CAAC,MAAO;AAIZ,WAAK,GAAG,UAAU;AAAA,QAChB;AAAA,QACA,CAAC,MAAM,kBAAkB,MAAM,mBAAmB,MAAM,KAAK,GAAG,sBAAsB,EAAE;AAAA,MAC1F;AAAA,IACF;
|
|
4
|
+
"sourcesContent": ["import { Component, BaseOptions, InitElements, InitElement } from '../core/component';\n\nconst _defaults: BaseOptions = {};\n\n/**\n * Collapse medium/large flexible app bars on scroll, and open the related\n * search view when the search field in a search app bar is selected.\n *\n * Observation is IntersectionObserver on a sentinel after the header.\n * A scroll listener would re-enter layout on every tick; this does not.\n */\nexport class AppBar extends Component<BaseOptions> {\n private _observer: IntersectionObserver | null = null;\n private _sentinel: HTMLElement | null = null;\n private _input: HTMLInputElement | null = null;\n private _view: HTMLElement | null = null;\n private _searchOpen = false;\n\n constructor(el: HTMLElement, options: Partial<BaseOptions>) {\n super(el, options, AppBar);\n this.el['Expressive_AppBar'] = this;\n this.options = { ...AppBar.defaults, ...options };\n this._setupCollapse();\n this._setupSearch();\n }\n\n static get defaults(): BaseOptions {\n return _defaults;\n }\n\n static init(el: HTMLElement, options?: Partial<BaseOptions>): AppBar;\n static init(els: InitElements<InitElement>, options?: Partial<BaseOptions>): AppBar[];\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<BaseOptions> = {}\n ): AppBar | AppBar[] {\n return super.init(els, options, AppBar);\n }\n\n static getInstance(el: HTMLElement): AppBar {\n return el['Expressive_AppBar'];\n }\n\n destroy() {\n this._observer?.disconnect();\n this._observer = null;\n this._sentinel?.remove();\n this._sentinel = null;\n this._input?.removeEventListener('focus', this._onSearchFocus);\n this._input?.removeEventListener('click', this._onSearchFocus);\n this._view?.removeEventListener('close', this._onSearchViewClose);\n this.el.classList.remove('collapsed');\n this.el['Expressive_AppBar'] = undefined;\n }\n\n private _setupCollapse() {\n if (!this.el.classList.contains('medium') && !this.el.classList.contains('large')) {\n return;\n }\n if (typeof IntersectionObserver === 'undefined') return;\n\n // Collapsing shrinks the header, and scroll anchoring then scrolls the page\n // back by the height it lost. The sentinel follows the header, so it moves\n // with the page and that correction cannot bring it back into view. It sits\n // 64px, the small bar's height, above the header's bottom edge. An expanded\n // bar therefore collapses once the page has scrolled by the height that\n // collapsing removes, and a collapsed bar expands when the page is back at\n // its top. Zero height and no margins keep it out of the layout.\n this._sentinel = document.createElement('span');\n this._sentinel.setAttribute('aria-hidden', 'true');\n this._sentinel.style.cssText =\n 'display:block;height:0;position:relative;top:-64px;pointer-events:none;visibility:hidden';\n this.el.insertAdjacentElement('afterend', this._sentinel);\n this._observer = new IntersectionObserver(this._onIntersect);\n this._observer.observe(this._sentinel);\n }\n\n private _onIntersect = (entries: IntersectionObserverEntry[]) => {\n const entry = entries[0];\n if (!entry) return;\n // Collapse only when the sentinel has gone above the pinned header. A\n // sentinel below the viewport would move back into view as the bar shrank,\n // and the bar would switch sizes on every frame.\n this.el.classList.toggle(\n 'collapsed',\n !entry.isIntersecting && entry.boundingClientRect.top < this.el.getBoundingClientRect().top\n );\n };\n\n private _setupSearch() {\n this._input = this.el.querySelector('input[type=\"search\"]');\n if (!this._input) return;\n\n const id = this._input.getAttribute('aria-controls');\n this._view = (id && document.getElementById(id)) || this.el.querySelector('.search-view');\n if (!this._view) return;\n\n this._input.addEventListener('focus', this._onSearchFocus);\n this._input.addEventListener('click', this._onSearchFocus);\n if (this._view instanceof HTMLDialogElement) {\n this._view.addEventListener('close', this._onSearchViewClose);\n }\n }\n\n private _onSearchViewClose = () => {\n this._searchOpen = (this._view as HTMLDialogElement).open;\n };\n\n private _onSearchFocus = () => {\n if (!this._view || this._searchOpen) return;\n if (this._view instanceof HTMLDialogElement) {\n this._searchOpen = true;\n if (!this._view.open) this._view.showModal();\n return;\n }\n this._view.hidden = false;\n this._input?.setAttribute('aria-expanded', 'true');\n };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA,IAAM,YAAyB,CAAC;AASzB,IAAM,SAAN,MAAM,gBAAe,UAAuB;AAAA,EAOjD,YAAY,IAAiB,SAA+B;AAC1D,UAAM,IAAI,SAAS,OAAM;AAP3B,SAAQ,YAAyC;AACjD,SAAQ,YAAgC;AACxC,SAAQ,SAAkC;AAC1C,SAAQ,QAA4B;AACpC,SAAQ,cAAc;AA6DtB,SAAQ,eAAe,CAAC,YAAyC;AAC/D,YAAM,QAAQ,QAAQ,CAAC;AACvB,UAAI,CAAC,MAAO;AAIZ,WAAK,GAAG,UAAU;AAAA,QAChB;AAAA,QACA,CAAC,MAAM,kBAAkB,MAAM,mBAAmB,MAAM,KAAK,GAAG,sBAAsB,EAAE;AAAA,MAC1F;AAAA,IACF;AAiBA,SAAQ,qBAAqB,MAAM;AACjC,WAAK,cAAe,KAAK,MAA4B;AAAA,IACvD;AAEA,SAAQ,iBAAiB,MAAM;AAC7B,UAAI,CAAC,KAAK,SAAS,KAAK,YAAa;AACrC,UAAI,KAAK,iBAAiB,mBAAmB;AAC3C,aAAK,cAAc;AACnB,YAAI,CAAC,KAAK,MAAM,KAAM,MAAK,MAAM,UAAU;AAC3C;AAAA,MACF;AACA,WAAK,MAAM,SAAS;AACpB,WAAK,QAAQ,aAAa,iBAAiB,MAAM;AAAA,IACnD;AAjGE,SAAK,GAAG,mBAAmB,IAAI;AAC/B,SAAK,UAAU,EAAE,GAAG,QAAO,UAAU,GAAG,QAAQ;AAChD,SAAK,eAAe;AACpB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,WAAW,WAAwB;AACjC,WAAO;AAAA,EACT;AAAA,EAIA,OAAO,KACL,KACA,UAAgC,CAAC,GACd;AACnB,WAAO,MAAM,KAAK,KAAK,SAAS,OAAM;AAAA,EACxC;AAAA,EAEA,OAAO,YAAY,IAAyB;AAC1C,WAAO,GAAG,mBAAmB;AAAA,EAC/B;AAAA,EAEA,UAAU;AACR,SAAK,WAAW,WAAW;AAC3B,SAAK,YAAY;AACjB,SAAK,WAAW,OAAO;AACvB,SAAK,YAAY;AACjB,SAAK,QAAQ,oBAAoB,SAAS,KAAK,cAAc;AAC7D,SAAK,QAAQ,oBAAoB,SAAS,KAAK,cAAc;AAC7D,SAAK,OAAO,oBAAoB,SAAS,KAAK,kBAAkB;AAChE,SAAK,GAAG,UAAU,OAAO,WAAW;AACpC,SAAK,GAAG,mBAAmB,IAAI;AAAA,EACjC;AAAA,EAEQ,iBAAiB;AACvB,QAAI,CAAC,KAAK,GAAG,UAAU,SAAS,QAAQ,KAAK,CAAC,KAAK,GAAG,UAAU,SAAS,OAAO,GAAG;AACjF;AAAA,IACF;AACA,QAAI,OAAO,yBAAyB,YAAa;AASjD,SAAK,YAAY,SAAS,cAAc,MAAM;AAC9C,SAAK,UAAU,aAAa,eAAe,MAAM;AACjD,SAAK,UAAU,MAAM,UACnB;AACF,SAAK,GAAG,sBAAsB,YAAY,KAAK,SAAS;AACxD,SAAK,YAAY,IAAI,qBAAqB,KAAK,YAAY;AAC3D,SAAK,UAAU,QAAQ,KAAK,SAAS;AAAA,EACvC;AAAA,EAcQ,eAAe;AACrB,SAAK,SAAS,KAAK,GAAG,cAAc,sBAAsB;AAC1D,QAAI,CAAC,KAAK,OAAQ;AAElB,UAAM,KAAK,KAAK,OAAO,aAAa,eAAe;AACnD,SAAK,QAAS,MAAM,SAAS,eAAe,EAAE,KAAM,KAAK,GAAG,cAAc,cAAc;AACxF,QAAI,CAAC,KAAK,MAAO;AAEjB,SAAK,OAAO,iBAAiB,SAAS,KAAK,cAAc;AACzD,SAAK,OAAO,iBAAiB,SAAS,KAAK,cAAc;AACzD,QAAI,KAAK,iBAAiB,mBAAmB;AAC3C,WAAK,MAAM,iBAAiB,SAAS,KAAK,kBAAkB;AAAA,IAC9D;AAAA,EACF;AAgBF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Component
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PD6HYHAE.mjs";
|
|
4
4
|
|
|
5
5
|
// src/ts/components/navigationRail.ts
|
|
6
6
|
var _defaults = {
|
|
@@ -10,6 +10,11 @@ var _defaults = {
|
|
|
10
10
|
onCloseEnd: null
|
|
11
11
|
};
|
|
12
12
|
var COMPACT = "(width < 600px)";
|
|
13
|
+
function deepActiveElement(root) {
|
|
14
|
+
let active = root.activeElement;
|
|
15
|
+
while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement;
|
|
16
|
+
return active;
|
|
17
|
+
}
|
|
13
18
|
var NavigationRail = class _NavigationRail extends Component {
|
|
14
19
|
constructor(el, options) {
|
|
15
20
|
super(el, options, _NavigationRail);
|
|
@@ -53,7 +58,7 @@ var NavigationRail = class _NavigationRail extends Component {
|
|
|
53
58
|
this._onClick = (e) => {
|
|
54
59
|
const target = e.target;
|
|
55
60
|
if (!(target instanceof Node)) return;
|
|
56
|
-
if (this._toggle
|
|
61
|
+
if (this._toggle?.contains(target)) {
|
|
57
62
|
this.toggle();
|
|
58
63
|
e.preventDefault();
|
|
59
64
|
return;
|
|
@@ -67,12 +72,9 @@ var NavigationRail = class _NavigationRail extends Component {
|
|
|
67
72
|
if (this.isExpanded && this._isModal()) {
|
|
68
73
|
const root = this.el.getRootNode();
|
|
69
74
|
const restoreFocus = this.el.contains(root.activeElement);
|
|
70
|
-
|
|
71
|
-
while (focused?.shadowRoot?.activeElement) focused = focused.shadowRoot.activeElement;
|
|
75
|
+
const focused = deepActiveElement(root);
|
|
72
76
|
this.collapse();
|
|
73
|
-
|
|
74
|
-
while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement;
|
|
75
|
-
if (!this.isExpanded && restoreFocus && active === focused) {
|
|
77
|
+
if (!this.isExpanded && restoreFocus && deepActiveElement(root) === focused) {
|
|
76
78
|
this._toggle?.focus();
|
|
77
79
|
}
|
|
78
80
|
}
|
|
@@ -122,4 +124,4 @@ var NavigationRail = class _NavigationRail extends Component {
|
|
|
122
124
|
export {
|
|
123
125
|
NavigationRail
|
|
124
126
|
};
|
|
125
|
-
//# sourceMappingURL=chunk-
|
|
127
|
+
//# sourceMappingURL=chunk-UBRZZWRA.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ts/components/navigationRail.ts"],
|
|
4
|
+
"sourcesContent": ["import { Component, BaseOptions, InitElements, InitElement } from '../core/component';\n\nexport interface NavigationRailOptions extends BaseOptions {\n /**\n * Called before the rail expands.\n */\n onOpenStart: (el: HTMLElement) => void;\n /**\n * Called after the rail expands.\n */\n onOpenEnd: (el: HTMLElement) => void;\n /**\n * Called before the rail collapses.\n */\n onCloseStart: (el: HTMLElement) => void;\n /**\n * Called after the rail collapses.\n */\n onCloseEnd: (el: HTMLElement) => void;\n}\n\nconst _defaults: NavigationRailOptions = {\n onOpenStart: null,\n onOpenEnd: null,\n onCloseStart: null,\n onCloseEnd: null\n};\n\nconst COMPACT = '(width < 600px)';\n\n/** The focused element, followed down through open shadow roots. */\nfunction deepActiveElement(root: Document | ShadowRoot): Element | null {\n let active = root.activeElement;\n while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement;\n return active;\n}\n\n/**\n * Navigation rail. Layout is CSS (collapsed / .expanded). This class\n * toggles that class from the menu button, closes a compact overlay on\n * Escape or a scrim tap, and keeps aria-expanded in sync.\n */\nexport class NavigationRail extends Component<NavigationRailOptions> {\n isExpanded: boolean;\n private _toggle: HTMLButtonElement | null;\n private _mql: MediaQueryList;\n\n constructor(el: HTMLElement, options: Partial<NavigationRailOptions>) {\n super(el, options, NavigationRail);\n this.el['Expressive_NavigationRail'] = this;\n\n this.options = {\n ...NavigationRail.defaults,\n ...options\n };\n\n this._toggle = this._findToggle();\n this._mql = window.matchMedia(COMPACT);\n this.isExpanded = this.el.classList.contains('expanded');\n this._sync();\n this.el.addEventListener('click', this._onClick);\n document.addEventListener('keydown', this._onKeyDown);\n }\n\n static get defaults(): NavigationRailOptions {\n return _defaults;\n }\n\n static init(el: HTMLElement, options?: Partial<NavigationRailOptions>): NavigationRail;\n static init(\n els: InitElements<InitElement>,\n options?: Partial<NavigationRailOptions>\n ): NavigationRail[];\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<NavigationRailOptions> = {}\n ): NavigationRail | NavigationRail[] {\n return super.init(els, options, NavigationRail);\n }\n\n static getInstance(el: HTMLElement): NavigationRail {\n return el['Expressive_NavigationRail'];\n }\n\n destroy() {\n this.el.removeEventListener('click', this._onClick);\n document.removeEventListener('keydown', this._onKeyDown);\n this.el['Expressive_NavigationRail'] = undefined;\n }\n\n /**\n * Expands the rail. On compact windows the overlay (scrim) is CSS.\n */\n expand = () => {\n if (this.isExpanded) return;\n if (typeof this.options.onOpenStart === 'function') {\n this.options.onOpenStart.call(this, this.el);\n }\n this.isExpanded = true;\n this.el.classList.add('expanded');\n this._sync();\n if (typeof this.options.onOpenEnd === 'function') {\n this.options.onOpenEnd.call(this, this.el);\n }\n };\n\n /**\n * Collapses the rail.\n */\n collapse = () => {\n if (!this.isExpanded) return;\n if (typeof this.options.onCloseStart === 'function') {\n this.options.onCloseStart.call(this, this.el);\n }\n this.isExpanded = false;\n this.el.classList.remove('expanded');\n this._sync();\n if (typeof this.options.onCloseEnd === 'function') {\n this.options.onCloseEnd.call(this, this.el);\n }\n };\n\n /**\n * Toggles expanded / collapsed.\n */\n toggle = () => {\n if (this.isExpanded) this.collapse();\n else this.expand();\n };\n\n private _findToggle(): HTMLButtonElement | null {\n const first = this.el.querySelector(':scope > button:not(.button)');\n return first instanceof HTMLButtonElement ? first : null;\n }\n\n private _isCompact() {\n return this._mql.matches;\n }\n\n private _isModal() {\n return this.el.classList.contains('modal') || this._isCompact();\n }\n\n private _sync() {\n this.el.setAttribute('aria-expanded', this.isExpanded ? 'true' : 'false');\n this._toggle?.setAttribute('aria-expanded', this.isExpanded ? 'true' : 'false');\n }\n\n private _onClick = (e: MouseEvent) => {\n const target = e.target;\n if (!(target instanceof Node)) return;\n if (this._toggle?.contains(target)) {\n this.toggle();\n e.preventDefault();\n return;\n }\n if (target === this.el && this.isExpanded && this._isModal()) {\n this.collapse();\n }\n };\n\n private _onKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape' || e.defaultPrevented) return;\n if (this.isExpanded && this._isModal()) {\n const root = this.el.getRootNode() as Document | ShadowRoot;\n const restoreFocus = this.el.contains(root.activeElement);\n const focused = deepActiveElement(root);\n this.collapse();\n if (!this.isExpanded && restoreFocus && deepActiveElement(root) === focused) {\n this._toggle?.focus();\n }\n }\n };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AAqBA,IAAM,YAAmC;AAAA,EACvC,aAAa;AAAA,EACb,WAAW;AAAA,EACX,cAAc;AAAA,EACd,YAAY;AACd;AAEA,IAAM,UAAU;AAGhB,SAAS,kBAAkB,MAA6C;AACtE,MAAI,SAAS,KAAK;AAClB,SAAO,QAAQ,YAAY,cAAe,UAAS,OAAO,WAAW;AACrE,SAAO;AACT;AAOO,IAAM,iBAAN,MAAM,wBAAuB,UAAiC;AAAA,EAKnE,YAAY,IAAiB,SAAyC;AACpE,UAAM,IAAI,SAAS,eAAc;AA6CnC;AAAA;AAAA;AAAA,kBAAS,MAAM;AACb,UAAI,KAAK,WAAY;AACrB,UAAI,OAAO,KAAK,QAAQ,gBAAgB,YAAY;AAClD,aAAK,QAAQ,YAAY,KAAK,MAAM,KAAK,EAAE;AAAA,MAC7C;AACA,WAAK,aAAa;AAClB,WAAK,GAAG,UAAU,IAAI,UAAU;AAChC,WAAK,MAAM;AACX,UAAI,OAAO,KAAK,QAAQ,cAAc,YAAY;AAChD,aAAK,QAAQ,UAAU,KAAK,MAAM,KAAK,EAAE;AAAA,MAC3C;AAAA,IACF;AAKA;AAAA;AAAA;AAAA,oBAAW,MAAM;AACf,UAAI,CAAC,KAAK,WAAY;AACtB,UAAI,OAAO,KAAK,QAAQ,iBAAiB,YAAY;AACnD,aAAK,QAAQ,aAAa,KAAK,MAAM,KAAK,EAAE;AAAA,MAC9C;AACA,WAAK,aAAa;AAClB,WAAK,GAAG,UAAU,OAAO,UAAU;AACnC,WAAK,MAAM;AACX,UAAI,OAAO,KAAK,QAAQ,eAAe,YAAY;AACjD,aAAK,QAAQ,WAAW,KAAK,MAAM,KAAK,EAAE;AAAA,MAC5C;AAAA,IACF;AAKA;AAAA;AAAA;AAAA,kBAAS,MAAM;AACb,UAAI,KAAK,WAAY,MAAK,SAAS;AAAA,UAC9B,MAAK,OAAO;AAAA,IACnB;AAoBA,SAAQ,WAAW,CAAC,MAAkB;AACpC,YAAM,SAAS,EAAE;AACjB,UAAI,EAAE,kBAAkB,MAAO;AAC/B,UAAI,KAAK,SAAS,SAAS,MAAM,GAAG;AAClC,aAAK,OAAO;AACZ,UAAE,eAAe;AACjB;AAAA,MACF;AACA,UAAI,WAAW,KAAK,MAAM,KAAK,cAAc,KAAK,SAAS,GAAG;AAC5D,aAAK,SAAS;AAAA,MAChB;AAAA,IACF;AAEA,SAAQ,aAAa,CAAC,MAAqB;AACzC,UAAI,EAAE,QAAQ,YAAY,EAAE,iBAAkB;AAC9C,UAAI,KAAK,cAAc,KAAK,SAAS,GAAG;AACtC,cAAM,OAAO,KAAK,GAAG,YAAY;AACjC,cAAM,eAAe,KAAK,GAAG,SAAS,KAAK,aAAa;AACxD,cAAM,UAAU,kBAAkB,IAAI;AACtC,aAAK,SAAS;AACd,YAAI,CAAC,KAAK,cAAc,gBAAgB,kBAAkB,IAAI,MAAM,SAAS;AAC3E,eAAK,SAAS,MAAM;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AA3HE,SAAK,GAAG,2BAA2B,IAAI;AAEvC,SAAK,UAAU;AAAA,MACb,GAAG,gBAAe;AAAA,MAClB,GAAG;AAAA,IACL;AAEA,SAAK,UAAU,KAAK,YAAY;AAChC,SAAK,OAAO,OAAO,WAAW,OAAO;AACrC,SAAK,aAAa,KAAK,GAAG,UAAU,SAAS,UAAU;AACvD,SAAK,MAAM;AACX,SAAK,GAAG,iBAAiB,SAAS,KAAK,QAAQ;AAC/C,aAAS,iBAAiB,WAAW,KAAK,UAAU;AAAA,EACtD;AAAA,EAEA,WAAW,WAAkC;AAC3C,WAAO;AAAA,EACT;AAAA,EAOA,OAAO,KACL,KACA,UAA0C,CAAC,GACR;AACnC,WAAO,MAAM,KAAK,KAAK,SAAS,eAAc;AAAA,EAChD;AAAA,EAEA,OAAO,YAAY,IAAiC;AAClD,WAAO,GAAG,2BAA2B;AAAA,EACvC;AAAA,EAEA,UAAU;AACR,SAAK,GAAG,oBAAoB,SAAS,KAAK,QAAQ;AAClD,aAAS,oBAAoB,WAAW,KAAK,UAAU;AACvD,SAAK,GAAG,2BAA2B,IAAI;AAAA,EACzC;AAAA,EA0CQ,cAAwC;AAC9C,UAAM,QAAQ,KAAK,GAAG,cAAc,8BAA8B;AAClE,WAAO,iBAAiB,oBAAoB,QAAQ;AAAA,EACtD;AAAA,EAEQ,aAAa;AACnB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEQ,WAAW;AACjB,WAAO,KAAK,GAAG,UAAU,SAAS,OAAO,KAAK,KAAK,WAAW;AAAA,EAChE;AAAA,EAEQ,QAAQ;AACd,SAAK,GAAG,aAAa,iBAAiB,KAAK,aAAa,SAAS,OAAO;AACxE,SAAK,SAAS,aAAa,iBAAiB,KAAK,aAAa,SAAS,OAAO;AAAA,EAChF;AA2BF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Carousel
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KVJAVDBC.mjs";
|
|
4
4
|
import {
|
|
5
5
|
Utils
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-M372EDXD.mjs";
|
|
7
7
|
import {
|
|
8
8
|
Component
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-PD6HYHAE.mjs";
|
|
10
10
|
|
|
11
11
|
// src/ts/components/tabs.ts
|
|
12
12
|
var _defaults = {
|
|
@@ -26,12 +26,7 @@ var Tabs = class _Tabs extends Component {
|
|
|
26
26
|
// and right positions are both read before either is written.
|
|
27
27
|
this._handleWindowResize = Utils.throttle(() => {
|
|
28
28
|
this._setTabsAndTabWidth();
|
|
29
|
-
if (this._tabWidth !== 0 && this._tabsWidth !== 0)
|
|
30
|
-
const left = this._calcLeftPos(this._activeTabLink);
|
|
31
|
-
const right = this._calcRightPos(this._activeTabLink);
|
|
32
|
-
this._indicator.style.left = left + "px";
|
|
33
|
-
this._indicator.style.right = right + "px";
|
|
34
|
-
}
|
|
29
|
+
if (this._tabWidth !== 0 && this._tabsWidth !== 0) this._positionIndicator();
|
|
35
30
|
}, 200);
|
|
36
31
|
this._handleTabClick = (e) => {
|
|
37
32
|
const target = e.target;
|
|
@@ -46,8 +41,7 @@ var Tabs = class _Tabs extends Component {
|
|
|
46
41
|
}
|
|
47
42
|
if (tabLink.hasAttribute("target")) return;
|
|
48
43
|
if (this.options.swipeable) {
|
|
49
|
-
const
|
|
50
|
-
const index = this._tabsCarousel.images.indexOf(panel);
|
|
44
|
+
const index = this._tabsCarousel.images.indexOf(this._panelFor(tabLink));
|
|
51
45
|
if (index >= 0) this._tabsCarousel.set(index);
|
|
52
46
|
e.preventDefault();
|
|
53
47
|
return;
|
|
@@ -76,10 +70,13 @@ var Tabs = class _Tabs extends Component {
|
|
|
76
70
|
...options
|
|
77
71
|
};
|
|
78
72
|
this._tabLinks = this._queryTabLinks();
|
|
73
|
+
if (!this._tabLinks.length) {
|
|
74
|
+
console.error("Tabs: no tab links (an <a> child, or one inside .tab) to show");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
79
77
|
this._tabLinks.forEach((link) => {
|
|
80
78
|
this._originalLinks.set(link, { active: link.classList.contains("active"), current: link.getAttribute("aria-current") });
|
|
81
|
-
|
|
82
|
-
const panel = link.hash && document.getElementById(link.hash.slice(1));
|
|
79
|
+
const panel = this._panelFor(link);
|
|
83
80
|
if (panel) this._originalPanels.set(panel, {
|
|
84
81
|
display: panel.style.display,
|
|
85
82
|
priority: panel.style.getPropertyPriority("display"),
|
|
@@ -87,7 +84,7 @@ var Tabs = class _Tabs extends Component {
|
|
|
87
84
|
carousel: panel.classList.contains("carousel-item")
|
|
88
85
|
});
|
|
89
86
|
});
|
|
90
|
-
(_a = this.options).swipeable && (_a.swipeable = window.innerWidth <= this.options.responsiveThreshold);
|
|
87
|
+
(_a = this.options).swipeable && (_a.swipeable = window.innerWidth <= this.options.responsiveThreshold && this._originalPanels.size > 0);
|
|
91
88
|
this._index = 0;
|
|
92
89
|
this._setupActiveTabLink();
|
|
93
90
|
if (this.options.swipeable) {
|
|
@@ -98,6 +95,9 @@ var Tabs = class _Tabs extends Component {
|
|
|
98
95
|
this._setTabsAndTabWidth();
|
|
99
96
|
this._createIndicator();
|
|
100
97
|
this._setupEventHandlers();
|
|
98
|
+
document.fonts?.ready.then(() => {
|
|
99
|
+
if (this.el["Expressive_Tabs"] === this) this._handleWindowResize();
|
|
100
|
+
});
|
|
101
101
|
}
|
|
102
102
|
static get defaults() {
|
|
103
103
|
return _defaults;
|
|
@@ -115,8 +115,8 @@ var Tabs = class _Tabs extends Component {
|
|
|
115
115
|
}
|
|
116
116
|
destroy() {
|
|
117
117
|
this._removeEventHandlers();
|
|
118
|
-
this._indicator
|
|
119
|
-
if (this.
|
|
118
|
+
this._indicator?.remove();
|
|
119
|
+
if (this._tabsCarousel) {
|
|
120
120
|
this._teardownSwipeableTabs();
|
|
121
121
|
}
|
|
122
122
|
this._originalPanels.forEach((original, panel) => {
|
|
@@ -157,8 +157,19 @@ var Tabs = class _Tabs extends Component {
|
|
|
157
157
|
indicator.classList.add("indicator");
|
|
158
158
|
this.el.appendChild(indicator);
|
|
159
159
|
this._indicator = indicator;
|
|
160
|
-
this.
|
|
161
|
-
|
|
160
|
+
this._positionIndicator();
|
|
161
|
+
}
|
|
162
|
+
/** Reads both positions before writing either. */
|
|
163
|
+
_positionIndicator() {
|
|
164
|
+
const left = this._calcLeftPos(this._activeTabLink);
|
|
165
|
+
const right = this._calcRightPos(this._activeTabLink);
|
|
166
|
+
this._indicator.style.left = left + "px";
|
|
167
|
+
this._indicator.style.right = right + "px";
|
|
168
|
+
}
|
|
169
|
+
/** The panel a link shows, or null for a `target` link or one without a hash. */
|
|
170
|
+
_panelFor(a) {
|
|
171
|
+
if (!a.hash || a.hasAttribute("target")) return null;
|
|
172
|
+
return document.getElementById(a.hash.slice(1));
|
|
162
173
|
}
|
|
163
174
|
/**
|
|
164
175
|
* Which tab is current, for the eye and for assistive technology.
|
|
@@ -180,31 +191,20 @@ var Tabs = class _Tabs extends Component {
|
|
|
180
191
|
tabLink.classList.add("active");
|
|
181
192
|
tabLink.setAttribute("aria-current", "page");
|
|
182
193
|
this._index = Array.from(this._tabLinks).indexOf(tabLink);
|
|
183
|
-
this._content =
|
|
194
|
+
this._content = this._panelFor(tabLink);
|
|
184
195
|
}
|
|
185
196
|
_setupActiveTabLink() {
|
|
186
|
-
this._activeTabLink = Array.from(this._tabLinks).find(
|
|
187
|
-
(a) => a.getAttribute("href") === location.hash
|
|
188
|
-
);
|
|
189
|
-
if (!this._activeTabLink) {
|
|
190
|
-
let activeTabLink = this.el.querySelector("a.active");
|
|
191
|
-
if (!activeTabLink) {
|
|
192
|
-
activeTabLink = this._tabLinks[0];
|
|
193
|
-
}
|
|
194
|
-
this._activeTabLink = activeTabLink;
|
|
195
|
-
}
|
|
197
|
+
this._activeTabLink = Array.from(this._tabLinks).find((a) => a.getAttribute("href") === location.hash) ?? this.el.querySelector("a.active") ?? this._tabLinks[0];
|
|
196
198
|
this._setActiveTabLink(this._activeTabLink);
|
|
197
199
|
this._originalPanels.forEach((_, panel) => panel.classList.toggle("active", panel === this._content));
|
|
198
200
|
}
|
|
199
201
|
_setupSwipeableTabs() {
|
|
200
202
|
const tabsContent = [];
|
|
201
203
|
this._tabLinks.forEach((a) => {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
tabsContent.push(currContent);
|
|
207
|
-
}
|
|
204
|
+
const currContent = this._panelFor(a);
|
|
205
|
+
if (!currContent) return;
|
|
206
|
+
currContent.classList.add("carousel-item");
|
|
207
|
+
tabsContent.push(currContent);
|
|
208
208
|
});
|
|
209
209
|
const tabsWrapper = document.createElement("div");
|
|
210
210
|
tabsWrapper.classList.add("tabs-content", "carousel", "flat");
|
|
@@ -238,11 +238,9 @@ var Tabs = class _Tabs extends Component {
|
|
|
238
238
|
}
|
|
239
239
|
_setupNormalTabs() {
|
|
240
240
|
Array.from(this._tabLinks).forEach((a) => {
|
|
241
|
-
if (a === this._activeTabLink
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if (currContent) currContent.style.display = "none";
|
|
245
|
-
}
|
|
241
|
+
if (a === this._activeTabLink) return;
|
|
242
|
+
const currContent = this._panelFor(a);
|
|
243
|
+
if (currContent) currContent.style.display = "none";
|
|
246
244
|
});
|
|
247
245
|
}
|
|
248
246
|
_setTabsAndTabWidth() {
|
|
@@ -271,17 +269,14 @@ var Tabs = class _Tabs extends Component {
|
|
|
271
269
|
this._indicator.style.transition = `
|
|
272
270
|
left ${this.options.duration}ms ease-out ${leftDelay}ms,
|
|
273
271
|
right ${this.options.duration}ms ease-out ${rightDelay}ms`;
|
|
274
|
-
this.
|
|
275
|
-
this._indicator.style.right = this._calcRightPos(this._activeTabLink) + "px";
|
|
272
|
+
this._positionIndicator();
|
|
276
273
|
}
|
|
277
274
|
/**
|
|
278
275
|
* Show tab content that corresponds to the tab with the id.
|
|
279
276
|
* @param tabId The id of the tab that you want to switch to.
|
|
280
277
|
*/
|
|
281
278
|
select(tabId) {
|
|
282
|
-
const tab = Array.from(this._tabLinks).find(
|
|
283
|
-
(a) => a.getAttribute("href") === "#" + tabId
|
|
284
|
-
);
|
|
279
|
+
const tab = Array.from(this._tabLinks).find((a) => a.getAttribute("href") === "#" + tabId);
|
|
285
280
|
if (tab) tab.click();
|
|
286
281
|
}
|
|
287
282
|
};
|
|
@@ -289,4 +284,4 @@ var Tabs = class _Tabs extends Component {
|
|
|
289
284
|
export {
|
|
290
285
|
Tabs
|
|
291
286
|
};
|
|
292
|
-
//# sourceMappingURL=chunk-
|
|
287
|
+
//# sourceMappingURL=chunk-UCOE7ZDL.mjs.map
|