@expressivecss/expressive 0.15.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 +1807 -1
- package/README.md +9 -8
- package/dist/css/expressive.css +19176 -11958
- 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/fonts/LICENSE-noto-sans-arabic +93 -0
- package/dist/fonts/LICENSE-noto-sans-hebrew +93 -0
- package/dist/fonts/LICENSE-noto-sans-thai +93 -0
- package/dist/fonts/material-symbols-outlined.woff2 +0 -0
- package/dist/fonts/material-symbols-rounded.woff2 +0 -0
- package/dist/fonts/material-symbols-sharp.woff2 +0 -0
- package/dist/fonts/noto-sans-arabic-arabic-400.woff2 +0 -0
- package/dist/fonts/noto-sans-arabic-arabic-500.woff2 +0 -0
- package/dist/fonts/noto-sans-arabic-arabic-700.woff2 +0 -0
- package/dist/fonts/noto-sans-cyrillic-400.woff2 +0 -0
- package/dist/fonts/noto-sans-cyrillic-500.woff2 +0 -0
- package/dist/fonts/noto-sans-cyrillic-700.woff2 +0 -0
- package/dist/fonts/noto-sans-cyrillic-ext-400.woff2 +0 -0
- package/dist/fonts/noto-sans-cyrillic-ext-500.woff2 +0 -0
- package/dist/fonts/noto-sans-cyrillic-ext-700.woff2 +0 -0
- package/dist/fonts/noto-sans-devanagari-400.woff2 +0 -0
- package/dist/fonts/noto-sans-devanagari-500.woff2 +0 -0
- package/dist/fonts/noto-sans-devanagari-700.woff2 +0 -0
- package/dist/fonts/noto-sans-greek-400.woff2 +0 -0
- package/dist/fonts/noto-sans-greek-500.woff2 +0 -0
- package/dist/fonts/noto-sans-greek-700.woff2 +0 -0
- package/dist/fonts/noto-sans-greek-ext-400.woff2 +0 -0
- package/dist/fonts/noto-sans-greek-ext-500.woff2 +0 -0
- package/dist/fonts/noto-sans-greek-ext-700.woff2 +0 -0
- package/dist/fonts/noto-sans-hebrew-hebrew-400.woff2 +0 -0
- package/dist/fonts/noto-sans-hebrew-hebrew-500.woff2 +0 -0
- package/dist/fonts/noto-sans-hebrew-hebrew-700.woff2 +0 -0
- package/dist/fonts/noto-sans-latin-700.woff2 +0 -0
- package/dist/fonts/noto-sans-latin-ext-400.woff2 +0 -0
- package/dist/fonts/noto-sans-latin-ext-500.woff2 +0 -0
- package/dist/fonts/noto-sans-latin-ext-700.woff2 +0 -0
- package/dist/fonts/noto-sans-thai-thai-400.woff2 +0 -0
- package/dist/fonts/noto-sans-thai-thai-500.woff2 +0 -0
- package/dist/fonts/noto-sans-thai-thai-700.woff2 +0 -0
- package/dist/fonts/noto-sans-vietnamese-400.woff2 +0 -0
- package/dist/fonts/noto-sans-vietnamese-500.woff2 +0 -0
- package/dist/fonts/noto-sans-vietnamese-700.woff2 +0 -0
- package/dist/fonts/roboto-cyrillic-400.woff2 +0 -0
- package/dist/fonts/roboto-cyrillic-500.woff2 +0 -0
- package/dist/fonts/roboto-cyrillic-700.woff2 +0 -0
- package/dist/fonts/roboto-cyrillic-ext-400.woff2 +0 -0
- package/dist/fonts/roboto-cyrillic-ext-500.woff2 +0 -0
- package/dist/fonts/roboto-cyrillic-ext-700.woff2 +0 -0
- package/dist/fonts/roboto-greek-400.woff2 +0 -0
- package/dist/fonts/roboto-greek-500.woff2 +0 -0
- package/dist/fonts/roboto-greek-700.woff2 +0 -0
- package/dist/fonts/roboto-greek-ext-400.woff2 +0 -0
- package/dist/fonts/roboto-greek-ext-500.woff2 +0 -0
- package/dist/fonts/roboto-greek-ext-700.woff2 +0 -0
- package/dist/fonts/roboto-latin-700.woff2 +0 -0
- package/dist/fonts/roboto-latin-ext-400.woff2 +0 -0
- package/dist/fonts/roboto-latin-ext-500.woff2 +0 -0
- package/dist/fonts/roboto-latin-ext-700.woff2 +0 -0
- package/dist/fonts/roboto-vietnamese-400.woff2 +0 -0
- package/dist/fonts/roboto-vietnamese-500.woff2 +0 -0
- package/dist/fonts/roboto-vietnamese-700.woff2 +0 -0
- package/dist/js/chunks/chunk-26VUH75M.mjs +102 -0
- package/dist/js/chunks/chunk-26VUH75M.mjs.map +7 -0
- package/dist/js/chunks/chunk-2LFCOGC3.mjs +233 -0
- package/dist/js/chunks/chunk-2LFCOGC3.mjs.map +7 -0
- package/dist/js/chunks/{chunk-DXGRXYYL.mjs → chunk-36GELQGX.mjs} +29 -46
- package/dist/js/chunks/chunk-36GELQGX.mjs.map +7 -0
- package/dist/js/chunks/{chunk-74MXKKLN.mjs → chunk-3FKWIRHW.mjs} +15 -29
- package/dist/js/chunks/chunk-3FKWIRHW.mjs.map +7 -0
- package/dist/js/chunks/chunk-3KF65KGL.mjs +209 -0
- package/dist/js/chunks/chunk-3KF65KGL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-KVJAVDBC.mjs → chunk-3KLZRQZI.mjs} +88 -116
- package/dist/js/chunks/chunk-3KLZRQZI.mjs.map +7 -0
- package/dist/js/chunks/{chunk-CK2XCICY.mjs → chunk-3XORNED5.mjs} +3 -11
- package/dist/js/chunks/chunk-3XORNED5.mjs.map +7 -0
- package/dist/js/chunks/chunk-4WBGAQN3.mjs +113 -0
- package/dist/js/chunks/chunk-4WBGAQN3.mjs.map +7 -0
- package/dist/js/chunks/{chunk-FM5CZOUB.mjs → chunk-5F4URJHL.mjs} +19 -30
- package/dist/js/chunks/chunk-5F4URJHL.mjs.map +7 -0
- package/dist/js/chunks/chunk-67UNY7RH.mjs +299 -0
- package/dist/js/chunks/chunk-67UNY7RH.mjs.map +7 -0
- package/dist/js/chunks/chunk-7CXNATJS.mjs +97 -0
- package/dist/js/chunks/chunk-7CXNATJS.mjs.map +7 -0
- package/dist/js/chunks/{chunk-UETTGDLI.mjs → chunk-7X44MKEQ.mjs} +43 -48
- package/dist/js/chunks/chunk-7X44MKEQ.mjs.map +7 -0
- package/dist/js/chunks/chunk-7ZAMOMGY.mjs +440 -0
- package/dist/js/chunks/chunk-7ZAMOMGY.mjs.map +7 -0
- package/dist/js/chunks/chunk-AEG6LOAJ.mjs +54 -0
- package/dist/js/chunks/chunk-AEG6LOAJ.mjs.map +7 -0
- package/dist/js/chunks/chunk-AQNFCJJ5.mjs +135 -0
- package/dist/js/chunks/chunk-AQNFCJJ5.mjs.map +7 -0
- package/dist/js/chunks/chunk-B55LWKBM.mjs +75 -0
- package/dist/js/chunks/chunk-B55LWKBM.mjs.map +7 -0
- package/dist/js/chunks/chunk-BB5VXYXT.mjs +28 -0
- package/dist/js/chunks/chunk-BB5VXYXT.mjs.map +7 -0
- package/dist/js/chunks/chunk-BDATLH3H.mjs +108 -0
- package/dist/js/chunks/chunk-BDATLH3H.mjs.map +7 -0
- package/dist/js/chunks/chunk-CWMQOT4O.mjs +232 -0
- package/dist/js/chunks/chunk-CWMQOT4O.mjs.map +7 -0
- package/dist/js/chunks/chunk-CY2CTOVM.mjs +81 -0
- package/dist/js/chunks/chunk-CY2CTOVM.mjs.map +7 -0
- package/dist/js/chunks/{chunk-NUHMOAOY.mjs → chunk-DWA5UYLJ.mjs} +363 -218
- package/dist/js/chunks/chunk-DWA5UYLJ.mjs.map +7 -0
- package/dist/js/chunks/chunk-EB2V4OKL.mjs +79 -0
- package/dist/js/chunks/chunk-EB2V4OKL.mjs.map +7 -0
- package/dist/js/chunks/chunk-EWO662ZC.mjs +188 -0
- package/dist/js/chunks/chunk-EWO662ZC.mjs.map +7 -0
- package/dist/js/chunks/{chunk-ZX6M7SWO.mjs → chunk-F7LAKFMX.mjs} +320 -141
- package/dist/js/chunks/chunk-F7LAKFMX.mjs.map +7 -0
- package/dist/js/chunks/{chunk-L27Q6ZMI.mjs → chunk-FNIIH2LU.mjs} +20 -33
- package/dist/js/chunks/chunk-FNIIH2LU.mjs.map +7 -0
- package/dist/js/chunks/chunk-GE3YMFS6.mjs +15 -0
- package/dist/js/chunks/chunk-GE3YMFS6.mjs.map +7 -0
- package/dist/js/chunks/chunk-GFWYMWYN.mjs +125 -0
- package/dist/js/chunks/chunk-GFWYMWYN.mjs.map +7 -0
- package/dist/js/chunks/chunk-GNRSYMVH.mjs +1 -0
- package/dist/js/chunks/chunk-H5ISU45X.mjs +87 -0
- package/dist/js/chunks/chunk-H5ISU45X.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GJL6GCIU.mjs → chunk-H6YIKFAQ.mjs} +311 -186
- package/dist/js/chunks/chunk-H6YIKFAQ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-BGZLF6JZ.mjs → chunk-HEH7E3KO.mjs} +155 -35
- package/dist/js/chunks/chunk-HEH7E3KO.mjs.map +7 -0
- package/dist/js/chunks/chunk-HQRLBTNM.mjs +152 -0
- package/dist/js/chunks/chunk-HQRLBTNM.mjs.map +7 -0
- package/dist/js/chunks/chunk-I2F7MLUU.mjs +137 -0
- package/dist/js/chunks/chunk-I2F7MLUU.mjs.map +7 -0
- package/dist/js/chunks/chunk-IQOTGGHX.mjs +797 -0
- package/dist/js/chunks/chunk-IQOTGGHX.mjs.map +7 -0
- package/dist/js/chunks/chunk-JH3YWKA6.mjs +225 -0
- package/dist/js/chunks/chunk-JH3YWKA6.mjs.map +7 -0
- package/dist/js/chunks/chunk-JOLJAYIJ.mjs +7 -0
- package/dist/js/chunks/chunk-JOLJAYIJ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-VGNYF6FB.mjs → chunk-KOTGMCMI.mjs} +116 -24
- package/dist/js/chunks/chunk-KOTGMCMI.mjs.map +7 -0
- package/dist/js/chunks/{chunk-LQWUDNHZ.mjs → chunk-LC4O5LFS.mjs} +21 -45
- package/dist/js/chunks/chunk-LC4O5LFS.mjs.map +7 -0
- package/dist/js/chunks/chunk-LEF33SCP.mjs +127 -0
- package/dist/js/chunks/chunk-LEF33SCP.mjs.map +7 -0
- package/dist/js/chunks/{chunk-PDG64UHF.mjs → chunk-LFORZRPH.mjs} +21 -23
- package/dist/js/chunks/chunk-LFORZRPH.mjs.map +7 -0
- package/dist/js/chunks/chunk-LWLNV5EC.mjs +451 -0
- package/dist/js/chunks/chunk-LWLNV5EC.mjs.map +7 -0
- package/dist/js/chunks/chunk-LXRHUQAX.mjs +491 -0
- package/dist/js/chunks/chunk-LXRHUQAX.mjs.map +7 -0
- package/dist/js/chunks/{chunk-SFI2U4YW.mjs → chunk-MA2SZZFB.mjs} +82 -111
- package/dist/js/chunks/chunk-MA2SZZFB.mjs.map +7 -0
- package/dist/js/chunks/chunk-MDBZAMIV.mjs +121 -0
- package/dist/js/chunks/chunk-MDBZAMIV.mjs.map +7 -0
- package/dist/js/chunks/chunk-NODZ5VAD.mjs +75 -0
- package/dist/js/chunks/chunk-NODZ5VAD.mjs.map +7 -0
- package/dist/js/chunks/chunk-O2WJB6TH.mjs +365 -0
- package/dist/js/chunks/chunk-O2WJB6TH.mjs.map +7 -0
- package/dist/js/chunks/chunk-PCABY5BN.mjs +35 -0
- package/dist/js/chunks/chunk-PCABY5BN.mjs.map +7 -0
- package/dist/js/chunks/chunk-PWKYVMND.mjs +120 -0
- package/dist/js/chunks/chunk-PWKYVMND.mjs.map +7 -0
- package/dist/js/chunks/{chunk-SMY7GJSS.mjs → chunk-QHZZT7YO.mjs} +66 -38
- package/dist/js/chunks/chunk-QHZZT7YO.mjs.map +7 -0
- package/dist/js/chunks/chunk-QND56EW2.mjs +439 -0
- package/dist/js/chunks/chunk-QND56EW2.mjs.map +7 -0
- package/dist/js/chunks/chunk-QNODAANY.mjs +376 -0
- package/dist/js/chunks/chunk-QNODAANY.mjs.map +7 -0
- package/dist/js/chunks/{chunk-KHXZ2A4K.mjs → chunk-QRO5FV3I.mjs} +156 -73
- package/dist/js/chunks/chunk-QRO5FV3I.mjs.map +7 -0
- package/dist/js/chunks/chunk-R7A7JRC5.mjs +440 -0
- package/dist/js/chunks/chunk-R7A7JRC5.mjs.map +7 -0
- package/dist/js/chunks/chunk-RKG2CBFE.mjs +74 -0
- package/dist/js/chunks/chunk-RKG2CBFE.mjs.map +7 -0
- package/dist/js/chunks/{chunk-XAEAEHIX.mjs → chunk-RSNS5OYS.mjs} +38 -25
- package/dist/js/chunks/chunk-RSNS5OYS.mjs.map +7 -0
- package/dist/js/chunks/{chunk-X4ISMKE2.mjs → chunk-RUDYMEJ3.mjs} +7 -6
- package/dist/js/chunks/chunk-RUDYMEJ3.mjs.map +7 -0
- package/dist/js/chunks/chunk-STJR62SU.mjs +161 -0
- package/dist/js/chunks/chunk-STJR62SU.mjs.map +7 -0
- package/dist/js/chunks/chunk-SUSD4UTN.mjs +220 -0
- package/dist/js/chunks/chunk-SUSD4UTN.mjs.map +7 -0
- package/dist/js/chunks/{chunk-5CEAOLUA.mjs → chunk-SYBOA5HC.mjs} +26 -48
- package/dist/js/chunks/chunk-SYBOA5HC.mjs.map +7 -0
- package/dist/js/chunks/chunk-T4MOBP3J.mjs +108 -0
- package/dist/js/chunks/chunk-T4MOBP3J.mjs.map +7 -0
- package/dist/js/chunks/chunk-TM7HPGTV.mjs +342 -0
- package/dist/js/chunks/chunk-TM7HPGTV.mjs.map +7 -0
- package/dist/js/chunks/{chunk-C6CHEWYP.mjs → chunk-TMQDZSDC.mjs} +71 -35
- package/dist/js/chunks/chunk-TMQDZSDC.mjs.map +7 -0
- package/dist/js/chunks/chunk-TVSX5YA2.mjs +48 -0
- package/dist/js/chunks/chunk-TVSX5YA2.mjs.map +7 -0
- package/dist/js/chunks/chunk-UHO5CV6K.mjs +80 -0
- package/dist/js/chunks/chunk-UHO5CV6K.mjs.map +7 -0
- package/dist/js/chunks/chunk-UKCNELUN.mjs +223 -0
- package/dist/js/chunks/chunk-UKCNELUN.mjs.map +7 -0
- package/dist/js/chunks/chunk-UKQK5GWR.mjs +167 -0
- package/dist/js/chunks/chunk-UKQK5GWR.mjs.map +7 -0
- package/dist/js/chunks/{chunk-TSZYSW7F.mjs → chunk-UTSLYQ65.mjs} +21 -48
- package/dist/js/chunks/chunk-UTSLYQ65.mjs.map +7 -0
- package/dist/js/chunks/chunk-VS5OJBOD.mjs +108 -0
- package/dist/js/chunks/chunk-VS5OJBOD.mjs.map +7 -0
- package/dist/js/chunks/chunk-VZMROW5A.mjs +759 -0
- package/dist/js/chunks/chunk-VZMROW5A.mjs.map +7 -0
- package/dist/js/chunks/chunk-W6FAL3TI.mjs +38 -0
- package/dist/js/chunks/chunk-W6FAL3TI.mjs.map +7 -0
- package/dist/js/chunks/chunk-XB6Y7P5W.mjs +69 -0
- package/dist/js/chunks/chunk-XB6Y7P5W.mjs.map +7 -0
- package/dist/js/chunks/chunk-XDAMOMVD.mjs +226 -0
- package/dist/js/chunks/chunk-XDAMOMVD.mjs.map +7 -0
- package/dist/js/chunks/{chunk-WDK4T63U.mjs → chunk-XJPMW5SP.mjs} +247 -172
- package/dist/js/chunks/chunk-XJPMW5SP.mjs.map +7 -0
- package/dist/js/chunks/{chunk-KUFHW3DS.mjs → chunk-YKANQILZ.mjs} +16 -21
- package/dist/js/chunks/chunk-YKANQILZ.mjs.map +7 -0
- package/dist/js/chunks/chunk-YLZOJLDI.mjs +175 -0
- package/dist/js/chunks/chunk-YLZOJLDI.mjs.map +7 -0
- package/dist/js/chunks/chunk-ZK7YY322.mjs +514 -0
- package/dist/js/chunks/chunk-ZK7YY322.mjs.map +7 -0
- package/dist/js/expressive.cjs +10266 -3628
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +10266 -3628
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +23 -22
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +181 -69
- package/dist/js/expressive.mjs.map +2 -2
- package/dist/js/internal/behaviors/bottomSheets.mjs +4 -3
- package/dist/js/internal/behaviors/copy.mjs +9 -0
- package/dist/js/internal/behaviors/copy.mjs.map +7 -0
- package/dist/js/internal/behaviors/dataTables.mjs +8 -0
- package/dist/js/internal/behaviors/dataTables.mjs.map +7 -0
- 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 +8 -0
- package/dist/js/internal/behaviors/imageCompare.mjs.map +7 -0
- package/dist/js/internal/behaviors/lists.mjs +8 -0
- package/dist/js/internal/behaviors/lists.mjs.map +7 -0
- package/dist/js/internal/behaviors/paneResize.mjs +8 -0
- package/dist/js/internal/behaviors/paneResize.mjs.map +7 -0
- package/dist/js/internal/behaviors/sheetDrag.mjs +7 -2
- package/dist/js/internal/behaviors/sideSheets.mjs +4 -3
- package/dist/js/internal/behaviors/sortable.mjs +8 -0
- package/dist/js/internal/behaviors/sortable.mjs.map +7 -0
- package/dist/js/internal/behaviors/theme.mjs +8 -0
- package/dist/js/internal/behaviors/theme.mjs.map +7 -0
- package/dist/js/internal/behaviors/tour.mjs +8 -0
- package/dist/js/internal/behaviors/tour.mjs.map +7 -0
- package/dist/js/internal/behaviors/transferList.mjs +8 -0
- package/dist/js/internal/behaviors/transferList.mjs.map +7 -0
- package/dist/js/internal/components/appBar.mjs +3 -2
- package/dist/js/internal/components/autocomplete.mjs +5 -4
- package/dist/js/internal/components/backToTop.mjs +9 -0
- package/dist/js/internal/components/backToTop.mjs.map +7 -0
- package/dist/js/internal/components/barChart.mjs +5 -4
- package/dist/js/internal/components/buttonGroup.mjs +3 -2
- package/dist/js/internal/components/buttons.mjs +3 -3
- package/dist/js/internal/components/cards.mjs +3 -3
- package/dist/js/internal/components/carousel.mjs +3 -3
- package/dist/js/internal/components/cascader.mjs +10 -0
- package/dist/js/internal/components/cascader.mjs.map +7 -0
- package/dist/js/internal/components/characterCounter.mjs +3 -2
- package/dist/js/internal/components/chips.mjs +7 -5
- package/dist/js/internal/components/colorPicker.mjs +9 -0
- package/dist/js/internal/components/colorPicker.mjs.map +7 -0
- package/dist/js/internal/components/columnChart.mjs +4 -3
- package/dist/js/internal/components/commandPalette.mjs +3 -3
- package/dist/js/internal/components/confetti.mjs +3 -2
- package/dist/js/internal/components/currencyInput.mjs +9 -0
- package/dist/js/internal/components/currencyInput.mjs.map +7 -0
- package/dist/js/internal/components/datepicker.mjs +12 -8
- package/dist/js/internal/components/expandingCard.mjs +3 -3
- package/dist/js/internal/components/funnelChart.mjs +10 -0
- package/dist/js/internal/components/funnelChart.mjs.map +7 -0
- package/dist/js/internal/components/heatmapChart.mjs +4 -3
- package/dist/js/internal/components/hoverCard.mjs +9 -0
- package/dist/js/internal/components/hoverCard.mjs.map +7 -0
- package/dist/js/internal/components/index.mjs +131 -65
- package/dist/js/internal/components/inputMask.mjs +9 -0
- package/dist/js/internal/components/inputMask.mjs.map +7 -0
- 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 +41 -4
- package/dist/js/internal/components/loadingOverlay.mjs +9 -0
- package/dist/js/internal/components/loadingOverlay.mjs.map +7 -0
- 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 +10 -0
- package/dist/js/internal/components/menubar.mjs.map +7 -0
- package/dist/js/internal/components/messageScroller.mjs +3 -3
- package/dist/js/internal/components/mixedChart.mjs +5 -4
- package/dist/js/internal/components/navigationRail.mjs +3 -2
- package/dist/js/internal/components/particles.mjs +3 -2
- package/dist/js/internal/components/pieChart.mjs +4 -3
- package/dist/js/internal/components/pullToRefresh.mjs +9 -0
- package/dist/js/internal/components/pullToRefresh.mjs.map +7 -0
- package/dist/js/internal/components/questionnaire.mjs +3 -3
- package/dist/js/internal/components/radarChart.mjs +4 -3
- package/dist/js/internal/components/radialChart.mjs +4 -3
- package/dist/js/internal/components/registry.mjs +60 -41
- package/dist/js/internal/components/richTextEditor.mjs +3 -3
- package/dist/js/internal/components/sankeyChart.mjs +10 -0
- package/dist/js/internal/components/sankeyChart.mjs.map +7 -0
- package/dist/js/internal/components/scatterChart.mjs +10 -0
- package/dist/js/internal/components/scatterChart.mjs.map +7 -0
- package/dist/js/internal/components/scrollspy.mjs +3 -2
- package/dist/js/internal/components/select.mjs +5 -4
- package/dist/js/internal/components/showMore.mjs +9 -0
- package/dist/js/internal/components/showMore.mjs.map +7 -0
- 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 +9 -0
- package/dist/js/internal/components/swipeActions.mjs.map +7 -0
- package/dist/js/internal/components/tabs.mjs +3 -4
- package/dist/js/internal/components/timepicker.mjs +5 -4
- package/dist/js/internal/components/tooltip.mjs +3 -3
- package/dist/js/internal/components/treeSelect.mjs +14 -0
- package/dist/js/internal/components/treeSelect.mjs.map +7 -0
- package/dist/js/internal/components/treemapChart.mjs +10 -0
- package/dist/js/internal/components/treemapChart.mjs.map +7 -0
- package/dist/js/internal/core/component.mjs +6 -3
- package/dist/js/internal/core/formControl.mjs +12 -0
- package/dist/js/internal/core/formControl.mjs.map +7 -0
- package/dist/js/internal/core/imageURL.mjs +7 -0
- package/dist/js/internal/core/imageURL.mjs.map +7 -0
- package/dist/js/internal/core/spring.mjs +11 -0
- package/dist/js/internal/core/spring.mjs.map +7 -0
- package/dist/js/internal/core/utils.mjs +21 -3
- package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +2 -2
- package/dist/js/internal/plugins/modalDisplayPlugin.mjs +13 -0
- package/dist/js/internal/plugins/modalDisplayPlugin.mjs.map +7 -0
- package/dist/js/modular.mjs +172 -69
- package/dist/types/behaviors/bottomSheets.d.ts +23 -5
- package/dist/types/behaviors/copy.d.ts +18 -0
- package/dist/types/behaviors/dataTables.d.ts +125 -0
- package/dist/types/behaviors/dialogs.d.ts +27 -1
- package/dist/types/behaviors/forms.d.ts +70 -4
- package/dist/types/behaviors/imageCompare.d.ts +13 -0
- package/dist/types/behaviors/lists.d.ts +12 -0
- package/dist/types/behaviors/paneResize.d.ts +29 -0
- package/dist/types/behaviors/sheetDrag.d.ts +18 -0
- package/dist/types/behaviors/sideSheets.d.ts +1 -1
- package/dist/types/behaviors/sortable.d.ts +28 -0
- package/dist/types/behaviors/theme.d.ts +22 -0
- package/dist/types/behaviors/tour.d.ts +36 -0
- package/dist/types/behaviors/transferList.d.ts +53 -0
- package/dist/types/components/appBar.d.ts +5 -6
- package/dist/types/components/autocomplete.d.ts +105 -20
- package/dist/types/components/backToTop.d.ts +36 -0
- package/dist/types/components/barChart.d.ts +3 -6
- package/dist/types/components/buttonGroup.d.ts +2 -4
- package/dist/types/components/buttons.d.ts +5 -5
- package/dist/types/components/cards.d.ts +3 -16
- package/dist/types/components/carousel.d.ts +16 -15
- package/dist/types/components/cascader.d.ts +130 -0
- package/dist/types/components/characterCounter.d.ts +2 -15
- package/dist/types/components/chips.d.ts +80 -19
- package/dist/types/components/colorPicker.d.ts +56 -0
- package/dist/types/components/columnChart.d.ts +23 -10
- package/dist/types/components/commandPalette.d.ts +11 -16
- package/dist/types/components/confetti.d.ts +2 -4
- package/dist/types/components/currencyInput.d.ts +60 -0
- package/dist/types/components/datepicker.d.ts +107 -56
- package/dist/types/components/expandingCard.d.ts +4 -6
- package/dist/types/components/funnelChart.d.ts +35 -0
- package/dist/types/components/heatmapChart.d.ts +42 -8
- package/dist/types/components/hoverCard.d.ts +59 -0
- package/dist/types/components/index.d.ts +16 -1
- package/dist/types/components/inputMask.d.ts +28 -0
- package/dist/types/components/keypad.d.ts +38 -6
- package/dist/types/components/lightbox.d.ts +14 -20
- package/dist/types/components/lineChart.d.ts +212 -12
- package/dist/types/components/loadingOverlay.d.ts +42 -0
- package/dist/types/components/mapView.d.ts +138 -27
- package/dist/types/components/menu.d.ts +74 -22
- package/dist/types/components/menubar.d.ts +37 -0
- package/dist/types/components/messageScroller.d.ts +2 -14
- package/dist/types/components/mixedChart.d.ts +15 -6
- package/dist/types/components/navigationRail.d.ts +16 -5
- package/dist/types/components/particles.d.ts +22 -5
- package/dist/types/components/pieChart.d.ts +33 -9
- package/dist/types/components/pullToRefresh.d.ts +80 -0
- package/dist/types/components/questionnaire.d.ts +58 -16
- package/dist/types/components/radarChart.d.ts +10 -6
- package/dist/types/components/radialChart.d.ts +58 -7
- package/dist/types/components/registry.d.ts +73 -3
- package/dist/types/components/richTextEditor.d.ts +45 -22
- package/dist/types/components/sankeyChart.d.ts +72 -0
- package/dist/types/components/scatterChart.d.ts +102 -0
- package/dist/types/components/scrollspy.d.ts +3 -5
- package/dist/types/components/select.d.ts +44 -33
- package/dist/types/components/showMore.d.ts +53 -0
- package/dist/types/components/slider.d.ts +2 -15
- package/dist/types/components/snackbar.d.ts +68 -1
- package/dist/types/components/swipeActions.d.ts +81 -0
- package/dist/types/components/tabs.d.ts +92 -30
- package/dist/types/components/timepicker.d.ts +128 -27
- package/dist/types/components/tooltip.d.ts +57 -21
- package/dist/types/components/treeSelect.d.ts +106 -0
- package/dist/types/components/treemapChart.d.ts +56 -0
- package/dist/types/core/component.d.ts +49 -25
- package/dist/types/core/formControl.d.ts +21 -0
- package/dist/types/core/imageURL.d.ts +2 -0
- package/dist/types/core/spring.d.ts +20 -0
- package/dist/types/core/utils.d.ts +123 -72
- package/dist/types/modular.d.ts +33 -1
- package/dist/types/plugins/dockedDisplayPlugin.d.ts +10 -8
- package/dist/types/plugins/modalDisplayPlugin.d.ts +39 -0
- package/package.json +17 -13
- package/src/sass/README.md +27 -18
- package/src/sass/abstracts/_elevation.scss +13 -7
- package/src/sass/abstracts/_index.scss +1 -0
- package/src/sass/abstracts/_mixins.scss +864 -78
- package/src/sass/abstracts/_spring.scss +63 -0
- package/src/sass/abstracts/_variables.scss +64 -21
- package/src/sass/base/_fonts.scss +61 -48
- package/src/sass/base/_global.scss +104 -24
- package/src/sass/base/_index.scss +2 -0
- package/src/sass/base/_normalize.scss +59 -114
- package/src/sass/base/_print.scss +21 -0
- package/src/sass/base/_prose.scss +68 -0
- package/src/sass/base/_typography.scss +9 -5
- package/src/sass/components/_accordion.scss +10 -19
- package/src/sass/components/_alert.scss +102 -0
- package/src/sass/components/_aura.scss +9 -3
- package/src/sass/components/_avatar.scss +3 -3
- package/src/sass/components/_back-to-top.scss +38 -0
- package/src/sass/components/_badges.scss +6 -5
- package/src/sass/components/_bar-chart.scss +31 -90
- package/src/sass/components/_bottom-sheet.scss +51 -16
- package/src/sass/components/_breadcrumb.scss +8 -7
- package/src/sass/components/_button-groups.scss +30 -63
- package/src/sass/components/_buttons.scss +137 -94
- package/src/sass/components/_calendar.scss +244 -0
- package/src/sass/components/_cards.scss +36 -44
- package/src/sass/components/_carousel.scss +37 -113
- package/src/sass/components/_cascader.scss +131 -0
- package/src/sass/components/_chips.scss +36 -46
- package/src/sass/components/_column-chart.scss +15 -26
- package/src/sass/components/_command-palette.scss +4 -7
- package/src/sass/components/_confetti.scss +1 -4
- package/src/sass/components/_countdown.scss +1 -1
- package/src/sass/components/_data-table.scss +172 -25
- package/src/sass/components/_datepicker.scss +54 -40
- package/src/sass/components/_description-list.scss +85 -0
- package/src/sass/components/_dialog.scss +48 -55
- package/src/sass/components/_docked-display.scss +1 -3
- package/src/sass/components/_drag-handle.scss +16 -20
- package/src/sass/components/_expanding-card.scss +21 -14
- package/src/sass/components/_fab-menu.scss +43 -39
- package/src/sass/components/_funnel-chart.scss +63 -0
- package/src/sass/components/_heatmap-chart.scss +114 -29
- package/src/sass/components/_icon-buttons.scss +8 -11
- package/src/sass/components/_icons-material-design.scss +2 -2
- package/src/sass/components/_image-compare.scss +108 -0
- package/src/sass/components/_index.scss +20 -0
- package/src/sass/components/_keypad.scss +39 -19
- package/src/sass/components/_kpi.scss +6 -11
- package/src/sass/components/_lightbox.scss +24 -13
- package/src/sass/components/_line-chart.scss +9 -63
- package/src/sass/components/_list.scss +59 -14
- package/src/sass/components/_loading-indicator.scss +1 -0
- package/src/sass/components/_loading-overlay.scss +105 -0
- package/src/sass/components/_map.scss +37 -11
- package/src/sass/components/_marquee.scss +4 -3
- package/src/sass/components/_mega-menu.scss +128 -0
- package/src/sass/components/_menu.scss +146 -127
- package/src/sass/components/_menubar.scss +47 -0
- package/src/sass/components/_message-scroller.scss +2 -2
- package/src/sass/components/_message.scss +3 -3
- package/src/sass/components/_mixed-chart.scss +27 -35
- package/src/sass/components/_modal-display.scss +21 -0
- package/src/sass/components/_navbar.scss +45 -36
- package/src/sass/components/_navigation-bar.scss +12 -77
- package/src/sass/components/_navigation-rail.scss +161 -92
- package/src/sass/components/_org-chart.scss +192 -0
- package/src/sass/components/_page-footer.scss +2 -4
- package/src/sass/components/_pagination.scss +9 -27
- package/src/sass/components/_panes.scss +35 -42
- package/src/sass/components/_particles.scss +1 -4
- package/src/sass/components/_pie-chart.scss +86 -68
- package/src/sass/components/_popover.scss +18 -5
- package/src/sass/components/_progress.scss +183 -44
- package/src/sass/components/_pull-to-refresh.scss +90 -0
- package/src/sass/components/_questionnaire.scss +74 -3
- package/src/sass/components/_radar-chart.scss +40 -42
- package/src/sass/components/_radial-chart.scss +108 -46
- package/src/sass/components/_rich-text-editor.scss +2 -2
- package/src/sass/components/_sankey-chart.scss +91 -0
- package/src/sass/components/_scatter-chart.scss +144 -0
- package/src/sass/components/_scrim.scss +0 -2
- package/src/sass/components/_scrollspy.scss +0 -2
- package/src/sass/components/_search.scss +27 -26
- package/src/sass/components/_show-more.scss +8 -0
- package/src/sass/components/_side-sheet.scss +32 -51
- package/src/sass/components/_skeleton.scss +26 -19
- package/src/sass/components/_snackbar.scss +25 -21
- package/src/sass/components/_split-button.scss +5 -5
- package/src/sass/components/_stat.scss +3 -8
- package/src/sass/components/_stepper.scss +1 -1
- package/src/sass/components/_swipe-actions.scss +71 -0
- package/src/sass/components/_table_of_contents.scss +1 -3
- package/src/sass/components/_tabs.scss +49 -46
- package/src/sass/components/_timeline.scss +12 -12
- package/src/sass/components/_timepicker.scss +111 -79
- package/src/sass/components/_toolbar.scss +36 -47
- package/src/sass/components/_tooltip.scss +25 -12
- package/src/sass/components/_tour.scss +89 -0
- package/src/sass/components/_transfer-list.scss +73 -0
- package/src/sass/components/_transitions.scss +4 -4
- package/src/sass/components/_tree.scss +7 -32
- package/src/sass/components/_treemap-chart.scss +98 -0
- package/src/sass/components/forms/_checkboxes.scss +107 -44
- package/src/sass/components/forms/_color-picker.scss +135 -0
- package/src/sass/components/forms/_color-swatches.scss +85 -0
- package/src/sass/components/forms/_drop-zone.scss +16 -13
- package/src/sass/components/forms/_fieldset.scss +4 -7
- package/src/sass/components/forms/_file-input.scss +12 -8
- package/src/sass/components/forms/_index.scss +3 -1
- package/src/sass/components/forms/_input-fields.scss +271 -90
- package/src/sass/components/forms/_radio-buttons.scss +34 -117
- package/src/sass/components/forms/_rating.scss +2 -32
- package/src/sass/components/forms/_select.scss +198 -20
- package/src/sass/components/forms/_slider.scss +92 -98
- package/src/sass/components/forms/_switches.scss +62 -180
- package/src/sass/custom.scss +10 -1
- package/src/sass/expressive.scss +3 -63
- package/src/sass/tokens/_contrast.scss +94 -0
- package/src/sass/tokens/_elevation.scss +16 -0
- package/src/sass/tokens/_index.scss +5 -0
- package/src/sass/tokens/_motion.scss +109 -0
- package/src/sass/tokens/_reference.scss +72 -141
- package/src/sass/tokens/_shape.scss +38 -0
- package/src/sass/tokens/_stacking.scss +27 -0
- package/src/sass/tokens/_state.scss +0 -2
- package/src/sass/tokens/_theme.scss +10 -1
- package/src/sass/tokens/_vibrant.scss +2 -5
- package/src/sass/utilities/_defer-render.scss +17 -0
- package/src/sass/utilities/_helpers.scss +184 -27
- package/src/sass/utilities/_index.scss +1 -0
- package/src/sass/utilities/_scroll-area.scss +0 -2
- package/src/sass/utilities/_spacing.scss +52 -34
- package/src/sass/utilities/_typescale.scss +8 -1
- package/src/sass/utilities/_visibility.scss +46 -77
- package/src/sass/utilities/_z-depth.scss +7 -4
- package/dist/js/chunks/chunk-33QVDDGR.mjs +0 -270
- package/dist/js/chunks/chunk-33QVDDGR.mjs.map +0 -7
- package/dist/js/chunks/chunk-45FER6RI.mjs +0 -59
- package/dist/js/chunks/chunk-45FER6RI.mjs.map +0 -7
- package/dist/js/chunks/chunk-5CEAOLUA.mjs.map +0 -7
- package/dist/js/chunks/chunk-6VATUZC6.mjs +0 -295
- package/dist/js/chunks/chunk-6VATUZC6.mjs.map +0 -7
- package/dist/js/chunks/chunk-74MXKKLN.mjs.map +0 -7
- package/dist/js/chunks/chunk-AIURVCG6.mjs +0 -55
- package/dist/js/chunks/chunk-AIURVCG6.mjs.map +0 -7
- package/dist/js/chunks/chunk-BGZLF6JZ.mjs.map +0 -7
- package/dist/js/chunks/chunk-C6CHEWYP.mjs.map +0 -7
- package/dist/js/chunks/chunk-CK2XCICY.mjs.map +0 -7
- package/dist/js/chunks/chunk-CXXM2L4F.mjs +0 -344
- package/dist/js/chunks/chunk-CXXM2L4F.mjs.map +0 -7
- package/dist/js/chunks/chunk-DXGRXYYL.mjs.map +0 -7
- package/dist/js/chunks/chunk-FM5CZOUB.mjs.map +0 -7
- package/dist/js/chunks/chunk-GJL6GCIU.mjs.map +0 -7
- package/dist/js/chunks/chunk-K3HZMFMD.mjs +0 -135
- package/dist/js/chunks/chunk-K3HZMFMD.mjs.map +0 -7
- package/dist/js/chunks/chunk-KHXZ2A4K.mjs.map +0 -7
- package/dist/js/chunks/chunk-KQACNQ22.mjs +0 -7
- package/dist/js/chunks/chunk-KQACNQ22.mjs.map +0 -7
- package/dist/js/chunks/chunk-KUFHW3DS.mjs.map +0 -7
- package/dist/js/chunks/chunk-KVJAVDBC.mjs.map +0 -7
- package/dist/js/chunks/chunk-L27Q6ZMI.mjs.map +0 -7
- package/dist/js/chunks/chunk-LQWUDNHZ.mjs.map +0 -7
- package/dist/js/chunks/chunk-M372EDXD.mjs +0 -322
- package/dist/js/chunks/chunk-M372EDXD.mjs.map +0 -7
- package/dist/js/chunks/chunk-M3MURWMB.mjs +0 -82
- package/dist/js/chunks/chunk-M3MURWMB.mjs.map +0 -7
- package/dist/js/chunks/chunk-NUHMOAOY.mjs.map +0 -7
- package/dist/js/chunks/chunk-OWG3LMUL.mjs +0 -169
- package/dist/js/chunks/chunk-OWG3LMUL.mjs.map +0 -7
- package/dist/js/chunks/chunk-PD6HYHAE.mjs +0 -48
- package/dist/js/chunks/chunk-PD6HYHAE.mjs.map +0 -7
- package/dist/js/chunks/chunk-PDG64UHF.mjs.map +0 -7
- package/dist/js/chunks/chunk-PO3AXVR3.mjs +0 -546
- package/dist/js/chunks/chunk-PO3AXVR3.mjs.map +0 -7
- package/dist/js/chunks/chunk-QYGK36OG.mjs +0 -181
- package/dist/js/chunks/chunk-QYGK36OG.mjs.map +0 -7
- package/dist/js/chunks/chunk-SFI2U4YW.mjs.map +0 -7
- package/dist/js/chunks/chunk-SMY7GJSS.mjs.map +0 -7
- package/dist/js/chunks/chunk-TCCA2HDG.mjs +0 -414
- package/dist/js/chunks/chunk-TCCA2HDG.mjs.map +0 -7
- package/dist/js/chunks/chunk-TSZYSW7F.mjs.map +0 -7
- package/dist/js/chunks/chunk-UAZSDUVP.mjs +0 -90
- package/dist/js/chunks/chunk-UAZSDUVP.mjs.map +0 -7
- package/dist/js/chunks/chunk-UBRZZWRA.mjs +0 -127
- package/dist/js/chunks/chunk-UBRZZWRA.mjs.map +0 -7
- package/dist/js/chunks/chunk-UCOE7ZDL.mjs +0 -287
- package/dist/js/chunks/chunk-UCOE7ZDL.mjs.map +0 -7
- package/dist/js/chunks/chunk-UETTGDLI.mjs.map +0 -7
- package/dist/js/chunks/chunk-UNCRDLP6.mjs +0 -136
- package/dist/js/chunks/chunk-UNCRDLP6.mjs.map +0 -7
- package/dist/js/chunks/chunk-VGNYF6FB.mjs.map +0 -7
- package/dist/js/chunks/chunk-VGPGBNGL.mjs +0 -68
- package/dist/js/chunks/chunk-VGPGBNGL.mjs.map +0 -7
- package/dist/js/chunks/chunk-VKAUVTQY.mjs +0 -1
- package/dist/js/chunks/chunk-VM4FTS7L.mjs +0 -48
- package/dist/js/chunks/chunk-VM4FTS7L.mjs.map +0 -7
- package/dist/js/chunks/chunk-WDK4T63U.mjs.map +0 -7
- package/dist/js/chunks/chunk-WOCCTVUF.mjs +0 -185
- package/dist/js/chunks/chunk-WOCCTVUF.mjs.map +0 -7
- package/dist/js/chunks/chunk-WQYN5L4E.mjs +0 -107
- package/dist/js/chunks/chunk-WQYN5L4E.mjs.map +0 -7
- package/dist/js/chunks/chunk-X4ISMKE2.mjs.map +0 -7
- package/dist/js/chunks/chunk-XAEAEHIX.mjs.map +0 -7
- package/dist/js/chunks/chunk-ZX6M7SWO.mjs.map +0 -7
- /package/dist/js/chunks/{chunk-VKAUVTQY.mjs.map → chunk-GNRSYMVH.mjs.map} +0 -0
|
@@ -1,30 +1,67 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LineChart
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IQOTGGHX.mjs";
|
|
4
4
|
|
|
5
5
|
// src/ts/components/heatmapChart.ts
|
|
6
|
+
function band(level, steps) {
|
|
7
|
+
return Math.sign(level) * Math.min(steps - 1, Math.floor(Math.abs(level) * steps)) / (steps - 1);
|
|
8
|
+
}
|
|
6
9
|
var HeatmapChart = class extends LineChart {
|
|
7
10
|
get _type() {
|
|
8
11
|
return "heatmap-chart";
|
|
9
12
|
}
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
/** Color carries the value, so there is no value axis. */
|
|
14
|
+
get _axis() {
|
|
15
|
+
return false;
|
|
12
16
|
}
|
|
13
|
-
|
|
14
|
-
return
|
|
17
|
+
get _count() {
|
|
18
|
+
return this.labels.length * this.series.length;
|
|
15
19
|
}
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
destroy() {
|
|
21
|
+
this._resizes?.disconnect();
|
|
22
|
+
super.destroy();
|
|
23
|
+
}
|
|
24
|
+
/** Redraws the grid, scrolled where it was. */
|
|
25
|
+
update() {
|
|
26
|
+
const left = this._scroll?.scrollLeft;
|
|
27
|
+
super.update();
|
|
28
|
+
if (this._scroll && left) this._scroll.scrollLeft = left;
|
|
18
29
|
}
|
|
19
30
|
/** Highlights one cell, numbered row by row. Pass -1 to hide the tooltip. */
|
|
20
31
|
show(index) {
|
|
21
32
|
if (!this._tooltip || index === this.activeIndex) return;
|
|
22
|
-
|
|
23
|
-
|
|
33
|
+
this._activate(this._cells[index], index);
|
|
34
|
+
}
|
|
35
|
+
_activate(cell, index) {
|
|
36
|
+
const box = cell ? this._box(cell) : null;
|
|
24
37
|
this._cells[this.activeIndex]?.classList.remove("active");
|
|
25
38
|
this.activeIndex = index;
|
|
26
|
-
this._tooltip.hidden = !
|
|
39
|
+
this._tooltip.hidden = !box;
|
|
40
|
+
if (box) this._fill(cell, index, box);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A cell's left, top and width in the plot, past any scrolling of the
|
|
44
|
+
* grid, and the plot's width. A key can move to a cell scrolled out of a
|
|
45
|
+
* wide grid, so it scrolls into view first.
|
|
46
|
+
*/
|
|
47
|
+
_box(cell) {
|
|
48
|
+
if (this._plot.matches(":focus-visible")) cell.scrollIntoView({ block: "nearest", inline: "nearest" });
|
|
49
|
+
return this._measure(cell);
|
|
50
|
+
}
|
|
51
|
+
_measure(cell) {
|
|
52
|
+
const [box, plot] = [cell.getBoundingClientRect(), this._plot.getBoundingClientRect()];
|
|
53
|
+
return [box.left - plot.left, box.top - plot.top, box.width, this._plot.clientWidth];
|
|
54
|
+
}
|
|
55
|
+
/** Keeps the tooltip on its cell as the grid scrolls, and hides it once the cell scrolls out. */
|
|
56
|
+
_follow(scroll) {
|
|
57
|
+
const cell = this._cells[this.activeIndex];
|
|
27
58
|
if (!cell) return;
|
|
59
|
+
const [view, box] = [scroll.getBoundingClientRect(), cell.getBoundingClientRect()];
|
|
60
|
+
if (box.right <= view.left || box.left >= view.right) this.show(-1);
|
|
61
|
+
else this._position(this._measure(cell));
|
|
62
|
+
}
|
|
63
|
+
/** Marks the cell and fills the tooltip beside it, on the side with more room. */
|
|
64
|
+
_fill(cell, index, [left, top, width, plotWidth]) {
|
|
28
65
|
cell.classList.add("active");
|
|
29
66
|
const columns = this.series.length;
|
|
30
67
|
const [row, series] = [Math.floor(index / columns), this.series[index % columns]];
|
|
@@ -36,6 +73,9 @@ var HeatmapChart = class extends LineChart {
|
|
|
36
73
|
else name.style.setProperty("--level", String(this._levels[index]));
|
|
37
74
|
text.textContent = series.text[row];
|
|
38
75
|
this._tooltip.replaceChildren(title, name, text);
|
|
76
|
+
this._position([left, top, width, plotWidth]);
|
|
77
|
+
}
|
|
78
|
+
_position([left, top, width, plotWidth]) {
|
|
39
79
|
const end = left + width / 2 > plotWidth / 2;
|
|
40
80
|
this._tooltip.classList.toggle("end", end);
|
|
41
81
|
this._tooltip.style.left = `${left + (end ? 0 : width)}px`;
|
|
@@ -73,10 +113,15 @@ var HeatmapChart = class extends LineChart {
|
|
|
73
113
|
const last = this._cells[this._cells.length - 1].getBoundingClientRect();
|
|
74
114
|
const [left, right] = [Math.min(first.left, last.left), Math.max(first.right, last.right)];
|
|
75
115
|
const [x, y] = [e.clientX, e.clientY];
|
|
76
|
-
if (x
|
|
77
|
-
const
|
|
78
|
-
const column =
|
|
79
|
-
return
|
|
116
|
+
if (this._off(x, y, [left, right, first.top, last.bottom])) return -1;
|
|
117
|
+
const band2 = (offset, size, count) => Math.min(count - 1, Math.floor(offset / (size || 1) * count));
|
|
118
|
+
const column = band2(x - left, right - left, columns);
|
|
119
|
+
return band2(y - first.top, last.bottom - first.top, rows) * columns + (this._reversed ? columns - 1 - column : column);
|
|
120
|
+
}
|
|
121
|
+
/** Whether a point is off the cells, or on cells scrolled out of view under the row labels. */
|
|
122
|
+
_off(x, y, [left, right, top, bottom]) {
|
|
123
|
+
const view = this._scroll.getBoundingClientRect();
|
|
124
|
+
return x < Math.max(left, view.left) || x > Math.min(right, view.right) || y < top || y > bottom;
|
|
80
125
|
}
|
|
81
126
|
/**
|
|
82
127
|
* The legend: a gradient from the lowest cell's shade to the highest's,
|
|
@@ -91,11 +136,43 @@ var HeatmapChart = class extends LineChart {
|
|
|
91
136
|
[low.textContent, high.textContent] = this._ends;
|
|
92
137
|
scale.className = "heatmap-chart-scale";
|
|
93
138
|
if (this._reversed) scale.style.setProperty("--heatmap-chart-to", "left");
|
|
94
|
-
|
|
95
|
-
scale.style.setProperty("--
|
|
139
|
+
const [from, to] = this._endLevels;
|
|
140
|
+
scale.style.setProperty("--low", String(from));
|
|
141
|
+
scale.style.setProperty("--high", String(to));
|
|
142
|
+
scale.classList.toggle("diverging", from < 0 && to > 0);
|
|
143
|
+
scale.style.setProperty("--mid", `${-from / (to - from || 1) * 100}%`);
|
|
144
|
+
scale.append(...this._bands().filter((level) => level >= from && level <= to).map((level) => {
|
|
145
|
+
const swatch = document.createElement("span");
|
|
146
|
+
swatch.style.setProperty("--level", String(level));
|
|
147
|
+
return swatch;
|
|
148
|
+
}));
|
|
96
149
|
legend.append(low, scale, high);
|
|
97
150
|
return [legend];
|
|
98
151
|
}
|
|
152
|
+
/** With data-steps, every band's shade from the lowest to the highest; otherwise none. */
|
|
153
|
+
_bands() {
|
|
154
|
+
const steps = this._steps;
|
|
155
|
+
if (!steps) return [];
|
|
156
|
+
return Array.from({ length: 2 * steps - 1 }, (_, k) => (k - steps + 1) / (steps - 1));
|
|
157
|
+
}
|
|
158
|
+
/** The number of bands data-steps asks for, or 0 for a smooth scale. */
|
|
159
|
+
get _steps() {
|
|
160
|
+
const steps = Math.round(this._number("steps") ?? 0);
|
|
161
|
+
return steps > 1 ? steps : 0;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* How a value shades its cell: from 0 at the scale's low end to 1 at its
|
|
165
|
+
* high end, or with data-mid from -1 to 1 either side of that midpoint,
|
|
166
|
+
* as far as the further end. With data-steps the shades fall into bands.
|
|
167
|
+
*/
|
|
168
|
+
_shade(low, high) {
|
|
169
|
+
const option = (name, fallback) => this._number(name) ?? this.options[name] ?? fallback;
|
|
170
|
+
const [min, max, mid] = [option("min", low), option("max", high), this._number("mid")];
|
|
171
|
+
const clamp = (value, floor) => Math.min(1, Math.max(floor, value));
|
|
172
|
+
const level = mid === null ? (value) => clamp((value - min) / (max - min || 1), 0) : (value) => clamp((Math.min(max, Math.max(min, value)) - mid) / (Math.max(max - mid, mid - min) || 1), -1);
|
|
173
|
+
const steps = this._steps;
|
|
174
|
+
return steps ? (value) => band(level(value), steps) : level;
|
|
175
|
+
}
|
|
99
176
|
/**
|
|
100
177
|
* A grid of the row headers and cells, row by row, with the column headers
|
|
101
178
|
* below. Each cell's --level shades it in CSS.
|
|
@@ -109,9 +186,7 @@ var HeatmapChart = class extends LineChart {
|
|
|
109
186
|
if (value < low) [low, this._ends[0]] = [value, series.text[row]];
|
|
110
187
|
if (value > high) [high, this._ends[1]] = [value, series.text[row]];
|
|
111
188
|
}));
|
|
112
|
-
const
|
|
113
|
-
const [min, max] = [option("min") ?? low, option("max") ?? high];
|
|
114
|
-
const shade = (value) => Math.min(1, Math.max(0, (value - min) / (max - min || 1)));
|
|
189
|
+
const shade = this._shade(low, high);
|
|
115
190
|
this._endLevels = [shade(low), shade(high)];
|
|
116
191
|
const grid = document.createElement("div");
|
|
117
192
|
grid.className = "heatmap-chart-grid";
|
|
@@ -128,8 +203,11 @@ var HeatmapChart = class extends LineChart {
|
|
|
128
203
|
const values = this.el.classList.contains("values");
|
|
129
204
|
this._cells = [];
|
|
130
205
|
this._levels = [];
|
|
206
|
+
const [rows, cells] = [document.createElement("div"), document.createElement("div")];
|
|
207
|
+
rows.className = "heatmap-chart-rows";
|
|
208
|
+
cells.className = "heatmap-chart-cells";
|
|
131
209
|
this.labels.forEach((_, row) => {
|
|
132
|
-
|
|
210
|
+
rows.append(span("heatmap-chart-row", label(this._rows[row].cells[0])));
|
|
133
211
|
this.series.forEach((series) => {
|
|
134
212
|
const value = series.values[row];
|
|
135
213
|
const level = value === null ? null : shade(value);
|
|
@@ -138,24 +216,38 @@ var HeatmapChart = class extends LineChart {
|
|
|
138
216
|
else cell.style.setProperty("--level", String(level));
|
|
139
217
|
this._cells.push(cell);
|
|
140
218
|
this._levels.push(level);
|
|
141
|
-
|
|
219
|
+
cells.append(cell);
|
|
142
220
|
});
|
|
143
221
|
});
|
|
144
222
|
const labels = this._header.slice(1, columns + 1).map(label);
|
|
223
|
+
const columnLabels = [];
|
|
145
224
|
labels.forEach((text, column) => {
|
|
146
225
|
if (!text) return;
|
|
147
226
|
let end = column + 1;
|
|
148
227
|
while (end < columns && !labels[end]) end++;
|
|
149
228
|
const element = span("heatmap-chart-column", text);
|
|
150
229
|
element.classList.toggle("run", end > column + 1);
|
|
151
|
-
element.style.gridArea = `${this.labels.length + 1} / ${column +
|
|
152
|
-
|
|
230
|
+
element.style.gridArea = `${this.labels.length + 1} / ${column + 1} / auto / ${end + 1}`;
|
|
231
|
+
cells.append(element);
|
|
232
|
+
columnLabels.push(element);
|
|
153
233
|
});
|
|
234
|
+
this._observeLabels(cells, columnLabels.some((element) => element.classList.contains("run")) ? [] : columnLabels);
|
|
235
|
+
const scroll = this._scroll = document.createElement("div");
|
|
236
|
+
scroll.className = "heatmap-chart-scroll";
|
|
237
|
+
scroll.tabIndex = -1;
|
|
238
|
+
scroll.addEventListener("focus", () => this._plot.focus());
|
|
239
|
+
scroll.addEventListener("scroll", () => this._follow(scroll), { passive: true });
|
|
240
|
+
this._resizes?.disconnect();
|
|
241
|
+
this._resizes = new ResizeObserver(() => this._follow(scroll));
|
|
242
|
+
this._resizes.observe(scroll);
|
|
243
|
+
scroll.append(cells);
|
|
244
|
+
grid.append(rows, scroll);
|
|
154
245
|
return grid;
|
|
155
246
|
}
|
|
156
247
|
};
|
|
248
|
+
HeatmapChart.key = "Expressive_HeatmapChart";
|
|
157
249
|
|
|
158
250
|
export {
|
|
159
251
|
HeatmapChart
|
|
160
252
|
};
|
|
161
|
-
//# sourceMappingURL=chunk-
|
|
253
|
+
//# sourceMappingURL=chunk-KOTGMCMI.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ts/components/heatmapChart.ts"],
|
|
4
|
+
"sourcesContent": ["import { LineChart, LineChartOptions } from './lineChart';\n\nexport type HeatmapChartOptions = LineChartOptions;\n\n/**\n * A shade in one of `steps` bands, each side of zero on a diverging scale:\n * the lowest band is the empty color, and the highest is the full color.\n */\nfunction band(level: number, steps: number) {\n return (Math.sign(level) * Math.min(steps - 1, Math.floor(Math.abs(level) * steps))) / (steps - 1);\n}\n\n/**\n * Heatmap chart. It reads its <table> like LineChart, but draws every cell\n * as a square of the grid, shaded from the lowest value to the highest, with\n * the row headers beside it and the column headers below. A `data-label` on\n * a header cell replaces its text on the grid; an empty one hides it. The\n * tooltip shows one cell, and the arrow keys move round the grid. With\n * `data-mid` the scale diverges either side of that value, and with\n * `data-steps` the shades fall into that many bands.\n *\n * Call `update()` after changing the table, or start it with `watch` or\n * `data-watch`.\n */\nexport class HeatmapChart extends LineChart {\n // No initializers: LineChart's constructor draws before they would run.\n /** Every cell, row by row. */\n private _cells: HTMLElement[];\n /** Each cell's shade from 0 to 1, or -1 to 1 on a diverging scale, or null for a gap. */\n private _levels: (number | null)[];\n /** The text of the lowest and highest cells, for the legend. */\n private _ends: [string, string];\n /** The shades of the lowest and highest cells, where the legend's gradient runs. */\n private _endLevels: [number, number];\n /** The box the cells scroll in, beside the row labels. */\n private _scroll: HTMLElement;\n /** Keeps the tooltip on its cell when the chart changes size. */\n private _resizes: ResizeObserver;\n\n protected get _type() {\n return 'heatmap-chart';\n }\n\n /** Color carries the value, so there is no value axis. */\n protected get _axis() {\n return false;\n }\n\n static key = 'Expressive_HeatmapChart';\n\n protected get _count() {\n return this.labels.length * this.series.length;\n }\n\n destroy() {\n this._resizes?.disconnect();\n super.destroy();\n }\n\n /** Redraws the grid, scrolled where it was. */\n update() {\n const left = this._scroll?.scrollLeft;\n super.update();\n if (this._scroll && left) this._scroll.scrollLeft = left;\n }\n\n /** Highlights one cell, numbered row by row. Pass -1 to hide the tooltip. */\n show(index: number) {\n if (!this._tooltip || index === this.activeIndex) return;\n this._activate(this._cells[index], index);\n }\n\n private _activate(cell: HTMLElement | undefined, index: number) {\n // Measure before the writes below, which would otherwise force a layout.\n const box = cell ? this._box(cell) : null;\n this._cells[this.activeIndex]?.classList.remove('active');\n this.activeIndex = index;\n this._tooltip.hidden = !box;\n if (box) this._fill(cell!, index, box);\n }\n\n /**\n * A cell's left, top and width in the plot, past any scrolling of the\n * grid, and the plot's width. A key can move to a cell scrolled out of a\n * wide grid, so it scrolls into view first.\n */\n private _box(cell: HTMLElement) {\n if (this._plot.matches(':focus-visible')) cell.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n return this._measure(cell);\n }\n\n private _measure(cell: HTMLElement) {\n const [box, plot] = [cell.getBoundingClientRect(), this._plot.getBoundingClientRect()];\n return [box.left - plot.left, box.top - plot.top, box.width, this._plot.clientWidth];\n }\n\n /** Keeps the tooltip on its cell as the grid scrolls, and hides it once the cell scrolls out. */\n private _follow(scroll: HTMLElement) {\n const cell = this._cells[this.activeIndex];\n if (!cell) return;\n const [view, box] = [scroll.getBoundingClientRect(), cell.getBoundingClientRect()];\n if (box.right <= view.left || box.left >= view.right) this.show(-1);\n else this._position(this._measure(cell));\n }\n\n /** Marks the cell and fills the tooltip beside it, on the side with more room. */\n private _fill(cell: HTMLElement, index: number, [left, top, width, plotWidth]: number[]) {\n cell.classList.add('active');\n const columns = this.series.length;\n const [row, series] = [Math.floor(index / columns), this.series[index % columns]];\n const title = document.createElement('strong');\n title.textContent = this.labels[row];\n const [name, text] = [document.createElement('span'), document.createElement('span')];\n name.textContent = series.name;\n // A gap's swatch is outlined like its cell.\n if (this._levels[index] === null) name.className = 'gap';\n else name.style.setProperty('--level', String(this._levels[index]));\n text.textContent = series.text[row];\n this._tooltip.replaceChildren(title, name, text);\n this._position([left, top, width, plotWidth]);\n }\n\n private _position([left, top, width, plotWidth]: number[]) {\n const end = left + width / 2 > plotWidth / 2;\n this._tooltip.classList.toggle('end', end);\n this._tooltip.style.left = `${left + (end ? 0 : width)}px`;\n this._tooltip.style.top = `${top}px`;\n }\n\n /** Arrows move the way they point, so left and right swap in RTL. */\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 [columns, last] = [this.series.length, this.labels.length - 1];\n const index = Math.max(0, this.activeIndex);\n const [row, column] = [Math.floor(index / columns), index % columns];\n const [next, back] = this._reversed ? ['ArrowLeft', 'ArrowRight'] : ['ArrowRight', 'ArrowLeft'];\n const to = {\n [next]: [row, column + 1],\n [back]: [row, column - 1],\n ArrowDown: [row + 1, column],\n ArrowUp: [row - 1, column],\n Home: [row, 0],\n End: [row, columns - 1]\n }[key];\n if (!to) return undefined;\n // The first key after focus or Escape shows the first cell.\n if (this.activeIndex < 0) return 0;\n const clamp = (value: number, max: number) => Math.min(max, Math.max(0, value));\n return clamp(to[0], last) * columns + clamp(to[1], columns - 1);\n }\n\n /**\n * The cell under the pointer by its position, or -1 off the grid. A touch\n * keeps its first target while it drags, so the target cannot be used. The\n * cells and gaps are even, so each band's edge falls in a gap and a gap\n * counts as the nearer cell.\n */\n protected _indexAt(e: PointerEvent) {\n const [columns, rows] = [this.series.length, this.labels.length];\n const first = this._cells[0].getBoundingClientRect();\n const last = this._cells[this._cells.length - 1].getBoundingClientRect();\n const [left, right] = [Math.min(first.left, last.left), Math.max(first.right, last.right)];\n const [x, y] = [e.clientX, e.clientY];\n if (this._off(x, y, [left, right, first.top, last.bottom])) return -1;\n const band = (offset: number, size: number, count: number) =>\n Math.min(count - 1, Math.floor((offset / (size || 1)) * count));\n const column = band(x - left, right - left, columns);\n return band(y - first.top, last.bottom - first.top, rows) * columns + (this._reversed ? columns - 1 - column : column);\n }\n\n /** Whether a point is off the cells, or on cells scrolled out of view under the row labels. */\n private _off(x: number, y: number, [left, right, top, bottom]: number[]) {\n const view = this._scroll.getBoundingClientRect();\n return x < Math.max(left, view.left) || x > Math.min(right, view.right) || y < top || y > bottom;\n }\n\n /**\n * The legend: a gradient from the lowest cell's shade to the highest's,\n * labelled with their text. A fixed scale wider than the data shows only\n * the part the data uses.\n */\n protected _guides(): Element[] {\n const legend = document.createElement('div');\n legend.className = 'heatmap-chart-legend';\n legend.setAttribute('aria-hidden', 'true');\n const [low, scale, high] = ['span', 'span', 'span'].map((tag) => document.createElement(tag));\n [low.textContent, high.textContent] = this._ends;\n scale.className = 'heatmap-chart-scale';\n if (this._reversed) scale.style.setProperty('--heatmap-chart-to', 'left');\n const [from, to] = this._endLevels;\n scale.style.setProperty('--low', String(from));\n scale.style.setProperty('--high', String(to));\n // A diverging scale whose data crosses the midpoint passes its empty color.\n scale.classList.toggle('diverging', from < 0 && to > 0);\n scale.style.setProperty('--mid', `${(-from / (to - from || 1)) * 100}%`);\n scale.append(...this._bands().filter((level) => level >= from && level <= to).map((level) => {\n const swatch = document.createElement('span');\n swatch.style.setProperty('--level', String(level));\n return swatch;\n }));\n legend.append(low, scale, high);\n return [legend];\n }\n\n /** With data-steps, every band's shade from the lowest to the highest; otherwise none. */\n private _bands() {\n const steps = this._steps;\n if (!steps) return [];\n return Array.from({ length: 2 * steps - 1 }, (_, k) => (k - steps + 1) / (steps - 1));\n }\n\n /** The number of bands data-steps asks for, or 0 for a smooth scale. */\n private get _steps() {\n const steps = Math.round(this._number('steps') ?? 0);\n return steps > 1 ? steps : 0;\n }\n\n /**\n * How a value shades its cell: from 0 at the scale's low end to 1 at its\n * high end, or with data-mid from -1 to 1 either side of that midpoint,\n * as far as the further end. With data-steps the shades fall into bands.\n */\n private _shade(low: number, high: number) {\n const option = (name: 'min' | 'max', fallback: number) => this._number(name) ?? this.options[name] ?? fallback;\n const [min, max, mid] = [option('min', low), option('max', high), this._number('mid')];\n const clamp = (value: number, floor: number) => Math.min(1, Math.max(floor, value));\n const level = mid === null\n ? (value: number) => clamp((value - min) / (max - min || 1), 0)\n : (value: number) => clamp((Math.min(max, Math.max(min, value)) - mid) / (Math.max(max - mid, mid - min) || 1), -1);\n const steps = this._steps;\n return steps ? (value: number) => band(level(value), steps) : level;\n }\n\n /**\n * A grid of the row headers and cells, row by row, with the column headers\n * below. Each cell's --level shades it in CSS.\n */\n protected _draw(): Element {\n const columns = this.series.length;\n let [low, high] = [Infinity, -Infinity];\n this._ends = ['', ''];\n this.series.forEach((series) => series.values.forEach((value, row) => {\n if (value === null) return;\n if (value < low) [low, this._ends[0]] = [value, series.text[row]];\n if (value > high) [high, this._ends[1]] = [value, series.text[row]];\n }));\n const shade = this._shade(low, high);\n this._endLevels = [shade(low), shade(high)];\n\n const grid = document.createElement('div');\n grid.className = 'heatmap-chart-grid';\n grid.setAttribute('aria-hidden', 'true');\n grid.style.setProperty('--columns', String(columns));\n grid.style.setProperty('--rows', String(this.labels.length));\n const span = (className: string, text = '') => {\n const element = document.createElement('span');\n element.className = className;\n element.textContent = text;\n return element;\n };\n const label = (cell: HTMLTableCellElement | undefined) =>\n cell?.dataset.label ?? cell?.textContent.trim() ?? '';\n const values = this.el.classList.contains('values');\n\n this._cells = [];\n this._levels = [];\n // The row labels stay put beside the cells, which scroll when they are too narrow.\n const [rows, cells] = [document.createElement('div'), document.createElement('div')];\n rows.className = 'heatmap-chart-rows';\n cells.className = 'heatmap-chart-cells';\n this.labels.forEach((_, row) => {\n rows.append(span('heatmap-chart-row', label(this._rows[row].cells[0])));\n this.series.forEach((series) => {\n const value = series.values[row];\n const level = value === null ? null : shade(value);\n const cell = span('heatmap-chart-cell', values ? series.text[row] : '');\n if (level === null) cell.classList.add('gap');\n else cell.style.setProperty('--level', String(level));\n this._cells.push(cell);\n this._levels.push(level);\n cells.append(cell);\n });\n });\n\n // A column label runs on over the empty labels after it.\n const labels = this._header.slice(1, columns + 1).map(label);\n const columnLabels: HTMLElement[] = [];\n labels.forEach((text, column) => {\n if (!text) return;\n let end = column + 1;\n while (end < columns && !labels[end]) end++;\n const element = span('heatmap-chart-column', text);\n element.classList.toggle('run', end > column + 1);\n element.style.gridArea = `${this.labels.length + 1} / ${column + 1} / auto / ${end + 1}`;\n cells.append(element);\n columnLabels.push(element);\n });\n // Labels the author already spaced out with empty ones are left as written.\n this._observeLabels(cells, columnLabels.some((element) => element.classList.contains('run')) ? [] : columnLabels);\n\n // The plot is the one Tab stop, so the scroll box is not another, and a\n // press that focuses it hands focus on to the plot.\n const scroll = (this._scroll = document.createElement('div'));\n scroll.className = 'heatmap-chart-scroll';\n scroll.tabIndex = -1;\n scroll.addEventListener('focus', () => this._plot.focus());\n scroll.addEventListener('scroll', () => this._follow(scroll), { passive: true });\n this._resizes?.disconnect();\n this._resizes = new ResizeObserver(() => this._follow(scroll));\n this._resizes.observe(scroll);\n scroll.append(cells);\n grid.append(rows, scroll);\n return grid;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["band"]
|
|
7
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Utils
|
|
3
|
-
} from "./chunk-M372EDXD.mjs";
|
|
4
1
|
import {
|
|
5
2
|
Component
|
|
6
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-EB2V4OKL.mjs";
|
|
4
|
+
import {
|
|
5
|
+
Utils
|
|
6
|
+
} from "./chunk-67UNY7RH.mjs";
|
|
7
7
|
|
|
8
8
|
// src/ts/components/messageScroller.ts
|
|
9
9
|
var _defaults = {
|
|
@@ -14,9 +14,9 @@ var _defaults = {
|
|
|
14
14
|
var EDGE = 2;
|
|
15
15
|
var UP_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "PageUp", "Home"]);
|
|
16
16
|
var RELEASE_EVENTS = ["pointerup", "pointercancel", "touchend", "touchcancel"];
|
|
17
|
-
var MessageScroller = class
|
|
17
|
+
var MessageScroller = class extends Component {
|
|
18
18
|
constructor(el, options) {
|
|
19
|
-
super(el, options
|
|
19
|
+
super(el, options);
|
|
20
20
|
this._opened = false;
|
|
21
21
|
this._following = false;
|
|
22
22
|
/** A press is down: it may be a tap or a scrollbar drag. */
|
|
@@ -65,10 +65,10 @@ var MessageScroller = class _MessageScroller extends Component {
|
|
|
65
65
|
this._handleMutations = (records) => {
|
|
66
66
|
for (const record of records) {
|
|
67
67
|
record.addedNodes.forEach((node) => {
|
|
68
|
-
if (node instanceof Element) this._resizeObserver
|
|
68
|
+
if (node instanceof Element) this._resizeObserver.observe(node);
|
|
69
69
|
});
|
|
70
70
|
record.removedNodes.forEach((node) => {
|
|
71
|
-
if (node instanceof Element) this._resizeObserver
|
|
71
|
+
if (node instanceof Element) this._resizeObserver.unobserve(node);
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
74
|
const previous = this._last;
|
|
@@ -101,11 +101,6 @@ var MessageScroller = class _MessageScroller extends Component {
|
|
|
101
101
|
}
|
|
102
102
|
this._sync();
|
|
103
103
|
};
|
|
104
|
-
this.el["Expressive_MessageScroller"] = this;
|
|
105
|
-
this.options = {
|
|
106
|
-
..._MessageScroller.defaults,
|
|
107
|
-
...options
|
|
108
|
-
};
|
|
109
104
|
this.viewport = el.querySelector(":scope > .message-scroller-viewport");
|
|
110
105
|
this.button = el.querySelector(":scope > .message-scroller-button");
|
|
111
106
|
if (!this.viewport) {
|
|
@@ -114,49 +109,29 @@ var MessageScroller = class _MessageScroller extends Component {
|
|
|
114
109
|
}
|
|
115
110
|
this._last = this.viewport.lastElementChild;
|
|
116
111
|
if (this.viewport.clientHeight > 0) this._open();
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
for (const item of Array.from(this.viewport.children)) this._resizeObserver.observe(item);
|
|
121
|
-
}
|
|
112
|
+
this._resizeObserver = new ResizeObserver(this._handleResize);
|
|
113
|
+
this._resizeObserver.observe(this.viewport, { box: "border-box" });
|
|
114
|
+
for (const item of Array.from(this.viewport.children)) this._resizeObserver.observe(item);
|
|
122
115
|
this._mutationObserver = new MutationObserver(this._handleMutations);
|
|
123
116
|
this._mutationObserver.observe(this.viewport, { childList: true });
|
|
124
|
-
|
|
117
|
+
const { signal } = this._events;
|
|
118
|
+
this.viewport.addEventListener("scroll", this._handleScroll, { passive: true, signal });
|
|
125
119
|
for (const type of ["wheel", "touchstart", "pointerdown", "keydown"]) {
|
|
126
|
-
this.viewport.addEventListener(type, this._handleUserScroll, { passive: true });
|
|
120
|
+
this.viewport.addEventListener(type, this._handleUserScroll, { passive: true, signal });
|
|
127
121
|
}
|
|
128
|
-
for (const type of RELEASE_EVENTS) document.addEventListener(type, this._handleRelease);
|
|
129
|
-
this.button?.addEventListener("click", this._handleButtonClick);
|
|
122
|
+
for (const type of RELEASE_EVENTS) document.addEventListener(type, this._handleRelease, { signal });
|
|
123
|
+
this.button?.addEventListener("click", this._handleButtonClick, { signal });
|
|
130
124
|
}
|
|
131
125
|
static get defaults() {
|
|
132
126
|
return _defaults;
|
|
133
127
|
}
|
|
134
|
-
/**
|
|
135
|
-
* Initializes instances of MessageScroller.
|
|
136
|
-
* @param els HTML elements.
|
|
137
|
-
* @param options Component options.
|
|
138
|
-
*/
|
|
139
|
-
static init(els, options = {}) {
|
|
140
|
-
return super.init(els, options, _MessageScroller);
|
|
141
|
-
}
|
|
142
|
-
static getInstance(el) {
|
|
143
|
-
return el["Expressive_MessageScroller"];
|
|
144
|
-
}
|
|
145
128
|
destroy() {
|
|
146
|
-
|
|
129
|
+
super.destroy();
|
|
147
130
|
if (!this.viewport) return;
|
|
148
131
|
this._resizeObserver?.disconnect();
|
|
149
132
|
this._mutationObserver?.disconnect();
|
|
150
|
-
this.viewport.removeEventListener("scroll", this._handleScroll);
|
|
151
|
-
for (const type of ["wheel", "touchstart", "pointerdown", "keydown"]) {
|
|
152
|
-
this.viewport.removeEventListener(type, this._handleUserScroll);
|
|
153
|
-
}
|
|
154
|
-
for (const type of RELEASE_EVENTS) document.removeEventListener(type, this._handleRelease);
|
|
155
133
|
this.viewport.style.removeProperty("--md-comp-message-scroller-spacer");
|
|
156
|
-
if (this.button)
|
|
157
|
-
this.button.removeEventListener("click", this._handleButtonClick);
|
|
158
|
-
this.button.inert = false;
|
|
159
|
-
}
|
|
134
|
+
if (this.button) this.button.inert = false;
|
|
160
135
|
}
|
|
161
136
|
/** Scrolls to the latest message and resumes following. */
|
|
162
137
|
scrollToEnd() {
|
|
@@ -214,7 +189,7 @@ var MessageScroller = class _MessageScroller extends Component {
|
|
|
214
189
|
}
|
|
215
190
|
this._target = target;
|
|
216
191
|
this._distance = Infinity;
|
|
217
|
-
const reduce =
|
|
192
|
+
const reduce = matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
218
193
|
v.scrollTo({
|
|
219
194
|
top: target === "end" ? v.scrollHeight : target,
|
|
220
195
|
behavior: reduce ? "auto" : "smooth"
|
|
@@ -285,8 +260,9 @@ var MessageScroller = class _MessageScroller extends Component {
|
|
|
285
260
|
this.button.inert = idle;
|
|
286
261
|
}
|
|
287
262
|
};
|
|
263
|
+
MessageScroller.key = "Expressive_MessageScroller";
|
|
288
264
|
|
|
289
265
|
export {
|
|
290
266
|
MessageScroller
|
|
291
267
|
};
|
|
292
|
-
//# sourceMappingURL=chunk-
|
|
268
|
+
//# sourceMappingURL=chunk-LC4O5LFS.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ts/components/messageScroller.ts"],
|
|
4
|
+
"sourcesContent": ["import { Utils } from '../core/utils';\nimport { Component, BaseOptions } from '../core/component';\n\nexport interface MessageScrollerOptions extends BaseOptions {\n /**\n * If true, the viewport follows new content while the reader is at the\n * end, and a newly appended scroll anchor is brought to the top.\n * @default true\n */\n autoScroll: boolean;\n /**\n * Where the transcript opens: `'end'`, `'start'`, or `'last-anchor'`, the\n * start of the last anchored turn. `'last-anchor'` opens at the end when\n * that turn already fits in the viewport.\n * @default 'end'\n */\n defaultScrollPosition: 'start' | 'end' | 'last-anchor';\n /**\n * Pixels of the previous message left visible above an anchored turn or a\n * message reached with `scrollToMessage()`.\n * @default 64\n */\n peek: number;\n}\n\nconst _defaults: MessageScrollerOptions = {\n autoScroll: true,\n defaultScrollPosition: 'end',\n peek: 64\n};\n\n// Distance from a scroll target, in px, that still counts as reaching it.\n// Fractional layouts rarely land on the exact pixel.\nconst EDGE = 2;\n\n// Keys that scroll toward the start. They release following at once, before\n// the next streamed chunk can pull the viewport back to the end.\nconst UP_KEYS = new Set(['ArrowUp', 'PageUp', 'Home']);\n\n// Listened on the document: a scrollbar drag can end outside the viewport.\nconst RELEASE_EVENTS = ['pointerup', 'pointercancel', 'touchend', 'touchcancel'];\n\ntype Target = number | 'end';\n\n/**\n * A chat scroll container: a `.message-scroller` frame holding a scrolling\n * `.message-scroller-viewport` of messages and an optional\n * `.message-scroller-button`. Every child of the viewport is one message.\n *\n * While the reader is at the end, the viewport follows streamed output.\n * Scrolling toward the start releases it; reaching the end again, or the\n * button, resumes it. An appended message marked `data-scroll-anchor` starts a\n * turn and is scrolled to the top, with blank space below it until the reply\n * fills the viewport. Messages added above keep the reader's place.\n */\nexport class MessageScroller extends Component<MessageScrollerOptions> {\n /** The scrolling element. */\n viewport: HTMLElement;\n /** The scroll-to-latest button, if present. */\n button: HTMLButtonElement | null;\n private _opened = false;\n private _following = false;\n /** A press is down: it may be a tap or a scrollbar drag. */\n private _holding = false;\n private _lastTop = 0;\n /** Where a programmatic scroll is heading; null when none is running. */\n private _target: Target | null = null;\n /** Distance left to the target at the last scroll event. */\n private _distance = Infinity;\n /** The first visible message and its offset from the viewport top. */\n private _ref: Element | null = null;\n private _refOffset = 0;\n /** The latest anchored turn, which the spacer lets reach the top. */\n private _anchor: Element | null = null;\n private _spacer = 0;\n private _last: Element | null = null;\n private _resizeObserver: ResizeObserver | null = null;\n private _mutationObserver: MutationObserver | null = null;\n\n constructor(el: HTMLElement, options: Partial<MessageScrollerOptions>) {\n super(el, options);\n this.viewport = el.querySelector(':scope > .message-scroller-viewport');\n this.button = el.querySelector(':scope > .message-scroller-button');\n if (!this.viewport) {\n console.error('MessageScroller needs a .message-scroller-viewport child.');\n return;\n }\n this._last = this.viewport.lastElementChild;\n // A viewport that is not rendered yet (a closed dialog, a hidden tab)\n // has no size to position against; it opens on its first resize.\n if (this.viewport.clientHeight > 0) this._open();\n this._resizeObserver = new ResizeObserver(this._handleResize);\n // Border box: the spacer changes the padding, which must not count.\n this._resizeObserver.observe(this.viewport, { box: 'border-box' });\n for (const item of Array.from(this.viewport.children)) this._resizeObserver.observe(item);\n this._mutationObserver = new MutationObserver(this._handleMutations);\n this._mutationObserver.observe(this.viewport, { childList: true });\n const { signal } = this._events;\n this.viewport.addEventListener('scroll', this._handleScroll, { passive: true, signal });\n for (const type of ['wheel', 'touchstart', 'pointerdown', 'keydown']) {\n this.viewport.addEventListener(type, this._handleUserScroll, { passive: true, signal });\n }\n for (const type of RELEASE_EVENTS) document.addEventListener(type, this._handleRelease, { signal });\n this.button?.addEventListener('click', this._handleButtonClick, { signal });\n }\n\n static get defaults(): MessageScrollerOptions {\n return _defaults;\n }\n\n static key = 'Expressive_MessageScroller';\n\n destroy() {\n super.destroy();\n if (!this.viewport) return;\n this._resizeObserver?.disconnect();\n this._mutationObserver?.disconnect();\n this.viewport.style.removeProperty('--md-comp-message-scroller-spacer');\n if (this.button) this.button.inert = false;\n }\n\n /** Scrolls to the latest message and resumes following. */\n scrollToEnd() {\n // Set now: output streaming faster than the scroll can end it early.\n this._following = this.options.autoScroll;\n this._scrollTo('end');\n }\n\n /** Scrolls to the first message. */\n scrollToStart() {\n this._following = false;\n this._scrollTo(0);\n }\n\n /**\n * Scrolls the element with this id to the top of the viewport, below the\n * peek, and stops following.\n * @returns false when no such element is inside the viewport.\n */\n scrollToMessage(id: string): boolean {\n const target = Utils.getElementById(this.viewport, id);\n if (!target || !this.viewport.contains(target)) return false;\n this._following = false;\n this._scrollTo(this._top(target) - this.options.peek);\n return true;\n }\n\n private _open() {\n this._opened = true;\n const v = this.viewport;\n const position = this.options.defaultScrollPosition;\n const anchors = v.querySelectorAll(':scope > [data-scroll-anchor]');\n const anchor = position === 'last-anchor' ? anchors[anchors.length - 1] : null;\n if (position === 'start') v.scrollTop = 0;\n else if (anchor && this._contentEnd() - this._top(anchor) + this.options.peek > v.clientHeight) {\n v.scrollTop = this._top(anchor) - this.options.peek;\n } else v.scrollTop = v.scrollHeight;\n this._settle();\n }\n\n /**\n * Records where the reader is once no programmatic scroll is running.\n * Content can grow between a scroll and the resize that re-pins the end,\n * so only moving toward the start releases following.\n */\n private _settle() {\n const top = this.viewport.scrollTop;\n const kept = this._following && top >= this._lastTop - EDGE;\n this._following = this.options.autoScroll && (kept || this._atEnd());\n this._lastTop = top;\n this._capture();\n this._sync();\n }\n\n // A programmatic scroll ends when it arrives, or when a scroll moves away\n // from its target because something else took over.\n private _handleScroll = () => {\n if (this._target !== null) {\n const distance = Math.abs(this.viewport.scrollTop - this._resolve(this._target));\n if (distance > EDGE && distance < this._distance) {\n this._distance = distance;\n return;\n }\n this._target = null;\n }\n this._settle();\n };\n\n private _handleUserScroll = (e: Event) => {\n if (e.type === 'wheel' && (e as WheelEvent).deltaY >= 0) return;\n if (e.type === 'keydown' && !UP_KEYS.has((e as KeyboardEvent).key)) return;\n this._target = null;\n // A press may be a tap on a message or the start of a drag. Hold the end\n // until it is released; a scroll toward the start releases following.\n if (e.type === 'pointerdown' || e.type === 'touchstart') this._holding = true;\n else this._following = false;\n };\n\n private _handleRelease = () => {\n if (!this._holding) return;\n this._holding = false;\n if (this._following) this.viewport.scrollTop = this.viewport.scrollHeight;\n this._sync();\n };\n\n private _handleButtonClick = () => this.scrollToEnd();\n\n private _handleMutations = (records: MutationRecord[]) => {\n for (const record of records) {\n record.addedNodes.forEach((node) => {\n if (node instanceof Element) this._resizeObserver.observe(node);\n });\n record.removedNodes.forEach((node) => {\n if (node instanceof Element) this._resizeObserver.unobserve(node);\n });\n }\n const previous = this._last;\n this._last = this.viewport.lastElementChild;\n if (!this._opened) return;\n // Restore here, not only on resize: this runs before any scroll event\n // that could record the shifted position as the reader's place.\n if (!this._following && this._target === null) this._restore();\n if (!this.options.autoScroll) return;\n // Only messages appended after the previous last one start a new turn;\n // anchors in prepended history do not. If the last one was removed, the\n // list was replaced and nothing counts as appended.\n if (previous && previous.parentElement !== this.viewport) return;\n for (let item = this._last; item && item !== previous; item = item.previousElementSibling) {\n if (item.hasAttribute('data-scroll-anchor')) {\n this._anchor = item;\n this._updateSpacer();\n // Follow the reply once the turn reaches the top, unless the reader\n // scrolls away first. _settle keeps it because the scroll went down.\n this._following = true;\n this._scrollTo(this._top(item) - this.options.peek);\n return;\n }\n }\n };\n\n private _handleResize = () => {\n if (!this._opened) {\n if (this.viewport.clientHeight > 0) this._open();\n return;\n }\n this._updateSpacer();\n const v = this.viewport;\n if (this._target === 'end') this._scrollTo('end');\n else if (this._target === null) {\n if (this._following && !this._holding) v.scrollTop = v.scrollHeight;\n else this._restore();\n }\n this._sync();\n };\n\n private _scrollTo(target: Target) {\n const v = this.viewport;\n if (Math.abs(v.scrollTop - this._resolve(target)) <= EDGE) {\n this._target = null;\n this._settle();\n return;\n }\n this._target = target;\n this._distance = Infinity;\n const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;\n v.scrollTo({\n top: target === 'end' ? v.scrollHeight : target,\n behavior: reduce ? 'auto' : 'smooth'\n });\n }\n\n private _resolve(target: Target) {\n const max = this.viewport.scrollHeight - this.viewport.clientHeight;\n return target === 'end' ? max : Math.max(0, Math.min(target, max));\n }\n\n private _atEnd() {\n const v = this.viewport;\n return v.scrollHeight - v.scrollTop - v.clientHeight <= EDGE;\n }\n\n /** Offset of an element from the top of the scrolled content. */\n private _top(el: Element) {\n const v = this.viewport;\n return el.getBoundingClientRect().top - v.getBoundingClientRect().top - v.clientTop + v.scrollTop;\n }\n\n /** Bottom of the content without the spacer, padding included. */\n private _contentEnd() {\n const last = this.viewport.lastElementChild;\n if (!last) return 0;\n const padding = parseFloat(getComputedStyle(this.viewport).paddingBlockEnd) - this._spacer;\n return this._top(last) + last.getBoundingClientRect().height + padding;\n }\n\n /** Remembers the first visible message so prepends can keep it in place. */\n private _capture() {\n const items = this.viewport.children;\n const top = this.viewport.getBoundingClientRect().top + this.viewport.clientTop;\n let low = 0;\n let high = items.length - 1;\n while (low < high) {\n const mid = (low + high) >> 1;\n if (items[mid].getBoundingClientRect().bottom > top) high = mid;\n else low = mid + 1;\n }\n this._ref = items[low] ?? null;\n this._refOffset = this._ref ? this._ref.getBoundingClientRect().top - top : 0;\n }\n\n /** Moves the remembered message back to where the reader last saw it. */\n private _restore() {\n if (this._ref?.parentElement !== this.viewport) {\n this._capture();\n return;\n }\n const top = this.viewport.getBoundingClientRect().top + this.viewport.clientTop;\n const delta = this._ref.getBoundingClientRect().top - top - this._refOffset;\n if (Math.abs(delta) >= 1) this.viewport.scrollTop += delta;\n }\n\n /** Sizes the blank space that lets the latest anchored turn reach the top. */\n private _updateSpacer() {\n let space = 0;\n if (this._anchor?.parentElement === this.viewport) {\n const room = this._top(this._anchor) - this.options.peek + this.viewport.clientHeight;\n space = Math.max(0, Math.ceil(room - this._contentEnd()));\n } else this._anchor = null;\n if (space === this._spacer) return;\n this._spacer = space;\n if (space) this.viewport.style.setProperty('--md-comp-message-scroller-spacer', `${space}px`);\n else this.viewport.style.removeProperty('--md-comp-message-scroller-spacer');\n }\n\n /** The button is inert while there is nothing below. */\n private _sync() {\n if (!this.button) return;\n const idle = this._atEnd();\n // The button's own root: inside a shadow root, document.activeElement is the host.\n const root = this.button.getRootNode() as Document | ShadowRoot;\n if (idle && root.activeElement === this.button) this.viewport.focus({ preventScroll: true });\n this.button.inert = idle;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Utils
|
|
3
|
+
} from "./chunk-67UNY7RH.mjs";
|
|
4
|
+
|
|
5
|
+
// src/ts/behaviors/dialogs.ts
|
|
6
|
+
function textElement(tag, text) {
|
|
7
|
+
const el = document.createElement(tag);
|
|
8
|
+
el.textContent = text;
|
|
9
|
+
return el;
|
|
10
|
+
}
|
|
11
|
+
function actionButton(label, value) {
|
|
12
|
+
const button = textElement("button", label);
|
|
13
|
+
button.type = "submit";
|
|
14
|
+
button.value = value;
|
|
15
|
+
return button;
|
|
16
|
+
}
|
|
17
|
+
var _Dialogs = class _Dialogs {
|
|
18
|
+
/**
|
|
19
|
+
* Asks a yes-or-no question in a modal alert dialog. Resolves true on the
|
|
20
|
+
* confirm button and false on Cancel, Escape or a scrim tap, then removes
|
|
21
|
+
* the dialog. The browser returns focus to the element that had it.
|
|
22
|
+
*/
|
|
23
|
+
static confirm(options) {
|
|
24
|
+
const dialog = _Dialogs._confirmDialog(options);
|
|
25
|
+
document.body.append(dialog);
|
|
26
|
+
dialog.showModal();
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
const removed = new MutationObserver(() => {
|
|
29
|
+
if (!dialog.isConnected) settle(false);
|
|
30
|
+
});
|
|
31
|
+
const settle = (answer) => {
|
|
32
|
+
removed.disconnect();
|
|
33
|
+
dialog.remove();
|
|
34
|
+
resolve(answer);
|
|
35
|
+
};
|
|
36
|
+
removed.observe(document, { childList: true, subtree: true });
|
|
37
|
+
dialog.addEventListener("close", () => settle(dialog.returnValue === "confirm"), { once: true });
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
static _confirmDialog({ text, headline, confirm, cancel }) {
|
|
41
|
+
const dialog = document.createElement("dialog");
|
|
42
|
+
dialog.setAttribute("role", "alertdialog");
|
|
43
|
+
const id = `expressive-confirm-${++_Dialogs._confirms}`;
|
|
44
|
+
const body = textElement("p", text);
|
|
45
|
+
body.id = `${id}-text`;
|
|
46
|
+
const cancelButton = actionButton(cancel ?? _Dialogs.i18n.cancel, "");
|
|
47
|
+
cancelButton.className = "text";
|
|
48
|
+
cancelButton.autofocus = true;
|
|
49
|
+
const form = document.createElement("form");
|
|
50
|
+
form.method = "dialog";
|
|
51
|
+
form.append(cancelButton, actionButton(confirm ?? _Dialogs.i18n.confirm, "confirm"));
|
|
52
|
+
dialog.append(body, form);
|
|
53
|
+
_Dialogs._name(dialog, body, id, headline);
|
|
54
|
+
return dialog;
|
|
55
|
+
}
|
|
56
|
+
/** Names the dialog by its headline and describes it by the text, or names it by the text alone. */
|
|
57
|
+
static _name(dialog, body, id, headline) {
|
|
58
|
+
if (!headline) {
|
|
59
|
+
dialog.setAttribute("aria-labelledby", body.id);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const heading = textElement("h2", headline);
|
|
63
|
+
heading.id = `${id}-headline`;
|
|
64
|
+
dialog.prepend(heading);
|
|
65
|
+
dialog.setAttribute("aria-labelledby", heading.id);
|
|
66
|
+
dialog.setAttribute("aria-describedby", body.id);
|
|
67
|
+
}
|
|
68
|
+
static Init() {
|
|
69
|
+
Utils.onDocumentReady(() => {
|
|
70
|
+
document.addEventListener("pointerdown", _Dialogs._onPointerDown, { passive: true });
|
|
71
|
+
document.addEventListener("pointerup", _Dialogs._onPointerUp, { passive: true });
|
|
72
|
+
document.addEventListener("pointercancel", _Dialogs._onPointerCancel, { passive: true });
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
static _onPointerDown(event) {
|
|
76
|
+
const dialog = _Dialogs._isPrimaryPress(event) ? _Dialogs._backdropDialog(event) : null;
|
|
77
|
+
_Dialogs._down = dialog && _Dialogs._lightDismissible(dialog) && _Dialogs._outside(event, dialog) ? { dialog, pointerId: event.pointerId } : null;
|
|
78
|
+
}
|
|
79
|
+
static _onPointerUp(event) {
|
|
80
|
+
const started = _Dialogs._down;
|
|
81
|
+
_Dialogs._down = null;
|
|
82
|
+
if (!started || started.pointerId !== event.pointerId) return;
|
|
83
|
+
if (!started.dialog.isConnected || !started.dialog.open) return;
|
|
84
|
+
if (!_Dialogs._lightDismissible(started.dialog)) return;
|
|
85
|
+
if (_Dialogs._backdropDialog(event) !== started.dialog) return;
|
|
86
|
+
if (_Dialogs._outside(event, started.dialog)) {
|
|
87
|
+
started.dialog.close();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
static _onPointerCancel() {
|
|
91
|
+
_Dialogs._down = null;
|
|
92
|
+
}
|
|
93
|
+
/** Backdrop hits retarget to the dialog itself, never a child. */
|
|
94
|
+
static _backdropDialog(event) {
|
|
95
|
+
const target = Utils.eventTarget(event);
|
|
96
|
+
if (!(target instanceof HTMLDialogElement) || !target.open) return null;
|
|
97
|
+
return target;
|
|
98
|
+
}
|
|
99
|
+
static _outside(event, dialog) {
|
|
100
|
+
const rect = dialog.getBoundingClientRect();
|
|
101
|
+
return event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom;
|
|
102
|
+
}
|
|
103
|
+
static _isPrimaryPress(event) {
|
|
104
|
+
if (!event.isPrimary) return false;
|
|
105
|
+
return event.pointerType !== "mouse" || event.button === 0;
|
|
106
|
+
}
|
|
107
|
+
// Read the attribute only. The IDL default for an unset closedby is
|
|
108
|
+
// "closerequest" (Escape, no light dismiss) — treating that as an
|
|
109
|
+
// author opt-out made every dialog undismissable from the scrim.
|
|
110
|
+
// Native closedby="any" already light-dismisses with the same "both ends
|
|
111
|
+
// outside" rule, so leave it to the browser where it has one.
|
|
112
|
+
static _lightDismissible(dialog) {
|
|
113
|
+
const value = dialog.getAttribute("closedby");
|
|
114
|
+
if (value === "any") return !("closedBy" in HTMLDialogElement.prototype);
|
|
115
|
+
return value !== "none" && value !== "closerequest";
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
/** The confirm dialog's default button labels. */
|
|
119
|
+
_Dialogs.i18n = { confirm: "OK", cancel: "Cancel" };
|
|
120
|
+
_Dialogs._down = null;
|
|
121
|
+
_Dialogs._confirms = 0;
|
|
122
|
+
var Dialogs = _Dialogs;
|
|
123
|
+
|
|
124
|
+
export {
|
|
125
|
+
Dialogs
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=chunk-LEF33SCP.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ts/behaviors/dialogs.ts"],
|
|
4
|
+
"sourcesContent": ["import { Utils } from '../core/utils';\n\nexport interface ConfirmOptions {\n /** The question, shown as the supporting text. */\n text: string;\n /** An optional headline above the text. */\n headline?: string;\n /** The confirm button's label. Defaults to `Dialogs.i18n.confirm`. */\n confirm?: string;\n /** The cancel button's label. Defaults to `Dialogs.i18n.cancel`. */\n cancel?: string;\n}\n\n/** An element holding `text`, set as text so markup in it is never parsed. */\nfunction textElement<K extends keyof HTMLElementTagNameMap>(tag: K, text: string): HTMLElementTagNameMap[K] {\n const el = document.createElement(tag);\n el.textContent = text;\n return el;\n}\n\n/** A submit button that closes its dialog with `value` as the return value. */\nfunction actionButton(label: string, value: string): HTMLButtonElement {\n const button = textElement('button', label);\n button.type = 'submit';\n button.value = value;\n return button;\n}\n\n/**\n * Light-dismiss for native `<dialog>` elements.\n *\n * `showModal()` does not close on a backdrop tap. A naive `click` listener\n * on the dialog (where `::backdrop` events retarget) also fires when the\n * user starts a gesture on the dialog and releases on the scrim \u2014 selecting\n * text, missing a button, dragging a thumb. Both ends of the pointer\n * gesture must land outside the dialog's border box.\n *\n * Default is on. Opt out with `closedby=\"none\"` or `closedby=\"closerequest\"`.\n * If the browser already honours `closedby=\"any\"`, we leave that alone.\n *\n * `Dialogs.confirm()` asks a yes-or-no question from script and needs no Init.\n */\nexport class Dialogs {\n /** The confirm dialog's default button labels. */\n static i18n = { confirm: 'OK', cancel: 'Cancel' };\n private static _down: { dialog: HTMLDialogElement; pointerId: number } | null = null;\n private static _confirms = 0;\n\n /**\n * Asks a yes-or-no question in a modal alert dialog. Resolves true on the\n * confirm button and false on Cancel, Escape or a scrim tap, then removes\n * the dialog. The browser returns focus to the element that had it.\n */\n static confirm(options: ConfirmOptions): Promise<boolean> {\n const dialog = Dialogs._confirmDialog(options);\n document.body.append(dialog);\n // A new dialog's returnValue is '', and Escape and close() leave it alone,\n // so only the confirm button sets it.\n dialog.showModal();\n return new Promise((resolve) => {\n // Removing an open dialog fires no close event, so watch for page code\n // that removes it, such as a route change, and answer false.\n const removed = new MutationObserver(() => {\n if (!dialog.isConnected) settle(false);\n });\n const settle = (answer: boolean) => {\n removed.disconnect();\n dialog.remove();\n resolve(answer);\n };\n removed.observe(document, { childList: true, subtree: true });\n dialog.addEventListener('close', () => settle(dialog.returnValue === 'confirm'), { once: true });\n });\n }\n\n private static _confirmDialog({ text, headline, confirm, cancel }: ConfirmOptions): HTMLDialogElement {\n const dialog = document.createElement('dialog');\n dialog.setAttribute('role', 'alertdialog');\n const id = `expressive-confirm-${++Dialogs._confirms}`;\n const body = textElement('p', text);\n body.id = `${id}-text`;\n const cancelButton = actionButton(cancel ?? Dialogs.i18n.cancel, '');\n cancelButton.className = 'text';\n // The less destructive action takes focus when the dialog opens.\n cancelButton.autofocus = true;\n const form = document.createElement('form');\n form.method = 'dialog';\n form.append(cancelButton, actionButton(confirm ?? Dialogs.i18n.confirm, 'confirm'));\n dialog.append(body, form);\n Dialogs._name(dialog, body, id, headline);\n return dialog;\n }\n\n /** Names the dialog by its headline and describes it by the text, or names it by the text alone. */\n private static _name(dialog: HTMLDialogElement, body: HTMLElement, id: string, headline?: string) {\n if (!headline) {\n dialog.setAttribute('aria-labelledby', body.id);\n return;\n }\n const heading = textElement('h2', headline);\n heading.id = `${id}-headline`;\n dialog.prepend(heading);\n dialog.setAttribute('aria-labelledby', heading.id);\n dialog.setAttribute('aria-describedby', body.id);\n }\n\n static Init() {\n Utils.onDocumentReady(() => {\n document.addEventListener('pointerdown', Dialogs._onPointerDown, { passive: true });\n document.addEventListener('pointerup', Dialogs._onPointerUp, { passive: true });\n document.addEventListener('pointercancel', Dialogs._onPointerCancel, { passive: true });\n });\n }\n\n static _onPointerDown(event: PointerEvent) {\n const dialog = Dialogs._isPrimaryPress(event) ? Dialogs._backdropDialog(event) : null;\n Dialogs._down =\n dialog && Dialogs._lightDismissible(dialog) && Dialogs._outside(event, dialog)\n ? { dialog, pointerId: event.pointerId }\n : null;\n }\n\n static _onPointerUp(event: PointerEvent) {\n const started = Dialogs._down;\n Dialogs._down = null;\n if (!started || started.pointerId !== event.pointerId) return;\n if (!started.dialog.isConnected || !started.dialog.open) return;\n if (!Dialogs._lightDismissible(started.dialog)) return;\n if (Dialogs._backdropDialog(event) !== started.dialog) return;\n if (Dialogs._outside(event, started.dialog)) {\n started.dialog.close();\n }\n }\n\n static _onPointerCancel() {\n Dialogs._down = null;\n }\n\n /** Backdrop hits retarget to the dialog itself, never a child. */\n private static _backdropDialog(event: Event): HTMLDialogElement | null {\n const target = Utils.eventTarget(event);\n if (!(target instanceof HTMLDialogElement) || !target.open) return null;\n return target;\n }\n\n private static _outside(event: PointerEvent, dialog: HTMLDialogElement): boolean {\n const rect = dialog.getBoundingClientRect();\n return (\n event.clientX < rect.left ||\n event.clientX > rect.right ||\n event.clientY < rect.top ||\n event.clientY > rect.bottom\n );\n }\n\n private static _isPrimaryPress(event: PointerEvent): boolean {\n if (!event.isPrimary) return false;\n return event.pointerType !== 'mouse' || event.button === 0;\n }\n\n // Read the attribute only. The IDL default for an unset closedby is\n // \"closerequest\" (Escape, no light dismiss) \u2014 treating that as an\n // author opt-out made every dialog undismissable from the scrim.\n // Native closedby=\"any\" already light-dismisses with the same \"both ends\n // outside\" rule, so leave it to the browser where it has one.\n private static _lightDismissible(dialog: HTMLDialogElement): boolean {\n const value = dialog.getAttribute('closedby');\n if (value === 'any') return !('closedBy' in HTMLDialogElement.prototype);\n return value !== 'none' && value !== 'closerequest';\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|