@expressivecss/expressive 0.16.0 → 0.17.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 +306 -1
- package/README.md +1 -1
- package/dist/css/expressive.css +540 -646
- 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-PA7NU5AK.mjs → chunk-26VUH75M.mjs} +6 -3
- package/dist/js/chunks/chunk-26VUH75M.mjs.map +7 -0
- package/dist/js/chunks/{chunk-NBJAUGPP.mjs → chunk-2LFCOGC3.mjs} +12 -23
- package/dist/js/chunks/chunk-2LFCOGC3.mjs.map +7 -0
- package/dist/js/chunks/{chunk-OP43LLIC.mjs → chunk-36GELQGX.mjs} +4 -4
- package/dist/js/chunks/{chunk-OP43LLIC.mjs.map → chunk-36GELQGX.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-EC26RU2D.mjs → chunk-3FKWIRHW.mjs} +6 -2
- package/dist/js/chunks/chunk-3FKWIRHW.mjs.map +7 -0
- package/dist/js/chunks/{chunk-Y6H2X7ZC.mjs → chunk-3KF65KGL.mjs} +3 -3
- package/dist/js/chunks/{chunk-4QUCNFSD.mjs → chunk-3KLZRQZI.mjs} +31 -10
- package/dist/js/chunks/chunk-3KLZRQZI.mjs.map +7 -0
- package/dist/js/chunks/{chunk-75E5EDJF.mjs → chunk-3XORNED5.mjs} +2 -2
- package/dist/js/chunks/{chunk-NNHVANQA.mjs → chunk-4WBGAQN3.mjs} +3 -3
- package/dist/js/chunks/{chunk-ZJNLAGY5.mjs → chunk-5F4URJHL.mjs} +2 -2
- package/dist/js/chunks/{chunk-ZVLOUDIJ.mjs → chunk-67UNY7RH.mjs} +50 -2
- package/dist/js/chunks/chunk-67UNY7RH.mjs.map +7 -0
- package/dist/js/chunks/{chunk-P6DRQ6KS.mjs → chunk-7CXNATJS.mjs} +6 -5
- package/dist/js/chunks/chunk-7CXNATJS.mjs.map +7 -0
- package/dist/js/chunks/{chunk-4TRZ2AER.mjs → chunk-7X44MKEQ.mjs} +15 -14
- package/dist/js/chunks/chunk-7X44MKEQ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GWZ76SR4.mjs → chunk-7ZAMOMGY.mjs} +12 -7
- package/dist/js/chunks/chunk-7ZAMOMGY.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GVZQH2H5.mjs → chunk-AEG6LOAJ.mjs} +2 -2
- package/dist/js/chunks/{chunk-Y6TLRA3U.mjs → chunk-AQNFCJJ5.mjs} +27 -21
- package/dist/js/chunks/chunk-AQNFCJJ5.mjs.map +7 -0
- package/dist/js/chunks/{chunk-OUCHKSAW.mjs → chunk-B55LWKBM.mjs} +16 -4
- package/dist/js/chunks/chunk-B55LWKBM.mjs.map +7 -0
- package/dist/js/chunks/{chunk-AI73GJKG.mjs → chunk-BB5VXYXT.mjs} +2 -2
- package/dist/js/chunks/{chunk-2RLBDFH4.mjs → chunk-BDATLH3H.mjs} +4 -4
- package/dist/js/chunks/{chunk-2CS6TITK.mjs → chunk-CWMQOT4O.mjs} +23 -10
- package/dist/js/chunks/chunk-CWMQOT4O.mjs.map +7 -0
- package/dist/js/chunks/{chunk-ZKWUWBUB.mjs → chunk-CY2CTOVM.mjs} +2 -2
- package/dist/js/chunks/{chunk-CSYWKEK3.mjs → chunk-DWA5UYLJ.mjs} +58 -27
- package/dist/js/chunks/chunk-DWA5UYLJ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-CMGXGYUC.mjs → chunk-EB2V4OKL.mjs} +14 -9
- package/dist/js/chunks/chunk-EB2V4OKL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-Z4GICXR2.mjs → chunk-EWO662ZC.mjs} +5 -7
- package/dist/js/chunks/chunk-EWO662ZC.mjs.map +7 -0
- package/dist/js/chunks/{chunk-VGY4M57S.mjs → chunk-F7LAKFMX.mjs} +67 -34
- package/dist/js/chunks/chunk-F7LAKFMX.mjs.map +7 -0
- package/dist/js/chunks/{chunk-67ZPPKXS.mjs → chunk-FNIIH2LU.mjs} +3 -3
- package/dist/js/chunks/chunk-GE3YMFS6.mjs +15 -0
- package/dist/js/chunks/chunk-GE3YMFS6.mjs.map +7 -0
- package/dist/js/chunks/{chunk-DZYVU75J.mjs → chunk-GFWYMWYN.mjs} +18 -14
- package/dist/js/chunks/chunk-GFWYMWYN.mjs.map +7 -0
- package/dist/js/chunks/{chunk-3L3QIYLC.mjs → chunk-H5ISU45X.mjs} +8 -6
- package/dist/js/chunks/chunk-H5ISU45X.mjs.map +7 -0
- package/dist/js/chunks/{chunk-QXKWVHBD.mjs → chunk-H6YIKFAQ.mjs} +67 -46
- package/dist/js/chunks/chunk-H6YIKFAQ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-KZPSAXIU.mjs → chunk-HEH7E3KO.mjs} +22 -12
- package/dist/js/chunks/chunk-HEH7E3KO.mjs.map +7 -0
- package/dist/js/chunks/{chunk-T3BNSRP3.mjs → chunk-HQRLBTNM.mjs} +3 -3
- package/dist/js/chunks/{chunk-NAC72P7R.mjs → chunk-I2F7MLUU.mjs} +2 -2
- package/dist/js/chunks/{chunk-ZM3XBHWV.mjs → chunk-IQOTGGHX.mjs} +86 -35
- package/dist/js/chunks/chunk-IQOTGGHX.mjs.map +7 -0
- package/dist/js/chunks/{chunk-QACZ6TUP.mjs → chunk-JH3YWKA6.mjs} +5 -4
- package/dist/js/chunks/chunk-JH3YWKA6.mjs.map +7 -0
- package/dist/js/chunks/chunk-JOLJAYIJ.mjs +7 -0
- package/dist/js/chunks/{chunk-4IKVPCSU.mjs.map → chunk-JOLJAYIJ.mjs.map} +1 -1
- package/dist/js/chunks/{chunk-BPF3I2MN.mjs → chunk-KOTGMCMI.mjs} +9 -2
- package/dist/js/chunks/chunk-KOTGMCMI.mjs.map +7 -0
- package/dist/js/chunks/{chunk-ANKFWNWT.mjs → chunk-LC4O5LFS.mjs} +3 -3
- package/dist/js/chunks/{chunk-4PIXLDNJ.mjs → chunk-LEF33SCP.mjs} +2 -2
- package/dist/js/chunks/{chunk-ILDRRG7T.mjs → chunk-LFORZRPH.mjs} +3 -3
- package/dist/js/chunks/{chunk-Z4OARDZ7.mjs → chunk-LWLNV5EC.mjs} +26 -17
- package/dist/js/chunks/chunk-LWLNV5EC.mjs.map +7 -0
- package/dist/js/chunks/{chunk-WU7XJ4RR.mjs → chunk-LXRHUQAX.mjs} +66 -25
- package/dist/js/chunks/chunk-LXRHUQAX.mjs.map +7 -0
- package/dist/js/chunks/{chunk-VMY55K2X.mjs → chunk-MA2SZZFB.mjs} +11 -7
- package/dist/js/chunks/chunk-MA2SZZFB.mjs.map +7 -0
- package/dist/js/chunks/{chunk-VJVQIXHC.mjs → chunk-MDBZAMIV.mjs} +8 -10
- package/dist/js/chunks/chunk-MDBZAMIV.mjs.map +7 -0
- package/dist/js/chunks/{chunk-4EWGD4V2.mjs → chunk-NODZ5VAD.mjs} +2 -2
- package/dist/js/chunks/{chunk-UGJHCHXG.mjs → chunk-O2WJB6TH.mjs} +79 -55
- package/dist/js/chunks/chunk-O2WJB6TH.mjs.map +7 -0
- package/dist/js/chunks/{chunk-7YZ5CN3V.mjs → chunk-PCABY5BN.mjs} +5 -3
- package/dist/js/chunks/chunk-PCABY5BN.mjs.map +7 -0
- package/dist/js/chunks/{chunk-X7SDA2J5.mjs → chunk-PWKYVMND.mjs} +9 -5
- package/dist/js/chunks/{chunk-X7SDA2J5.mjs.map → chunk-PWKYVMND.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-SPPHF7YZ.mjs → chunk-QHZZT7YO.mjs} +35 -14
- package/dist/js/chunks/chunk-QHZZT7YO.mjs.map +7 -0
- package/dist/js/chunks/{chunk-LDXCC2L3.mjs → chunk-QND56EW2.mjs} +5 -4
- package/dist/js/chunks/chunk-QND56EW2.mjs.map +7 -0
- package/dist/js/chunks/{chunk-NVQ5EHCU.mjs → chunk-QNODAANY.mjs} +4 -4
- package/dist/js/chunks/{chunk-7NLUI3RR.mjs → chunk-QRO5FV3I.mjs} +23 -13
- package/dist/js/chunks/chunk-QRO5FV3I.mjs.map +7 -0
- package/dist/js/chunks/{chunk-FCNF4GRJ.mjs → chunk-R7A7JRC5.mjs} +6 -11
- package/dist/js/chunks/chunk-R7A7JRC5.mjs.map +7 -0
- package/dist/js/chunks/{chunk-S23RJ3XY.mjs → chunk-RKG2CBFE.mjs} +4 -16
- package/dist/js/chunks/chunk-RKG2CBFE.mjs.map +7 -0
- package/dist/js/chunks/{chunk-6FSEUFVW.mjs → chunk-RSNS5OYS.mjs} +6 -6
- package/dist/js/chunks/chunk-RSNS5OYS.mjs.map +7 -0
- package/dist/js/chunks/{chunk-ROH2HDB4.mjs → chunk-RUDYMEJ3.mjs} +2 -2
- package/dist/js/chunks/{chunk-BIGU5RCJ.mjs → chunk-STJR62SU.mjs} +13 -5
- package/dist/js/chunks/chunk-STJR62SU.mjs.map +7 -0
- package/dist/js/chunks/{chunk-752ADW4M.mjs → chunk-SUSD4UTN.mjs} +27 -32
- package/dist/js/chunks/chunk-SUSD4UTN.mjs.map +7 -0
- package/dist/js/chunks/{chunk-B7DQFHA5.mjs → chunk-SYBOA5HC.mjs} +7 -12
- package/dist/js/chunks/chunk-SYBOA5HC.mjs.map +7 -0
- package/dist/js/chunks/{chunk-TFABTUAZ.mjs → chunk-T4MOBP3J.mjs} +2 -2
- package/dist/js/chunks/{chunk-GCWWEZKO.mjs → chunk-TM7HPGTV.mjs} +3 -3
- package/dist/js/chunks/{chunk-5KIHWJI2.mjs → chunk-TMQDZSDC.mjs} +34 -12
- package/dist/js/chunks/chunk-TMQDZSDC.mjs.map +7 -0
- package/dist/js/chunks/{chunk-ZO6ZLHFF.mjs → chunk-TVSX5YA2.mjs} +3 -3
- package/dist/js/chunks/{chunk-INLZWHLY.mjs → chunk-UHO5CV6K.mjs} +2 -2
- package/dist/js/chunks/{chunk-INLZWHLY.mjs.map → chunk-UHO5CV6K.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-7YQBHTK3.mjs → chunk-UKCNELUN.mjs} +6 -8
- package/dist/js/chunks/chunk-UKCNELUN.mjs.map +7 -0
- package/dist/js/chunks/{chunk-VH4BMAZS.mjs → chunk-UKQK5GWR.mjs} +13 -13
- package/dist/js/chunks/chunk-UKQK5GWR.mjs.map +7 -0
- package/dist/js/chunks/{chunk-OYNUDOHR.mjs → chunk-UTSLYQ65.mjs} +7 -6
- package/dist/js/chunks/{chunk-OYNUDOHR.mjs.map → chunk-UTSLYQ65.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-7W7TV6NY.mjs → chunk-VS5OJBOD.mjs} +2 -2
- package/dist/js/chunks/{chunk-7W7TV6NY.mjs.map → chunk-VS5OJBOD.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-KYIEG4U3.mjs → chunk-VZMROW5A.mjs} +43 -14
- package/dist/js/chunks/chunk-VZMROW5A.mjs.map +7 -0
- package/dist/js/chunks/{chunk-VFV75DHF.mjs → chunk-XB6Y7P5W.mjs} +11 -12
- package/dist/js/chunks/chunk-XB6Y7P5W.mjs.map +7 -0
- package/dist/js/chunks/{chunk-CZSQHXEV.mjs → chunk-XDAMOMVD.mjs} +20 -21
- package/dist/js/chunks/chunk-XDAMOMVD.mjs.map +7 -0
- package/dist/js/chunks/{chunk-EVCVFEV3.mjs → chunk-XJPMW5SP.mjs} +21 -35
- package/dist/js/chunks/chunk-XJPMW5SP.mjs.map +7 -0
- package/dist/js/chunks/{chunk-VR3L2WN5.mjs → chunk-YKANQILZ.mjs} +7 -6
- package/dist/js/chunks/chunk-YKANQILZ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-JUKBBN6P.mjs → chunk-YLZOJLDI.mjs} +2 -2
- package/dist/js/chunks/{chunk-U4B3VHFS.mjs → chunk-ZK7YY322.mjs} +28 -21
- package/dist/js/chunks/chunk-ZK7YY322.mjs.map +7 -0
- package/dist/js/expressive.cjs +2739 -2387
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +2739 -2387
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +7 -7
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +76 -75
- package/dist/js/expressive.mjs.map +1 -1
- package/dist/js/internal/behaviors/bottomSheets.mjs +3 -3
- package/dist/js/internal/behaviors/copy.mjs +3 -3
- package/dist/js/internal/behaviors/dataTables.mjs +2 -4
- package/dist/js/internal/behaviors/dialogs.mjs +2 -2
- package/dist/js/internal/behaviors/forms.mjs +2 -2
- package/dist/js/internal/behaviors/imageCompare.mjs +2 -2
- package/dist/js/internal/behaviors/lists.mjs +2 -2
- package/dist/js/internal/behaviors/paneResize.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/behaviors/sortable.mjs +2 -2
- package/dist/js/internal/behaviors/theme.mjs +2 -2
- package/dist/js/internal/behaviors/tour.mjs +2 -2
- package/dist/js/internal/behaviors/transferList.mjs +2 -2
- package/dist/js/internal/components/appBar.mjs +3 -3
- package/dist/js/internal/components/autocomplete.mjs +5 -4
- package/dist/js/internal/components/backToTop.mjs +3 -3
- package/dist/js/internal/components/barChart.mjs +5 -5
- package/dist/js/internal/components/buttonGroup.mjs +3 -3
- 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/cascader.mjs +4 -4
- package/dist/js/internal/components/characterCounter.mjs +3 -3
- package/dist/js/internal/components/chips.mjs +7 -6
- package/dist/js/internal/components/colorPicker.mjs +3 -3
- package/dist/js/internal/components/columnChart.mjs +4 -4
- package/dist/js/internal/components/commandPalette.mjs +3 -3
- package/dist/js/internal/components/confetti.mjs +3 -3
- package/dist/js/internal/components/currencyInput.mjs +3 -3
- package/dist/js/internal/components/datepicker.mjs +8 -7
- package/dist/js/internal/components/expandingCard.mjs +3 -3
- package/dist/js/internal/components/funnelChart.mjs +4 -4
- package/dist/js/internal/components/heatmapChart.mjs +4 -4
- package/dist/js/internal/components/hoverCard.mjs +3 -3
- package/dist/js/internal/components/index.mjs +60 -59
- package/dist/js/internal/components/inputMask.mjs +3 -3
- package/dist/js/internal/components/keypad.mjs +3 -3
- package/dist/js/internal/components/lightbox.mjs +3 -3
- package/dist/js/internal/components/lineChart.mjs +23 -7
- package/dist/js/internal/components/loadingOverlay.mjs +3 -3
- package/dist/js/internal/components/mapView.mjs +3 -3
- package/dist/js/internal/components/menu.mjs +3 -3
- package/dist/js/internal/components/menubar.mjs +4 -4
- package/dist/js/internal/components/messageScroller.mjs +3 -3
- package/dist/js/internal/components/mixedChart.mjs +5 -5
- package/dist/js/internal/components/navigationRail.mjs +3 -3
- package/dist/js/internal/components/particles.mjs +3 -3
- package/dist/js/internal/components/pieChart.mjs +4 -4
- package/dist/js/internal/components/pullToRefresh.mjs +3 -3
- package/dist/js/internal/components/questionnaire.mjs +3 -3
- package/dist/js/internal/components/radarChart.mjs +4 -4
- package/dist/js/internal/components/radialChart.mjs +4 -4
- package/dist/js/internal/components/registry.mjs +59 -58
- package/dist/js/internal/components/richTextEditor.mjs +3 -3
- package/dist/js/internal/components/sankeyChart.mjs +4 -4
- package/dist/js/internal/components/scatterChart.mjs +4 -4
- package/dist/js/internal/components/scrollspy.mjs +3 -3
- package/dist/js/internal/components/select.mjs +5 -4
- package/dist/js/internal/components/showMore.mjs +3 -3
- package/dist/js/internal/components/slider.mjs +3 -3
- package/dist/js/internal/components/snackbar.mjs +2 -2
- package/dist/js/internal/components/swipeActions.mjs +3 -3
- package/dist/js/internal/components/tabs.mjs +3 -3
- package/dist/js/internal/components/timepicker.mjs +5 -5
- package/dist/js/internal/components/tooltip.mjs +3 -3
- package/dist/js/internal/components/treeSelect.mjs +6 -5
- package/dist/js/internal/components/treemapChart.mjs +4 -4
- package/dist/js/internal/core/component.mjs +6 -4
- package/dist/js/internal/core/formControl.mjs +2 -2
- package/dist/js/internal/core/imageURL.mjs +7 -0
- package/dist/js/internal/core/imageURL.mjs.map +7 -0
- package/dist/js/internal/core/utils.mjs +11 -1
- package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +2 -2
- package/dist/js/internal/plugins/modalDisplayPlugin.mjs +3 -3
- package/dist/js/modular.mjs +76 -75
- package/dist/types/behaviors/bottomSheets.d.ts +5 -3
- package/dist/types/behaviors/dataTables.d.ts +2 -6
- package/dist/types/behaviors/forms.d.ts +7 -7
- package/dist/types/behaviors/imageCompare.d.ts +2 -1
- package/dist/types/behaviors/transferList.d.ts +2 -0
- package/dist/types/components/autocomplete.d.ts +14 -3
- package/dist/types/components/carousel.d.ts +7 -0
- package/dist/types/components/chips.d.ts +15 -0
- package/dist/types/components/colorPicker.d.ts +14 -0
- package/dist/types/components/currencyInput.d.ts +5 -4
- package/dist/types/components/datepicker.d.ts +54 -27
- package/dist/types/components/funnelChart.d.ts +1 -4
- package/dist/types/components/heatmapChart.d.ts +3 -0
- package/dist/types/components/hoverCard.d.ts +1 -0
- package/dist/types/components/inputMask.d.ts +0 -2
- package/dist/types/components/lineChart.d.ts +43 -5
- package/dist/types/components/mapView.d.ts +113 -11
- package/dist/types/components/menu.d.ts +14 -0
- package/dist/types/components/particles.d.ts +14 -1
- package/dist/types/components/pieChart.d.ts +1 -2
- package/dist/types/components/richTextEditor.d.ts +40 -9
- package/dist/types/components/select.d.ts +1 -3
- package/dist/types/components/showMore.d.ts +2 -0
- package/dist/types/components/slider.d.ts +0 -1
- package/dist/types/components/snackbar.d.ts +7 -1
- package/dist/types/components/tabs.d.ts +3 -3
- package/dist/types/components/timepicker.d.ts +15 -6
- package/dist/types/components/tooltip.d.ts +1 -1
- package/dist/types/components/treemapChart.d.ts +2 -2
- package/dist/types/core/component.d.ts +9 -3
- package/dist/types/core/imageURL.d.ts +2 -0
- package/dist/types/core/utils.d.ts +39 -1
- package/dist/types/modular.d.ts +1 -1
- package/dist/types/plugins/modalDisplayPlugin.d.ts +8 -1
- package/package.json +8 -6
- package/src/sass/abstracts/_mixins.scss +459 -59
- package/src/sass/abstracts/_variables.scss +25 -0
- package/src/sass/components/_accordion.scss +1 -3
- package/src/sass/components/_aura.scss +1 -0
- package/src/sass/components/_back-to-top.scss +3 -3
- package/src/sass/components/_bar-chart.scss +2 -83
- package/src/sass/components/_bottom-sheet.scss +7 -0
- package/src/sass/components/_breadcrumb.scss +1 -7
- package/src/sass/components/_button-groups.scss +15 -38
- package/src/sass/components/_buttons.scss +24 -74
- package/src/sass/components/_calendar.scss +1 -3
- package/src/sass/components/_carousel.scss +10 -10
- package/src/sass/components/_cascader.scss +3 -14
- package/src/sass/components/_column-chart.scss +1 -19
- package/src/sass/components/_confetti.scss +3 -4
- package/src/sass/components/_data-table.scss +10 -0
- package/src/sass/components/_dialog.scss +10 -18
- package/src/sass/components/_expanding-card.scss +1 -5
- package/src/sass/components/_fab-menu.scss +4 -12
- package/src/sass/components/_funnel-chart.scss +1 -62
- package/src/sass/components/_heatmap-chart.scss +2 -6
- package/src/sass/components/_icon-buttons.scss +1 -4
- package/src/sass/components/_line-chart.scss +2 -70
- package/src/sass/components/_map.scss +4 -0
- package/src/sass/components/_marquee.scss +3 -3
- package/src/sass/components/_mega-menu.scss +8 -17
- package/src/sass/components/_menu.scss +10 -11
- package/src/sass/components/_menubar.scss +1 -13
- package/src/sass/components/_mixed-chart.scss +1 -37
- package/src/sass/components/_navbar.scss +11 -16
- package/src/sass/components/_navigation-bar.scss +2 -5
- package/src/sass/components/_navigation-rail.scss +25 -15
- package/src/sass/components/_page-footer.scss +1 -3
- package/src/sass/components/_pagination.scss +3 -14
- package/src/sass/components/_panes.scss +3 -16
- package/src/sass/components/_particles.scss +3 -4
- package/src/sass/components/_pie-chart.scss +8 -70
- package/src/sass/components/_progress.scss +31 -13
- package/src/sass/components/_radar-chart.scss +2 -32
- package/src/sass/components/_radial-chart.scss +2 -48
- package/src/sass/components/_sankey-chart.scss +5 -28
- package/src/sass/components/_scatter-chart.scss +2 -11
- package/src/sass/components/_search.scss +1 -4
- package/src/sass/components/_side-sheet.scss +9 -14
- package/src/sass/components/_skeleton.scss +24 -15
- package/src/sass/components/_snackbar.scss +11 -13
- package/src/sass/components/_table_of_contents.scss +1 -3
- package/src/sass/components/_tabs.scss +4 -20
- package/src/sass/components/_timepicker.scss +2 -1
- package/src/sass/components/_toolbar.scss +1 -4
- package/src/sass/components/_tooltip.scss +9 -5
- package/src/sass/components/_tree.scss +5 -17
- package/src/sass/components/_treemap-chart.scss +2 -26
- package/src/sass/components/forms/_checkboxes.scss +2 -21
- package/src/sass/components/forms/_drop-zone.scss +1 -4
- package/src/sass/components/forms/_fieldset.scss +1 -4
- package/src/sass/components/forms/_file-input.scss +6 -0
- package/src/sass/components/forms/_input-fields.scss +21 -4
- package/src/sass/components/forms/_radio-buttons.scss +2 -24
- package/src/sass/components/forms/_select.scss +6 -7
- package/src/sass/components/forms/_slider.scss +1 -4
- package/src/sass/components/forms/_switches.scss +14 -21
- package/src/sass/utilities/_helpers.scss +1 -1
- package/src/sass/utilities/_visibility.scss +1 -3
- package/dist/js/chunks/chunk-2CS6TITK.mjs.map +0 -7
- package/dist/js/chunks/chunk-3L3QIYLC.mjs.map +0 -7
- package/dist/js/chunks/chunk-4IKVPCSU.mjs +0 -7
- package/dist/js/chunks/chunk-4QUCNFSD.mjs.map +0 -7
- package/dist/js/chunks/chunk-4TRZ2AER.mjs.map +0 -7
- package/dist/js/chunks/chunk-5KIHWJI2.mjs.map +0 -7
- package/dist/js/chunks/chunk-6FSEUFVW.mjs.map +0 -7
- package/dist/js/chunks/chunk-752ADW4M.mjs.map +0 -7
- package/dist/js/chunks/chunk-7NLUI3RR.mjs.map +0 -7
- package/dist/js/chunks/chunk-7YQBHTK3.mjs.map +0 -7
- package/dist/js/chunks/chunk-7YZ5CN3V.mjs.map +0 -7
- package/dist/js/chunks/chunk-B7DQFHA5.mjs.map +0 -7
- package/dist/js/chunks/chunk-BIGU5RCJ.mjs.map +0 -7
- package/dist/js/chunks/chunk-BPF3I2MN.mjs.map +0 -7
- package/dist/js/chunks/chunk-CMGXGYUC.mjs.map +0 -7
- package/dist/js/chunks/chunk-CSYWKEK3.mjs.map +0 -7
- package/dist/js/chunks/chunk-CZSQHXEV.mjs.map +0 -7
- package/dist/js/chunks/chunk-DZYVU75J.mjs.map +0 -7
- package/dist/js/chunks/chunk-EC26RU2D.mjs.map +0 -7
- package/dist/js/chunks/chunk-EVCVFEV3.mjs.map +0 -7
- package/dist/js/chunks/chunk-FCNF4GRJ.mjs.map +0 -7
- package/dist/js/chunks/chunk-GWZ76SR4.mjs.map +0 -7
- package/dist/js/chunks/chunk-KYIEG4U3.mjs.map +0 -7
- package/dist/js/chunks/chunk-KZPSAXIU.mjs.map +0 -7
- package/dist/js/chunks/chunk-LDXCC2L3.mjs.map +0 -7
- package/dist/js/chunks/chunk-NBJAUGPP.mjs.map +0 -7
- package/dist/js/chunks/chunk-OUCHKSAW.mjs.map +0 -7
- package/dist/js/chunks/chunk-P6DRQ6KS.mjs.map +0 -7
- package/dist/js/chunks/chunk-PA7NU5AK.mjs.map +0 -7
- package/dist/js/chunks/chunk-QACZ6TUP.mjs.map +0 -7
- package/dist/js/chunks/chunk-QXKWVHBD.mjs.map +0 -7
- package/dist/js/chunks/chunk-S23RJ3XY.mjs.map +0 -7
- package/dist/js/chunks/chunk-SPPHF7YZ.mjs.map +0 -7
- package/dist/js/chunks/chunk-U4B3VHFS.mjs.map +0 -7
- package/dist/js/chunks/chunk-UGJHCHXG.mjs.map +0 -7
- package/dist/js/chunks/chunk-VFV75DHF.mjs.map +0 -7
- package/dist/js/chunks/chunk-VGY4M57S.mjs.map +0 -7
- package/dist/js/chunks/chunk-VH4BMAZS.mjs.map +0 -7
- package/dist/js/chunks/chunk-VJVQIXHC.mjs.map +0 -7
- package/dist/js/chunks/chunk-VMY55K2X.mjs.map +0 -7
- package/dist/js/chunks/chunk-VR3L2WN5.mjs.map +0 -7
- package/dist/js/chunks/chunk-WU7XJ4RR.mjs.map +0 -7
- package/dist/js/chunks/chunk-Y6TLRA3U.mjs.map +0 -7
- package/dist/js/chunks/chunk-Z4GICXR2.mjs.map +0 -7
- package/dist/js/chunks/chunk-Z4OARDZ7.mjs.map +0 -7
- package/dist/js/chunks/chunk-ZM3XBHWV.mjs.map +0 -7
- package/dist/js/chunks/chunk-ZVLOUDIJ.mjs.map +0 -7
- /package/dist/js/chunks/{chunk-Y6H2X7ZC.mjs.map → chunk-3KF65KGL.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-75E5EDJF.mjs.map → chunk-3XORNED5.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-NNHVANQA.mjs.map → chunk-4WBGAQN3.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-ZJNLAGY5.mjs.map → chunk-5F4URJHL.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-GVZQH2H5.mjs.map → chunk-AEG6LOAJ.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-AI73GJKG.mjs.map → chunk-BB5VXYXT.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-2RLBDFH4.mjs.map → chunk-BDATLH3H.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-ZKWUWBUB.mjs.map → chunk-CY2CTOVM.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-67ZPPKXS.mjs.map → chunk-FNIIH2LU.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-T3BNSRP3.mjs.map → chunk-HQRLBTNM.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-NAC72P7R.mjs.map → chunk-I2F7MLUU.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-ANKFWNWT.mjs.map → chunk-LC4O5LFS.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-4PIXLDNJ.mjs.map → chunk-LEF33SCP.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-ILDRRG7T.mjs.map → chunk-LFORZRPH.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-4EWGD4V2.mjs.map → chunk-NODZ5VAD.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-NVQ5EHCU.mjs.map → chunk-QNODAANY.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-ROH2HDB4.mjs.map → chunk-RUDYMEJ3.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-TFABTUAZ.mjs.map → chunk-T4MOBP3J.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-GCWWEZKO.mjs.map → chunk-TM7HPGTV.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-ZO6ZLHFF.mjs.map → chunk-TVSX5YA2.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-JUKBBN6P.mjs.map → chunk-YLZOJLDI.mjs.map} +0 -0
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/components/carousel.ts"],
|
|
4
|
-
"sourcesContent": ["import { restoreAttribute } from '../core/utils';\nimport { Component, BaseOptions } from '../core/component';\n\nexport interface CarouselI18nOptions {\n carousel: string;\n item: string;\n of: string;\n indicators: string;\n slide: string;\n}\n\nexport interface CarouselOptions extends BaseOptions {\n /**\n * Milliseconds allowed for a programmatic scroll to land. The track itself\n * scrolls at the browser's own smooth-scroll speed; this only bounds how\n * long the component waits for `scrollend` before assuming it arrived, and\n * is added to `interval` to time each auto-advance rest.\n * @default 200\n */\n duration: number;\n /**\n * Show paging dots. Only drawn when there is more than one item.\n * @default false\n */\n indicators: boolean;\n /**\n * Stop auto-advance at the last item instead of looping back to the first.\n * A scroll track never wraps under arrow keys or `set()` either way.\n * @default false\n */\n noWrap: boolean;\n /**\n * Milliseconds to rest between automatic advances, on top of `duration` -\n * the gap follows each transition rather than containing it, so a full cycle\n * takes `duration + interval`. 0 leaves auto-advance off.\n * Whenever it is set the track pauses on hover and on keyboard focus, and\n * `prefers-reduced-motion: reduce` suppresses it entirely - auto-advancing\n * content is WCAG 2.2.2 territory, so neither is an option an author can\n * turn off. `noWrap` stops it after one pass instead of looping.\n * @default 0\n */\n interval: number;\n /**\n * Fixed track height in pixels. `null` sizes the carousel from its content.\n * A fixed height gives the indicators their own row below the track instead\n * of laying them over the media.\n * @default null\n */\n height: number | null;\n /**\n * Called when a new item becomes the center.\n * @default null\n */\n onCycleTo: (current: Element, dragged: boolean) => void;\n /**\n * Accessible names generated for an unlabeled carousel, its items and its\n * indicators.\n */\n i18n: Partial<CarouselI18nOptions>;\n}\n\nconst _defaults: CarouselOptions = {\n duration: 200,\n indicators: false,\n noWrap: false,\n interval: 0,\n height: null,\n onCycleTo: null,\n i18n: {\n carousel: 'Carousel',\n item: 'Item',\n of: 'of',\n indicators: 'Slides',\n slide: 'Slide'\n }\n};\n\nconst naturallyFocusable =\n 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), ' +\n 'textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nexport class Carousel extends Component<CarouselOptions> {\n hasMultipleSlides: boolean;\n showIndicators: boolean;\n pressed: boolean;\n dragged: boolean;\n images: HTMLElement[];\n _indicators: HTMLUListElement | HTMLElement;\n count: number;\n center: number = 0;\n scrollingTimeout: ReturnType<typeof setTimeout>;\n oneTimeCallback: (current: Element, dragged: boolean) => void | null;\n\n private _ownIndicators: boolean = false;\n private _trackEl: HTMLElement | null = null;\n private _ignoreScroll: boolean = false;\n private _alignAfterResize = false;\n private _scrollEndTimeout: ReturnType<typeof setTimeout>;\n private _trackRaf: number = null;\n private _started: boolean = false;\n private _vertical: boolean = false;\n private _resizeObserver: ResizeObserver | null = null;\n private _resizeTimeout: ReturnType<typeof setTimeout> = null;\n private _dragPointerId: number | null = null;\n private _dragStartX: number = 0;\n private _dragStartY: number = 0;\n private _dragStartScroll: number = 0;\n private _suppressClick: boolean = false;\n private _suppressClickTimeout: ReturnType<typeof setTimeout> = null;\n private _generatedContainerRole: boolean = false;\n private _generatedContainerLabel: boolean = false;\n private _generatedContainerDescription: boolean = false;\n private _generatedWideLayout: boolean = false;\n private _generatedFixedHeight: boolean = false;\n private _authoredInlineHeight: string | null = null;\n private _autoAdvanceTimer: ReturnType<typeof setTimeout> = null;\n private _autoAdvances: boolean = false;\n private _autoPaused: boolean = false;\n private _hovered: boolean = false;\n private _focused: boolean = false;\n private _motion = window.matchMedia('(prefers-reduced-motion: reduce)');\n private _generatedItemTabIndexes = new Set<HTMLElement>();\n private _generatedItemLabels = new Set<HTMLElement>();\n private _generatedItemDescriptions = new Set<HTMLElement>();\n private _generatedItemSizes = new Set<HTMLElement>();\n private _authoredItemSizes = new Set<HTMLElement>();\n private _itemA11yOriginal = new Map<\n HTMLElement,\n { ariaHidden: string | null; tabIndex: string | null }\n >();\n\n private get _scroller(): HTMLElement {\n return this._trackEl ?? this.el;\n }\n\n constructor(el: HTMLElement, options: Partial<CarouselOptions>) {\n super(el, options);\n\n this._vertical = this.el.classList.contains('full-screen');\n\n this.pressed = false;\n this.dragged = false;\n this.images = this._collectItems();\n if (!this.images.length) {\n console.error('Carousel: no .carousel-item elements to show');\n return;\n }\n this.images.forEach((item) => {\n this._itemA11yOriginal.set(item, {\n ariaHidden: item.getAttribute('aria-hidden'),\n tabIndex: item.getAttribute('tabindex')\n });\n if (item.hasAttribute('data-carousel-size')) this._authoredItemSizes.add(item);\n });\n\n this.hasMultipleSlides = this.images.length > 1;\n this.showIndicators = this.options.indicators && this.hasMultipleSlides;\n this.count = this.images.length;\n\n this._autoAdvances = this.options.interval > 0 && this.hasMultipleSlides;\n\n this.images.forEach((item) => item.classList.add('carousel-item'));\n if (this.options.height !== null) {\n this._generatedFixedHeight = !this.el.classList.contains('fixed-height');\n this._authoredInlineHeight = this.el.style.getPropertyValue('--carousel-height') || null;\n this.el.classList.add('fixed-height');\n this.el.style.setProperty('--carousel-height', `${this.options.height}px`);\n }\n this._wrapTrack();\n this._syncAdaptiveMode();\n\n if (this.showIndicators) this._setupIndicators();\n\n this._setupAccessibility();\n\n this._setupEventHandlers();\n this._started = true;\n\n const start = Math.max(\n 0,\n this.images.findIndex((el) => el.classList.contains('active'))\n );\n this.center = start;\n this._syncActive(start, false);\n this._updateParallax();\n this._scrollToIndex(start, false);\n\n this._syncAutoAdvance();\n }\n\n static get defaults(): CarouselOptions {\n return _defaults;\n }\n\n static key = 'Expressive_Carousel';\n\n destroy() {\n if (this._started) this._teardown();\n super.destroy();\n }\n\n private _collectItems(): HTMLElement[] {\n const explicit = Array.from(this.el.children).filter(\n (el): el is HTMLElement => el instanceof HTMLElement && el.classList.contains('carousel-item')\n );\n if (explicit.length) return explicit;\n return Array.from(this.el.children).filter((el): el is HTMLElement => {\n if (!(el instanceof HTMLElement)) return false;\n if (el.classList.contains('indicators')) {\n return false;\n }\n return el.tagName !== 'NAV';\n });\n }\n\n private _setupAccessibility() {\n if (!this.el.hasAttribute('role')) {\n this.el.setAttribute('role', 'region');\n this._generatedContainerRole = true;\n }\n if (!this.el.hasAttribute('aria-label') && !this.el.hasAttribute('aria-labelledby')) {\n this.el.setAttribute('aria-label', this.options.i18n.carousel);\n this._generatedContainerLabel = true;\n }\n if (!this.el.hasAttribute('aria-roledescription')) {\n this.el.setAttribute('aria-roledescription', 'carousel');\n this._generatedContainerDescription = true;\n }\n\n this.images.forEach((item, index) => {\n if (!item.hasAttribute('aria-roledescription')) {\n item.setAttribute('aria-roledescription', 'slide');\n this._generatedItemDescriptions.add(item);\n }\n\n if (!item.hasAttribute('aria-label') && !item.hasAttribute('aria-labelledby')) {\n const mediaName = item.querySelector('img[alt]')?.getAttribute('alt')?.trim();\n const textName = item.textContent?.replace(/\\s+/g, ' ').trim();\n const name = mediaName || textName;\n const position = `${this.options.i18n.item} ${index + 1} ${this.options.i18n.of} ${this.count}`;\n item.setAttribute('aria-label', name ? `${name}, ${position}` : position);\n this._generatedItemLabels.add(item);\n }\n\n if (!item.matches(naturallyFocusable) && !item.querySelector(naturallyFocusable)) {\n item.tabIndex = 0;\n this._generatedItemTabIndexes.add(item);\n }\n });\n }\n\n private _setupIndicators() {\n const existing = Array.from(this.el.children).find(\n (el): el is HTMLElement => el instanceof HTMLElement && el.classList.contains('indicators')\n );\n this._indicators = existing ?? document.createElement('nav');\n this._ownIndicators = !existing;\n this._indicators.classList.add('indicators');\n this._indicators.setAttribute('aria-label', this.options.i18n.indicators);\n this._indicators.replaceChildren();\n\n this.images.forEach((_, i) => {\n const button = document.createElement('button');\n button.type = 'button';\n button.classList.add('indicator-item');\n button.setAttribute('aria-label', `${this.options.i18n.slide} ${i + 1}`);\n this._indicators.appendChild(button);\n });\n\n if (this._ownIndicators) this.el.appendChild(this._indicators);\n }\n\n _setupEventHandlers() {\n const { signal } = this._events;\n this.el.addEventListener('keydown', this._handleKeydown, { signal });\n this._motion.addEventListener('change', this._handleMotionChange, { signal });\n if (this._autoAdvances) {\n this.el.addEventListener('mouseenter', this._handleAutoAdvanceState, { signal });\n this.el.addEventListener('mouseleave', this._handleAutoAdvanceState, { signal });\n this.el.addEventListener('focusin', this._handleAutoAdvanceState, { signal });\n this.el.addEventListener('focusout', this._handleAutoAdvanceState, { signal });\n // Browsers clamp a background tab's timers rather than stopping them, so\n // without this the track keeps cycling out of sight.\n document.addEventListener('visibilitychange', this._handleAutoAdvanceState, { signal });\n }\n if (this.showIndicators && this._indicators) {\n this._indicators.addEventListener('click', this._handleIndicatorClick, { signal });\n }\n this._resizeObserver = new ResizeObserver(() => this._handleThrottledResize());\n this._resizeObserver.observe(this.el);\n\n // Full-screen needs a window signal when orientation changes without\n // changing the container width. ResizeObserver handles every other track,\n // including pane resizes.\n if (this.el.classList.contains('full-screen')) {\n window.addEventListener('resize', this._handleThrottledResize, { passive: true, signal });\n }\n\n this._scroller.addEventListener('scroll', this._handleTrackScroll, { passive: true, signal });\n this._scroller.addEventListener('pointerdown', this._handleTrackPointerDown, { signal });\n this._scroller.addEventListener('wheel', this._handleNativeScroll, { passive: true, signal });\n this._scroller.addEventListener('click', this._handleTrackClick, { capture: true, signal });\n this._scroller.addEventListener('dragstart', this._handleTrackDragStart, { signal });\n this._scroller.addEventListener('transitionend', this._handleItemResize, { signal });\n }\n\n private _teardown() {\n this._started = false;\n this._events.abort();\n this._resizeObserver?.disconnect();\n this._resizeObserver = null;\n this._finishScroll();\n this._autoAdvances = false;\n this._syncAutoAdvance();\n if (this._trackRaf !== null) cancelAnimationFrame(this._trackRaf);\n window.clearTimeout(this.scrollingTimeout);\n window.clearTimeout(this._suppressClickTimeout);\n clearTimeout(this._resizeTimeout);\n if (this._ownIndicators) this._indicators?.remove();\n this._unwrapTrack();\n this.images.forEach((el) => {\n el.style.removeProperty('--md-comp-carousel-item-parallax');\n if (this._generatedItemLabels.has(el)) el.removeAttribute('aria-label');\n if (this._generatedItemDescriptions.has(el)) el.removeAttribute('aria-roledescription');\n if (this._generatedItemSizes.has(el)) el.removeAttribute('data-carousel-size');\n const original = this._itemA11yOriginal.get(el);\n if (original) {\n restoreAttribute(el, 'aria-hidden', original.ariaHidden);\n restoreAttribute(el, 'tabindex', original.tabIndex);\n }\n });\n if (this._generatedContainerRole) this.el.removeAttribute('role');\n if (this._generatedContainerLabel) this.el.removeAttribute('aria-label');\n if (this._generatedContainerDescription) this.el.removeAttribute('aria-roledescription');\n if (this._generatedFixedHeight) this.el.classList.remove('fixed-height');\n if (this.options.height !== null) {\n if (this._authoredInlineHeight === null) this.el.style.removeProperty('--carousel-height');\n else this.el.style.setProperty('--carousel-height', this._authoredInlineHeight);\n }\n if (this._generatedWideLayout) {\n this.el.classList.remove(\n 'multi-wide',\n 'multi-large',\n 'multi-extra-large',\n 'full-screen-horizontal'\n );\n }\n }\n\n _handleThrottledResize = () => {\n if (!this._started || this._resizeTimeout !== null) return;\n this._handleResize();\n this._resizeTimeout = setTimeout(() => {\n this._resizeTimeout = null;\n this._handleResize();\n }, 200);\n };\n\n _handleAutoAdvanceState = (e: Event) => {\n if (e.type === 'mouseenter') this._hovered = true;\n else if (e.type === 'mouseleave') this._hovered = false;\n else if (e.type === 'focusin') this._focused = true;\n else if (e.type === 'focusout') this._focused = this.el.contains((e as FocusEvent).relatedTarget as Node);\n this._syncAutoAdvance();\n };\n\n private _handleMotionChange = () => {\n this._syncAutoAdvance();\n if (this._motion.matches) this._scrollToIndex(this.center, false);\n this._updateParallax();\n };\n\n /** Start or stop the timer to match the current pause state. */\n private _syncAutoAdvance() {\n const run =\n this._autoAdvances &&\n !this._autoPaused &&\n !this._hovered &&\n !this._focused &&\n !this._motion.matches &&\n !document.hidden;\n if (run && this._autoAdvanceTimer === null) {\n // Each rest is armed after the move before it, never on a fixed phase.\n // A repeating timer assumes the work it triggers is instant; a smooth\n // scroll is not, so a fixed period either lands mid-scroll or, once a\n // tick is dropped, leaves whatever is left of the period as the next\n // rest.\n this._autoAdvanceTimer = setTimeout(\n this._tick,\n this.options.duration + this.options.interval\n );\n } else if (!run && this._autoAdvanceTimer !== null) {\n clearTimeout(this._autoAdvanceTimer);\n this._autoAdvanceTimer = null;\n }\n }\n\n private _tick = () => {\n this._autoAdvanceTimer = null;\n this._advance();\n this._syncAutoAdvance();\n };\n\n private _advance = () => {\n const next = this.center + 1;\n if (next < this.count) {\n this.set(next);\n return;\n }\n // Arrow keys and `set()` never wrap, because a scroll container has ends.\n // Auto-advance is the one caller that can: looping back to the first item\n // is just a scroll. An author who asked for no wrapping gets one pass and\n // then silence.\n if (this.options.noWrap) {\n this._autoAdvances = false;\n this._syncAutoAdvance();\n return;\n }\n this.set(0);\n };\n\n private _handleNativeScroll = () => {\n this._alignAfterResize = false;\n this._finishScroll();\n };\n\n /** The document only hears from a carousel while a mouse press is down on its track. */\n private _setDragListeners(on: boolean) {\n const method = on ? 'addEventListener' : 'removeEventListener';\n // The signal also removes them when the carousel is destroyed mid-drag.\n const options = { signal: this._events.signal };\n document[method]('pointermove', this._handleTrackPointerMove, options);\n document[method]('pointerup', this._handleTrackPointerUp, options);\n document[method]('pointercancel', this._handleTrackPointerUp, options);\n }\n\n _handleTrackPointerDown = (e: PointerEvent) => {\n this._handleNativeScroll();\n if (e.pointerType !== 'mouse' || e.button !== 0) return;\n this.pressed = true;\n this.dragged = false;\n this._suppressClick = false;\n this._dragPointerId = e.pointerId;\n this._dragStartX = e.clientX;\n this._dragStartY = e.clientY;\n this._dragStartScroll = this._vertical ? this._scroller.scrollTop : this._scroller.scrollLeft;\n this._setDragListeners(true);\n };\n\n _handleTrackPointerMove = (e: PointerEvent) => {\n if (!this.pressed || e.pointerId !== this._dragPointerId) return;\n const deltaX = e.clientX - this._dragStartX;\n const deltaY = e.clientY - this._dragStartY;\n const primaryDelta = this._vertical ? deltaY : deltaX;\n const crossDelta = this._vertical ? deltaX : deltaY;\n\n if (!this.dragged) {\n if (Math.abs(primaryDelta) < 6 || Math.abs(primaryDelta) <= Math.abs(crossDelta)) return;\n this.dragged = true;\n this.el.classList.add('dragging');\n try {\n this._scroller.setPointerCapture(e.pointerId);\n } catch {\n // Pointer capture is optional in older browsers and test DOMs.\n }\n }\n\n if (this._vertical) this._scroller.scrollTop = this._dragStartScroll - deltaY;\n else this._scroller.scrollLeft = this._dragStartScroll - deltaX;\n e.preventDefault();\n };\n\n _handleTrackPointerUp = (e: PointerEvent) => {\n if (!this.pressed || e.pointerId !== this._dragPointerId) return;\n this.pressed = false;\n this._dragPointerId = null;\n this._setDragListeners(false);\n this.el.classList.remove('dragging');\n try {\n this._scroller.releasePointerCapture(e.pointerId);\n } catch {\n // Pointer capture may already have been released.\n }\n\n if (!this.dragged) return;\n this._suppressClick = true;\n window.clearTimeout(this._suppressClickTimeout);\n this._suppressClickTimeout = setTimeout(() => {\n this._suppressClick = false;\n }, 0);\n this._syncActive(this._nearestIndex(), true);\n };\n\n _handleTrackClick = (e: MouseEvent) => {\n if (!this._suppressClick) return;\n this._suppressClick = false;\n e.preventDefault();\n e.stopImmediatePropagation();\n };\n\n _handleTrackDragStart = (e: DragEvent) => {\n if ((e.target as HTMLElement).closest('a, img, picture, video')) e.preventDefault();\n };\n\n private _handleItemResize = (e: TransitionEvent) => {\n if (this._alignAfterResize && !this.pressed && e.propertyName === 'flex-basis' && this.images.includes(e.target as HTMLElement)) {\n this._scrollToIndex(this.center, false);\n }\n };\n\n _handleIndicatorClick = (e: Event) => {\n e.stopPropagation();\n const indicator = (e.target as HTMLElement).closest('.indicator-item');\n if (!indicator || !this._indicators.contains(indicator)) return;\n const index = [...this._indicators.children].indexOf(indicator);\n if (index < 0) return;\n this._cycleTo(index);\n };\n\n /**\n * Keys the carousel leaves alone. Modified keys are shortcuts (Alt+Left is\n * Back), and a nested widget that reads arrows itself - a field, a slider,\n * tabs, a menu, media controls - keeps them.\n */\n private _keyBelongsElsewhere(e: KeyboardEvent) {\n const target = e.target as HTMLElement;\n return [e.defaultPrevented, e.altKey, e.ctrlKey, e.metaKey, e.shiftKey, target.isContentEditable].some(Boolean) ||\n this.el.contains(target.closest(\n 'input, textarea, select, video[controls], audio[controls], [role=\"slider\"], [role=\"tablist\"], [role=\"menu\"]'\n ));\n }\n\n _handleKeydown = (e: KeyboardEvent) => {\n if (this._keyBelongsElsewhere(e)) return;\n const rtl = getComputedStyle(this._scroller).direction === 'rtl';\n const forward = this._vertical ? e.key === 'ArrowDown' : e.key === (rtl ? 'ArrowLeft' : 'ArrowRight');\n const backward = this._vertical ? e.key === 'ArrowUp' : e.key === (rtl ? 'ArrowRight' : 'ArrowLeft');\n if (e.key === 'Home') {\n e.preventDefault();\n this.set(0);\n this._focusItem(0);\n } else if (e.key === 'End') {\n e.preventDefault();\n this.set(this.count - 1);\n this._focusItem(this.count - 1);\n } else if (forward) {\n e.preventDefault();\n this.next();\n this._focusItem(this.center);\n } else if (backward) {\n e.preventDefault();\n this.prev();\n this._focusItem(this.center);\n }\n };\n\n _handleTrackScroll = () => {\n if (!this.el.classList.contains('scrolling')) this.el.classList.add('scrolling');\n window.clearTimeout(this.scrollingTimeout);\n this.scrollingTimeout = setTimeout(() => this.el.classList.remove('scrolling'), 120);\n if (this._trackRaf !== null) return;\n this._trackRaf = requestAnimationFrame(() => {\n this._trackRaf = null;\n // Read the nearest index before the parallax writes invalidate style.\n const index = this._ignoreScroll ? this.center : this._nearestIndex();\n this._updateParallax();\n if (index !== this.center) this._syncActive(index, this.dragged);\n });\n };\n\n _handleResize = () => {\n if (!this._started || !this.images.length) return;\n this._syncAdaptiveMode();\n this._syncLayoutRoles(this.center);\n if (!this.pressed) this._scrollToIndex(this.center, false);\n this._updateParallax();\n };\n\n private _paintIndicators(center: number) {\n if (!this.showIndicators || !this._indicators) return;\n const pos = ((center % this.count) + this.count) % this.count;\n this._indicators.querySelectorAll('.indicator-item').forEach((el, i) => {\n const on = i === pos;\n el.classList.toggle('active', on);\n if (on) el.setAttribute('aria-current', 'true');\n else el.removeAttribute('aria-current');\n });\n }\n\n /** Whether `index` is still the active item once its change is reported. */\n private _syncActive(index: number, dragged: boolean): boolean {\n const prev = this.center;\n this.center = index;\n this.images.forEach((el, i) => el.classList.toggle('active', i === index));\n this._paintIndicators(index);\n this._syncLayoutRoles(index);\n const curr = this.images[index];\n const detail = { item: curr, dragged };\n if (prev !== index && !this._notify('change', this.options.onCycleTo, { args: [curr, dragged], detail, current: () => this.center === index })) return false;\n if (typeof this.oneTimeCallback === 'function') {\n this.oneTimeCallback.call(this, curr, dragged);\n this.oneTimeCallback = null;\n }\n return true;\n }\n\n private _syncLayoutRoles(index: number) {\n // Every size is worked out before any is written. Writing `large` to all\n // items and then reading clientWidth forced a layout in that interim\n // state on every center change.\n type Size = 'large' | 'medium' | 'small';\n const sizes: Size[] = this.images.map(() => 'large');\n const setSize = (i: number, size: Size) => {\n if (this.images[i]) sizes[i] = size;\n };\n\n if (\n this.el.classList.contains('uncontained') ||\n (this.el.classList.contains('full-screen') && this._vertical)\n ) {\n // Every item stays large.\n } else if (\n this.el.classList.contains('hero') ||\n this.el.classList.contains('full-screen-horizontal')\n ) {\n setSize(index + 1, 'small');\n if (this.el.classList.contains('center-aligned')) setSize(index - 1, 'small');\n } else {\n const width = this.el.clientWidth;\n const desiredLargeCount = width >= 1600 ? 4 : width >= 1200 ? 3 : width >= 600 ? 2 : 1;\n const largeCount = Math.min(desiredLargeCount, Math.max(1, this.count - 2));\n this.el.classList.remove('multi-wide', 'multi-large', 'multi-extra-large');\n if (largeCount === 2) this.el.classList.add('multi-wide');\n else if (largeCount === 3) this.el.classList.add('multi-large');\n else if (largeCount >= 4) this.el.classList.add('multi-extra-large');\n this._generatedWideLayout = this._generatedWideLayout || largeCount > 1;\n setSize(index + largeCount, 'medium');\n setSize(index + largeCount + 1, 'small');\n }\n\n this.images.forEach((item, i) => {\n if (this._authoredItemSizes.has(item)) return;\n item.setAttribute('data-carousel-size', sizes[i]);\n this._generatedItemSizes.add(item);\n });\n }\n\n private _syncAdaptiveMode() {\n if (!this.el.classList.contains('full-screen')) return;\n const landscape = window.matchMedia('(orientation: landscape)').matches;\n const horizontal = this.el.clientWidth >= 840 || landscape;\n const wasVertical = this._vertical;\n this._vertical = !horizontal;\n this.el.classList.toggle('full-screen-horizontal', horizontal);\n this._generatedWideLayout = this._generatedWideLayout || horizontal;\n\n if (this._started && wasVertical !== this._vertical) {\n this._scroller.scrollTo({ left: 0, top: 0, behavior: 'auto' });\n }\n }\n\n private _focusItem(index: number) {\n const item = this.images[index];\n if (!item) return;\n const focusable = item.matches(naturallyFocusable)\n ? item\n : item.querySelector<HTMLElement>(naturallyFocusable);\n (focusable ?? item).focus({ preventScroll: true });\n }\n\n private _updateParallax() {\n if (this._motion.matches) {\n this.images.forEach((item) =>\n item.style.setProperty('--md-comp-carousel-item-parallax', '0px')\n );\n return;\n }\n\n const scrollerRect = this._scroller.getBoundingClientRect();\n const viewportCenter = this._vertical\n ? scrollerRect.top + scrollerRect.height / 2\n : scrollerRect.left + scrollerRect.width / 2;\n const viewportSize = Math.max(1, this._vertical ? scrollerRect.height : scrollerRect.width);\n\n // All reads, then all writes: a write between two reads forces a style\n // recalculation per item on every scroll frame.\n const rects = this.images.map((item) => item.getBoundingClientRect());\n this.images.forEach((item, i) => {\n const rect = rects[i];\n const itemCenter = this._vertical ? rect.top + rect.height / 2 : rect.left + rect.width / 2;\n const progress = Math.max(-1, Math.min(1, (itemCenter - viewportCenter) / viewportSize));\n item.style.setProperty('--md-comp-carousel-item-parallax', `${progress * -24}px`);\n });\n }\n\n private _wrapTrack() {\n const track = document.createElement('div');\n track.className = 'carousel-track';\n this.images[0].before(track);\n this.images.forEach((el) => track.appendChild(el));\n this._trackEl = track;\n }\n\n private _unwrapTrack() {\n if (!this._trackEl) return;\n this.images.forEach((el) => this.el.insertBefore(el, this._trackEl));\n this._trackEl.remove();\n this._trackEl = null;\n }\n\n private _nearestIndex(): number {\n const centered = this.el.classList.contains('center-aligned');\n const style = getComputedStyle(this._scroller);\n const rtl = !this._vertical && style.direction === 'rtl';\n const position = this._vertical ? this._scroller.scrollTop : this._scroller.scrollLeft;\n const viewport = this._vertical ? this._scroller.clientHeight : this._scroller.clientWidth;\n const extent = (this._vertical ? this._scroller.scrollHeight : this._scroller.scrollWidth) - viewport;\n const padding = parseFloat(this._vertical ? style.paddingBlockStart : style.paddingInlineStart) || 0;\n let best = this.center;\n let bestDist = Infinity;\n let centerDist = Infinity;\n this.images.forEach((el, i) => {\n const start = this._vertical ? el.offsetTop : el.offsetLeft;\n const size = this._vertical ? el.offsetHeight : el.offsetWidth;\n const target = centered ? start - (viewport - size) / 2 : start + (rtl ? size - viewport + padding : -padding);\n const bounded = Math.max(rtl ? -extent : 0, Math.min(rtl ? 0 : extent, target));\n const dist = Math.abs(bounded - position);\n if (i === this.center) centerDist = dist;\n if (dist < bestDist) {\n bestDist = dist;\n best = i;\n }\n });\n // Items past the scroll end all clamp to it, and a subpixel wobble there\n // (WebKit reports -179 for -178 in a right-to-left track) must not hand\n // the selection to a later item that only shares the clamped position.\n return centerDist - bestDist <= 1 ? this.center : best;\n }\n\n private _scrollToIndex(n: number, smooth = true) {\n const el = this.images[n];\n if (!el) return;\n this._finishScroll();\n const centered = this.el.classList.contains('center-aligned');\n const style = getComputedStyle(this._scroller);\n const inlinePadding = Number.parseFloat(style.paddingInlineStart) || 0;\n const blockPadding = Number.parseFloat(style.paddingBlockStart) || 0;\n const left = centered\n ? el.offsetLeft - (this._scroller.clientWidth - el.offsetWidth) / 2\n : style.direction === 'rtl'\n ? el.offsetLeft + el.offsetWidth - this._scroller.clientWidth + inlinePadding\n : el.offsetLeft - inlinePadding;\n const top = el.offsetTop - blockPadding;\n this._ignoreScroll = true;\n // Item sizes are still transitioning, so the track can be too narrow to\n // reach the target and clamps short of it. Firefox takes whatever item\n // sits at that clamped position as the snap target and re-snaps to it\n // after each later layout change, undoing the alignment below. Snapping\n // returns in _finishScroll, once the track has settled on the item.\n this._scroller.style.scrollSnapType = 'none';\n this._scroller.scrollTo({\n left: this._vertical ? 0 : left,\n top: this._vertical ? top : 0,\n behavior: smooth && !this._motion.matches ? 'smooth' : 'instant'\n });\n this._scroller.addEventListener('scrollend', this._handleScrollEnd);\n this._scrollEndTimeout = setTimeout(this._finishScroll, this.options.duration + 350);\n }\n\n private _finishScroll = () => {\n this._ignoreScroll = false;\n this._scroller.style.scrollSnapType = '';\n clearTimeout(this._scrollEndTimeout);\n this._scroller.removeEventListener('scrollend', this._handleScrollEnd);\n };\n\n private _handleScrollEnd = () => {\n // An earlier scroll can finish after a new navigation has started.\n if (this._nearestIndex() === this.center && !this.images.some(item => item.getAnimations().some(animation => animation.playState === 'running'))) {\n this._finishScroll();\n }\n };\n\n _cycleTo(n: number, callback: CarouselOptions['onCycleTo'] = null) {\n this._alignAfterResize = true;\n if (typeof callback === 'function') this.oneTimeCallback = callback;\n // A listener that moved to another item, or destroyed the carousel, has\n // already scrolled where it wanted.\n if (this._syncActive(n, false)) this._scrollToIndex(n);\n }\n\n /**\n * Stop auto-advance until start() is called. Without an `interval` there is\n * nothing to stop and this does nothing.\n */\n pause() {\n this._autoPaused = true;\n this._syncAutoAdvance();\n }\n\n /** Resume auto-advance after pause(). */\n start() {\n this._autoPaused = false;\n this._syncAutoAdvance();\n }\n\n next(n: number = 1) {\n if (isNaN(n)) n = 1;\n const index = this.center + n;\n if (index >= this.count || index < 0) return;\n this._cycleTo(index);\n }\n\n prev(n: number = 1) {\n if (isNaN(n)) n = 1;\n const index = this.center - n;\n if (index >= this.count || index < 0) return;\n this._cycleTo(index);\n }\n\n set(n: number, callback?: CarouselOptions['onCycleTo']) {\n if (n === undefined || isNaN(n)) n = 0;\n if (n >= this.count || n < 0) return;\n this._cycleTo(n, callback);\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["el"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/components/commandPalette.ts"],
|
|
4
|
-
"sourcesContent": ["import { Utils } from '../core/utils';\nimport { Component, BaseOptions } from '../core/component';\n\nexport interface CommandPaletteOptions extends BaseOptions {\n /**\n * Letter that toggles the palette together with Command on Apple platforms\n * or Ctrl elsewhere. A key event the page has already handled is left\n * alone. `null` turns the shortcut off. `data-shortcut` on the dialog sets\n * it; an empty `data-shortcut` turns it off.\n * @default 'k'\n */\n shortcut: string | null;\n /**\n * If true, the palette closes after a command runs.\n * @default true\n */\n closeOnRun: boolean;\n}\n\nconst _defaults: CommandPaletteOptions = {\n shortcut: 'k',\n closeOnRun: true\n};\n\n// On Apple platforms Ctrl+letter is text editing (Ctrl+K deletes to the end\n// of the line), so only Command opens the palette there.\nconst APPLE = typeof navigator !== 'undefined' && /Mac|iPhone|iPad|iPod/.test(navigator.platform);\n\n/** Case- and accent-insensitive text for matching. */\nconst fold = (text: string) =>\n text.normalize('NFD').replace(/\\p{Diacritic}/gu, '').toLowerCase();\n\n/**\n * A command palette: a native modal <dialog class=\"command-palette\"> holding\n * a search input and a list of commands. Typing filters the list; the arrow\n * keys move through what is left and Enter runs it, while focus stays in the\n * input. The dialog owns modality, Escape and returning focus.\n *\n * The input is a combobox and the list a listbox of options, with the active\n * option reported through aria-activedescendant. A command is the link or\n * button inside an option; running it clicks that element, so a page wires\n * commands with ordinary hrefs and click handlers.\n */\nexport class CommandPalette extends Component<CommandPaletteOptions> {\n declare el: HTMLDialogElement;\n /** The search input. */\n input: HTMLInputElement;\n /** The list of commands. */\n list: HTMLElement;\n private _active: HTMLElement | null = null;\n private _generatedIds: HTMLElement[] = [];\n /** Wires and refilters commands the page adds or removes later. */\n private _observer: MutationObserver | null = null;\n\n // HTMLElement, not HTMLDialogElement: init() takes the element type from\n // here, and has always accepted any HTMLElement.\n constructor(el: HTMLElement, options: Partial<CommandPaletteOptions>) {\n const shortcut = el.dataset.shortcut;\n super(el, { ...(shortcut !== undefined ? { shortcut: shortcut || null } : {}), ...options });\n this.input = el.querySelector(':scope > input');\n this.list = el.querySelector(':scope > :is(ul, ol)');\n if (!this.input || !this.list) {\n console.error('CommandPalette needs an <input> and a <ul> as children of the dialog.');\n return;\n }\n this._setupAccessibility();\n this._filter();\n // A page adding commands while the user arrows through the list keeps\n // their place.\n this._observer = new MutationObserver(() => this._filter(true));\n // Also refilter when the page hides, shows, disables or enables a command.\n // Not aria-disabled: _filter writes that itself, which would loop.\n this._observer.observe(this.list, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['hidden', 'disabled']\n });\n const { signal } = this._events;\n this.input.addEventListener('input', this._handleInput, { signal });\n this.input.addEventListener('keydown', this._handleKeydown, { signal });\n this.input.addEventListener('keydown', this._handleEscape, { signal });\n this.list.addEventListener('click', this._handleListClick, { signal });\n this.list.addEventListener('pointermove', this._handlePointerMove, { signal });\n this.el.addEventListener('close', this._handleClose, { signal });\n document.addEventListener('keydown', this._handleShortcut, { signal });\n }\n\n static get defaults(): CommandPaletteOptions {\n return _defaults;\n }\n\n static key = 'Expressive_CommandPalette';\n\n /** If the palette is open. */\n get isOpen() {\n return this.el.open;\n }\n\n /** Opens the palette as a modal dialog with the search input focused. */\n open = () => {\n if (!this.el.open) this.el.showModal();\n this.input?.focus();\n };\n\n /** Closes the palette. The dialog returns focus to where it was. */\n close = () => {\n if (this.el.open) this.el.close();\n };\n\n destroy() {\n this._observer?.disconnect();\n if (this.input && this.list) {\n for (const name of ['role', 'aria-controls', 'aria-expanded', 'aria-autocomplete', 'aria-activedescendant']) {\n this.input.removeAttribute(name);\n }\n this.list.removeAttribute('role');\n for (const item of this._items()) {\n for (const name of ['role', 'aria-selected', 'aria-disabled', 'data-filtered']) item.removeAttribute(name);\n item.classList.remove('active');\n this._action(item)?.removeAttribute('tabindex');\n }\n for (const label of this._labels()) {\n label.removeAttribute('role');\n label.removeAttribute('data-filtered');\n }\n for (const el of this._generatedIds) el.removeAttribute('id');\n const empty = this._empty();\n if (empty) empty.hidden = false;\n }\n super.destroy();\n }\n\n private _items() {\n return Array.from(this.list.children).filter(\n (child): child is HTMLElement => child instanceof HTMLElement && !child.classList.contains('label')\n );\n }\n\n private _labels() {\n return Array.from(this.list.querySelectorAll<HTMLElement>(':scope > .label'));\n }\n\n private _empty() {\n return this.el.querySelector<HTMLElement>(':scope > .command-palette-empty');\n }\n\n private _action(item: HTMLElement) {\n return item.querySelector<HTMLElement>(':scope > :is(a[href], button)');\n }\n\n private _ensureId(el: HTMLElement, prefix: string) {\n if (!el.id) {\n el.id = `${prefix}-${Utils.guid()}`;\n this._generatedIds.push(el);\n }\n return el.id;\n }\n\n private _setupAccessibility() {\n this.list.setAttribute('role', 'listbox');\n this.input.setAttribute('role', 'combobox');\n this.input.setAttribute('aria-controls', this._ensureId(this.list, 'command-palette-list'));\n this.input.setAttribute('aria-expanded', 'true');\n this.input.setAttribute('aria-autocomplete', 'list');\n }\n\n /** Every command, including ones added since the last pass, is an option. */\n private _wireItems() {\n for (const item of this._items()) {\n if (item.getAttribute('role') === 'option') continue;\n item.setAttribute('role', 'option');\n this._ensureId(item, 'command-palette-option');\n // Focus stays in the input; the commands are reached with the arrows.\n this._action(item)?.setAttribute('tabindex', '-1');\n }\n // A listbox holds only options; a group heading is a visual divider.\n for (const label of this._labels()) label.setAttribute('role', 'none');\n }\n\n /** Commands on screen: neither hidden by the page nor filtered out. */\n private _shown() {\n return this._items().filter((item) => !item.hidden && !item.hasAttribute('data-filtered'));\n }\n\n /** Shown commands the arrows and Enter can reach: disabled ones are skipped. */\n private _visible() {\n return this._shown().filter((item) => item.getAttribute('aria-disabled') !== 'true');\n }\n\n /** A disabled link or button cannot run, so its option says so. */\n private _isDisabled(item: HTMLElement) {\n const action = this._action(item);\n return !!action && (action.matches(':disabled') || action.getAttribute('aria-disabled') === 'true');\n }\n\n private _setActive(item: HTMLElement | null) {\n if (this._active === item) return;\n this._active?.classList.remove('active');\n this._active?.removeAttribute('aria-selected');\n this._active = item;\n if (item) {\n item.classList.add('active');\n item.setAttribute('aria-selected', 'true');\n this.input.setAttribute('aria-activedescendant', item.id);\n item.scrollIntoView({ block: 'nearest' });\n } else {\n this.input.removeAttribute('aria-activedescendant');\n }\n }\n\n /**\n * Shows the commands matching the query. Filtering marks rows with\n * data-filtered rather than hidden, so a command the page hides stays\n * hidden. `keepActive` holds the active command while it is still\n * reachable, for list changes the user did not make.\n */\n private _filter(keepActive = false) {\n this._wireItems();\n const terms = fold(this.input.value).split(/\\s+/).filter(Boolean);\n for (const item of this._items()) {\n // data-keywords may sit on the row or on its link or button.\n const keywords = item.dataset.keywords ?? this._action(item)?.dataset.keywords ?? '';\n const text = fold(`${item.textContent} ${keywords}`);\n item.toggleAttribute('data-filtered', !terms.every((term) => text.includes(term)));\n if (this._isDisabled(item)) item.setAttribute('aria-disabled', 'true');\n else item.removeAttribute('aria-disabled');\n }\n // A heading stays only while one of the commands under it does.\n for (const label of this._labels()) {\n let next = label.nextElementSibling as HTMLElement | null;\n let any = false;\n while (next && !next.classList.contains('label')) {\n if (!next.hidden && !next.hasAttribute('data-filtered')) any = true;\n next = next.nextElementSibling as HTMLElement | null;\n }\n label.toggleAttribute('data-filtered', !any);\n }\n const visible = this._visible();\n const empty = this._empty();\n if (empty) empty.hidden = this._shown().length > 0;\n this._setActive(keepActive && visible.includes(this._active) ? this._active : visible[0] ?? null);\n }\n\n private _move(step: number) {\n const visible = this._visible();\n if (!visible.length) return;\n const index = visible.indexOf(this._active);\n this._setActive(visible[(index + step + visible.length) % visible.length]);\n }\n\n /** Runs a command by clicking its link or button; the click handler closes. */\n private _run(item: HTMLElement) {\n (this._action(item) ?? item).click();\n }\n\n _handleInput = () => this._filter();\n\n _handleKeydown = (e: KeyboardEvent) => {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n this._move(e.key === 'ArrowDown' ? 1 : -1);\n } else if (e.key === 'Enter' && !Utils.isComposing(e) && this._active) {\n e.preventDefault();\n this._run(this._active);\n }\n };\n\n /**\n * The first Escape clears a typed query and the next closes the palette.\n * Chromium and Firefox clear a search input on their own; WebKit closed at\n * once, and so did every engine for a text input. Escape that cancels an\n * IME composition is left to the IME.\n */\n _handleEscape = (e: KeyboardEvent) => {\n if (e.key !== 'Escape' || !this.input.value || Utils.isComposing(e)) return;\n e.preventDefault();\n this.input.value = '';\n this.input.dispatchEvent(new Event('input', { bubbles: true }));\n };\n\n _handleListClick = (e: MouseEvent) => {\n const item = (<Element>e.target).closest<HTMLElement>('[role=\"option\"]');\n if (!item || !this.list.contains(item) || item.getAttribute('aria-disabled') === 'true') return;\n const action = this._action(item);\n // A click on the row's padding runs its command; that click comes back\n // through here and closes the palette.\n if (action && !action.contains(<Node>e.target)) {\n action.click();\n return;\n }\n if (this.options.closeOnRun) this.close();\n };\n\n _handlePointerMove = (e: PointerEvent) => {\n const item = (<Element>e.target).closest<HTMLElement>('[role=\"option\"]');\n if (item && this.list.contains(item) && item.getAttribute('aria-disabled') !== 'true') this._setActive(item);\n };\n\n /**\n * Each opening starts from the full list. The close event is queued, so a\n * palette reopened straight away may already be open again; its new search\n * is left alone.\n */\n _handleClose = () => {\n if (this.el.open) return;\n this.input.value = '';\n this._filter();\n };\n\n _handleShortcut = (e: KeyboardEvent) => {\n const { shortcut } = this.options;\n if (!shortcut || e.defaultPrevented || e.altKey || e.shiftKey) return;\n if (!(APPLE ? e.metaKey && !e.ctrlKey : e.ctrlKey && !e.metaKey)) return;\n // A non-Latin layout reports its own letter in e.key, so fall back to the\n // physical key there. A Latin layout matches on the letter it types.\n const letter = shortcut.toLowerCase();\n const latin = /^[a-z]$/i.test(e.key);\n const hit = e.key.toLowerCase() === letter ||\n (!latin && /^[a-z]$/.test(letter) && e.code === `Key${letter.toUpperCase()}`);\n if (!hit) return;\n e.preventDefault();\n if (this.el.open) this.close();\n else this.open();\n };\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/components/particles.ts"],
|
|
4
|
-
"sourcesContent": ["import { Component, BaseOptions } from '../core/component';\n\nexport interface ParticlesOptions extends BaseOptions {\n /**\n * Number of particles.\n * @default 100\n */\n quantity: number;\n /**\n * How firmly particles hold their place against the pointer. Lower\n * follows the pointer further.\n * @default 50\n */\n staticity: number;\n /**\n * Frames a particle takes to catch up with the pointer. Higher is slower.\n * @default 50\n */\n ease: number;\n /**\n * Base radius in pixels. Each particle adds 0 or 1 to it.\n * @default 0.4\n */\n size: number;\n /**\n * A CSS color. Empty uses the canvas's CSS `color`, which defaults to the\n * theme's on-surface color.\n * @default ''\n */\n color: string;\n /**\n * Horizontal drift in pixels per frame. Negative drifts left.\n * @default 0\n */\n vx: number;\n /**\n * Vertical drift in pixels per frame. Negative drifts up.\n * @default 0\n */\n vy: number;\n}\n\nconst _defaults: ParticlesOptions = {\n quantity: 100,\n staticity: 50,\n ease: 50,\n size: 0.4,\n color: '',\n vx: 0,\n vy: 0\n};\n\ninterface Particle {\n x: number;\n y: number;\n translateX: number;\n translateY: number;\n size: number;\n alpha: number;\n targetAlpha: number;\n dx: number;\n dy: number;\n magnetism: number;\n}\n\n/**\n * Particles. A `<canvas class=\"particles\">` covers its nearest positioned\n * ancestor with slowly drifting dots that lean toward the pointer. Under\n * reduced motion the dots are drawn once and stay still.\n */\nexport class Particles extends Component<ParticlesOptions> {\n declare el: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D | null;\n private _style: CSSStyleDeclaration;\n private _particles: Particle[] = [];\n private _width = 0;\n private _height = 0;\n private _frame = 0;\n private _last = 0;\n // Pointer offset from the canvas center, kept from its last move inside.\n private _mouse = { x: 0, y: 0 };\n private _still = false;\n private _visible = true;\n private _motion: MediaQueryList | null = null;\n private _theme: MutationObserver | null = null;\n private _resizeObserver: ResizeObserver | null = null;\n private _visibility: IntersectionObserver | null = null;\n\n constructor(el: HTMLElement, options: Partial<ParticlesOptions>) {\n super(el, options);\n this._ctx = this.el.getContext('2d');\n if (!this._ctx) return;\n this._style = getComputedStyle(this.el);\n this._motion = matchMedia('(prefers-reduced-motion: reduce)');\n const { signal } = this._events;\n this._motion.addEventListener('change', this._onMotion, { signal });\n // Still dots are painted once, so a theme or color-scheme change\n // repaints them. Moving ones read the color every frame anyway.\n matchMedia('(prefers-color-scheme: dark)').addEventListener('change', this._repaint, { signal });\n this._theme = new MutationObserver(this._repaint);\n this._theme.observe(document.documentElement, { attributes: true, attributeFilter: ['theme'], subtree: true });\n this._still = this._motion.matches;\n this._reset();\n this._resizeObserver = new ResizeObserver(() => {\n if (this.el.clientWidth !== this._width || this.el.clientHeight !== this._height) this._reset();\n });\n this._resizeObserver.observe(this.el);\n // Animates only while on screen. A canvas scrolled away, hidden or\n // removed without destroy() stops drawing and following the pointer.\n // Entries arrive oldest first, so the last one is the current state.\n this._visibility = new IntersectionObserver((entries) => {\n this._visible = entries[entries.length - 1].isIntersecting;\n this._animate();\n });\n this._visibility.observe(this.el);\n }\n\n static get defaults(): ParticlesOptions {\n return _defaults;\n }\n\n static key = 'Expressive_Particles';\n\n destroy() {\n this._stop();\n this._theme?.disconnect();\n this._resizeObserver?.disconnect();\n this._visibility?.disconnect();\n if (this._ctx) {\n this._ctx.setTransform(1, 0, 0, 1, 0, 0);\n this._ctx.clearRect(0, 0, this.el.width, this.el.height);\n }\n super.destroy();\n }\n\n private _animate() {\n if (this._visible && !this._still) this._start();\n else this._stop();\n }\n\n private _onMotion = () => {\n this._still = this._motion.matches;\n if (this._still) {\n for (const p of this._particles) p.alpha = p.targetAlpha;\n this._paint();\n }\n this._animate();\n };\n\n private _repaint = () => {\n if (this._still) this._paint();\n };\n\n private _start() {\n if (this._frame) return;\n window.addEventListener('pointermove', this._onPointerMove, { passive: true });\n this._frame = requestAnimationFrame((now) => { this._last = now; this._draw(now); });\n }\n\n private _stop() {\n cancelAnimationFrame(this._frame);\n this._frame = 0;\n window.removeEventListener('pointermove', this._onPointerMove);\n }\n\n private _onPointerMove = (e: PointerEvent) => {\n const r = this.el.getBoundingClientRect();\n const x = e.clientX - r.left - r.width / 2;\n const y = e.clientY - r.top - r.height / 2;\n if (Math.abs(x) < r.width / 2 && Math.abs(y) < r.height / 2) this._mouse = { x, y };\n };\n\n // Matches the pixel buffer to the canvas box and scatters a new set.\n private _reset() {\n this._width = this.el.clientWidth;\n this._height = this.el.clientHeight;\n this.el.width = Math.round(this._width * devicePixelRatio);\n this.el.height = Math.round(this._height * devicePixelRatio);\n this._particles = Array.from({ length: this.options.quantity }, () => this._particle());\n if (this._still) {\n for (const p of this._particles) p.alpha = p.targetAlpha;\n this._paint();\n }\n }\n\n private _particle(): Particle {\n return {\n x: Math.floor(Math.random() * this._width),\n y: Math.floor(Math.random() * this._height),\n translateX: 0,\n translateY: 0,\n size: Math.floor(Math.random() * 2) + this.options.size,\n alpha: 0,\n targetAlpha: Math.round((Math.random() * 0.6 + 0.1) * 10) / 10,\n dx: (Math.random() - 0.5) * 0.1,\n dy: (Math.random() - 0.5) * 0.1,\n magnetism: 0.1 + Math.random() * 4\n };\n }\n\n private _draw(now: number) {\n // Frames are counted at 60 per second whatever the display rate.\n const step = Math.min((now - this._last) / (1000 / 60), 4);\n this._last = now;\n const { staticity, ease, vx, vy } = this.options;\n const follow = Math.min(step / ease, 1);\n this._particles = this._particles.map((p) => {\n p.x += (p.dx + vx) * step;\n p.y += (p.dy + vy) * step;\n p.translateX += (this._mouse.x / (staticity / p.magnetism) - p.translateX) * follow;\n p.translateY += (this._mouse.y / (staticity / p.magnetism) - p.translateY) * follow;\n // Fades in, and fades out within 20px of an edge.\n const x = p.x + p.translateX;\n const y = p.y + p.translateY;\n const edge = Math.min(x - p.size, this._width - x - p.size, y - p.size, this._height - y - p.size) / 20;\n p.alpha = edge > 1 ? Math.min(p.alpha + 0.02 * step, p.targetAlpha) : p.targetAlpha * edge;\n const gone = p.x < -p.size || p.x > this._width + p.size || p.y < -p.size || p.y > this._height + p.size;\n return gone ? this._particle() : p;\n });\n this._paint();\n this._frame = requestAnimationFrame((t) => this._draw(t));\n }\n\n private _paint() {\n const ctx = this._ctx!;\n const dpr = devicePixelRatio;\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, this.el.width, this.el.height);\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n // Read every frame, so a theme or color-scheme change applies at once.\n ctx.fillStyle = this.options.color || this._style.color;\n for (const p of this._particles) {\n if (p.alpha <= 0) continue;\n ctx.globalAlpha = p.alpha;\n ctx.beginPath();\n ctx.arc(p.x + p.translateX, p.y + p.translateY, p.size, 0, 2 * Math.PI);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/components/radarChart.ts"],
|
|
4
|
-
"sourcesContent": ["import { LineChart, LineChartOptions, polarPoint, Series } from './lineChart';\nimport { svgNode as node } from '../core/utils';\n\nexport type RadarChartOptions = LineChartOptions;\n\n/** Grid rings, evenly spaced from the middle to the rim. */\nconst RINGS = 4;\n\n/**\n * A series' rows split at its gaps into runs, the last carrying on round\n * past the top spoke into the first.\n */\nfunction runs(values: (number | null)[]) {\n const list: number[][] = [[]];\n values.forEach((value, i) => (value === null ? list.push([]) : list[list.length - 1].push(i)));\n if (list.length > 1) list[0] = [...list.pop()!, ...list[0]];\n return list.filter((run) => run.length);\n}\n\n// A run of corners as a path: closed round a whole shape; open where a gap\n// breaks it, a dot for a lone corner; and filled as a wedge from the middle.\nconst closed = (corners: string[]) => `M${corners.join('L')}Z`;\nconst open = (corners: string[]) => `M${corners.join('L')}${corners.length > 1 ? '' : 'h0'}`;\nconst wedge = (corners: string[]) => `M0,0L${corners.join('L')}Z`;\n\n/**\n * Radar chart. It reads its <table> like LineChart, but each row is a spoke,\n * clockwise from the top, and each value column is a series drawn as a\n * shape joining its values on the spokes, from zero in the middle to the\n * scale's top at the rim. The row labels sit round the rim.\n *\n * Call `update()` after changing the table, or start it with `watch` or\n * `data-watch`.\n */\nexport class RadarChart extends LineChart {\n protected get _type() {\n return 'radar-chart';\n }\n\n /** The scale starts at zero, the middle, so shapes compare by size. */\n protected get _fromZero() {\n return true;\n }\n\n protected get _circular() {\n return true;\n }\n\n static key = 'Expressive_RadarChart';\n\n /**\n * The cursor is a spoke turned by --turn, and the tooltip sits past its\n * tip. LineChart's points on the spoke keep their top, a share of the\n * radius, which stops at the rim and the middle like the shapes.\n */\n protected _place(index: number) {\n for (const dot of this._cursor.children as HTMLCollectionOf<HTMLElement>) {\n dot.style.top = `${Math.min(100, Math.max(0, parseFloat(dot.style.top)))}%`;\n }\n const turn = this._turn(index);\n this._cursor.style.setProperty('--turn', String(turn));\n this._tooltip.style.setProperty('--turn', String(turn));\n // On the right half it opens leftwards, over the chart.\n this._tooltip.classList.toggle('end', turn > 0 && turn < 0.5);\n }\n\n /** A row's spoke as a fraction of a turn clockwise from the top. */\n private _turn(index: number) {\n return index / this.labels.length;\n }\n\n /** Only the legend; the labels go round the rim in _draw. */\n protected _guides(): Element[] {\n return this._legend();\n }\n\n /** The nearest spoke to the pointer, by its angle from the middle. */\n protected _indexAt(e: PointerEvent) {\n const [turn] = this._polarAt(e);\n return Math.round(turn * this.labels.length) % this.labels.length;\n }\n\n /** The grid rings' shares of the radius: one per .axis label above zero, or quarters. */\n private _rings(share: (value: number) => number) {\n if (!this._axis) return Array.from({ length: RINGS }, (_, r) => (r + 1) / RINGS);\n return this.series[0].scale.ticks.filter((tick) => tick > 0).map(share);\n }\n\n /**\n * One series' group: its outline, broken at a gap like a line chart's,\n * its .area fill and its .points.\n */\n private _series(series: Series, corner: (index: number) => string) {\n const group = node('g', {\n class: `radar-chart-series ${series.className}`.trim(),\n 'data-series': series.color\n });\n const lines = runs(series.values).map((run) => run.map(corner));\n const [outline, fill] = series.values.includes(null) ? [open, wedge] : [closed, closed];\n group.append(node('path', { class: 'radar-chart-shape', d: lines.map(outline).join('') }));\n const list = this.el.classList;\n if (list.contains('area')) group.append(node('path', { class: 'radar-chart-area', d: lines.map(fill).join('') }));\n // Round caps on zero-length lines, so CSS sizes the points in pixels.\n if (list.contains('points')) group.append(node('path', { class: 'radar-chart-points', d: lines.flat().map((c) => `M${c}h0`).join('') }));\n return group;\n }\n\n /**\n * An SVG in a -50 to 50 box: the rings and spokes of the grid, then each\n * series' shape, with its points for .points. The rim is the box's edge;\n * the labels round it are HTML.\n */\n protected _draw(): Element {\n const at = (index: number, share: number) => polarPoint(this._turn(index), 50 * share);\n // The rim is the scale's top, so _y is the distance in from the rim.\n const share = (value: number) => Math.min(1, Math.max(0, 1 - this._y(value) / 100));\n const rows = this.labels.map((_, i) => i);\n const ring = (r: number) => `M${rows.map((i) => at(i, r)).join('L')}Z`;\n\n const svg = node('svg', { viewBox: '-50 -50 100 100', 'aria-hidden': 'true', focusable: 'false' });\n svg.append(node('path', {\n class: 'radar-chart-grid',\n d: this._rings(share).map(ring).join('')\n + rows.map((i) => `M0,0L${at(i, 1)}`).join('')\n }));\n this.series.forEach((series) => svg.append(this._series(series, (i) => at(i, share(series.values[i]!)))));\n\n const labels = document.createElement('ol');\n labels.className = 'radar-chart-axes';\n labels.setAttribute('aria-hidden', 'true');\n this.labels.forEach((text, i) => {\n const li = document.createElement('li');\n li.textContent = text;\n li.style.setProperty('--turn', String(this._turn(i)));\n labels.append(li);\n });\n\n const web = document.createElement('div');\n web.className = 'radar-chart-web';\n web.append(svg, labels);\n return web;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["share"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/components/scatterChart.ts"],
|
|
4
|
-
"sourcesContent": ["import { svgNode } from '../core/utils';\nimport { LineChart, LineChartOptions, ChartScale, Series, affix, cellValue, morph, numberFormat, pace, tickText } from './lineChart';\n\nexport interface ScatterChartOptions extends LineChartOptions {\n /**\n * Lowest value on the x axis. Defaults to the data minimum less 10% of\n * the range. Overridden by `data-x-min` on the chart.\n */\n xMin: number | null;\n /**\n * Highest value on the x axis. Defaults to the data maximum plus 10% of\n * the range. Overridden by `data-x-max` on the chart.\n */\n xMax: number | null;\n}\n\n/**\n * A drawn point: its row and series, where it sits in the plot, in percent,\n * and its diameter as a share of the largest bubble's.\n */\ninterface Mark {\n row: number;\n series: Series;\n x: number;\n y: number;\n size: number;\n}\n\n/** Points as path data: round caps on zero-length lines. */\nconst dots = (marks: Mark[]) => marks.map(({ x, y }) => `M${x},${y}h0`).join('');\n\n/** A point's row and series column, which update() matches old and new points by. */\nconst place = ({ row, series }: Mark) => `${row} ${series.column}`;\n\n/** A tooltip line part. */\nconst span = (text: string) => Object.assign(document.createElement('span'), { textContent: text });\n\n/** A CSS time, such as 400ms or 0.4s, in milliseconds. */\nconst ms = (time: string) => parseFloat(time) * (time.trim().endsWith('ms') ? 1 : 1000);\n\n/**\n * Sizes a bubble, and with motion timing grows or shrinks it from its old\n * point's size. The Web Animations API, since SVG animation cannot reach a\n * size that CSS computes from a token.\n */\nfunction sized(path: SVGElement, size: number, was: Mark | undefined, timing: ReturnType<typeof pace>) {\n path.style.setProperty('--scatter-chart-size', `${size}`);\n if (!timing || !was || was.size === size) return;\n path.animate({ '--scatter-chart-size': [`${was.size}`, `${size}`] }, { duration: ms(timing.dur), easing: `cubic-bezier(${timing.keySplines})` });\n}\n\n/**\n * Scatter chart. It reads its <table> like LineChart, but the first value\n * column is the x axis: each row draws one point per later column, at the\n * row's x value and that column's y value. A row without an x value, or a\n * cell without a y value, draws no point.\n *\n * With `.bubble`, the last column sizes each row's points, so their areas\n * follow its values, and a row without a positive size draws no point.\n *\n * Call `update()` after changing the table, or start it with `watch` or\n * `data-watch`.\n */\nexport class ScatterChart extends LineChart {\n // No initializers: LineChart's constructor draws before they would run.\n /** Each row's x value, or null. */\n private _xs: (number | null)[];\n /** Each row's size: 1 without .bubble, or the last cell's value, null unless positive. */\n private _sizes: (number | null)[];\n /** The x scale. */\n private _xFit: ChartScale;\n /** The signs around the x column's numbers, which its axis labels repeat. */\n private _xAffix: [string, string];\n /** The drawn points, row by row and within a row by series. */\n private _marks: Mark[];\n /** During update(), the points drawn before it, which the new ones move from. */\n private _drawn: Mark[];\n\n protected get _type() {\n return 'scatter-chart';\n }\n\n protected get _seriesFrom() {\n return 2;\n }\n\n protected get _seriesTo() {\n return this._bubble ? -1 : undefined;\n }\n\n private get _bubble() {\n return this.el.classList.contains('bubble');\n }\n\n static get defaults(): ScatterChartOptions {\n return { ...LineChart.defaults, xMin: null, xMax: null };\n }\n\n static key = 'Expressive_ScatterChart';\n\n /**\n * Reads each row's x value into `_xs` and its size into `_sizes`, which\n * the scales and the points use, and leaves out the values of rows\n * without either, so they neither draw nor stretch a scale. Nothing stacks.\n */\n protected _arrange(series: Series[]) {\n const xs = (this._xs = this._rows.map((row) => cellValue(row.cells[1])));\n const sizes = (this._sizes = this._rows.map((row) => this._size(row)));\n for (const each of series) {\n each.values = each.tops = each.values.map((value, row) => (xs[row] === null || sizes[row] === null ? null : value));\n }\n }\n\n /** A row's size: 1 without .bubble, or its last cell's value, null unless positive. */\n private _size(row: HTMLTableRowElement) {\n if (!this._bubble) return 1;\n const size = cellValue(row.cells[this._header.length - 1]) ?? 0;\n return size > 0 ? size : null;\n }\n\n protected get _count() {\n return this._marks?.length ?? 0;\n }\n\n /** Highlights one point, numbered as `_marks` lists them. Pass -1 to hide the tooltip. */\n show(index: number) {\n if (!this._tooltip || index === this.activeIndex) return;\n this.activeIndex = index;\n const mark = this._marks[index];\n this._cursor.hidden = this._tooltip.hidden = !mark;\n if (mark) this._fill(mark);\n }\n\n /**\n * Puts the marker on a point, at a bubble's size, and fills the tooltip\n * beside it: the row, its x header and text, the series and its text, and\n * with .bubble the size header and text, as the author wrote them. Past\n * the middle the tooltip opens back over the plot.\n */\n private _fill({ row, series, x, y, size }: Mark) {\n this._cursor.dataset.series = series.color;\n this._cursor.style.setProperty('--scatter-chart-size', `${size}`);\n for (const part of [this._cursor, this._tooltip]) Object.assign(part.style, { left: `${x}%`, top: `${y}%` });\n this._tooltip.classList.toggle('end', x > 50);\n const [title, name] = [document.createElement('strong'), span(series.name)];\n title.textContent = this.labels[row];\n name.dataset.series = series.color;\n const sizeText = this._bubble ? this._cellText(row, this._header.length - 1) : [];\n this._tooltip.replaceChildren(title, ...this._cellText(row, 1), name, span(series.text[row]), ...sizeText);\n }\n\n /** A column's header, without a swatch since it names no series, and the row's text in it. */\n private _cellText(row: number, column: number) {\n const header = span(this._header[column].textContent.trim());\n header.className = 'x';\n return [header, span(this._rows[row].cells[column]?.textContent.trim() ?? '')];\n }\n\n /** The point nearest the pointer, or -1 with none. */\n protected _indexAt(e: PointerEvent) {\n const [plot, box] = [this._plot, this._plot.getBoundingClientRect()];\n const away = ({ x, y }: Mark) => Math.hypot(\n box.left + plot.clientLeft + (x / 100) * plot.clientWidth - e.clientX,\n box.top + plot.clientTop + (y / 100) * plot.clientHeight - e.clientY);\n return this._marks.reduce((nearest, mark, i) => (nearest < 0 || away(mark) < away(this._marks[nearest]) ? i : nearest), -1);\n }\n\n /**\n * Steps through the points in table order. The arrows keep their meaning\n * in a right-to-left chart, since table order is no direction on screen.\n */\n protected _keyTarget(key: string): number | undefined {\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 const last = this._marks.length - 1;\n const step = ({ ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 } as Record<string, number>)[key];\n if (step) return Math.min(last, Math.max(0, this.activeIndex + step));\n return ({ Home: 0, End: last } as Record<string, number>)[key];\n }\n\n protected _read() {\n [this._drawn, this._marks] = [this._marks ?? [], []];\n super._read();\n if (!this.series.length) return;\n this._xFit = this._xScale();\n this._xAffix = affix(this._rows.map((row) => row.cells[1]));\n }\n\n /** The x scale over the rows with a point, between `xMin` and `xMax` where they are set. */\n private _xScale(): ChartScale {\n const [low, high] = this._xRange();\n const [min, max] = [this._xEnd('xMin'), this._xEnd('xMax')];\n return this._fit(min ?? low, max ?? high, [min !== null, max !== null]);\n }\n\n /** The x values of the rows with a point, with 10% of their span to spare each side. */\n private _xRange(): [number, number] {\n const xs = this._xs.filter((_, row) => this._hasPoint(row)) as number[];\n if (!xs.length) return [-1, 1];\n const [low, high] = [xs.reduce((a, b) => Math.min(a, b)), xs.reduce((a, b) => Math.max(a, b))];\n const pad = (high - low) * 0.1 || 1;\n return [low - pad, high + pad];\n }\n\n /** An x scale end from its data attribute or option, or null. */\n private _xEnd(name: 'xMin' | 'xMax') {\n return this._number(name) ?? (this.options as Partial<ScatterChartOptions>)[name] ?? null;\n }\n\n /** A value's distance across the plot from its inline start, in percent. */\n private _xAt(value: number) {\n const { min, max } = this._xFit;\n const x = ((value - min) / (max - min || 1)) * 100;\n return this._reversed ? 100 - x : x;\n }\n\n /** Whether any series shown draws a point in a row. */\n private _hasPoint(row: number) {\n return this.series.some((series) => series.values[row] !== null);\n }\n\n /** The points, each diameter the square root of its row's share of the largest size drawn, so areas follow sizes. */\n private _layout(): Mark[] {\n const largest = this._sizes.reduce<number>((most, size, row) => (this._hasPoint(row) ? Math.max(most, size!) : most), 0);\n return this.labels.flatMap((_, row) => this.series\n .filter((series) => series.values[row] !== null)\n .map((series) => ({\n row,\n series,\n x: this._xAt(this._xs[row]!),\n y: series.y(series.values[row]!),\n size: Math.sqrt(this._sizes[row]! / largest)\n })));\n }\n\n /** One group per series, its points round caps on zero-length lines, so CSS sizes them in pixels. */\n protected _draw(): Element {\n this._marks = this._layout();\n const svg = svgNode('svg', {\n viewBox: '0 0 100 100',\n preserveAspectRatio: 'none',\n 'aria-hidden': 'true',\n focusable: 'false'\n });\n const timing = this._before.length ? pace(this.el) : null;\n const was = new Map(this._drawn.map((old) => [place(old), old]));\n svg.append(...this.series.map((series) => this._group(series, timing, was)));\n return svg;\n }\n\n /**\n * A series' points, in one path, or with .bubble one path each, largest\n * first so smaller bubbles stay on top.\n */\n private _group(series: Series, timing: ReturnType<typeof pace>, was: Map<string, Mark>) {\n const group = svgNode('g', {\n class: `scatter-chart-series ${series.className}`.trim(),\n 'data-series': series.color\n });\n const marks = this._marks.filter((mark) => mark.series === series);\n const sets = this._bubble ? marks.sort((a, b) => b.size - a.size).map((mark) => [mark]) : [marks];\n group.append(...sets.map((set) => this._pointPath(set, timing, was)));\n return group;\n }\n\n /**\n * A path of points. After update() each moves from where its row's point\n * in the same column was drawn, or appears where it is.\n */\n private _pointPath(marks: Mark[], timing: ReturnType<typeof pace>, was: Map<string, Mark>) {\n const path = svgNode('path', { class: 'scatter-chart-points', d: dots(marks) });\n if (timing) morph(path, dots(marks.map((mark) => was.get(place(mark)) ?? mark)), timing);\n if (this._bubble) sized(path, marks[0].size, was.get(place(marks[0])), timing);\n return path;\n }\n\n /** With .axis, the y scale's labels, and the x scale's below the plot with a grid line at each. */\n protected _axes(): Element[] {\n return this._axis ? [...super._axes(), this._xAxis()] : [];\n }\n\n private _xAxis() {\n const axis = document.createElement('ol');\n axis.className = 'scatter-chart-axis x';\n axis.setAttribute('aria-hidden', 'true');\n const number = numberFormat(this.el, { notation: 'compact', maximumSignificantDigits: 3 });\n for (const tick of this._xFit.ticks) {\n const li = document.createElement('li');\n const label = document.createElement('span');\n label.textContent = tickText(number, tick, this._xAffix);\n li.style.setProperty('--at', `${this._xAt(tick)}%`);\n li.append(label);\n axis.append(li);\n }\n return axis;\n }\n\n /** The legend only: the rows have no labels along an axis. */\n protected _guides(): Element[] {\n return this._legend();\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/components/mapView.ts"],
|
|
4
|
-
"sourcesContent": ["import { Utils } from '../core/utils';\nimport { Component, BaseOptions } from '../core/component';\n\n/** `[longitude, latitude]`, MapLibre's order. */\nexport type LngLat = [number, number];\n\n/**\n * The parts of the `maplibre-gl` module this component uses. Declared here so\n * the published types do not depend on MapLibre.\n */\nexport interface MapLibre {\n Map: new (options: object) => any;\n Marker: new (options: object) => any;\n Popup: new (options: object) => any;\n}\n\n/** A style for each color scheme. The map follows the page's theme. */\nexport interface MapThemedStyle {\n light: string | object;\n dark: string | object;\n}\n\nexport interface MapViewOptions extends BaseOptions {\n /**\n * The `maplibre-gl` module. ExpressiveCSS does not bundle MapLibre, so the\n * page imports it and passes it in.\n * @default null\n */\n maplibregl: MapLibre | null;\n /**\n * A MapLibre style URL or object, or `{ light, dark }` to follow the theme.\n * @default OpenFreeMap Positron and Dark\n */\n style: string | object | MapThemedStyle;\n /**\n * Starting `[longitude, latitude]`.\n * @default [0, 20]\n */\n center: LngLat;\n /**\n * Starting zoom level.\n * @default 1\n */\n zoom: number;\n /**\n * More MapLibre `Map` options, such as `maxZoom` or `bearing`.\n * @default {}\n */\n mapOptions: object;\n}\n\nexport interface MapLineOptions {\n /** CSS color. Defaults to the route or arc color token. */\n color?: string;\n /** Width in pixels. Routes default to 4, arcs to 2. */\n width?: number;\n /** 0 to 1. */\n opacity?: number;\n /** Dash and gap lengths in line widths, such as `[2, 2]`. */\n dashArray?: number[];\n}\n\nexport interface MapArc {\n from: LngLat;\n to: LngLat;\n}\n\nexport interface MapClusterOptions {\n /** CSS color. Defaults to the cluster color token. */\n color?: string;\n /**\n * Pixels within which points join a cluster.\n * @default 50\n */\n radius?: number;\n /**\n * Last zoom level that clusters points.\n * @default 14\n */\n maxZoom?: number;\n}\n\nconst OPENFREEMAP = 'https://tiles.openfreemap.org/styles/';\n\nconst _defaults: MapViewOptions = {\n maplibregl: null,\n style: { light: `${OPENFREEMAP}positron`, dark: `${OPENFREEMAP}dark` },\n center: [0, 20],\n zoom: 1,\n mapOptions: {}\n};\n\ntype Overlay = { draw: () => void; off?: () => void };\n\nconst isLngLat = (value: number[]): value is LngLat =>\n value.length === 2 && value.every(Number.isFinite) && Math.abs(value[1]) <= 90;\n\n// MapLibre throws on a bad position only after the map exists, which leaked\n// the map and stopped every later element in the same init(). A value that\n// is not \"lng,lat\", such as Google's lat,lng order past 90, is skipped.\nconst lngLat = (el: HTMLElement): LngLat | null => {\n // Number('') is 0, so an empty part (\"12.5,\") becomes NaN and fails.\n const value = el.dataset.lngLat.split(',').map((part) => (part.trim() ? Number(part) : NaN));\n if (isLngLat(value)) return value;\n console.warn(`MapView skipped data-lng-lat=\"${el.dataset.lngLat}\": expected \"longitude,latitude\".`, el);\n return null;\n};\n\n/** The elements with a usable `data-lng-lat`, each paired with its position. */\nconst positioned = (elements: HTMLElement[]) =>\n elements.map((el) => [el, lngLat(el)] as const).filter((pair): pair is readonly [HTMLElement, LngLat] => pair[1] !== null);\n\n// A quadratic B\u00E9zier from `from` to `to`, bowed north of an eastward line.\n// ponytail: drawn in degrees, so an arc across the antimeridian goes the long\n// way round; split it at \u00B1180 if that matters.\nfunction arc([x0, y0]: LngLat, [x2, y2]: LngLat, steps = 32): LngLat[] {\n const bow = x2 >= x0 ? 0.25 : -0.25;\n const x1 = (x0 + x2) / 2 - (y2 - y0) * bow;\n const y1 = (y0 + y2) / 2 + (x2 - x0) * bow;\n return Array.from({ length: steps + 1 }, (_, i) => {\n const t = i / steps, u = 1 - t;\n return [u * u * x0 + 2 * u * t * x1 + t * t * x2, u * u * y0 + 2 * u * t * y1 + t * t * y2];\n });\n}\n\n// How far each arrow key nudges a focused draggable marker, in steps.\nconst ARROWS: Record<string, [number, number]> = { ArrowLeft: [-1, 0], ArrowRight: [1, 0], ArrowUp: [0, -1], ArrowDown: [0, 1] };\nconst plainArrow = (e: KeyboardEvent) => (Utils.plainKey(e) ? ARROWS[e.key] : undefined);\n\n/**\n * An interactive map built on MapLibre: a `.map` holding `.map-marker`,\n * `.map-popup` and `.map-controls` children.\n *\n * Each marker sits at its `data-lng-lat`. A marker button with\n * `aria-controls` opens the `.map-popup` it names; a popup with its own\n * `data-lng-lat` and no marker opens at init. Buttons in `.map-controls`\n * run their `data-action`: `zoom-in`, `zoom-out`, `compass`, `locate`,\n * `fullscreen` or `pan-up`, `pan-down`, `pan-left` and `pan-right`. A\n * `data-draggable` marker moves without a drag too: a tap picks it up and\n * the next tap on the map drops it, and the arrow keys nudge it. Routes, arcs and clusters are data, so they are added from\n * script. The default style follows the page's light or dark theme, and\n * line and cluster colors come from the theme.\n *\n * The class is `MapView` rather than `Map` so importing it does not shadow\n * JavaScript's `Map`.\n */\nexport class MapView extends Component<MapViewOptions> {\n /** The MapLibre map. */\n map: any = null;\n /** The MapLibre markers made from `.map-marker` children, in order. */\n markers: any[] = [];\n private _children: Element[] = [];\n private _popups: any[] = [];\n private _markerPopups = new Map<HTMLElement, any>();\n private _overlays = new Map<string, Overlay>();\n private _styleReady = false;\n private _dark = false;\n private _location: any = null;\n private _observer: MutationObserver | null = null;\n // Looked up once: `move` fires every frame of a pan or zoom.\n private _zoomIn: HTMLButtonElement[] = [];\n private _zoomOut: HTMLButtonElement[] = [];\n // The draggable marker a tap picked up, waiting for the tap that drops it.\n private _picked: HTMLElement | null = null;\n // The marker whose drag just ended, so the click that follows does not pick it up.\n private _dragged: HTMLElement | null = null;\n // Undoes what the map added to the page's markup, for destroy().\n private _restore: (() => void)[] = [];\n private _actions: Record<string, (button: HTMLButtonElement) => void> = {\n 'zoom-in': () => this.map.zoomIn(),\n 'zoom-out': () => this.map.zoomOut(),\n compass: () => this.map.resetNorthPitch(),\n locate: (button) => this._locate(button),\n fullscreen: () => this._toggleFullscreen(),\n 'pan-up': () => this._pan(0, -1),\n 'pan-down': () => this._pan(0, 1),\n 'pan-left': () => this._pan(-1, 0),\n 'pan-right': () => this._pan(1, 0)\n };\n\n constructor(el: HTMLElement, options: Partial<MapViewOptions>) {\n super(el, options);\n const lib = this.options.maplibregl;\n if (!lib) {\n console.error('MapView needs the maplibre-gl module in options.maplibregl.');\n return;\n }\n\n this._children = [...el.children];\n this._zoomIn = [...this._buttons('zoom-in')];\n this._zoomOut = [...this._buttons('zoom-out')];\n this._dark = this._isDark();\n this.map = new lib.Map({\n ...this.options.mapOptions,\n container: el,\n style: this._style(),\n center: this.options.center,\n zoom: this.options.zoom\n });\n this.map.on('style.load', this._handleStyleLoad);\n this.map.on('move', this._sync);\n this.map.on('click', this._handleMapClick);\n\n const children = this._children.filter((child): child is HTMLElement => child instanceof HTMLElement);\n const claimed = new Set<Element>();\n for (const [marker, at] of positioned(children.filter((child) => child.matches('.map-marker[data-lng-lat]')))) {\n const target = marker.hasAttribute('aria-controls') ? Utils.getElementById(marker, marker.getAttribute('aria-controls')) : null;\n const popup = target?.parentElement === el && target.matches('.map-popup') ? target : null;\n if (popup) claimed.add(popup);\n this._addMarker(marker, popup, at);\n }\n for (const [popup, at] of positioned(children.filter((child) => child.matches('.map-popup[data-lng-lat]') && !claimed.has(child)))) {\n this._popup(popup, 0).setLngLat(at).addTo(this.map);\n }\n\n const { signal } = this._events;\n if (this._themed()) {\n matchMedia('(prefers-color-scheme: dark)').addEventListener('change', this._handleScheme, { signal });\n this._observer = new MutationObserver(this._handleScheme);\n this._observer.observe(document.documentElement, { attributes: true, attributeFilter: ['theme'], subtree: true });\n }\n for (const button of this._buttons('fullscreen')) button.hidden = !document.fullscreenEnabled;\n document.addEventListener('fullscreenchange', this._handleFullscreen, { signal });\n el.addEventListener('click', this._handleClick, { signal });\n el.addEventListener('keydown', this._handleKeydown, { signal });\n this._sync();\n }\n\n static get defaults(): MapViewOptions {\n return _defaults;\n }\n\n static key = 'Expressive_MapView';\n\n destroy() {\n super.destroy();\n if (!this.map) return;\n this._releaseMarkers();\n this._observer?.disconnect();\n for (const overlay of this._overlays.values()) overlay.off?.();\n for (const popup of this._popups) popup.remove();\n for (const marker of this.markers) {\n marker.remove();\n const element: HTMLElement = marker.getElement();\n element.classList.remove(...[...element.classList].filter((name) => name.startsWith('maplibregl-')));\n element.style.removeProperty('transform');\n element.style.removeProperty('opacity');\n if (element.hasAttribute('aria-controls')) element.removeAttribute('aria-expanded');\n }\n this._location?.remove();\n this._location = null;\n this.map.remove();\n this.map = null;\n this.markers = [];\n this._popups = [];\n this._markerPopups.clear();\n this._overlays.clear();\n this.el.style.removeProperty('--md-comp-map-bearing');\n for (const button of this.el.querySelectorAll<HTMLButtonElement>('.map-controls [data-action]')) {\n button.disabled = false;\n button.hidden = false;\n button.removeAttribute('aria-pressed');\n }\n this.el.append(...this._children);\n }\n\n /** Draws a line through `[longitude, latitude]` points. Replaces an overlay with the same id. */\n addRoute(id: string, coordinates: LngLat[], options: MapLineOptions = {}) {\n this._line(id, { type: 'LineString', coordinates }, 'route', { width: 4, ...options });\n }\n\n /** Draws a curved line for each `{ from, to }`. Replaces an overlay with the same id. */\n addArcs(id: string, arcs: MapArc[], options: MapLineOptions = {}) {\n this._line(id, { type: 'MultiLineString', coordinates: arcs.map(({ from, to }) => arc(from, to)) }, 'arc', { width: 2, ...options });\n }\n\n /**\n * Draws GeoJSON points, or the URL of a GeoJSON file, as clusters that\n * show their count and zoom in when clicked. The layers are\n * `${id}-clusters`, `${id}-count` and `${id}-points`.\n */\n addClusters(id: string, data: object | string, options: MapClusterOptions = {}) {\n const clusters = `${id}-clusters`, points = `${id}-points`;\n const zoomIn = async (e: any) => {\n const [feature] = e.features;\n const zoom = await this.map.getSource(id).getClusterExpansionZoom(feature.properties.cluster_id);\n // destroy() may have run while the zoom was looked up.\n this.map?.easeTo({ center: feature.geometry.coordinates, zoom });\n };\n const pointer = () => { this.map.getCanvas().style.cursor = 'pointer'; };\n const reset = () => { this.map.getCanvas().style.cursor = ''; };\n const listen = (method: 'on' | 'off') => {\n this.map[method]('click', clusters, zoomIn);\n for (const layer of [clusters, points]) {\n this.map[method]('mouseenter', layer, pointer);\n this.map[method]('mouseleave', layer, reset);\n }\n };\n this._draw(id, {\n draw: () => {\n const color = options.color ?? this._color('var(--md-comp-map-cluster-color)');\n const surface = this._color('var(--md-comp-map-marker-ring-color)');\n this.map.addSource(id, {\n type: 'geojson',\n data,\n cluster: true,\n clusterRadius: options.radius ?? 50,\n clusterMaxZoom: options.maxZoom ?? 14\n });\n this.map.addLayer({\n id: clusters,\n type: 'circle',\n source: id,\n filter: ['has', 'point_count'],\n paint: {\n 'circle-color': color,\n 'circle-radius': ['step', ['get', 'point_count'], 16, 10, 20, 100, 26],\n 'circle-stroke-width': 6,\n 'circle-stroke-color': color,\n 'circle-stroke-opacity': 0.3\n }\n });\n // A symbol layer needs the style's glyphs and one of its fonts.\n const style = this.map.getStyle();\n const font = style.glyphs && style.layers.find((layer: any) => layer.layout?.['text-font'])?.layout['text-font'];\n if (font) {\n this.map.addLayer({\n id: `${id}-count`,\n type: 'symbol',\n source: id,\n filter: ['has', 'point_count'],\n layout: { 'text-field': ['get', 'point_count_abbreviated'], 'text-font': font, 'text-size': 12 },\n paint: { 'text-color': this._color('var(--md-comp-map-cluster-label-color)') }\n });\n }\n this.map.addLayer({\n id: points,\n type: 'circle',\n source: id,\n filter: ['!', ['has', 'point_count']],\n paint: { 'circle-color': color, 'circle-radius': 6, 'circle-stroke-width': 2, 'circle-stroke-color': surface }\n });\n },\n off: () => listen('off')\n });\n listen('on');\n }\n\n /** Removes a route, arcs or clusters added with this id. */\n removeOverlay(id: string) {\n const overlay = this._overlays.get(id);\n if (!overlay) return;\n this._overlays.delete(id);\n overlay.off?.();\n if (!this._styleReady || !this.map.getSource(id)) return;\n for (const layer of this.map.getStyle().layers) if (layer.source === id) this.map.removeLayer(layer.id);\n this.map.removeSource(id);\n }\n\n private _line(id: string, geometry: object, token: string, options: MapLineOptions) {\n this._draw(id, {\n draw: () => {\n this.map.addSource(id, { type: 'geojson', data: { type: 'Feature', properties: {}, geometry } });\n this.map.addLayer({\n id,\n type: 'line',\n source: id,\n layout: { 'line-cap': 'round', 'line-join': 'round' },\n paint: {\n 'line-color': options.color ?? this._color(`var(--md-comp-map-${token}-color)`),\n 'line-width': options.width,\n 'line-opacity': options.opacity ?? 1,\n ...(options.dashArray && { 'line-dasharray': options.dashArray })\n }\n });\n }\n });\n }\n\n // Sources and layers go with the style, so every overlay is drawn again\n // when a theme change swaps it.\n private _draw(id: string, overlay: Overlay) {\n this.removeOverlay(id);\n this._overlays.set(id, overlay);\n if (this._styleReady) overlay.draw();\n }\n\n private _addMarker(element: HTMLElement, content: HTMLElement | null, at: LngLat) {\n const marker = new this.options.maplibregl.Marker({\n element,\n draggable: element.hasAttribute('data-draggable')\n }).setLngLat(at).addTo(this.map);\n marker.on('dragend', () => this._moved(marker));\n if (element.hasAttribute('data-draggable')) this._makeMovable(element, marker);\n this.markers.push(marker);\n if (!content) return;\n element.setAttribute('aria-expanded', 'false');\n const popup = this._popup(content, 16);\n popup.on('open', () => element.setAttribute('aria-expanded', 'true'));\n popup.on('close', () => {\n element.setAttribute('aria-expanded', 'false');\n if (!document.activeElement || document.activeElement === document.body) element.focus();\n });\n this._markerPopups.set(element, popup);\n }\n\n /** A marker moved: its `data-lng-lat` holds the new place, and it fires `change`. */\n private _moved(marker: any) {\n const element: HTMLElement = marker.getElement();\n const { lng, lat } = marker.getLngLat();\n element.dataset.lngLat = `${lng},${lat}`;\n element.dispatchEvent(new Event('change', { bubbles: true }));\n }\n\n // A drag is not the only way to move it (WCAG 2.5.7): a tap picks it up,\n // and the arrow keys nudge it. A button is already a control; anything\n // else becomes one, and destroy() takes that back off.\n private _makeMovable(element: HTMLElement, marker: any) {\n const added = element instanceof HTMLButtonElement ? [] : ['role', 'tabindex'].filter((name) => !element.hasAttribute(name));\n if (added.includes('role')) element.setAttribute('role', 'button');\n if (added.includes('tabindex')) element.tabIndex = 0;\n element.setAttribute('aria-pressed', 'false');\n this._restore.push(() => ['aria-pressed', ...added].forEach((name) => element.removeAttribute(name)));\n element.addEventListener('keydown', (e) => this._nudge(e, marker), { signal: this._events.signal });\n marker.on('dragstart', () => (this._dragged = element));\n marker.on('dragend', () => setTimeout(() => (this._dragged = null)));\n }\n\n /** Takes back the attributes `_makeMovable()` added. Destroy removes its listeners. */\n private _releaseMarkers() {\n this._restore.splice(0).forEach((undo) => undo());\n this._picked = null;\n }\n\n /** The arrow keys move a focused draggable marker 10px, and the map stays put. */\n private _nudge(e: KeyboardEvent, marker: any) {\n const step = plainArrow(e);\n if (!step) return;\n e.preventDefault();\n e.stopPropagation();\n const at = this.map.project(marker.getLngLat());\n marker.setLngLat(this.map.unproject([at.x + step[0] * 10, at.y + step[1] * 10]));\n this._moved(marker);\n }\n\n /** Picks a marker up, or puts down the one already picked up. */\n private _pick(element: HTMLElement | null) {\n this._picked?.setAttribute('aria-pressed', 'false');\n this._picked = element;\n element?.setAttribute('aria-pressed', 'true');\n }\n\n // A tap on a draggable marker picks it up, or puts it back down; the click\n // that ends a drag does neither.\n private _tapMarker(element: HTMLElement | null) {\n if (element?.hasAttribute('data-draggable')) this._tapMovable(element);\n else if (this._markerPopups.has(element)) this._toggle(element);\n }\n\n private _tapMovable(element: HTMLElement) {\n if (this._dragged !== element) this._pick(this._picked === element ? null : element);\n }\n\n /** A third of the map's width or height in a direction. */\n private _pan(x: number, y: number) {\n const { width, height } = this.el.getBoundingClientRect();\n this.map.panBy([(x * width) / 3, (y * height) / 3]);\n }\n\n // Either can be refused (an iframe without allowfullscreen, say). The\n // button state follows fullscreenchange, so there is nothing to undo.\n private _toggleFullscreen() {\n const request = document.fullscreenElement === this.el ? document.exitFullscreen() : this.el.requestFullscreen();\n request.catch(() => {});\n }\n\n private _popup(content: HTMLElement, offset: number) {\n const popup = new this.options.maplibregl.Popup({ closeOnClick: false, maxWidth: 'none', offset }).setDOMContent(content);\n this._popups.push(popup);\n return popup;\n }\n\n private _toggle(marker: HTMLElement) {\n const popup = this._markerPopups.get(marker);\n if (popup.isOpen()) popup.remove();\n else popup.setLngLat(this.markers.find((m) => m.getElement() === marker).getLngLat()).addTo(this.map);\n }\n\n private _buttons(action: string) {\n return this.el.querySelectorAll<HTMLButtonElement>(`.map-controls [data-action=\"${action}\"]`);\n }\n\n private _locate(button: HTMLButtonElement) {\n navigator.geolocation?.getCurrentPosition(\n ({ coords }) => {\n if (!this.map) return;\n const center = [coords.longitude, coords.latitude];\n if (!this._location) {\n const dot = document.createElement('span');\n dot.className = 'map-marker location';\n dot.setAttribute('aria-hidden', 'true');\n this._location = new this.options.maplibregl.Marker({ element: dot });\n }\n this._location.setLngLat(center).addTo(this.map);\n this.map.flyTo({ center, zoom: Math.max(this.map.getZoom(), 14) });\n },\n (error) => { if (this.map && error.code === error.PERMISSION_DENIED) button.disabled = true; }\n );\n }\n\n // Resolves a CSS color where the map is, so light-dark() and scoped\n // themes apply, then paints it on a canvas to read back the sRGB value.\n // MapLibre does not parse the oklch() the theme tokens compute to.\n private _color(value: string) {\n const probe = document.createElement('span');\n probe.hidden = true;\n probe.style.color = value;\n this.el.append(probe);\n const context = document.createElement('canvas').getContext('2d', { willReadFrequently: true });\n context.fillStyle = getComputedStyle(probe).color;\n probe.remove();\n context.fillRect(0, 0, 1, 1);\n const [r, g, b, a] = context.getImageData(0, 0, 1, 1).data;\n return `rgba(${r}, ${g}, ${b}, ${Math.round((a / 255) * 100) / 100})`;\n }\n\n private _isDark() {\n return this._color('light-dark(black, white)') === 'rgba(255, 255, 255, 1)';\n }\n\n private _themed() {\n const style = this.options.style;\n return typeof style === 'object' && 'light' in style && 'dark' in style;\n }\n\n private _style() {\n return this._themed() ? this.options.style[this._dark ? 'dark' : 'light'] : this.options.style;\n }\n\n private _handleStyleLoad = () => {\n this._styleReady = true;\n for (const overlay of this._overlays.values()) overlay.draw();\n };\n\n private _handleScheme = () => {\n const dark = this._isDark();\n if (dark === this._dark) return;\n this._dark = dark;\n this._styleReady = false;\n this.map.setStyle(this._style(), { diff: false });\n };\n\n private _sync = () => {\n const zoom = this.map.getZoom();\n for (const button of this._zoomIn) button.disabled = zoom >= this.map.getMaxZoom();\n for (const button of this._zoomOut) button.disabled = zoom <= this.map.getMinZoom();\n this.el.style.setProperty('--md-comp-map-bearing', `${-this.map.getBearing()}deg`);\n };\n\n private _handleFullscreen = () => {\n for (const button of this._buttons('fullscreen')) {\n button.setAttribute('aria-pressed', String(document.fullscreenElement === this.el));\n }\n };\n\n private _handleClick = (e: MouseEvent) => {\n const target = e.target as Element;\n const button = target.closest<HTMLButtonElement>('.map-controls [data-action]');\n if (button) this._actions[button.dataset.action]?.(button);\n else this._tapMarker(target.closest<HTMLElement>('.map-marker'));\n };\n\n // A click on the map closes marker popups, but not the one being toggled.\n private _handleMapClick = (e: any) => {\n const target = e.originalEvent.target as Node;\n this._drop(target, e.lngLat);\n for (const [marker, popup] of this._markerPopups) {\n if (!marker.contains(target) && !popup.getElement()?.contains(target)) popup.remove();\n }\n };\n\n // A tap on the map, not on a marker, puts a picked-up marker there.\n private _drop(target: Node, at: any) {\n if (!this._picked || (target as Element).closest?.('.map-marker')) return;\n const marker = this.markers.find((m) => m.getElement() === this._picked);\n marker.setLngLat(at);\n this._moved(marker);\n this._pick(null);\n }\n\n private _handleKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') this._escape(e);\n };\n\n // Escape puts down a picked-up marker first, then closes a popup.\n private _escape(e: KeyboardEvent) {\n if (this._picked) {\n e.preventDefault();\n this._pick(null);\n return;\n }\n for (const popup of this._popups) {\n if (popup.getElement()?.contains(e.target as Node)) {\n e.preventDefault();\n popup.remove();\n }\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/components/radialChart.ts"],
|
|
4
|
-
"sourcesContent": ["import { LineChart, LineChartOptions, rowLegend, seriesColor } from './lineChart';\nimport { svgNode as node } from '../core/utils';\n\nexport type RadialChartOptions = LineChartOptions;\n\n/** The outer ring's outer edge in a 100-unit box. */\nconst RADIUS = 46;\n/** The rings never fill more of the radius than this, leaving a middle. */\nconst FILL = 0.8;\n\n/**\n * Radial chart. It reads its <table> like LineChart, but draws each row of\n * the first value column as a ring, outermost first, filled clockwise from\n * the top as a share of `data-max` above zero (100 by default). With `.gauge` the rings\n * are half circles over the middle. With `.labels` they are three quarters\n * of a circle, leaving the top left quarter for each row's name at the\n * ring's start; a gauge's names hang under its base line instead.\n * `data-segments` splits each ring into that many segments, filled whole,\n * and `.gradient` shades each fill along the ring, from a light tint at its\n * start to its full color at its end. A <tfoot>\n * row shows in the middle, and\n * a legend lists the rows when there is more than one. Further columns show\n * in the tooltip.\n *\n * Call `update()` after changing the ring tokens, and after changing the table\n * unless it was started with `watch` or `data-watch`.\n */\nexport class RadialChart extends LineChart {\n // No initializers: LineChart's constructor draws before they would run.\n /** Each ring's middle radius, and their shared width. */\n private _radii: number[];\n private _width: number;\n /** The gap between rings, and between segments. */\n private _gap: number;\n /** Each row's share of the maximum, from 0 to 1. */\n private _fractions: number[];\n private _rings: SVGCircleElement[];\n /** With .gradient, each ring's fill drawn again as a conic gradient, or null for none. */\n private _sweeps: (HTMLElement | null)[];\n\n protected get _type() {\n return 'radial-chart';\n }\n\n /** The rings fill to data-max, so there is no value axis. */\n protected get _axis() {\n return false;\n }\n\n protected get _points() {\n return false;\n }\n\n protected get _circular() {\n return true;\n }\n\n private get _gauge() {\n return this.el.classList.contains('gauge');\n }\n\n /** Whether .labels names the rings, which a sparkline never does. */\n private get _labeled() {\n const list = this.el.classList;\n return list.contains('labels') && !list.contains('sparkline');\n }\n\n /** How much of a circle a full ring spans. */\n private get _span() {\n if (this._gauge) return 0.5;\n return this._labeled ? 0.75 : 1;\n }\n\n /** The number of segments data-segments asks for, or 0 for whole rings. */\n private get _segments() {\n const segments = Math.round(this._number('segments') ?? 0);\n return segments > 1 ? segments : 0;\n }\n\n /** A share as drawn: with segments, to the nearest whole segment. */\n private _lit(fraction: number) {\n const segments = this._segments;\n return segments ? Math.round(fraction * segments) / segments : fraction;\n }\n\n /**\n * A ring's dash pattern for a share of its span. Round caps reach half the\n * width past each end of a dash, so a capped dash is one width shorter and\n * its gap one width longer; one shorter than the width is a dot. With\n * segments, each lit segment is a dash with the ring gap after it, and\n * the last gap runs out the circle so the pattern does not repeat.\n */\n private _dash(fraction: number, length: number, capped: boolean) {\n const [cap, segments, span] = [capped ? this._width : 0, this._segments, this._span * length];\n if (!segments) return `${Math.max(0.001, fraction * span - cap).toFixed(3)} ${length.toFixed(3)}`;\n // A dash and its gap make one segment, even where a small ring leaves\n // too little room for the gap and the caps.\n const size = span / segments;\n const dash = Math.max(0.001, size - this._gap - cap);\n const lit = Array.from({ length: Math.round(fraction * segments) }, () => `${dash.toFixed(3)} ${(size - dash).toFixed(3)}`);\n return `${lit.join(' ').replace(/ [\\d.]+$/, '') || 0} ${length.toFixed(3)}`;\n }\n\n /** The distance between rings' middles, or one ring's width. */\n private get _step() {\n return this._radii.length > 1 ? this._radii[0] - this._radii[1] : this._width;\n }\n\n static key = 'Expressive_RadialChart';\n\n show(index: number) {\n if (!this._tooltip || index === this.activeIndex) return;\n super.show(index);\n this._rings.forEach((ring, i) => ring.classList.toggle('active', i === index));\n this._sweeps.forEach((sweep, i) => sweep?.classList.toggle('active', i === index));\n // LineChart hides the tooltip for -1 and for an index past the last row.\n if (this._tooltip.hidden) return;\n const color = seriesColor(index);\n this._tooltip.querySelectorAll<HTMLElement>('[data-series]').forEach((span) => {\n span.dataset.series = color;\n });\n }\n\n /** The tooltip sits where the ring's fill ends. */\n protected _place(index: number) {\n const turn = this._turn(this._fractions[index]);\n const r = this._radii[index];\n const [x, y] = [r * Math.sin(turn * 2 * Math.PI), -r * Math.cos(turn * 2 * Math.PI)];\n this._tooltip.style.left = `${50 + x}%`;\n this._tooltip.style.top = `${((50 + y) / (this._gauge ? 50 : 100)) * 100}%`;\n // On the right half it opens leftwards, over the rings.\n this._tooltip.classList.toggle('end', x > 0);\n }\n\n /** A fraction of the ring as a turn clockwise from the top. */\n private _turn(fraction: number) {\n // A gauge starts at nine o'clock.\n return fraction * this._span - (this._gauge ? 0.25 : 0);\n }\n\n /** For more than one row, a legend of every row with its color and cell. */\n protected _guides(): Element[] {\n if (this.labels.length < 2) return [];\n const text = this.series[0].text;\n const colors = this.labels.map((_, i) => seriesColor(i));\n return [rowLegend('radial-chart-legend', colors, this.labels.map((label, i) => [label, text[i]]))];\n }\n\n /** The ring under the pointer by its distance from the middle, or -1. */\n protected _indexAt(e: PointerEvent) {\n const box = this._plot.getBoundingClientRect();\n // The middle is half the width down in both shapes.\n const [x, y] = [e.clientX - box.left - box.width / 2, e.clientY - box.top - box.width / 2];\n if (this._gauge && y > 0) return this._nameAt(e);\n // A gap belongs to a ring beside it.\n const distance = this._distance(x, y, box.width);\n return this._radii.findIndex((r) => Math.abs(distance - r) <= this._step / 2);\n }\n\n /**\n * How far a point is from the middle in the SVG's 100-unit box. In the\n * top left quarter .labels leaves empty, the names run straight across,\n * so only the height counts and a name picks its own ring.\n */\n private _distance(x: number, y: number, width: number) {\n // Only three-quarter rings leave that quarter empty.\n if (this._span === 0.75 && x < 0 && y < 0) return (-y / width) * 100;\n return (Math.hypot(x, y) / width) * 100;\n }\n\n /** Under a gauge's base line, the ring whose name is under the pointer, or -1. */\n private _nameAt(e: PointerEvent) {\n const name = (e.target as Element).closest('.radial-chart-names > span');\n return name ? [...name.parentElement!.children].indexOf(name) : -1;\n }\n\n /** The rings' turn, from three o'clock to the top or, for a gauge, to nine, and the SVG's box. */\n private get _frame(): [transform: string, viewBox: string] {\n return this._gauge ? ['rotate(180)', '-50 -50 100 50'] : ['rotate(-90)', '-50 -50 100 100'];\n }\n\n /**\n * With .gradient, a ring's fill drawn again in HTML: a conic gradient from\n * a tint of its colour at the ring's start to the full colour where the\n * fill ends, masked to the fill's own dash, so it follows the ring round.\n * An SVG stroke takes no conic gradient.\n */\n private _sweep(r: number, i: number, length: number) {\n const fraction = this._fractions[i];\n if (!fraction || !this.el.classList.contains('gradient')) return null;\n const [transform, viewBox] = this._frame;\n const width = this._width.toFixed(3);\n const dash = this._dash(fraction, length, true);\n const image = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='${viewBox}'><circle r='${r.toFixed(3)}' stroke-width='${width}' transform='${transform}' stroke-dasharray='${dash}' stroke-dashoffset='${(-this._width / 2).toFixed(3)}' stroke-linecap='round' fill='none' stroke='black'/></svg>`;\n const sweep = document.createElement('div');\n sweep.className = 'radial-chart-sweep';\n sweep.dataset.series = seriesColor(i);\n sweep.style.setProperty('--radial-chart-shape', `url(\"data:image/svg+xml,${encodeURIComponent(image)}\")`);\n sweep.style.setProperty('--radial-chart-from', `${this._turn(0)}turn`);\n sweep.style.setProperty('--radial-chart-to', `${fraction * this._span}turn`);\n return sweep;\n }\n\n /**\n * With .labels, each row's name left of its ring's start at the top,\n * ending at the middle line. CSS shrinks the text to fit crowded rings.\n * A gauge's names hang under its base line in a row each, innermost\n * first, starting below their rings' starts.\n */\n private _names(): Element[] {\n if (!this._labeled) return [];\n const count = this._radii.length;\n const names = document.createElement('div');\n names.className = 'radial-chart-names';\n names.style.setProperty('--radial-chart-step', this._step.toFixed(3));\n // The plot leaves room under a gauge for the rows.\n this._plot.style.setProperty('--radial-chart-rows', String(count));\n names.append(...this._radii.map((r, i) => {\n const name = document.createElement('span');\n // The ring's top, or a gauge ring's start along the base line.\n name.style.setProperty('--radial-chart-at', `${(50 - r).toFixed(3)}%`);\n name.style.setProperty('--radial-chart-row', String(count - 1 - i));\n name.textContent = this.labels[i];\n return name;\n }));\n return [names];\n }\n\n /**\n * An SVG of rings in a -50 to 50 box, the top half for a gauge. Each row\n * is a track circle and a fill circle whose dash is its share; CSS draws\n * them from --radial-chart-dash. The total is HTML over it.\n */\n protected _draw(): Element {\n const style = getComputedStyle(this.el);\n const token = (name: string, fallback: number) => {\n const value = parseFloat(style.getPropertyValue(`--md-comp-radial-chart-${name}`));\n return Number.isFinite(value) ? value : fallback;\n };\n const count = this.labels.length;\n let [width, gap] = [Math.max(0, token('thickness', 8)), Math.max(0, token('gap', 2))];\n // Too many rings to leave a middle thin, with their gaps, to fit.\n // ponytail: past about 18 rings they are hairlines; that many values want a bar chart.\n const scale = Math.min(1, (RADIUS * FILL) / (count * width + (count - 1) * gap || 1));\n [width, gap] = [width * scale, gap * scale];\n [this._width, this._gap] = [width, gap];\n this._radii = this.labels.map((_, i) => RADIUS - width / 2 - i * (width + gap));\n // A maximum of zero or less means nothing, so it falls back.\n const max = [parseFloat(this.el.dataset.max ?? ''), this.options.max ?? NaN, 100].find((value) => value > 0)!;\n this._fractions = this.series[0].values.map((value) => this._lit(Math.min(1, Math.max(0, (value ?? 0) / max))));\n\n const [transform, viewBox] = this._frame;\n const svg = node('svg', { viewBox, focusable: 'false' });\n const span = this._span;\n this._sweeps = [];\n this._rings = this._radii.map((r, i) => {\n const length = 2 * Math.PI * r;\n // A capped dash starts half a width in, where its round cap ends.\n const circle = (name: string, fraction: number, capped: boolean) => {\n const ring = node('circle', { class: name, r: r.toFixed(3), transform, 'stroke-width': width.toFixed(3) });\n ring.style.setProperty('--radial-chart-dash', this._dash(fraction, length, capped));\n if (capped) {\n ring.style.setProperty('--radial-chart-offset', (-width / 2).toFixed(3));\n ring.classList.add('capped');\n }\n return ring;\n };\n const ring = circle('radial-chart-ring', this._fractions[i], true) as SVGCircleElement;\n ring.dataset.series = seriesColor(i);\n // An empty ring would still draw its round cap.\n if (!this._fractions[i]) ring.classList.add('empty');\n // Only a track short of a whole circle, or in segments, has ends to round.\n svg.append(circle('radial-chart-track', 1, span < 1 || !!this._segments), ring);\n this._sweeps.push(this._sweep(r, i, length));\n return ring;\n });\n\n const rings = document.createElement('div');\n rings.className = 'radial-chart-rings';\n rings.setAttribute('aria-hidden', 'true');\n rings.style.setProperty('--radial-chart-middle', `${(this._radii[count - 1] - this._width / 2) * 2}%`);\n rings.append(svg, ...this._sweeps.filter((sweep) => sweep !== null), ...this._names());\n\n const total = this._total('radial-chart-total');\n if (total) rings.append(total);\n return rings;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["ring"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/behaviors/imageCompare.ts"],
|
|
4
|
-
"sourcesContent": ["import { Utils } from '../core/utils';\n\nconst rangeSelector = '.image-compare > input[type=\"range\"]';\n\n/**\n * Image compare. Keeps `--md-comp-image-compare-position` on each\n * `.image-compare` in step with its range input, so the divider and the\n * revealed image follow the value. Listens on the document, so compares added\n * later follow too once moved; `ImageCompare.sync(el)` sets one at once.\n */\nexport class ImageCompare {\n private static _initialized = false;\n\n static Init() {\n if (ImageCompare._initialized || typeof document === 'undefined') return;\n ImageCompare._initialized = true;\n document.addEventListener('input', (e) => {\n const range = Utils.eventTarget(e);\n if (range?.matches(rangeSelector)) ImageCompare.sync(<HTMLInputElement>range);\n });\n Utils.onDocumentReady(() => {\n document.querySelectorAll<HTMLInputElement>(rangeSelector).forEach((range) => ImageCompare.sync(range));\n });\n }\n\n /** Moves the divider of a compare to its range's current value. */\n static sync(range: HTMLInputElement) {\n const min = parseFloat(range.min) || 0;\n const max = Number.isNaN(parseFloat(range.max)) ? 100 : parseFloat(range.max);\n const fraction = max === min ? 0 : (parseFloat(range.value) - min) / (max - min);\n range.parentElement.style.setProperty('--md-comp-image-compare-position', `${fraction * 100}%`);\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;AAEA,IAAM,gBAAgB;AAQf,IAAM,gBAAN,MAAM,cAAa;AAAA,EAGxB,OAAO,OAAO;AACZ,QAAI,cAAa,gBAAgB,OAAO,aAAa,YAAa;AAClE,kBAAa,eAAe;AAC5B,aAAS,iBAAiB,SAAS,CAAC,MAAM;AACxC,YAAM,QAAQ,MAAM,YAAY,CAAC;AACjC,UAAI,OAAO,QAAQ,aAAa,EAAG,eAAa,KAAuB,KAAK;AAAA,IAC9E,CAAC;AACD,UAAM,gBAAgB,MAAM;AAC1B,eAAS,iBAAmC,aAAa,EAAE,QAAQ,CAAC,UAAU,cAAa,KAAK,KAAK,CAAC;AAAA,IACxG,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,OAAO,KAAK,OAAyB;AACnC,UAAM,MAAM,WAAW,MAAM,GAAG,KAAK;AACrC,UAAM,MAAM,OAAO,MAAM,WAAW,MAAM,GAAG,CAAC,IAAI,MAAM,WAAW,MAAM,GAAG;AAC5E,UAAM,WAAW,QAAQ,MAAM,KAAK,WAAW,MAAM,KAAK,IAAI,QAAQ,MAAM;AAC5E,UAAM,cAAc,MAAM,YAAY,oCAAoC,GAAG,WAAW,GAAG,GAAG;AAAA,EAChG;AACF;AAtBa,cACI,eAAe;AADzB,IAAM,eAAN;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/components/slider.ts"],
|
|
4
|
-
"sourcesContent": ["import { Component, BaseOptions } from '../core/component';\nimport { Utils } from '../core/utils';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface SliderOptions extends BaseOptions {}\n\nconst _defaults: SliderOptions = {};\n\n// Inline values _set() replaced, per element, so destroy() can put back what\n// an author wrote. Per element, not per instance: both handles of a range\n// write the same host properties.\nconst _authored = new WeakMap<HTMLElement, Record<string, string>>();\n\nexport class Slider extends Component<SliderOptions> {\n declare el: HTMLInputElement;\n private _pointerDown: boolean;\n private _resizeObserver: ResizeObserver | null = null;\n value: HTMLElement;\n thumb: HTMLElement;\n\n constructor(el: HTMLInputElement, options: Partial<SliderOptions>) {\n super(el, options);\n\n this._pointerDown = false;\n this._setupThumb();\n this._sync();\n this._setupEventHandlers();\n this._resizeObserver = new ResizeObserver(() => this._sync());\n this._resizeObserver.observe(this.el);\n // The bubble and stop row are placed from the input's offsets, which\n // move when the host resizes around an input that keeps its size.\n if (this.el.parentElement) this._resizeObserver.observe(this.el.parentElement);\n }\n\n static get defaults(): SliderOptions {\n return _defaults;\n }\n\n static key = 'Expressive_Slider';\n\n destroy() {\n this._resizeObserver?.disconnect();\n this._removeThumb();\n super.destroy();\n const host = this._host();\n for (const el of [this.el, host]) {\n for (const name in _authored.get(el)) el.style.setProperty(name, _authored.get(el)[name]);\n _authored.delete(el);\n }\n // The other handle of a range writes the shared host properties again.\n host?.querySelectorAll('input[type=\"range\"]').forEach((el) => el['Expressive_Slider']?._sync());\n }\n\n _set(el: HTMLElement, name: string, value: string) {\n const authored = _authored.get(el) ?? {};\n _authored.set(el, authored);\n authored[name] ??= el.style.getPropertyValue(name);\n el.style.setProperty(name, value);\n }\n\n // Eleven listeners used to cover four stages, because each one was written\n // twice - once for mouse, once for touch. One of the touch spellings,\n // `touchleave`, was never implemented by any browser at all.\n _setupEventHandlers() {\n const { signal } = this._events;\n this.el.addEventListener('change', this._handleRangeChange, { signal });\n this.el.addEventListener('pointerdown', this._handleRangePointerDown, { signal });\n // `input` alone tracks a drag. A `pointermove` sync used to run as well,\n // twice per frame, and before the browser had moved the value.\n this.el.addEventListener('input', this._handleRangeInput, { signal });\n this.el.addEventListener('pointerup', this._handleRangePointerUp, { signal });\n this.el.addEventListener('pointercancel', this._handleRangePointerUp, { signal });\n this.el.addEventListener('blur', this._handleRangeRelease, { signal });\n // `mouseout`, not `pointerout`: this used to be a `mouseout`/`touchleave`\n // pair, and `touchleave` was never implemented by any browser, so the\n // handler has only ever run for a mouse. `pointerout` also fires when a\n // touch lifts, which would clear the thumb's active state at a moment\n // nothing cleared it before.\n this.el.addEventListener('mouseout', this._handleRangeRelease, { signal });\n // A form reset restores the value without an input event.\n this.el.form?.addEventListener('reset', this._handleFormReset, { signal });\n }\n\n // The reset event fires before the browser restores the values.\n _handleFormReset = () => {\n setTimeout(() => {\n if (Slider.getInstance(this.el) === this) this._sync();\n });\n };\n\n _handleRangeChange = () => {\n this._clampDual();\n this._sync();\n this.thumb.classList.add('active');\n };\n\n _handleRangePointerDown = (e: PointerEvent) => {\n if (!e.isPrimary) return;\n if (e.pointerType === 'mouse' && e.button !== 0) return;\n this._pointerDown = true;\n this.el.classList.add('active');\n this._clampDual();\n this._sync();\n // An `e.type !== 'input'` guard used to sit here. This handler is only ever\n // bound to a press, so it was never anything but true.\n this.thumb.classList.add('active');\n };\n\n _handleRangeInput = () => {\n this._clampDual();\n this._sync();\n this.thumb.classList.add('active');\n };\n\n _handleRangePointerUp = (e: PointerEvent) => {\n if (!e.isPrimary) return;\n this._pointerDown = false;\n this.el.classList.remove('active');\n };\n\n _handleRangeRelease = () => {\n if (!this._pointerDown) {\n this.thumb.classList.remove('active');\n }\n };\n\n _setupThumb() {\n this.thumb = document.createElement('span');\n this.value = document.createElement('span');\n this.thumb.classList.add('thumb');\n this.value.classList.add('value');\n this.thumb.append(this.value);\n this.el.after(this.thumb);\n }\n\n _removeThumb() {\n this.thumb.remove();\n }\n\n _isVertical(): boolean {\n return !!this.el.closest('.vertical');\n }\n\n _host(): HTMLElement | null {\n // `.slider` is the documented host now; without it here a dual-handle\n // control could not find its wrapper, so the handles never clamped and the\n // shared start/end fractions never tracked the interval.\n return this.el.closest('.slider, label');\n }\n\n _clampDual() {\n const host = this._host();\n const peers = host?.querySelectorAll('input[type=\"range\"]');\n if (!peers || peers.length !== 2) return;\n const start = peers[0] as HTMLInputElement;\n const end = peers[1] as HTMLInputElement;\n if (this.el === start && +start.value > +end.value) start.value = end.value;\n if (this.el === end && +end.value < +start.value) end.value = start.value;\n }\n\n /** The input's range, defaulting like the browser does: 0 to 100. */\n private _bounds(el: HTMLInputElement) {\n const parsedMax = parseFloat(el.max);\n return { max: Number.isNaN(parsedMax) ? 100 : parsedMax, min: parseFloat(el.min) || 0 };\n }\n\n _fraction(el: HTMLInputElement): number {\n const { max, min } = this._bounds(el);\n const val = parseFloat(el.value) || 0;\n return max === min ? 0 : (val - min) / (max - min);\n }\n\n _sync() {\n const percent = this._fraction(this.el);\n const fraction = `${percent * 100}%`;\n\n // Read before writing. This runs on every pointer move during a drag, and\n // setting the custom property first made each of the four offset reads\n // below flush a fresh layout.\n const left = this.el.offsetLeft;\n const top = this.el.offsetTop;\n const width = this.el.offsetWidth;\n const height = this.el.offsetHeight;\n const style = getComputedStyle(this.el);\n const rtl = style.direction === 'rtl';\n const vertical = this._isVertical();\n const handle = parseFloat(style.getPropertyValue('--md-comp-slider-handle-width')) || 4;\n const length = vertical ? height : width;\n const position = handle / 2 + percent * (length - handle);\n\n this._set(this.el, '--md-comp-slider-active-fraction', fraction);\n this._set(this.el, '--md-comp-slider-active-position', `${position}px`);\n\n const host = this._host();\n const peers = host?.querySelectorAll('input[type=\"range\"]');\n if (host && peers && peers.length === 2) {\n const nums = Array.from(peers).map((el) => this._fraction(el as HTMLInputElement));\n this._set(host, '--md-comp-slider-start-fraction', `${Math.min(...nums) * 100}%`);\n this._set(host, '--md-comp-slider-end-fraction', `${Math.max(...nums) * 100}%`);\n this._set(host, '--md-comp-slider-start-position', `${handle / 2 + Math.min(...nums) * (length - handle)}px`);\n this._set(host, '--md-comp-slider-end-position', `${handle / 2 + Math.max(...nums) * (length - handle)}px`);\n }\n if (host?.classList.contains('stops')) {\n const { max, min } = this._bounds(this.el);\n const step = parseFloat(this.el.step);\n // Stops sit at min + k * step up to max, so a step that does not divide\n // the range ends short of max. No step, `any`, zero or a negative step\n // clears the spacing, and the host paints no dots.\n const stops = step > 0 && Number.isFinite(step) && max > min;\n this._set(host, '--md-comp-slider-stop-count', stops ? String(Math.floor((max - min) / step + 1e-9) + 1) : '');\n this._set(host, '--md-comp-slider-stop-spacing', stops ? `${((length - handle) * step) / (max - min)}px` : '');\n // The tick row is the host's ::after, which cannot read the input's\n // properties. A dual host has no single position.\n if (peers?.length === 1) {\n this._set(host, '--md-comp-slider-active-position', `${position}px`);\n this._set(host, '--md-comp-slider-track-center', `${top + height / 2}px`);\n }\n }\n\n this.value.textContent = this.el.value;\n if (vertical) {\n this.thumb.style.left = `${left + width / 2}px`;\n this.thumb.style.top = `${top + height - position}px`;\n } else {\n this.thumb.style.left = `${left + (rtl ? width - position : position)}px`;\n this.thumb.style.top = `${top}px`;\n }\n }\n\n /**\n * Initializes every range input in the current document.\n */\n static Init() {\n // Deferred like every other Init(): this ran at import time, so a bundle\n // loaded in <head> found no inputs at all.\n Utils.onDocumentReady(() => {\n // An image compare's range is invisible and drawn by its container; a\n // color picker's hue range paints its own track.\n Slider.init(document.querySelectorAll<HTMLInputElement>('input[type=range]:not(.image-compare > input, .color-picker-hue)'));\n });\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/components/hoverCard.ts"],
|
|
4
|
-
"sourcesContent": ["import { Utils } from '../core/utils';\nimport { Component, BaseOptions } from '../core/component';\n\nexport interface HoverCardOptions extends BaseOptions {\n /**\n * How long the pointer or keyboard focus rests on the link before the card shows.\n * @default 500\n */\n enterDelay: number;\n /**\n * How long the card stays after the pointer and focus leave the link and the card.\n * @default 300\n */\n exitDelay: number;\n}\n\nconst _defaults: HoverCardOptions = {\n enterDelay: 500,\n exitDelay: 300\n};\n\n// Links can share one card, such as a name mentioned twice; the link that\n// last showed it owns it, and the next one takes it over.\nconst owners = new WeakMap<HTMLElement, HoverCard>();\n\n/**\n * Hover card. A `.hover-card-trigger` link names its card, a `.popover` with\n * `popover=\"hint\"`, in `aria-details`. The card shows against the link after\n * `enterDelay` and stays while the pointer or focus is on either.\n */\nexport class HoverCard extends Component<HoverCardOptions> {\n /** The card the link's `aria-details` names, or null when it names none. */\n cardEl: HTMLElement | null;\n /** Whether the instance has the card showing. */\n private _shown = false;\n /** What keeps the card wanted: the pointer, keyboard focus, or both. */\n private _holds = new Set<'pointer' | 'focus'>();\n private _timeout: ReturnType<typeof setTimeout>;\n /** The anchor name the card is placed against while this link shows it. */\n private _anchorName = `--hover-card-${Utils.guid()}`;\n\n constructor(el: HTMLElement, options: Partial<HoverCardOptions>) {\n super(el, options);\n this.cardEl = Utils.getElementById(el, el.getAttribute('aria-details') ?? '');\n if (!this.cardEl) {\n console.error(`HoverCard: aria-details names no element; the link shows no card.`);\n return;\n }\n // The browser hides a hint card itself on a click elsewhere, on Escape\n // and when another hint opens.\n const { signal } = this._events;\n this.cardEl.addEventListener('toggle', this._handleToggle, { signal });\n for (const target of [this.el, this.cardEl]) {\n target.addEventListener('pointerenter', this._handlePointerEnter, { signal });\n target.addEventListener('pointerleave', this._handlePointerLeave, { signal });\n target.addEventListener('focusout', this._handleFocusOut, { signal });\n }\n this.el.addEventListener('focus', this._handleLinkFocus, { signal });\n this.cardEl.addEventListener('focusin', this._handleCardFocus, { signal });\n }\n\n static get defaults(): HoverCardOptions {\n return _defaults;\n }\n\n static key = 'Expressive_HoverCard';\n\n destroy() {\n clearTimeout(this._timeout);\n if (this._shown) {\n this.cardEl.hidePopover();\n this._hidden();\n }\n super.destroy();\n }\n\n /**\n * Show the card now, without enterDelay.\n */\n open = () => {\n clearTimeout(this._timeout);\n if (!this.cardEl || this._shown) return;\n owners.get(this.cardEl)?.close();\n // `source` makes the link the card's anchor and invoker, so Tab moves from\n // the link into the card. It throws for a card without the popover\n // attribute, before any state changes.\n (this.cardEl.showPopover as (options?: { source?: Element }) => void).call(this.cardEl, { source: this.el });\n owners.set(this.cardEl, this);\n this._shown = true;\n this._listenForEscape(true);\n this._anchor(true);\n this._notify('open');\n };\n\n /**\n * Hide the card now, without exitDelay.\n */\n close = () => {\n clearTimeout(this._timeout);\n if (!this._shown) return;\n this.cardEl.hidePopover();\n this._hidden();\n this._notify('close');\n };\n\n private _hidden() {\n this._shown = false;\n this._listenForEscape(false);\n this._anchor(false);\n }\n\n // `source` anchors the card too, but Firefox keeps the first source's\n // anchor for good, so a card two links share would stay at the first. A\n // named anchor, set only while the card shows, follows the link that shows it.\n private _anchor(on: boolean) {\n Utils.setAnchorName(this.el, this._anchorName, on);\n if (on) this.cardEl.style.setProperty('position-anchor', this._anchorName);\n else this.cardEl.style.removeProperty('position-anchor');\n for (const el of [this.el, this.cardEl]) if (!el.getAttribute('style')) el.removeAttribute('style');\n }\n\n /** Wanted cards show after enterDelay; once nothing holds the card, it hides after exitDelay. */\n private _schedule() {\n clearTimeout(this._timeout);\n const wanted = this._holds.size > 0;\n if (wanted === this._shown) return;\n const [change, delay] = wanted ? [this.open, this.options.enterDelay] as const : [this.close, this.options.exitDelay] as const;\n this._timeout = setTimeout(change, delay);\n }\n\n private _hold(by: 'pointer' | 'focus') {\n this._holds.add(by);\n this._schedule();\n }\n\n private _release(by: 'pointer' | 'focus') {\n this._holds.delete(by);\n this._schedule();\n }\n\n // A touch is a tap that follows the link, never a hover; pointer events\n // say so, and the mouse events a tap sends afterwards are not listened to.\n private _handlePointerEnter = (e: PointerEvent) => {\n if (e.pointerType !== 'touch') this._hold('pointer');\n };\n\n private _handlePointerLeave = (e: PointerEvent) => {\n if (e.pointerType !== 'touch') this._release('pointer');\n };\n\n // A pointer press also focuses the link, and the hover already covers it,\n // so only keyboard focus holds the card from the link.\n private _handleLinkFocus = () => {\n if (this.el.matches(':focus-visible')) this._hold('focus');\n };\n\n private _handleCardFocus = () => this._hold('focus');\n\n private _handleFocusOut = (e: FocusEvent) => {\n const next = e.relatedTarget as Node | null;\n if (!next || !(this.el.contains(next) || this.cardEl.contains(next))) this._release('focus');\n };\n\n /** Escape is listened for only while the card shows. close() removes it, and destroy() through the signal. */\n private _listenForEscape(on: boolean) {\n const doc = this.el.ownerDocument;\n if (on) doc.addEventListener('keydown', this._handleKeydown, { capture: true, signal: this._events.signal });\n else doc.removeEventListener('keydown', this._handleKeydown, true);\n }\n\n // Escape always hides the card, but it is only the card's key when focus is\n // on the link or in the card; otherwise it still reaches the dialog or menu\n // that has focus. An engine that does not know popover=\"hint\" treats the\n // card as manual, which Escape would not close.\n private _handleKeydown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape' || Utils.isComposing(e)) return;\n if (Utils.focusIsIn(this.el, this.cardEl)) this._takeEscape(e);\n this.close();\n };\n\n /** Keeps Escape from the page and, when focus is in the card, takes it back to the link before the card hides. */\n private _takeEscape(e: KeyboardEvent) {\n e.preventDefault();\n e.stopPropagation();\n if (Utils.focusIsIn(this.cardEl)) this.el.focus();\n }\n\n private _handleToggle = (e: Event) => {\n if ((e as ToggleEvent).newState !== 'closed' || !this._shown) return;\n this._hidden();\n this._notify('close');\n };\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;AAgBA,IAAM,YAA8B;AAAA,EAClC,YAAY;AAAA,EACZ,WAAW;AACb;AAIA,IAAM,SAAS,oBAAI,QAAgC;AAO5C,IAAM,YAAN,cAAwB,UAA4B;AAAA,EAWzD,YAAY,IAAiB,SAAoC;AAC/D,UAAM,IAAI,OAAO;AARnB;AAAA,SAAQ,SAAS;AAEjB;AAAA,SAAQ,SAAS,oBAAI,IAAyB;AAG9C;AAAA,SAAQ,cAAc,gBAAgB,MAAM,KAAK,CAAC;AAwClD;AAAA;AAAA;AAAA,gBAAO,MAAM;AACX,mBAAa,KAAK,QAAQ;AAC1B,UAAI,CAAC,KAAK,UAAU,KAAK,OAAQ;AACjC,aAAO,IAAI,KAAK,MAAM,GAAG,MAAM;AAI/B,MAAC,KAAK,OAAO,YAAyD,KAAK,KAAK,QAAQ,EAAE,QAAQ,KAAK,GAAG,CAAC;AAC3G,aAAO,IAAI,KAAK,QAAQ,IAAI;AAC5B,WAAK,SAAS;AACd,WAAK,iBAAiB,IAAI;AAC1B,WAAK,QAAQ,IAAI;AACjB,WAAK,QAAQ,MAAM;AAAA,IACrB;AAKA;AAAA;AAAA;AAAA,iBAAQ,MAAM;AACZ,mBAAa,KAAK,QAAQ;AAC1B,UAAI,CAAC,KAAK,OAAQ;AAClB,WAAK,OAAO,YAAY;AACxB,WAAK,QAAQ;AACb,WAAK,QAAQ,OAAO;AAAA,IACtB;AAuCA;AAAA;AAAA,SAAQ,sBAAsB,CAAC,MAAoB;AACjD,UAAI,EAAE,gBAAgB,QAAS,MAAK,MAAM,SAAS;AAAA,IACrD;AAEA,SAAQ,sBAAsB,CAAC,MAAoB;AACjD,UAAI,EAAE,gBAAgB,QAAS,MAAK,SAAS,SAAS;AAAA,IACxD;AAIA;AAAA;AAAA,SAAQ,mBAAmB,MAAM;AAC/B,UAAI,KAAK,GAAG,QAAQ,gBAAgB,EAAG,MAAK,MAAM,OAAO;AAAA,IAC3D;AAEA,SAAQ,mBAAmB,MAAM,KAAK,MAAM,OAAO;AAEnD,SAAQ,kBAAkB,CAAC,MAAkB;AAC3C,YAAM,OAAO,EAAE;AACf,UAAI,CAAC,QAAQ,EAAE,KAAK,GAAG,SAAS,IAAI,KAAK,KAAK,OAAO,SAAS,IAAI,GAAI,MAAK,SAAS,OAAO;AAAA,IAC7F;AAaA;AAAA;AAAA;AAAA;AAAA,SAAQ,iBAAiB,CAAC,MAAqB;AAC7C,UAAI,EAAE,QAAQ,YAAY,MAAM,YAAY,CAAC,EAAG;AAChD,UAAI,MAAM,UAAU,KAAK,IAAI,KAAK,MAAM,EAAG,MAAK,YAAY,CAAC;AAC7D,WAAK,MAAM;AAAA,IACb;AASA,SAAQ,gBAAgB,CAAC,MAAa;AACpC,UAAK,EAAkB,aAAa,YAAY,CAAC,KAAK,OAAQ;AAC9D,WAAK,QAAQ;AACb,WAAK,QAAQ,OAAO;AAAA,IACtB;AApJE,SAAK,SAAS,MAAM,eAAe,IAAI,GAAG,aAAa,cAAc,KAAK,EAAE;AAC5E,QAAI,CAAC,KAAK,QAAQ;AAChB,cAAQ,MAAM,mEAAmE;AACjF;AAAA,IACF;AAGA,UAAM,EAAE,OAAO,IAAI,KAAK;AACxB,SAAK,OAAO,iBAAiB,UAAU,KAAK,eAAe,EAAE,OAAO,CAAC;AACrE,eAAW,UAAU,CAAC,KAAK,IAAI,KAAK,MAAM,GAAG;AAC3C,aAAO,iBAAiB,gBAAgB,KAAK,qBAAqB,EAAE,OAAO,CAAC;AAC5E,aAAO,iBAAiB,gBAAgB,KAAK,qBAAqB,EAAE,OAAO,CAAC;AAC5E,aAAO,iBAAiB,YAAY,KAAK,iBAAiB,EAAE,OAAO,CAAC;AAAA,IACtE;AACA,SAAK,GAAG,iBAAiB,SAAS,KAAK,kBAAkB,EAAE,OAAO,CAAC;AACnE,SAAK,OAAO,iBAAiB,WAAW,KAAK,kBAAkB,EAAE,OAAO,CAAC;AAAA,EAC3E;AAAA,EAEA,WAAW,WAA6B;AACtC,WAAO;AAAA,EACT;AAAA,EAIA,UAAU;AACR,iBAAa,KAAK,QAAQ;AAC1B,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,YAAY;AACxB,WAAK,QAAQ;AAAA,IACf;AACA,UAAM,QAAQ;AAAA,EAChB;AAAA,EA+BQ,UAAU;AAChB,SAAK,SAAS;AACd,SAAK,iBAAiB,KAAK;AAC3B,SAAK,QAAQ,KAAK;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKQ,QAAQ,IAAa;AAC3B,UAAM,cAAc,KAAK,IAAI,KAAK,aAAa,EAAE;AACjD,QAAI,GAAI,MAAK,OAAO,MAAM,YAAY,mBAAmB,KAAK,WAAW;AAAA,QACpE,MAAK,OAAO,MAAM,eAAe,iBAAiB;AACvD,eAAW,MAAM,CAAC,KAAK,IAAI,KAAK,MAAM,EAAG,KAAI,CAAC,GAAG,aAAa,OAAO,EAAG,IAAG,gBAAgB,OAAO;AAAA,EACpG;AAAA;AAAA,EAGQ,YAAY;AAClB,iBAAa,KAAK,QAAQ;AAC1B,UAAM,SAAS,KAAK,OAAO,OAAO;AAClC,QAAI,WAAW,KAAK,OAAQ;AAC5B,UAAM,CAAC,QAAQ,KAAK,IAAI,SAAS,CAAC,KAAK,MAAM,KAAK,QAAQ,UAAU,IAAa,CAAC,KAAK,OAAO,KAAK,QAAQ,SAAS;AACpH,SAAK,WAAW,WAAW,QAAQ,KAAK;AAAA,EAC1C;AAAA,EAEQ,MAAM,IAAyB;AACrC,SAAK,OAAO,IAAI,EAAE;AAClB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEQ,SAAS,IAAyB;AACxC,SAAK,OAAO,OAAO,EAAE;AACrB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA,EA0BQ,iBAAiB,IAAa;AACpC,UAAM,MAAM,KAAK,GAAG;AACpB,QAAI,GAAI,KAAI,iBAAiB,WAAW,KAAK,gBAAgB,EAAE,SAAS,MAAM,QAAQ,KAAK,QAAQ,OAAO,CAAC;AAAA,QACtG,KAAI,oBAAoB,WAAW,KAAK,gBAAgB,IAAI;AAAA,EACnE;AAAA;AAAA,EAaQ,YAAY,GAAkB;AACpC,MAAE,eAAe;AACjB,MAAE,gBAAgB;AAClB,QAAI,MAAM,UAAU,KAAK,MAAM,EAAG,MAAK,GAAG,MAAM;AAAA,EAClD;AAOF;AAlKa,UAmCJ,MAAM;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|