@expressivecss/expressive 0.14.1 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +88 -1
- package/README.md +1 -1
- package/dist/css/expressive.css +200 -241
- package/dist/css/expressive.css.map +1 -1
- package/dist/css/expressive.min.css +1 -1
- package/dist/css/expressive.min.css.map +1 -1
- package/dist/js/chunks/{chunk-4KMNFIFZ.mjs → chunk-33QVDDGR.mjs} +3 -3
- package/dist/js/chunks/{chunk-SPETGK25.mjs → chunk-45FER6RI.mjs} +5 -5
- package/dist/js/chunks/chunk-45FER6RI.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GIW4K4SE.mjs → chunk-5CEAOLUA.mjs} +11 -10
- package/dist/js/chunks/{chunk-GIW4K4SE.mjs.map → chunk-5CEAOLUA.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-LRZMJZ3T.mjs → chunk-6VATUZC6.mjs} +10 -6
- package/dist/js/chunks/chunk-6VATUZC6.mjs.map +7 -0
- package/dist/js/chunks/{chunk-QDAL4IYN.mjs → chunk-74MXKKLN.mjs} +2 -2
- package/dist/js/chunks/{chunk-QDAL4IYN.mjs.map → chunk-74MXKKLN.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-CUQPB25U.mjs → chunk-AIURVCG6.mjs} +3 -3
- package/dist/js/chunks/{chunk-KHV6DZXX.mjs → chunk-BGZLF6JZ.mjs} +16 -16
- package/dist/js/chunks/chunk-BGZLF6JZ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-BG6ZRB5H.mjs → chunk-C6CHEWYP.mjs} +2 -2
- package/dist/js/chunks/{chunk-GVGT6MIU.mjs → chunk-CK2XCICY.mjs} +2 -2
- package/dist/js/chunks/{chunk-KY6U46SM.mjs → chunk-CXXM2L4F.mjs} +8 -9
- package/dist/js/chunks/chunk-CXXM2L4F.mjs.map +7 -0
- package/dist/js/chunks/{chunk-Z2NRKI7R.mjs → chunk-DXGRXYYL.mjs} +25 -37
- package/dist/js/chunks/chunk-DXGRXYYL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-MZ6Z24BX.mjs → chunk-FM5CZOUB.mjs} +3 -7
- package/dist/js/chunks/{chunk-MZ6Z24BX.mjs.map → chunk-FM5CZOUB.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-5HQSGDZ5.mjs → chunk-GJL6GCIU.mjs} +34 -55
- package/dist/js/chunks/chunk-GJL6GCIU.mjs.map +7 -0
- package/dist/js/chunks/chunk-K3HZMFMD.mjs +135 -0
- package/dist/js/chunks/chunk-K3HZMFMD.mjs.map +7 -0
- package/dist/js/chunks/{chunk-TBM3FT7G.mjs → chunk-KHXZ2A4K.mjs} +12 -15
- package/dist/js/chunks/{chunk-TBM3FT7G.mjs.map → chunk-KHXZ2A4K.mjs.map} +2 -2
- package/dist/js/chunks/chunk-KQACNQ22.mjs +7 -0
- package/dist/js/chunks/{chunk-KBNN3QDH.mjs.map → chunk-KQACNQ22.mjs.map} +1 -1
- package/dist/js/chunks/{chunk-UEXCIMJZ.mjs → chunk-KUFHW3DS.mjs} +2 -2
- package/dist/js/chunks/{chunk-A7ALMYUR.mjs → chunk-KVJAVDBC.mjs} +7 -15
- package/dist/js/chunks/chunk-KVJAVDBC.mjs.map +7 -0
- package/dist/js/chunks/{chunk-YDCS5S3J.mjs → chunk-L27Q6ZMI.mjs} +2 -2
- package/dist/js/chunks/{chunk-NS2UMNZV.mjs → chunk-LQWUDNHZ.mjs} +3 -3
- package/dist/js/chunks/{chunk-MNPROCZF.mjs → chunk-M372EDXD.mjs} +4 -10
- package/dist/js/chunks/chunk-M372EDXD.mjs.map +7 -0
- package/dist/js/chunks/{chunk-YMSXJON6.mjs → chunk-M3MURWMB.mjs} +15 -12
- package/dist/js/chunks/{chunk-YMSXJON6.mjs.map → chunk-M3MURWMB.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-JIDMQGK6.mjs → chunk-NUHMOAOY.mjs} +18 -33
- package/dist/js/chunks/chunk-NUHMOAOY.mjs.map +7 -0
- package/dist/js/chunks/{chunk-VGZSAFTX.mjs → chunk-OWG3LMUL.mjs} +7 -11
- package/dist/js/chunks/chunk-OWG3LMUL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-LTWPGFBR.mjs → chunk-PD6HYHAE.mjs} +4 -15
- package/dist/js/chunks/chunk-PD6HYHAE.mjs.map +7 -0
- package/dist/js/chunks/{chunk-ZAS25YFD.mjs → chunk-PDG64UHF.mjs} +3 -3
- package/dist/js/chunks/{chunk-QERLECVU.mjs → chunk-PO3AXVR3.mjs} +38 -64
- package/dist/js/chunks/chunk-PO3AXVR3.mjs.map +7 -0
- package/dist/js/chunks/{chunk-ILP3PDTL.mjs → chunk-QYGK36OG.mjs} +7 -13
- package/dist/js/chunks/chunk-QYGK36OG.mjs.map +7 -0
- package/dist/js/chunks/{chunk-S3XDFGSZ.mjs → chunk-SFI2U4YW.mjs} +28 -44
- package/dist/js/chunks/chunk-SFI2U4YW.mjs.map +7 -0
- package/dist/js/chunks/{chunk-FS7XY3HT.mjs → chunk-SMY7GJSS.mjs} +3 -3
- package/dist/js/chunks/{chunk-O5XPWXIQ.mjs → chunk-TCCA2HDG.mjs} +39 -31
- package/dist/js/chunks/chunk-TCCA2HDG.mjs.map +7 -0
- package/dist/js/chunks/{chunk-PM655FXL.mjs → chunk-TSZYSW7F.mjs} +4 -4
- package/dist/js/chunks/{chunk-PM655FXL.mjs.map → chunk-TSZYSW7F.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-UEZUJQ66.mjs → chunk-UAZSDUVP.mjs} +3 -4
- package/dist/js/chunks/{chunk-UEZUJQ66.mjs.map → chunk-UAZSDUVP.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-6N2XAEFK.mjs → chunk-UBRZZWRA.mjs} +10 -8
- package/dist/js/chunks/chunk-UBRZZWRA.mjs.map +7 -0
- package/dist/js/chunks/{chunk-5BKHWHYY.mjs → chunk-UCOE7ZDL.mjs} +41 -46
- package/dist/js/chunks/chunk-UCOE7ZDL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-4TKTLGEM.mjs → chunk-UETTGDLI.mjs} +3 -3
- package/dist/js/chunks/{chunk-RHRQKTTX.mjs → chunk-UNCRDLP6.mjs} +6 -9
- package/dist/js/chunks/chunk-UNCRDLP6.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GUB3TNO2.mjs → chunk-VGNYF6FB.mjs} +3 -6
- package/dist/js/chunks/{chunk-GUB3TNO2.mjs.map → chunk-VGNYF6FB.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-X7OCHZVF.mjs → chunk-VGPGBNGL.mjs} +4 -12
- package/dist/js/chunks/chunk-VGPGBNGL.mjs.map +7 -0
- package/dist/js/chunks/chunk-VKAUVTQY.mjs +1 -0
- package/dist/js/chunks/{chunk-HKT2S7VM.mjs → chunk-VM4FTS7L.mjs} +3 -3
- package/dist/js/chunks/{chunk-3GVFZ4XO.mjs → chunk-WDK4T63U.mjs} +8 -11
- package/dist/js/chunks/chunk-WDK4T63U.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GZKEFWPM.mjs → chunk-WOCCTVUF.mjs} +38 -34
- package/dist/js/chunks/chunk-WOCCTVUF.mjs.map +7 -0
- package/dist/js/chunks/{chunk-QJABDLSD.mjs → chunk-WQYN5L4E.mjs} +11 -16
- package/dist/js/chunks/chunk-WQYN5L4E.mjs.map +7 -0
- package/dist/js/chunks/{chunk-DAIU5SLG.mjs → chunk-X4ISMKE2.mjs} +2 -2
- package/dist/js/chunks/{chunk-3DHK5CZU.mjs → chunk-XAEAEHIX.mjs} +6 -8
- package/dist/js/chunks/chunk-XAEAEHIX.mjs.map +7 -0
- package/dist/js/chunks/{chunk-4HZMB7LI.mjs → chunk-ZX6M7SWO.mjs} +24 -24
- package/dist/js/chunks/chunk-ZX6M7SWO.mjs.map +7 -0
- package/dist/js/expressive.cjs +484 -507
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +484 -507
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +10 -13
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +54 -50
- package/dist/js/expressive.mjs.map +1 -1
- package/dist/js/internal/behaviors/bottomSheets.mjs +3 -3
- package/dist/js/internal/behaviors/dialogs.mjs +2 -2
- package/dist/js/internal/behaviors/forms.mjs +2 -2
- package/dist/js/internal/behaviors/sheetDrag.mjs +2 -2
- package/dist/js/internal/behaviors/sideSheets.mjs +3 -3
- package/dist/js/internal/components/appBar.mjs +2 -2
- package/dist/js/internal/components/autocomplete.mjs +4 -4
- package/dist/js/internal/components/barChart.mjs +4 -4
- package/dist/js/internal/components/buttonGroup.mjs +2 -2
- package/dist/js/internal/components/buttons.mjs +3 -3
- package/dist/js/internal/components/cards.mjs +3 -3
- package/dist/js/internal/components/carousel.mjs +3 -3
- package/dist/js/internal/components/characterCounter.mjs +2 -2
- package/dist/js/internal/components/chips.mjs +5 -5
- package/dist/js/internal/components/columnChart.mjs +3 -3
- package/dist/js/internal/components/commandPalette.mjs +3 -3
- package/dist/js/internal/components/confetti.mjs +2 -2
- package/dist/js/internal/components/datepicker.mjs +6 -6
- package/dist/js/internal/components/expandingCard.mjs +3 -3
- package/dist/js/internal/components/heatmapChart.mjs +3 -3
- package/dist/js/internal/components/index.mjs +47 -43
- package/dist/js/internal/components/keypad.mjs +9 -0
- package/dist/js/internal/components/keypad.mjs.map +7 -0
- package/dist/js/internal/components/lightbox.mjs +3 -3
- package/dist/js/internal/components/lineChart.mjs +6 -2
- package/dist/js/internal/components/mapView.mjs +3 -3
- package/dist/js/internal/components/menu.mjs +3 -3
- package/dist/js/internal/components/messageScroller.mjs +3 -3
- package/dist/js/internal/components/mixedChart.mjs +4 -4
- package/dist/js/internal/components/navigationRail.mjs +2 -2
- package/dist/js/internal/components/particles.mjs +2 -2
- package/dist/js/internal/components/pieChart.mjs +3 -3
- package/dist/js/internal/components/questionnaire.mjs +3 -3
- package/dist/js/internal/components/radarChart.mjs +3 -3
- package/dist/js/internal/components/radialChart.mjs +3 -3
- package/dist/js/internal/components/registry.mjs +41 -40
- package/dist/js/internal/components/richTextEditor.mjs +3 -3
- package/dist/js/internal/components/scrollspy.mjs +2 -2
- package/dist/js/internal/components/select.mjs +4 -4
- package/dist/js/internal/components/slider.mjs +3 -3
- package/dist/js/internal/components/snackbar.mjs +2 -2
- package/dist/js/internal/components/tabs.mjs +4 -4
- package/dist/js/internal/components/timepicker.mjs +4 -4
- package/dist/js/internal/components/tooltip.mjs +3 -3
- package/dist/js/internal/core/component.mjs +1 -1
- package/dist/js/internal/core/utils.mjs +1 -1
- package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +2 -2
- package/dist/js/modular.mjs +54 -50
- package/dist/types/components/autocomplete.d.ts +1 -0
- package/dist/types/components/datepicker.d.ts +3 -4
- package/dist/types/components/expandingCard.d.ts +2 -0
- package/dist/types/components/index.d.ts +1 -0
- package/dist/types/components/keypad.d.ts +34 -0
- package/dist/types/components/lightbox.d.ts +3 -5
- package/dist/types/components/lineChart.d.ts +4 -0
- package/dist/types/components/menu.d.ts +1 -0
- package/dist/types/components/radialChart.d.ts +0 -1
- package/dist/types/components/registry.d.ts +4 -0
- package/dist/types/components/slider.d.ts +2 -0
- package/dist/types/components/snackbar.d.ts +1 -0
- package/dist/types/components/tabs.d.ts +4 -0
- package/dist/types/components/timepicker.d.ts +2 -0
- package/dist/types/modular.d.ts +1 -1
- package/dist/types/plugins/dockedDisplayPlugin.d.ts +1 -0
- package/package.json +1 -1
- package/src/sass/abstracts/_breakpoints.scss +0 -1
- package/src/sass/abstracts/_elevation.scss +1 -1
- package/src/sass/abstracts/_mixins.scss +20 -60
- package/src/sass/abstracts/_variables.scss +10 -0
- package/src/sass/base/_global.scss +3 -12
- package/src/sass/base/_index.scss +1 -1
- package/src/sass/components/_badges.scss +1 -8
- package/src/sass/components/_bar-chart.scss +1 -1
- package/src/sass/components/_button-groups.scss +31 -66
- package/src/sass/components/_cards.scss +6 -25
- package/src/sass/components/_carousel.scss +16 -55
- package/src/sass/components/_chips.scss +0 -6
- package/src/sass/components/_column-chart.scss +1 -1
- package/src/sass/components/_data-table.scss +1 -3
- package/src/sass/components/_datepicker.scss +3 -22
- package/src/sass/components/_dialog.scss +1 -4
- package/src/sass/components/_heatmap-chart.scss +2 -2
- package/src/sass/components/_icon-buttons.scss +0 -1
- package/src/sass/components/_index.scss +1 -0
- package/src/sass/components/_keypad.scss +162 -0
- package/src/sass/components/_lightbox.scss +3 -8
- package/src/sass/components/_map.scss +2 -2
- package/src/sass/components/_menu.scss +31 -74
- package/src/sass/components/_mixed-chart.scss +1 -1
- package/src/sass/components/_navbar.scss +9 -45
- package/src/sass/components/_navigation-rail.scss +23 -32
- package/src/sass/components/_page-footer.scss +15 -12
- package/src/sass/components/_panes.scss +2 -6
- package/src/sass/components/_progress.scss +6 -4
- package/src/sass/components/_side-sheet.scss +1 -4
- package/src/sass/components/_stepper.scss +0 -4
- package/src/sass/components/_timepicker.scss +4 -36
- package/src/sass/components/_toolbar.scss +0 -4
- package/src/sass/components/forms/_checkboxes.scss +37 -65
- package/src/sass/components/forms/_fieldset.scss +3 -3
- package/src/sass/components/forms/_file-input.scss +0 -1
- package/src/sass/components/forms/_radio-buttons.scss +10 -36
- package/src/sass/components/forms/_select.scss +0 -3
- package/src/sass/components/forms/_slider.scss +72 -259
- package/src/sass/tokens/_state.scss +2 -2
- package/src/sass/tokens/_theme.scss +1 -1
- package/src/sass/utilities/_colors.scss +6 -1
- package/src/sass/utilities/_index.scss +1 -1
- package/dist/js/chunks/chunk-3DHK5CZU.mjs.map +0 -7
- package/dist/js/chunks/chunk-3GVFZ4XO.mjs.map +0 -7
- package/dist/js/chunks/chunk-4HZMB7LI.mjs.map +0 -7
- package/dist/js/chunks/chunk-5BKHWHYY.mjs.map +0 -7
- package/dist/js/chunks/chunk-5HQSGDZ5.mjs.map +0 -7
- package/dist/js/chunks/chunk-6N2XAEFK.mjs.map +0 -7
- package/dist/js/chunks/chunk-A7ALMYUR.mjs.map +0 -7
- package/dist/js/chunks/chunk-GZKEFWPM.mjs.map +0 -7
- package/dist/js/chunks/chunk-ILP3PDTL.mjs.map +0 -7
- package/dist/js/chunks/chunk-JIDMQGK6.mjs.map +0 -7
- package/dist/js/chunks/chunk-KBNN3QDH.mjs +0 -7
- package/dist/js/chunks/chunk-KHV6DZXX.mjs.map +0 -7
- package/dist/js/chunks/chunk-KY6U46SM.mjs.map +0 -7
- package/dist/js/chunks/chunk-LRZMJZ3T.mjs.map +0 -7
- package/dist/js/chunks/chunk-LTWPGFBR.mjs.map +0 -7
- package/dist/js/chunks/chunk-MNPROCZF.mjs.map +0 -7
- package/dist/js/chunks/chunk-O5XPWXIQ.mjs.map +0 -7
- package/dist/js/chunks/chunk-QERLECVU.mjs.map +0 -7
- package/dist/js/chunks/chunk-QJABDLSD.mjs.map +0 -7
- package/dist/js/chunks/chunk-RHRQKTTX.mjs.map +0 -7
- package/dist/js/chunks/chunk-S3XDFGSZ.mjs.map +0 -7
- package/dist/js/chunks/chunk-SPETGK25.mjs.map +0 -7
- package/dist/js/chunks/chunk-VGZSAFTX.mjs.map +0 -7
- package/dist/js/chunks/chunk-X7OCHZVF.mjs.map +0 -7
- package/dist/js/chunks/chunk-Z2NRKI7R.mjs.map +0 -7
- package/dist/js/chunks/chunk-ZKZKNSLC.mjs +0 -1
- /package/dist/js/chunks/{chunk-4KMNFIFZ.mjs.map → chunk-33QVDDGR.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-CUQPB25U.mjs.map → chunk-AIURVCG6.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-BG6ZRB5H.mjs.map → chunk-C6CHEWYP.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-GVGT6MIU.mjs.map → chunk-CK2XCICY.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-UEXCIMJZ.mjs.map → chunk-KUFHW3DS.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-YDCS5S3J.mjs.map → chunk-L27Q6ZMI.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-NS2UMNZV.mjs.map → chunk-LQWUDNHZ.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-ZAS25YFD.mjs.map → chunk-PDG64UHF.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-FS7XY3HT.mjs.map → chunk-SMY7GJSS.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-4TKTLGEM.mjs.map → chunk-UETTGDLI.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-ZKZKNSLC.mjs.map → chunk-VKAUVTQY.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-HKT2S7VM.mjs.map → chunk-VM4FTS7L.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-DAIU5SLG.mjs.map → chunk-X4ISMKE2.mjs.map} +0 -0
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/behaviors/forms.ts"],
|
|
4
|
-
"sourcesContent": ["import { Utils } from '../core/utils';\n\nexport class Forms {\n /**\n * Checks if the label has validation and apply\n * the correct class and styles\n * @param textfield\n */\n static validateField(textfield: HTMLInputElement) {\n if (!textfield) {\n console.error('No text field element found');\n return;\n }\n\n const hasLength = textfield.getAttribute('data-length') !== null;\n const lenAttr = parseInt(textfield.getAttribute('data-length'));\n const len = textfield.value.length;\n\n if (\n len === 0 &&\n textfield.validity.badInput === false &&\n !textfield.required &&\n textfield.classList.contains('validate')\n ) {\n textfield.classList.remove('invalid');\n } else if (textfield.classList.contains('validate')) {\n // Check for character counter attributes\n if (\n (textfield.validity.valid && hasLength && len <= lenAttr) ||\n (textfield.validity.valid && !hasLength)\n ) {\n textfield.classList.remove('invalid');\n } else {\n textfield.classList.add('invalid');\n }\n }\n }\n\n /**\n * Resizes the given TextArea after updating the\n * value content dynamically.\n * @param e EventTarget\n */\n static textareaAutoResize(e: EventTarget) {\n const textarea = e as HTMLTextAreaElement;\n if (!textarea) return;\n\n // Measure the textarea against itself: collapse it to its natural height,\n // then read the content height back. `.expressive-textarea` is\n // `overflow-y: hidden`, so scrollHeight is the full content height and\n // offsetHeight - clientHeight is exactly the borders (no scrollbar to\n // account for) - which border-box sizing needs added back.\n //\n // This replaces a mirror div that the value was copied into via\n // `innerHTML = innerHTML.replace(...)` - a full serialize and reparse of\n // the text on every keystroke, plus getComputedStyle and seven style\n // writes, run twice per keystroke because it was bound to keydown and\n // keyup both.\n if (!textarea.hasAttribute('original-height')) {\n textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString());\n }\n const originalHeight = parseInt(textarea.getAttribute('original-height'));\n if (isNaN(originalHeight)) return;\n\n textarea.style.height = 'auto';\n // Three reads after a single write: one layout flush for the whole resize.\n const borders = textarea.offsetHeight - textarea.clientHeight;\n const contentHeight = textarea.scrollHeight + borders;\n textarea.style.height = Math.max(originalHeight, contentHeight) + 'px';\n }\n\n private static _initialized = false;\n\n /**\n * Safe to call more than once: the root entry calls it on import, and a page\n * that also loads the modular entry may call it again.\n */\n static Init() {\n if (Forms._initialized) return;\n Forms._initialized = true;\n Utils.onDocumentReady(() => {\n document.addEventListener('change', (e: KeyboardEvent) => {\n const target = <HTMLInputElement>e.target;\n if (target instanceof HTMLInputElement && target.type === 'file') {\n const zone = target.closest('.drop-zone');\n if (zone) Forms.listDropZoneFiles(zone, target);\n }\n if (target instanceof HTMLInputElement) {\n // The sibling-label loop that used to live here compared\n // `tagName == 'label'` (tagName is uppercase) so it never matched,\n // and no rule in the Sass styles `label.active` anyway - the\n // floating label is driven by CSS, not by a class from here.\n Forms.validateField(target);\n }\n });\n\n document.addEventListener('keyup', (e: KeyboardEvent) => {\n const target = <HTMLInputElement>e.target;\n // Radio and Checkbox focus class\n if (target instanceof HTMLInputElement && ['radio', 'checkbox'].includes(target.type)) {\n // TAB, check if tabbing to radio or checkbox.\n if (e.key === Utils.keys.TAB) {\n target.classList.add('tabbed');\n target.addEventListener('blur', () => target.classList.remove('tabbed'), {\n once: true\n });\n }\n }\n });\n\n document.addEventListener('click', Forms.togglePassword);\n // Capture, so the password is hidden again before any submit handler\n // reads the form or the browser offers to save it.\n document.addEventListener('submit', Forms.resetFormExtras, true);\n document.addEventListener('reset', Forms.resetFormExtras, true);\n for (const type of ['dragenter', 'dragover', 'dragleave', 'drop']) {\n document.addEventListener(type, Forms.markDropZone);\n }\n\n document.querySelectorAll('.expressive-textarea').forEach((textArea: HTMLTextAreaElement) => {\n Forms.InitTextarea(textArea);\n });\n\n // File Input Path\n document\n .querySelectorAll('.file-field input[type=\"file\"]')\n .forEach((fileInput: HTMLInputElement) => {\n Forms.InitFileInputPath(fileInput);\n });\n });\n }\n\n /**\n * A .password-toggle button shows or hides the password in its field. The\n * button's own name stays put (\"Show password\"); aria-pressed carries the\n * state, so there is no generated text to translate.\n */\n static togglePassword(e: MouseEvent) {\n const button = (<Element>e.target).closest?.('.password-toggle');\n const input = button?.closest('.field')?.querySelector<HTMLInputElement>(\n 'input[type=\"password\"], input[data-password]'\n );\n if (!input) return;\n const show = input.type === 'password';\n // Marked so the input is still found once it has become type=\"text\".\n input.toggleAttribute('data-password', show);\n input.type = show ? 'text' : 'password';\n button.setAttribute('aria-pressed', String(show));\n }\n\n /**\n * A revealed password goes back to type=\"password\" when its form is\n * submitted or reset, so it is never sent or autofilled as plain text and\n * a reset field does not stay revealed. A reset form also drops the file\n * lists it would otherwise leave showing: reset fires no change event.\n */\n static resetFormExtras(e: Event) {\n const form = e.target;\n if (!(form instanceof HTMLFormElement)) return;\n form.querySelectorAll<HTMLInputElement>('input[data-password]').forEach((input) => {\n input.removeAttribute('data-password');\n input.type = 'password';\n input.closest('.field')?.querySelector('.password-toggle')?.setAttribute('aria-pressed', 'false');\n });\n if (e.type === 'reset') {\n form.querySelectorAll('.drop-zone-files').forEach((list) => list.replaceChildren());\n form.querySelectorAll('.drop-zone.dragover').forEach((zone) => zone.classList.remove('dragover'));\n }\n }\n\n /**\n * The native file input covers its .drop-zone, so the browser already takes\n * a dropped file. This only shows the drag: the input is the topmost\n * element, so every drag event over the zone targets it and leaving it is\n * leaving the zone.\n */\n static markDropZone(e: DragEvent) {\n const input = <Element>e.target;\n if (!(input instanceof HTMLInputElement) || input.type !== 'file') return;\n const zone = input.closest('.drop-zone');\n if (!zone) return;\n const over = e.type === 'dragenter' || e.type === 'dragover';\n zone.classList.toggle('dragover', over && !input.disabled);\n }\n\n /** Lists the chosen files, name and size, in the zone's .drop-zone-files. */\n static listDropZoneFiles(zone: Element, input: HTMLInputElement) {\n const list = zone.querySelector('.drop-zone-files');\n if (!list) return;\n const size = (bytes: number) => {\n const [value, unit] =\n bytes >= 1e6 ? [bytes / 1e6, 'megabyte'] : bytes >= 1e3 ? [bytes / 1e3, 'kilobyte'] : [bytes, 'byte'];\n return new Intl.NumberFormat(undefined, { style: 'unit', unit, maximumFractionDigits: 1 }).format(value);\n };\n list.replaceChildren(\n ...Array.from(input.files ?? [], (file) => {\n const item = document.createElement('li');\n const name = document.createElement('span');\n const meta = document.createElement('span');\n name.textContent = file.name;\n meta.textContent = size(file.size);\n item.append(name, meta);\n return item;\n })\n );\n }\n\n static InitTextarea(textarea: HTMLTextAreaElement) {\n // Save Data in Element\n textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString());\n Forms.textareaAutoResize(textarea);\n // `input` rather than keydown + keyup: it fires once per actual value\n // change and also covers paste, drag-drop and IME composition, which the\n // key events missed.\n textarea.addEventListener('input', (e) => Forms.textareaAutoResize(e.target));\n }\n\n static InitFileInputPath(fileInput: HTMLInputElement) {\n fileInput.addEventListener('change', () => {\n const fileField = fileInput.closest('.file-field');\n const pathInput = <HTMLInputElement>fileField.querySelector('input.file-path');\n const files = fileInput.files;\n const filenames = [];\n for (let i = 0; i < files.length; i++) {\n filenames.push(files[i].name);\n }\n pathInput.value = filenames.join(', ');\n pathInput.dispatchEvent(\n new Event('change', { bubbles: true, cancelable: true, composed: true })\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/menu.ts"],
|
|
4
|
-
"sourcesContent": ["import { Utils } from '../core/utils';\nimport { Component, BaseOptions, InitElements, InitElement, Openable } from '../core/component';\n\nexport interface MenuOptions extends BaseOptions {\n /**\n * Defines the edge the menu is aligned to.\n * @default 'left'\n */\n alignment: 'left' | 'right';\n /**\n * If true, automatically focus menu el for keyboard.\n * @default true\n */\n autoFocus: boolean;\n /**\n * If true, constrainWidth to the size of the menu activator.\n *\n * A trigger narrower than the surface's own 112dp minimum cannot be\n * honoured, so such a menu is sized to its content instead - see\n * MIN_SURFACE_WIDTH.\n * @default true\n */\n constrainWidth: boolean;\n /**\n * Provide an element that will be the bounding container of the menu.\n * @default null\n */\n container: Element | ShadowRoot;\n /**\n * If false, the menu will show below the trigger.\n * That is the M3 placement. Pass `true` to cover the trigger.\n * @default false\n */\n coverTrigger: boolean;\n /**\n * If true, close menu on item click.\n * @default true\n */\n closeOnClick: boolean;\n /**\n * If true, the menu will open on hover.\n * @default false\n */\n hover: boolean;\n /**\n * If true, the trigger is a region and the menu is its context menu: it\n * opens at the pointer on right-click, long-press or the keyboard context\n * menu key instead of on click. `data-context-menu` on the trigger sets it.\n * @default false\n */\n contextMenu: boolean;\n /**\n * The duration of the transition enter in milliseconds.\n * @default 150\n */\n inDuration: number;\n /**\n * The duration of the transition out in milliseconds.\n * @default 250\n */\n outDuration: number;\n /**\n * Function called when menu starts entering.\n * @default null\n */\n onOpenStart: (el: HTMLElement) => void;\n /**\n * Function called when menu finishes entering.\n * @default null\n */\n onOpenEnd: (el: HTMLElement) => void;\n /**\n * Function called when menu starts exiting.\n * @default null\n */\n onCloseStart: (el: HTMLElement) => void;\n /**\n * Function called when menu finishes exiting.\n * @default null\n */\n onCloseEnd: (el: HTMLElement) => void;\n /**\n * Function called when item is clicked.\n * @default null\n */\n onItemClick: (el: HTMLLIElement) => void;\n}\n\n// The menu surface's own width bounds, stated in `components/_menu.scss` and\n// restated here because the constraint below has to reason about them.\nconst MIN_SURFACE_WIDTH = 112;\nconst MAX_SURFACE_WIDTH = 280;\n\nconst _defaults: MenuOptions = {\n alignment: 'left',\n autoFocus: true,\n constrainWidth: true,\n container: null,\n coverTrigger: false,\n closeOnClick: true,\n hover: false,\n contextMenu: false,\n inDuration: 150,\n outDuration: 250,\n onOpenStart: null,\n onOpenEnd: null,\n onCloseStart: null,\n onCloseEnd: null,\n onItemClick: null\n};\n\nconst SPACE = ' ';\n\nexport class Menu extends Component<MenuOptions> implements Openable {\n static _menus: Menu[] = [];\n /** ID of the menu element. */\n id: string;\n /** The DOM element of the menu. */\n menuEl: HTMLElement;\n /** If the menu is open. */\n isOpen: boolean;\n /** If the menu content is scrollable. */\n isScrollable: boolean;\n isTouchMoving: boolean;\n /** The index of the item focused. */\n focusedIndex: number;\n filterQuery: string[];\n filterTimeout: ReturnType<typeof setTimeout>;\n private _pendingTimers = new Set<ReturnType<typeof setTimeout>>();\n private _transition = 0;\n private _originalInert: string | null;\n private _menuClickTargets = new WeakMap<Event, HTMLElement>();\n /**\n * Viewport point the open context menu belongs to. Null outside a\n * right-click, so a keyboard or programmatic open uses the region's corner\n * rather than an old pointer position.\n */\n private _contextPoint: { x: number; y: number } | null = null;\n /** What had focus when a context menu opened; focus goes back there. */\n private _contextReturn: HTMLElement | null = null;\n\n constructor(el: HTMLElement, options: Partial<MenuOptions>) {\n super(el, options, Menu);\n this.el['Expressive_Menu'] = this;\n\n Menu._menus.push(this);\n this.id = Utils.getIdFromTrigger(el);\n this.menuEl = Utils.getElementById(el, this.id);\n this._originalInert = this.menuEl?.getAttribute('inert') ?? null;\n\n this.options = {\n ...Menu.defaults,\n contextMenu: el.hasAttribute('data-context-menu'),\n ...options\n };\n\n this.isOpen = false;\n this.isScrollable = false;\n this.isTouchMoving = false;\n this.focusedIndex = -1;\n this.filterQuery = [];\n // A context region is content, not a button: expanded, haspopup and\n // controls are not valid on it, and the menu key is how it is discovered.\n if (!this.options.contextMenu) {\n this.el.ariaExpanded = 'false';\n if (!this.el.hasAttribute('aria-haspopup')) this.el.setAttribute('aria-haspopup', 'menu');\n if (this.id && !this.el.hasAttribute('aria-controls'))\n this.el.setAttribute('aria-controls', this.id);\n }\n\n // Keep the menu next to the trigger so positioning stays local.\n this._moveMenuToElement();\n this._setupAccessibility();\n this._makeMenuFocusable();\n this._setupSubmenus();\n this._setupEventHandlers();\n }\n\n static get defaults(): MenuOptions {\n return _defaults;\n }\n\n /**\n * Initializes instance of Menu.\n * @param el HTML element.\n * @param options Component options.\n */\n static init(el: HTMLElement, options?: Partial<MenuOptions>): Menu;\n /**\n * Initializes instances of Menu.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(els: InitElements<InitElement>, options?: Partial<MenuOptions>): Menu[];\n /**\n * Initializes instances of Menu.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<MenuOptions> = {}\n ): Menu | Menu[] {\n return super.init(els, options, Menu);\n }\n\n static getInstance(el: HTMLElement): Menu {\n return el['Expressive_Menu'];\n }\n\n destroy() {\n this._clearPendingTimers();\n this.isOpen = false;\n this._setExpanded(false);\n clearTimeout(this.filterTimeout);\n this._resetMenuStyles();\n this._restoreInert();\n this._removeEventHandlers();\n // Temporary handlers only exist while open, but removing them is a no-op\n // otherwise and leaving them attached leaks the instance.\n this._removeTemporaryEventHandlers();\n const index = Menu._menus.indexOf(this);\n if (index >= 0) Menu._menus.splice(index, 1);\n this.el['Expressive_Menu'] = undefined;\n }\n\n _setupEventHandlers() {\n // Trigger keydown handler\n this.el.addEventListener('keydown', this._handleTriggerKeydown);\n // Item click handler\n this.menuEl?.addEventListener('click', this._handleMenuClick);\n if (this.menuEl?.querySelector(':scope > li > menu')) {\n this.menuEl.addEventListener('mouseover', this._handleSubmenuAlign);\n }\n if (this.options.contextMenu) {\n this.el.addEventListener('contextmenu', this._handleContextMenu);\n } else if (this.options.hover) {\n // Hover event handlers\n this.el.addEventListener('mouseenter', this._handleMouseEnter);\n this.el.addEventListener('mouseleave', this._handleMouseLeave);\n this.menuEl.addEventListener('mouseleave', this._handleMouseLeave);\n // Click event handlers\n } else {\n this.el.addEventListener('click', this._handleClick);\n }\n }\n\n _removeEventHandlers() {\n // `menuEl` is optional-chained on the way in (the trigger may point at\n // an id that does not resolve); it has to be here too, or destroy() throws\n // before it can detach anything else.\n this.el.removeEventListener('keydown', this._handleTriggerKeydown);\n this.menuEl?.removeEventListener('click', this._handleMenuClick);\n this.menuEl?.removeEventListener('mouseover', this._handleSubmenuAlign);\n if (this.options.contextMenu) {\n this.el.removeEventListener('contextmenu', this._handleContextMenu);\n } else if (this.options.hover) {\n this.el.removeEventListener('mouseenter', this._handleMouseEnter);\n this.el.removeEventListener('mouseleave', this._handleMouseLeave);\n this.menuEl?.removeEventListener('mouseleave', this._handleMouseLeave);\n } else {\n this.el.removeEventListener('click', this._handleClick);\n }\n }\n\n _setupTemporaryEventHandlers() {\n document.body.addEventListener('click', this._handleDocumentClick);\n this.menuEl?.addEventListener('touchmove', this._handleDocumentTouchmove, { passive: true });\n document.body.addEventListener('touchmove', this._handleDocumentTouchmove, {\n passive: true\n });\n this.menuEl?.addEventListener('keydown', this._handleMenuKeydown);\n window.addEventListener('resize', this._handleWindowResize);\n // A right-click elsewhere fires no click, so it would leave the menu open.\n if (this.options.contextMenu) document.addEventListener('contextmenu', this._handleDocumentContextMenu);\n }\n\n _removeTemporaryEventHandlers() {\n document.body.removeEventListener('click', this._handleDocumentClick);\n this.menuEl?.removeEventListener('touchmove', this._handleDocumentTouchmove);\n document.body.removeEventListener('touchmove', this._handleDocumentTouchmove);\n this.menuEl?.removeEventListener('keydown', this._handleMenuKeydown);\n window.removeEventListener('resize', this._handleWindowResize);\n document.removeEventListener('contextmenu', this._handleDocumentContextMenu);\n }\n\n _handleContextMenu = (e: MouseEvent) => {\n // A nested region already answered this right-click; this one closes so\n // two menus never stack.\n if (e.defaultPrevented) {\n this.close();\n return;\n }\n // A right-click on another open menu inside this region belongs to that\n // menu, which keeps itself open.\n const path = e.composedPath();\n if (Menu._menus.some((menu) => menu !== this && menu.isOpen && path.includes(menu.menuEl))) return;\n e.preventDefault();\n if (!this.isOpen) {\n const root = this.el.getRootNode() as Document | ShadowRoot;\n this._contextReturn = root.activeElement instanceof HTMLElement ? root.activeElement : null;\n }\n // The menu key and Shift+F10 fire this too, with a point that may sit\n // outside the region (0, 0 in some engines). Those leave the point unset\n // and open at the region's start corner.\n const rect = this.el.getBoundingClientRect();\n const fromPointer =\n (e.clientX !== 0 || e.clientY !== 0) &&\n e.clientX >= rect.left && e.clientX <= rect.right &&\n e.clientY >= rect.top && e.clientY <= rect.bottom;\n this._contextPoint = fromPointer ? { x: e.clientX, y: e.clientY } : null;\n if (this.isOpen) this.recalculateDimensions();\n else this.open();\n };\n\n _handleDocumentContextMenu = (e: MouseEvent) => {\n const path = e.composedPath();\n // A right-click on the menu itself keeps it open and the browser's own\n // menu shut.\n if (path.includes(this.menuEl)) {\n e.preventDefault();\n return;\n }\n if (!path.includes(this.el)) this.close();\n };\n\n _handleClick = (e: MouseEvent) => {\n e.preventDefault();\n //this._moveMenu((<HTMLElement>e.target).closest('li'));\n if (this.isOpen) {\n this.close();\n } else {\n this.open();\n }\n };\n\n _handleMouseEnter = () => {\n //this._moveMenu((<HTMLElement>e.target).closest('li'));\n this.open();\n };\n\n _handleMouseLeave = (e: MouseEvent) => {\n const toEl = e.relatedTarget as HTMLElement;\n // relatedTarget is null when the pointer leaves the window entirely.\n if (!toEl) {\n this.close();\n return;\n }\n const leaveToMenuContent = !!(this.menuEl && toEl && this.menuEl.contains(toEl));\n let leaveToActiveMenuTrigger = false;\n const closestTrigger = toEl.closest('.menu-trigger');\n if (\n closestTrigger &&\n !!closestTrigger['Expressive_Menu'] &&\n closestTrigger['Expressive_Menu'].isOpen\n ) {\n leaveToActiveMenuTrigger = true;\n }\n // Close hover menu if mouse did not leave to either active menu-trigger or menu-content\n if (!leaveToActiveMenuTrigger && !leaveToMenuContent) {\n this.close();\n }\n };\n\n _handleDocumentClick = (e: MouseEvent) => {\n const path = e.composedPath();\n const menuTarget = this._menuClickTargets.get(e);\n this._menuClickTargets.delete(e);\n const target = menuTarget ?? <HTMLElement>(path[0] || e.target);\n const inside = !!menuTarget || path.includes(this.menuEl) || this.menuEl?.contains(target);\n if (this._isSubmenuTriggerClick(target)) return;\n if (this.options.closeOnClick && inside && !this.isTouchMoving) {\n // isTouchMoving to check if scrolling on mobile.\n this.close();\n } else if (!inside) {\n // Do this one frame later so that if the element clicked also triggers _handleClick\n // For example, if a label for a select was clicked, that we don't close/open the menu\n this._schedule(() => {\n if (this.isOpen) {\n this.close();\n }\n }, 0);\n }\n this.isTouchMoving = false;\n };\n\n _handleTriggerKeydown = (e: KeyboardEvent) => {\n // A context region keeps its keys for its own content; the browser turns\n // the menu key and Shift+F10 into a contextmenu event.\n if (this.options.contextMenu) return;\n // M3: Space, Enter, Arrow Down, and Arrow Up open a closed menu.\n const opensMenu =\n e.key === SPACE ||\n e.key === Utils.keys.ENTER ||\n e.key === Utils.keys.ARROW_DOWN ||\n e.key === Utils.keys.ARROW_UP;\n if (opensMenu && !this.isOpen) {\n e.preventDefault();\n this.open();\n }\n };\n\n _handleDocumentTouchmove = (e: TouchEvent) => {\n const target = <HTMLElement>e.target;\n if (e.composedPath().includes(this.menuEl) || this.menuEl?.contains(target)) {\n this.isTouchMoving = true;\n }\n };\n\n _handleMenuClick = (e: MouseEvent) => {\n const target = <HTMLElement>e.target;\n // Closed shadow roots hide the original target from document listeners.\n this._menuClickTargets.set(e, target);\n const li = target.closest('li');\n if (li?.matches('.disabled, [aria-disabled=\"true\"]')) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (li && this._isSubmenuTriggerClick(target)) {\n e.preventDefault();\n e.stopPropagation();\n this._toggleSubmenu(li);\n return;\n }\n if (li && typeof this.options.onItemClick === 'function') {\n this.options.onItemClick.call(this, li);\n }\n };\n\n private _setupAccessibility() {\n if (!this.menuEl) return;\n if (!this.menuEl.hasAttribute('role')) this.menuEl.setAttribute('role', 'menu');\n\n const menus = [this.menuEl, ...this.menuEl.querySelectorAll('menu')];\n menus.forEach((menu) => {\n if (!menu.hasAttribute('role')) menu.setAttribute('role', 'menu');\n if (menu.getAttribute('role') !== 'menu') return;\n\n menu.querySelectorAll(':scope > li').forEach((li) => {\n if (li.classList.contains('divider')) {\n if (!li.hasAttribute('role')) li.setAttribute('role', 'separator');\n return;\n }\n if (li.classList.contains('gap')) {\n li.setAttribute('aria-hidden', 'true');\n return;\n }\n if (li.classList.contains('label') || li.classList.contains('optgroup')) {\n if (!li.hasAttribute('role')) li.setAttribute('role', 'presentation');\n return;\n }\n if (!li.hasAttribute('role')) li.setAttribute('role', 'menuitem');\n if (li.classList.contains('disabled') && !li.hasAttribute('aria-disabled')) {\n li.setAttribute('aria-disabled', 'true');\n }\n });\n });\n }\n\n private _isSubmenuTriggerClick(target: HTMLElement) {\n if (!this.menuEl) return false;\n const li = target.closest('li');\n if (!li || !this.menuEl.contains(li)) return false;\n const submenu = li.querySelector(':scope > menu');\n if (!submenu) return false;\n return !submenu.contains(target);\n }\n\n private _setupSubmenus() {\n this.menuEl?.querySelectorAll('li').forEach((li) => {\n if (!li.querySelector(':scope > menu')) return;\n const trigger = li.querySelector(':scope > a, :scope > button, :scope > span') ?? li;\n trigger.setAttribute('aria-haspopup', 'menu');\n trigger.setAttribute('aria-expanded', 'false');\n });\n }\n\n private _toggleSubmenu(li: HTMLElement) {\n const open = !li.classList.contains('open');\n li.parentElement?.querySelectorAll(':scope > li.open').forEach((other) => {\n if (other !== li) {\n other.classList.remove('open', 'submenu-start');\n this._syncSubmenuAria(other as HTMLElement, false);\n }\n });\n li.classList.toggle('open', open);\n if (open) this._alignSubmenu(li);\n this._syncSubmenuAria(li, open);\n }\n\n private _syncSubmenuAria(li: HTMLElement, open: boolean) {\n const trigger = li.querySelector(':scope > a, :scope > button, :scope > span') ?? li;\n trigger.setAttribute('aria-expanded', open ? 'true' : 'false');\n }\n\n private _handleSubmenuAlign = (e: MouseEvent) => {\n const target = e.target;\n if (!(target instanceof Element)) return;\n const li = target.closest('li');\n if (li?.querySelector(':scope > menu') && this.menuEl?.contains(li)) {\n this._alignSubmenu(li as HTMLElement);\n }\n };\n\n private _alignSubmenu(li: HTMLElement) {\n const menu = li.querySelector(':scope > menu') as HTMLElement | null;\n if (!menu) return;\n // Flyouts stay `display: block` (visibility/opacity hide them) so the\n // rect is readable without temporarily painting the menu.\n li.classList.remove('submenu-start');\n const rect = menu.getBoundingClientRect();\n if (rect.left < 8 || rect.right > window.innerWidth - 8) li.classList.add('submenu-start');\n }\n\n private _closeSubmenus() {\n this.menuEl?.querySelectorAll('li.open').forEach((li) => {\n li.classList.remove('open', 'submenu-start');\n this._syncSubmenuAria(li as HTMLElement, false);\n });\n }\n\n private _containingSubmenu(e: Event): HTMLElement | null {\n const target = e.target;\n if (!(target instanceof Element)) return null;\n const submenu = target.closest('li > menu');\n if (submenu instanceof HTMLElement && this.menuEl?.contains(submenu)) return submenu;\n return null;\n }\n\n private _focusedRow(e: Event): HTMLElement | null {\n const target = e.target;\n if (!(target instanceof Element)) return null;\n const li = target.closest('li');\n if (li instanceof HTMLElement && this.menuEl?.contains(li)) return li;\n return null;\n }\n\n _handleMenuKeydown = (e: KeyboardEvent) => {\n if (!this.isOpen || e.ctrlKey || e.metaKey || e.altKey || e.isComposing) return;\n const list = this._containingSubmenu(e) ?? this.menuEl;\n const rtl = getComputedStyle(list).direction === 'rtl';\n const openKey = rtl ? Utils.keys.ARROW_LEFT : Utils.keys.ARROW_RIGHT;\n const backKey = rtl ? Utils.keys.ARROW_RIGHT : Utils.keys.ARROW_LEFT;\n if ([openKey, backKey, Utils.keys.ARROW_UP, Utils.keys.ARROW_DOWN, Utils.keys.ESC, Utils.keys.TAB].includes(e.key)) {\n clearTimeout(this.filterTimeout);\n this._resetFilterQuery();\n }\n const arrowUpOrDown =\n e.key === Utils.keys.ARROW_DOWN || e.key === Utils.keys.ARROW_UP;\n if (e.key === Utils.keys.TAB) {\n e.preventDefault();\n this.close();\n } else if (e.key === openKey) {\n const li = this._focusedRow(e);\n if (li?.querySelector(':scope > menu') && !li.matches('.disabled, [aria-disabled=\"true\"]')) {\n e.preventDefault();\n li.classList.add('open');\n this._alignSubmenu(li);\n this._syncSubmenuAria(li, true);\n const first = Array.from(li.querySelector(':scope > menu').children).find(\n child => child instanceof HTMLElement && child.tabIndex !== -1\n ) as HTMLElement | undefined;\n if (first) this._focusRow(first);\n }\n } else if (e.key === backKey) {\n const submenu = this._containingSubmenu(e);\n if (submenu) {\n e.preventDefault();\n const parentLi = submenu.parentElement as HTMLElement;\n parentLi.classList.remove('open', 'submenu-start');\n this._syncSubmenuAria(parentLi, false);\n this._focusRow(parentLi);\n }\n }\n // Navigate down menu list\n else if (arrowUpOrDown && this.isOpen) {\n e.preventDefault();\n const direction = e.key === Utils.keys.ARROW_DOWN ? 1 : -1;\n const row = this._focusedRow(e);\n let newFocusedIndex = row ? Array.from(list.children).indexOf(row) : this.focusedIndex;\n let hasFoundNewIndex = false;\n do {\n newFocusedIndex = newFocusedIndex + direction;\n if (\n !!list.children[newFocusedIndex] &&\n (<HTMLLIElement>list.children[newFocusedIndex]).tabIndex !== -1\n ) {\n hasFoundNewIndex = true;\n break;\n }\n } while (newFocusedIndex < list.children.length && newFocusedIndex >= 0);\n\n if (hasFoundNewIndex) {\n if (this.focusedIndex >= 0) list.children[this.focusedIndex]?.classList.remove('active');\n const item = list.children[newFocusedIndex] as HTMLElement;\n item.classList.add('active');\n this._focusRow(item);\n }\n }\n // SPACE OR ENTER selects the focused item.\n else if ((e.key === Utils.keys.ENTER || e.key === SPACE) && this.isOpen) {\n const li = this._focusedRow(e);\n e.preventDefault();\n if (li?.matches('.disabled, [aria-disabled=\"true\"]')) return;\n if (li?.querySelector(':scope > menu')) {\n this._toggleSubmenu(li);\n return;\n }\n const focusedElement = li ?? this.menuEl.children[this.focusedIndex];\n const activatableElement = <HTMLElement>focusedElement?.querySelector(':scope > a, :scope > button');\n if (!!activatableElement) {\n activatableElement.click();\n } else if (focusedElement instanceof HTMLElement) {\n focusedElement.click();\n }\n }\n // Close menu on ESC\n else if (e.key === Utils.keys.ESC && this.isOpen) {\n e.preventDefault();\n const openSub = this._containingSubmenu(e)?.parentElement ??\n Array.from(this.menuEl.querySelectorAll('li.open')).reverse()[0];\n if (openSub) {\n openSub.classList.remove('open', 'submenu-start');\n this._syncSubmenuAria(openSub as HTMLElement, false);\n this._focusRow(openSub as HTMLElement);\n } else {\n this.close();\n }\n }\n\n const keyText = e.key.toLowerCase();\n if (e.key.length === 1 && e.key !== SPACE && !e.ctrlKey && !e.metaKey && !e.altKey && !e.isComposing) {\n this.filterQuery.push(keyText);\n const string = this.filterQuery.join('');\n // textContent rather than innerText: this scans every item on every\n // keystroke, and innerText forces a layout flush per item.\n const newOptionEl = Array.from(list.querySelectorAll(':scope > li')).find(\n (el) => (el as HTMLElement).tabIndex !== -1 &&\n !el.matches('.disabled, [aria-disabled=\"true\"]') &&\n Array.from(el.childNodes).filter(node => !(node instanceof Element && node.matches('menu')))\n .map(node => node.textContent).join('').trim().toLowerCase().startsWith(string)\n );\n if (newOptionEl) {\n this._focusRow(newOptionEl as HTMLElement);\n }\n // Re-arm rather than stack: without the clear, every keystroke left a live\n // timer behind and the query could reset while the user was still typing.\n clearTimeout(this.filterTimeout);\n this.filterTimeout = setTimeout(this._resetFilterQuery, 1000);\n }\n };\n\n _handleWindowResize = () => {\n // Only re-place the menu if it's still visible\n // Accounts for elements hiding via media queries\n if (this.el.offsetParent) {\n this.recalculateDimensions();\n }\n };\n\n _resetFilterQuery = () => {\n this.filterQuery = [];\n };\n\n private _restoreInert() {\n if (this._originalInert === null) this.menuEl?.removeAttribute('inert');\n else this.menuEl?.setAttribute('inert', this._originalInert);\n }\n\n private _focusRow(item: HTMLElement) {\n this.focusedIndex = Array.from(item.parentElement.children).indexOf(item);\n item.focus({ preventScroll: true });\n item.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n }\n\n _resetMenuStyles() {\n // destroy() runs this even when the menu target was never found.\n if (!this.menuEl) return;\n this.menuEl.style.display = '';\n this._resetMenuPositioningStyles();\n this.menuEl.style.transform = '';\n this.menuEl.style.opacity = '';\n }\n\n _resetMenuPositioningStyles() {\n this.menuEl.style.width = '';\n this.menuEl.style.height = '';\n this.menuEl.style.left = '';\n this.menuEl.style.top = '';\n this.menuEl.style.transformOrigin = '';\n }\n\n _moveMenuToElement(containerEl: HTMLElement = null) {\n if (this.options.container) {\n this.options.container.append(this.menuEl);\n return;\n }\n if (containerEl) {\n if (!containerEl.contains(this.menuEl)) containerEl.append(this.menuEl);\n return;\n }\n this.el.after(this.menuEl);\n }\n\n _makeMenuFocusable() {\n if (!this.menuEl) return;\n this.menuEl.popover = '';\n // Focus moves directly to menu items; the surface itself is not a stop.\n this.menuEl.tabIndex = -1;\n // Only set tabindex if it hasn't been set by user\n this.menuEl.querySelectorAll(':scope li, :scope > hr').forEach((el) => {\n if (\n el instanceof HTMLHRElement ||\n el.classList.contains('divider') ||\n el.classList.contains('gap') ||\n el.classList.contains('label') ||\n el.classList.contains('optgroup')\n ) {\n el.setAttribute('tabindex', '-1');\n return;\n }\n if (!el.getAttribute('tabindex')) el.setAttribute('tabindex', '0');\n });\n }\n\n private _focusInitialItem() {\n if (!this.menuEl || !this.options.autoFocus) return;\n const first = Array.from(this.menuEl.children).find(\n (child) => child instanceof HTMLElement && child.tabIndex !== -1\n ) as HTMLElement | undefined;\n if (!first) return;\n this.focusedIndex = Array.from(this.menuEl.children).indexOf(first);\n first.focus({ preventScroll: true });\n }\n\n _focusFocusedItem() {\n if (\n this.focusedIndex >= 0 &&\n this.focusedIndex < this.menuEl.children.length &&\n this.options.autoFocus\n ) {\n (this.menuEl.children[this.focusedIndex] as HTMLElement).focus({\n preventScroll: true\n });\n this.menuEl.children[this.focusedIndex].scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n inline: 'nearest'\n });\n }\n }\n\n _getMenuPosition(closestOverflowParent: HTMLElement) {\n const triggerBRect = this.el.getBoundingClientRect();\n const menuBRect = this.menuEl.getBoundingClientRect();\n\n let idealHeight = menuBRect.height;\n let idealWidth = menuBRect.width;\n let idealXPos = triggerBRect.left - menuBRect.left;\n let idealYPos = triggerBRect.top - menuBRect.top;\n\n const menuBounds = {\n left: idealXPos,\n top: idealYPos,\n height: idealHeight,\n width: idealWidth\n };\n\n const alignments = Utils.checkPossibleAlignments(\n this.el,\n closestOverflowParent,\n menuBounds,\n this.options.coverTrigger ? 0 : triggerBRect.height\n );\n\n let verticalAlignment = 'top';\n let horizontalAlignment = this.options.alignment;\n idealYPos += this.options.coverTrigger ? 0 : triggerBRect.height;\n\n // Reset isScrollable\n this.isScrollable = false;\n\n if (!alignments.top) {\n if (alignments.bottom) {\n verticalAlignment = 'bottom';\n\n if (!this.options.coverTrigger) {\n idealYPos -= triggerBRect.height;\n }\n } else {\n this.isScrollable = true;\n\n // Determine which side has most space and cutoff at correct height\n idealHeight -= 20; // Add padding when cutoff\n if (alignments.spaceOnTop > alignments.spaceOnBottom) {\n verticalAlignment = 'bottom';\n idealHeight += alignments.spaceOnTop;\n idealYPos -= this.options.coverTrigger\n ? alignments.spaceOnTop - 20\n : alignments.spaceOnTop - 20 + triggerBRect.height;\n } else {\n idealHeight += alignments.spaceOnBottom;\n }\n }\n }\n\n // If preferred horizontal alignment is possible\n if (!alignments[horizontalAlignment]) {\n const oppositeAlignment = horizontalAlignment === 'left' ? 'right' : 'left';\n if (alignments[oppositeAlignment]) {\n horizontalAlignment = oppositeAlignment;\n } else {\n // Determine which side has most space and cutoff at correct height\n if (alignments.spaceOnLeft > alignments.spaceOnRight) {\n horizontalAlignment = 'right';\n idealWidth += alignments.spaceOnLeft;\n idealXPos -= alignments.spaceOnLeft;\n } else {\n horizontalAlignment = 'left';\n idealWidth += alignments.spaceOnRight;\n }\n }\n }\n\n if (verticalAlignment === 'bottom') {\n idealYPos =\n idealYPos - menuBRect.height + (this.options.coverTrigger ? triggerBRect.height : 0);\n }\n if (horizontalAlignment === 'right') {\n idealXPos = idealXPos - menuBRect.width + triggerBRect.width;\n }\n return {\n x: idealXPos,\n y: idealYPos,\n verticalAlignment: verticalAlignment,\n horizontalAlignment: horizontalAlignment,\n height: idealHeight,\n width: idealWidth\n };\n }\n\n private _schedule(callback: () => void, delay: number) {\n const timer = setTimeout(() => {\n this._pendingTimers.delete(timer);\n callback();\n }, delay);\n this._pendingTimers.add(timer);\n }\n\n private _clearPendingTimers() {\n for (const timer of this._pendingTimers) clearTimeout(timer);\n this._pendingTimers.clear();\n return ++this._transition;\n }\n\n _animateIn() {\n const transition = this._transition;\n const duration = this.options.inDuration;\n this.menuEl.style.transition = 'none';\n // from\n this.menuEl.style.opacity = '0';\n this.menuEl.style.transform = 'scale(0.85)';\n this._schedule(() => {\n this.menuEl.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;\n this.menuEl.style.opacity = '1';\n this.menuEl.style.transform = 'scale(1)';\n }, 1);\n this._schedule(() => {\n this._focusInitialItem();\n if (transition !== this._transition) return;\n if (typeof this.options.onOpenEnd === 'function') this.options.onOpenEnd.call(this, this.el);\n }, duration);\n }\n\n _animateOut() {\n const duration = this.options.outDuration;\n // easeOutQuad (opacity) & easeOutQuint\n this.menuEl.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;\n // to\n this.menuEl.style.opacity = '0';\n this.menuEl.style.transform = 'scale(0.85)';\n this._schedule(() => {\n this._resetMenuStyles();\n if (typeof this.options.onCloseEnd === 'function')\n this.options.onCloseEnd.call(this, this.el);\n }, duration);\n }\n\n private _getClosestAncestor(el: HTMLElement, condition: (Function) => boolean): HTMLElement {\n let ancestor: Node = el.parentNode;\n while (ancestor !== null && ancestor !== undefined && ancestor !== document) {\n // A shadow root is not an element and getComputedStyle() rejects it, so\n // step over it to the host - the elements that actually clip the menu\n // are above that.\n if (ancestor.nodeType === Node.ELEMENT_NODE && condition(ancestor)) {\n return <HTMLElement>ancestor;\n }\n ancestor = ancestor.parentNode ?? (<ShadowRoot>ancestor).host;\n }\n return null;\n }\n\n _placeMenu() {\n // Container here will be closest ancestor with overflow: hidden\n let closestOverflowParent: HTMLElement = this._getClosestAncestor(\n this.menuEl,\n (ancestor: HTMLElement) => {\n return (\n !['HTML', 'BODY'].includes(ancestor.tagName) &&\n getComputedStyle(ancestor).overflow !== 'visible'\n );\n }\n );\n // Fallback\n if (!closestOverflowParent) {\n const parent = !!this.menuEl.offsetParent ? this.menuEl.offsetParent : this.menuEl.parentNode;\n // Same hazard as the walk: the parent is a shadow root when the menu was\n // moved into one, and the next line reads its computed style.\n closestOverflowParent = <HTMLElement>((<ShadowRoot>parent).host ?? parent);\n }\n\n if (getComputedStyle(closestOverflowParent).position === 'static')\n closestOverflowParent.style.position = 'relative';\n\n //this._moveMenu(closestOverflowParent);\n\n // Set width before calculating positionInfo. Both callers reset the\n // positioning styles first, so this reads the surface's natural width.\n const natural = this.menuEl.getBoundingClientRect().width;\n // A trigger narrower than the surface's own minimum is not a constraint\n // the menu can honour: the width is written and `min-width` overrides it,\n // leaving the surface at the floor with every item inside it wrapped. So\n // constrain only to a trigger wide enough to mean something, and size by\n // content otherwise. An icon button and a split button's chevron are both\n // that case - 40dp and 48dp against a 112dp floor.\n const triggerWidth = this.el.getBoundingClientRect().width;\n const idealWidth =\n this.options.constrainWidth && !this.options.contextMenu && triggerWidth >= MIN_SURFACE_WIDTH\n ? triggerWidth\n : Math.min(MAX_SURFACE_WIDTH, Math.max(MIN_SURFACE_WIDTH, natural));\n this.menuEl.style.width = idealWidth + 'px';\n\n if (this.options.contextMenu) {\n this._placeMenuAtPoint(this._contextPoint ?? this._regionCorner(), closestOverflowParent);\n return;\n }\n\n const positionInfo = this._getMenuPosition(closestOverflowParent);\n this.menuEl.style.left = positionInfo.x + 'px';\n this.menuEl.style.top = positionInfo.y + 'px';\n this.menuEl.style.height = positionInfo.height + 'px';\n this.menuEl.style.width = positionInfo.width + 'px';\n this.menuEl.style.transformOrigin = `${\n positionInfo.horizontalAlignment === 'left' ? '0' : '100%'\n } ${positionInfo.verticalAlignment === 'top' ? '0' : '100%'}`;\n }\n\n /** Where a context menu opens without a pointer: the region's start corner. */\n private _regionCorner() {\n const rect = this.el.getBoundingClientRect();\n const rtl = getComputedStyle(this.el).direction === 'rtl';\n return { x: rtl ? rect.right : rect.left, y: rect.bottom };\n }\n\n /**\n * Places a context menu with its start corner on the point, flipping to\n * the other side of the point where it would not fit. The bounds are the\n * viewport, narrowed to a scrolling or clipping ancestor the menu sits in;\n * a menu taller than them gets their height and scrolls.\n *\n * The menu rests at left/top 0 of its containing block, so its rect is the\n * offset to subtract - the same trick _getMenuPosition uses. It is measured\n * without the entry animation's scale, which a second right-click can catch.\n */\n private _placeMenuAtPoint({ x, y }: { x: number; y: number }, container: HTMLElement) {\n // A running transition would still report the interpolated scale, so it\n // is suspended for the read; the target transform is unchanged after.\n const { transform, transition } = this.menuEl.style;\n this.menuEl.style.transition = 'none';\n this.menuEl.style.transform = 'none';\n const menu = this.menuEl.getBoundingClientRect();\n this.menuEl.style.transform = transform;\n this.menuEl.style.transition = transition;\n\n let bounds = { left: 0, top: 0, right: window.innerWidth, bottom: window.innerHeight };\n if (container && getComputedStyle(container).overflow !== 'visible') {\n const clip = container.getBoundingClientRect();\n bounds = {\n left: Math.max(bounds.left, clip.left),\n top: Math.max(bounds.top, clip.top),\n right: Math.min(bounds.right, clip.right),\n bottom: Math.min(bounds.bottom, clip.bottom)\n };\n }\n\n const width = menu.width;\n const height = Math.min(menu.height, bounds.bottom - bounds.top);\n this.isScrollable = height < menu.height;\n if (this.isScrollable) this.menuEl.style.height = height + 'px';\n\n const rtl = getComputedStyle(this.el).direction === 'rtl';\n const fitsRight = x + width <= bounds.right;\n const fitsLeft = x - width >= bounds.left;\n const leftward = rtl ? fitsLeft || !fitsRight : !fitsRight && fitsLeft;\n const upward = y + height > bounds.bottom && y - height >= bounds.top;\n const clamp = (value: number, min: number, max: number) => Math.max(min, Math.min(value, max));\n const left = clamp(leftward ? x - width : x, bounds.left, bounds.right - width);\n const top = clamp(upward ? y - height : y, bounds.top, bounds.bottom - height);\n this.menuEl.style.left = left - menu.left + 'px';\n this.menuEl.style.top = top - menu.top + 'px';\n this.menuEl.style.transformOrigin = `${leftward ? '100%' : '0'} ${upward ? '100%' : '0'}`;\n }\n\n private _setExpanded(expanded: boolean) {\n if (!this.options.contextMenu) this.el.ariaExpanded = String(expanded);\n }\n\n /**\n * Open menu.\n */\n open = () => {\n if (this.isOpen || this.el['Expressive_Menu'] !== this) return;\n const transition = this._clearPendingTimers();\n this.isOpen = true;\n // onOpenStart callback\n if (typeof this.options.onOpenStart === 'function') {\n this.options.onOpenStart.call(this, this.el);\n }\n if (transition !== this._transition) return;\n // Reset styles\n this._resetMenuStyles();\n this.menuEl.style.display = 'block';\n this._restoreInert();\n this._placeMenu();\n // Do this one frame later so that we don't bind an event handler that's immediately\n // called when the event bubbles up to the document and closes the menu\n this._schedule(() => this._setupTemporaryEventHandlers(), 0);\n // Queue handlers before initial focus, including zero-duration entry.\n this._animateIn();\n this._setExpanded(true);\n };\n\n /**\n * Close menu.\n */\n close = () => {\n if (!this.isOpen) return;\n const transition = this._clearPendingTimers();\n const root = this.menuEl.getRootNode() as Document | ShadowRoot;\n const focused = root.activeElement;\n this.isOpen = false;\n this.menuEl.setAttribute('inert', '');\n clearTimeout(this.filterTimeout);\n this._resetFilterQuery();\n this.focusedIndex = -1;\n this._closeSubmenus();\n // onCloseStart callback\n if (typeof this.options.onCloseStart === 'function') {\n this.options.onCloseStart.call(this, this.el);\n }\n if (transition !== this._transition) return;\n this._animateOut();\n this._removeTemporaryEventHandlers();\n this._setExpanded(false);\n if (this.options.autoFocus && this.menuEl.contains(focused) &&\n (root.activeElement === focused || this.el.ownerDocument.activeElement === this.el.ownerDocument.body)) {\n // A context region may not take focus itself; return to what had it.\n const back = this._contextReturn;\n (back?.isConnected && back !== this.el.ownerDocument.body ? back : this.el).focus();\n }\n this._contextReturn = null;\n this._contextPoint = null;\n };\n\n /**\n * While menu is open, you can recalculate its dimensions if its contents have changed.\n */\n recalculateDimensions = () => {\n if (this.isOpen) {\n this._resetMenuPositioningStyles();\n this._placeMenu();\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/snackbar.ts"],
|
|
4
|
-
"sourcesContent": ["import { BaseOptions } from '../core/component';\nimport { Utils } from '../core/utils';\n\nexport interface SnackbarOptions extends BaseOptions {\n /**\n * The content of the Snackbar.\n * @default \"\"\n */\n text: string;\n /**\n * Optional action label. Rendered as a trailing text button.\n * @default \"\"\n */\n action: string;\n /**\n * Called when the action button is pressed. The snackbar still dismisses.\n * @default null\n */\n onAction: () => void;\n /**\n * Show a trailing close icon button.\n * Defaults to true when action is set, otherwise false.\n */\n dismissible: boolean;\n /**\n * Element id of a `<template>` (or another element) used as the snackbar body.\n * @default \"\"\n */\n snackbarId?: string;\n /**\n * Length in ms the Snackbar stays before dismissal.\n * `Infinity` keeps it on screen until the user acts.\n * When `action` is set and this is omitted, the default is Infinity.\n * @default 4000\n */\n displayLength: number;\n /**\n * Transition in duration in milliseconds.\n * @default 300\n */\n inDuration: number;\n /**\n * Transition out duration in milliseconds.\n * @default 375\n */\n outDuration: number;\n /**\n * Classes to be added to the snackbar element.\n * @default \"\"\n */\n classes: string;\n /**\n * Callback function called when the snackbar is dismissed.\n * @default null\n */\n completeCallback: () => void;\n /**\n * The percentage of the snackbar's width it takes for a drag\n * to dismiss a Snackbar.\n * @default 0.8\n */\n activationPercent: number;\n /**\n * Any element in the tree the snackbar should render into. A Snackbar has no\n * originating element to infer this from, so pass one when the page lives in\n * a shadow root \u2014 the container is appended to that root instead of to\n * `document.body`, where a root-scoped stylesheet could not reach it.\n * @default null\n */\n root: HTMLElement;\n}\n\nconst _defaults: SnackbarOptions = {\n text: '',\n action: '',\n onAction: null,\n dismissible: false,\n displayLength: 4000,\n inDuration: 300,\n outDuration: 375,\n classes: '',\n completeCallback: null,\n activationPercent: 0.8,\n root: null\n};\n\nexport class Snackbar {\n /** The snackbar element. */\n el: HTMLElement;\n /**\n * The remaining amount of time in ms that the snackbar\n * will stay before dismissal.\n */\n timeRemaining: number;\n /**\n * Describes the current pan state of the Snackbar.\n */\n panning: boolean;\n options: SnackbarOptions;\n message: string;\n counterTimeout: ReturnType<typeof setTimeout>;\n /** Wall-clock time the snackbar is due to dismiss, for pause/resume. */\n private _deadline: number;\n wasSwiped: boolean;\n startingXPos: number;\n xPos: number;\n time: number;\n deltaX: number;\n velocityX: number;\n /** Swipe distance that dismisses, measured once when the drag starts. */\n private _activationDistance: number;\n private _dismissed = false;\n private _returnFocus: HTMLElement | null = null;\n private _events: AbortController;\n private _restoreElement: (() => void) | null = null;\n private _transitionTimer: ReturnType<typeof setTimeout>;\n private _dismissTimer: ReturnType<typeof setTimeout>;\n private _focusTimer: ReturnType<typeof setTimeout>;\n\n static _snackbars: Snackbar[];\n static _container: HTMLElement;\n static _draggedSnackbar: Snackbar;\n /** Which pointer owns the drag in flight; a second finger is ignored. */\n static _dragPointerId: number | null = null;\n\n constructor(options: Partial<SnackbarOptions> = {}) {\n this.options = {\n ...Snackbar.defaults,\n ...options\n };\n if (options.displayLength === undefined && this.options.action) {\n this.options.displayLength = Infinity;\n }\n if (options.dismissible === undefined && this.options.action) this.options.dismissible = true;\n this.message = this.options.text;\n this.panning = false;\n this.timeRemaining = this.options.displayLength;\n // One snackbar at a time so a new update does not stack over the page.\n while (Snackbar._snackbars.length > 0) {\n const snackbar = Snackbar._snackbars.shift();\n snackbar._dismissed = true;\n snackbar._restoreFocus(true);\n }\n let focused = document.activeElement;\n while (focused?.shadowRoot?.activeElement) focused = focused.shadowRoot.activeElement;\n this._returnFocus = focused instanceof HTMLElement ? focused : null;\n this.el = this._createSnackbar();\n // One container serves every snackbar, and only one snackbar shows at a\n // time \u2014 so it is moved rather than duplicated when the root changes.\n const root = Utils.portalRoot(this.options.root ?? document.body);\n if (\n !Snackbar._container ||\n !Snackbar._container.isConnected ||\n Snackbar._container.parentNode !== root\n ) {\n if (Snackbar._container) Snackbar._removeContainer();\n Snackbar._createContainer(root);\n }\n Snackbar._container.appendChild(this.el);\n this.el['Expressive_Snackbar'] = this;\n Snackbar._snackbars.push(this);\n this._animateIn();\n this._setTimer();\n }\n\n static get defaults(): SnackbarOptions {\n return _defaults;\n }\n\n static getInstance(el: HTMLElement): Snackbar {\n return el['Expressive_Snackbar'];\n }\n\n static _createContainer(root: HTMLElement | ShadowRoot = document.body) {\n const container = document.createElement('div');\n container.setAttribute('id', 'snackbar-container');\n // One listener per stage. These used to be a touch trio on the container\n // plus a mouse trio split across the container and the document, with a\n // helper picking `targetTouches[0].clientX` or `clientX` apart afterwards.\n // Move and up stay on the document so a drag that leaves the container\n // still completes.\n container.addEventListener('pointerdown', Snackbar._onDragStart);\n document.addEventListener('pointermove', Snackbar._onDragMove);\n document.addEventListener('pointerup', Snackbar._onDragEnd);\n document.addEventListener('pointercancel', Snackbar._onDragCancel);\n root.appendChild(container);\n Snackbar._container = container;\n }\n\n static _removeContainer() {\n document.removeEventListener('pointermove', Snackbar._onDragMove);\n document.removeEventListener('pointerup', Snackbar._onDragEnd);\n document.removeEventListener('pointercancel', Snackbar._onDragCancel);\n Snackbar._container.remove();\n Snackbar._container = null;\n }\n\n static _onDragStart(e: PointerEvent) {\n if (!e.isPrimary) return;\n if (e.pointerType === 'mouse' && e.button !== 0) return;\n const target = e.target as HTMLElement | null;\n // Don't start a swipe from the action or close \u2014 those are buttons.\n if (target && !target.closest('button, a') && target.closest('.snackbar')) {\n const snackbarElem = target.closest('.snackbar') as HTMLElement;\n const snackbar: Snackbar = snackbarElem['Expressive_Snackbar'];\n if (!snackbar) return;\n snackbar.panning = true;\n snackbar._pauseTimer();\n Snackbar._draggedSnackbar = snackbar;\n snackbar.el.classList.add('panning');\n snackbar.el.style.transition = '';\n Snackbar._dragPointerId = e.pointerId;\n snackbar.startingXPos = e.clientX;\n snackbar.velocityX = 0;\n snackbar.time = Date.now();\n snackbar.xPos = e.clientX;\n // A translateX does not change the width, so one read covers the drag.\n snackbar._activationDistance = snackbar.el.offsetWidth * snackbar.options.activationPercent;\n }\n }\n\n static _onDragMove(e: PointerEvent) {\n if (Snackbar._dragPointerId !== e.pointerId) return;\n if (!!Snackbar._draggedSnackbar) {\n e.preventDefault();\n const snackbar = Snackbar._draggedSnackbar;\n snackbar.deltaX = Math.abs(snackbar.xPos - e.clientX);\n snackbar.xPos = e.clientX;\n snackbar.velocityX = snackbar.deltaX / (Date.now() - snackbar.time);\n snackbar.time = Date.now();\n\n const totalDeltaX = snackbar.xPos - snackbar.startingXPos;\n const activationDistance = snackbar._activationDistance;\n snackbar.el.style.transform = `translateX(${totalDeltaX}px)`;\n snackbar.el.style.opacity = (1 - Math.abs(totalDeltaX / activationDistance)).toString();\n }\n }\n\n static _onDragEnd(e: PointerEvent) {\n if (Snackbar._dragPointerId !== e.pointerId) return;\n Snackbar._dragPointerId = null;\n if (!!Snackbar._draggedSnackbar) {\n const snackbar = Snackbar._draggedSnackbar;\n snackbar.panning = false;\n snackbar.el.classList.remove('panning');\n\n const totalDeltaX = snackbar.xPos - snackbar.startingXPos;\n const activationDistance = snackbar._activationDistance;\n const velocity = Date.now() - snackbar.time < 100 ? snackbar.velocityX : 0;\n const shouldBeDismissed = Math.abs(totalDeltaX) > activationDistance || velocity > 1;\n\n // Remove snackbar\n if (shouldBeDismissed) {\n snackbar.wasSwiped = true;\n snackbar.dismiss();\n // Animate snackbar back to original position\n } else {\n snackbar.el.style.transition = 'transform .2s, opacity .2s';\n snackbar.el.style.transform = '';\n snackbar.el.style.opacity = '';\n snackbar._resumeTimer();\n }\n Snackbar._draggedSnackbar = null;\n }\n }\n\n /**\n * A cancelled pointer is not a short swipe. Snap back and resume the timer\n * without consulting the distance travelled - the browser took the gesture\n * over, so the movement so far says nothing about what the user wanted.\n */\n static _onDragCancel(e: PointerEvent) {\n if (Snackbar._dragPointerId !== e.pointerId) return;\n Snackbar._dragPointerId = null;\n const snackbar = Snackbar._draggedSnackbar;\n if (!snackbar) return;\n snackbar.panning = false;\n snackbar.el.classList.remove('panning');\n snackbar.el.style.transition = 'transform .2s, opacity .2s';\n snackbar.el.style.transform = '';\n snackbar.el.style.opacity = '';\n snackbar._resumeTimer();\n Snackbar._draggedSnackbar = null;\n }\n\n /**\n * dismiss all snackbars.\n */\n static dismissAll() {\n // Copy first: dismiss() splices the list it is iterating.\n for (const snackbar of [...Snackbar._snackbars]) {\n snackbar.dismiss();\n }\n }\n\n _createSnackbar() {\n let snackbar: HTMLElement = this.options.snackbarId\n ? Utils.getElementById(this.options.root ?? document.body, this.options.snackbarId)\n : document.createElement('div');\n if (snackbar instanceof HTMLTemplateElement) {\n const node = (snackbar as HTMLTemplateElement).content.cloneNode(true);\n snackbar = (node as HTMLElement).firstElementChild as HTMLElement;\n } else if (snackbar && this.options.snackbarId) {\n const placeholder = document.createComment('');\n snackbar.before(placeholder);\n const children = [...snackbar.childNodes];\n const attributes = ['class', 'style', 'role', 'aria-live', 'aria-atomic', 'inert']\n .map(name => [name, snackbar.getAttribute(name)]);\n this._restoreElement = () => {\n snackbar.replaceChildren(...children);\n for (const [name, value] of attributes) {\n if (value === null) snackbar.removeAttribute(name);\n else snackbar.setAttribute(name, value);\n }\n placeholder.replaceWith(snackbar);\n };\n }\n if (!snackbar) throw new Error('Snackbar body not found');\n this._events = new (snackbar.ownerDocument.defaultView ?? window).AbortController();\n const listenerOptions = { signal: this._events.signal };\n snackbar.classList.add('snackbar');\n snackbar.setAttribute('role', 'status');\n snackbar.setAttribute('aria-live', 'polite');\n snackbar.setAttribute('aria-atomic', 'true');\n snackbar.inert = false;\n snackbar.addEventListener('focusin', (e) => {\n if (e.relatedTarget instanceof HTMLElement && !snackbar.contains(e.relatedTarget)) {\n this._returnFocus = e.relatedTarget;\n }\n this._pauseTimer();\n }, listenerOptions);\n snackbar.addEventListener('keydown', (e) => {\n if (e.key !== 'Escape' || e.defaultPrevented || this._dismissed) return;\n e.preventDefault();\n e.stopPropagation();\n this.dismiss();\n }, listenerOptions);\n snackbar.addEventListener('focusout', () => {\n clearTimeout(this._focusTimer);\n this._focusTimer = setTimeout(() => this._resumeTimer(), 0);\n }, listenerOptions);\n snackbar.addEventListener('pointerenter', () => this._pauseTimer(), listenerOptions);\n snackbar.addEventListener('pointerleave', () => this._resumeTimer(), listenerOptions);\n // Add custom classes onto snackbar\n if (this.options.classes.length > 0) {\n snackbar.classList.add(...this.options.classes.split(' ').filter(Boolean));\n }\n if (this.message) {\n const text = document.createElement('p');\n text.textContent = this.message;\n snackbar.replaceChildren(text);\n }\n if (this.options.action) {\n const action = document.createElement('button');\n action.type = 'button';\n action.textContent = this.options.action;\n action.addEventListener('click', (e) => {\n e.stopPropagation();\n if (this._dismissed) return;\n try {\n if (typeof this.options.onAction === 'function') this.options.onAction();\n } finally {\n this.dismiss();\n }\n }, listenerOptions);\n snackbar.appendChild(action);\n }\n if (this.options.dismissible) {\n const close = document.createElement('button');\n close.type = 'button';\n close.className = 'circle';\n close.setAttribute('aria-label', 'Dismiss');\n const icon = document.createElement('i');\n icon.className = 'material-symbols';\n icon.setAttribute('aria-hidden', 'true');\n icon.textContent = 'close';\n close.appendChild(icon);\n close.addEventListener('click', (e) => {\n e.stopPropagation();\n this.dismiss();\n }, listenerOptions);\n snackbar.appendChild(close);\n }\n return snackbar;\n }\n\n private _remove() {\n if (this._events.signal.aborted) return;\n this._events.abort();\n clearTimeout(this.counterTimeout);\n clearTimeout(this._transitionTimer);\n clearTimeout(this._dismissTimer);\n clearTimeout(this._focusTimer);\n this.counterTimeout = null;\n if (Snackbar._draggedSnackbar === this) {\n Snackbar._draggedSnackbar = null;\n Snackbar._dragPointerId = null;\n }\n this.el['Expressive_Snackbar'] = undefined;\n if (this._restoreElement) this._restoreElement();\n else this.el.remove();\n const index = Snackbar._snackbars.indexOf(this);\n if (index >= 0) Snackbar._snackbars.splice(index, 1);\n if (!Snackbar._snackbars.length && Snackbar._container?.childElementCount === 0) {\n Snackbar._removeContainer();\n }\n }\n\n _animateIn() {\n this.el.style.display = '';\n this.el.style.opacity = '0';\n this.el.style.transform = 'translateY(24px)';\n this.el.style.transition = `\n transform ${this.options.inDuration}ms ease,\n opacity ${this.options.inDuration}ms ease\n `;\n this._transitionTimer = setTimeout(() => {\n this.el.style.transform = '';\n this.el.style.opacity = '1';\n }, 1);\n }\n\n /**\n * Arm the dismissal timer.\n *\n * One timeout, not a 20ms interval ticking a counter down: the old form woke\n * the page up 50 times a second per snackbar purely to subtract 20 from a\n * number. Dragging pauses the countdown via _pauseTimer/_resumeTimer instead.\n */\n _setTimer() {\n if (this.timeRemaining === Infinity) return;\n this._deadline = Date.now() + this.timeRemaining;\n this.counterTimeout = setTimeout(() => this.dismiss(), this.timeRemaining);\n }\n\n /** Stop the countdown, banking the time that was left on it. */\n _pauseTimer() {\n if (this.counterTimeout == null) return;\n clearTimeout(this.counterTimeout);\n this.counterTimeout = null;\n this.timeRemaining = Math.max(0, this._deadline - Date.now());\n }\n\n /** Restart a countdown stopped by {@link _pauseTimer}. */\n _resumeTimer() {\n if (this._dismissed || this.panning || this.el.matches(':hover, :focus-within') || this.counterTimeout != null) return;\n this._setTimer();\n }\n\n private _restoreFocus(remove = false) {\n const focused = (this.el.getRootNode() as Document | ShadowRoot).activeElement;\n const returnFocus = focused && this.el.contains(focused) ? this._returnFocus : null;\n this.el.inert = true;\n if (remove) this._remove();\n if (returnFocus?.isConnected) returnFocus.focus({ preventScroll: true });\n }\n\n /**\n * Dismiss snackbar with animation.\n */\n dismiss() {\n if (this._dismissed) return;\n this._dismissed = true;\n clearTimeout(this.counterTimeout);\n this.counterTimeout = null;\n this._restoreFocus();\n if (this._events.signal.aborted) return;\n const activationDistance = this.el.offsetWidth * this.options.activationPercent;\n\n if (this.wasSwiped) {\n this.el.style.transition = 'transform .05s, opacity .05s';\n this.el.style.transform = `translateX(${activationDistance}px)`;\n this.el.style.opacity = '0';\n }\n\n // easeOutExpo\n this.el.style.transition = `\n margin ${this.options.outDuration}ms ease,\n opacity ${this.options.outDuration}ms ease`;\n\n clearTimeout(this._transitionTimer);\n this._transitionTimer = setTimeout(() => {\n this.el.style.opacity = '0';\n this.el.style.marginTop = '-40px';\n }, 1);\n\n this._dismissTimer = setTimeout(() => {\n this._remove();\n // Call the optional callback\n if (typeof this.options.completeCallback === 'function') {\n this.options.completeCallback();\n }\n }, this.options.outDuration);\n }\n\n static {\n Snackbar._snackbars = [];\n Snackbar._container = null;\n Snackbar._draggedSnackbar = null;\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/chips.ts"],
|
|
4
|
-
"sourcesContent": ["import { Utils } from '../core/utils';\nimport { Autocomplete, AutocompleteOptions } from './autocomplete';\nimport { Component, BaseOptions, InitElements, InitElement } from '../core/component';\n\nexport interface ChipData {\n /**\n * Unique identifier.\n */\n id: number | string;\n /**\n * Chip text. If not specified, \"id\" will be used.\n */\n text?: string;\n /**\n * Chip image (URL).\n */\n image?: string;\n}\n\nexport interface ChipsI18nOptions {\n /** Prefix for the delete button's accessible name. */\n remove: string;\n}\n\nexport interface ChipsOptions extends BaseOptions {\n /**\n * Set the chip data.\n * @default []\n */\n data: ChipData[];\n /**\n * Set first placeholder when there are no tags.\n * @default \"\"\n */\n placeholder: string;\n /**\n * Set second placeholder when adding additional tags.\n * @default \"\"\n */\n secondaryPlaceholder: string;\n /**\n * Set autocomplete options.\n * @default {}\n */\n autocompleteOptions: Partial<AutocompleteOptions>;\n /**\n * Toggles abililty to add custom value not in autocomplete list.\n * @default false\n */\n autocompleteOnly: boolean;\n /**\n * Set chips limit.\n * @default Infinity\n */\n limit: number;\n /**\n * Specifies class to be used in \"close\" button.\n * @default 'material-symbols'\n */\n closeIconClass: string;\n /**\n * Specifies option to render user input field\n * @default false;\n */\n allowUserInput: boolean;\n /**\n * Strings the component generates. `remove` prefixes the delete button's\n * accessible name, giving \"Remove Apple\".\n * @default { remove: 'Remove' }\n */\n i18n: Partial<ChipsI18nOptions>;\n /**\n * Callback for chip add.\n * @default null\n */\n onChipAdd: (element: HTMLElement, chip: HTMLElement) => void;\n /**\n * Callback for chip select.\n * @default null\n */\n onChipSelect: (element: HTMLElement, chip: HTMLElement) => void;\n /**\n * Callback for chip delete.\n * @default null\n */\n onChipDelete: (element: HTMLElement, chip: HTMLElement) => void;\n}\n\nconst _defaults: ChipsOptions = {\n data: [],\n placeholder: '',\n secondaryPlaceholder: '',\n closeIconClass: 'material-symbols',\n autocompleteOptions: {},\n autocompleteOnly: false,\n limit: Infinity,\n allowUserInput: false,\n i18n: { remove: 'Remove' },\n onChipAdd: null,\n onChipSelect: null,\n onChipDelete: null\n};\n\nexport class Chips extends Component<ChipsOptions> {\n /** Array of the current chips data. */\n chipsData: ChipData[];\n /** If the chips has autocomplete enabled. */\n hasAutocomplete: boolean;\n /** Autocomplete instance, if any. */\n autocomplete: Autocomplete;\n _input: HTMLInputElement;\n _label: HTMLLabelElement;\n _chips: HTMLElement[];\n static _keydown: boolean;\n private _selectedChip: HTMLElement;\n\n /**\n * Selection is drawn by a class now, not by `:focus`, so it does not clear\n * itself when focus moves - every path that changes the selection has to go\n * through here or the class and the field drift apart.\n *\n * Deliberately no `aria-selected`: the chip is not an option in a listbox,\n * and putting the attribute on an element with no such role is the same\n * defect the semantics standard exists to remove.\n */\n private _setSelected(chip: HTMLElement | null) {\n this._selectedChip?.classList.remove('selected');\n this._selectedChip = chip;\n chip?.classList.add('selected');\n }\n\n constructor(el: HTMLElement, options: Partial<ChipsOptions>) {\n super(el, options, Chips);\n this.el['Expressive_Chips'] = this;\n\n this.options = {\n ...Chips.defaults,\n ...options\n };\n // Spreading options over the defaults replaces the i18n object wholesale,\n // so passing one string would drop the rest. Same fix as Datepicker.\n if (options?.i18n) this.options.i18n = { ...Chips.defaults.i18n, ...options.i18n };\n\n this.el.classList.add('chips');\n this.chipsData = [];\n this._chips = [];\n\n // Render initial chips\n if (this.options.data.length) {\n this.chipsData = this.options.data;\n this._renderChips();\n }\n\n // Render input element, setup event handlers\n if (this.options.allowUserInput) {\n this.el.classList.add('field');\n this._setupInput();\n this._setupEventHandlers();\n // move input to end\n this.el.append(this._input);\n }\n // After _setupInput: the label points at the input's id, which is only\n // assigned there. Running this first threw on any .chips with a <label>.\n this._setupLabel();\n }\n\n static get defaults() {\n return _defaults;\n }\n\n /**\n * Initializes instance of Chips.\n * @param el HTML element.\n * @param options Component options.\n */\n static init(el: HTMLElement, options?: Partial<ChipsOptions>): Chips;\n /**\n * Initializes instances of Chips.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(els: InitElements<InitElement>, options?: Partial<ChipsOptions>): Chips[];\n /**\n * Initializes instances of Chips.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<ChipsOptions> = {}\n ): Chips | Chips[] {\n return super.init(els, options, Chips);\n }\n\n static getInstance(el: HTMLElement): Chips {\n return el['Expressive_Chips'];\n }\n\n getData() {\n return this.chipsData;\n }\n\n destroy() {\n if (this.autocomplete && Autocomplete.getInstance(this._input) === this.autocomplete) {\n this.autocomplete.destroy();\n }\n if (this.options.allowUserInput) {\n this._removeEventHandlers();\n }\n this._chips.forEach((c) => c.remove());\n this._chips = [];\n this.el['Expressive_Chips'] = undefined;\n }\n\n _setupEventHandlers() {\n this.el.addEventListener('click', this._handleChipClick);\n this.el.addEventListener('keydown', Chips._handleChipsKeydown);\n this.el.addEventListener('keyup', Chips._handleChipsKeyup);\n this.el.addEventListener('blur', Chips._handleChipsBlur, true);\n this._input.addEventListener('focus', this._handleInputFocus);\n this._input.addEventListener('blur', this._handleInputBlur);\n this._input.addEventListener('keydown', this._handleInputKeydown);\n }\n\n _removeEventHandlers() {\n this.el.removeEventListener('click', this._handleChipClick);\n this.el.removeEventListener('keydown', Chips._handleChipsKeydown);\n this.el.removeEventListener('keyup', Chips._handleChipsKeyup);\n this.el.removeEventListener('blur', Chips._handleChipsBlur, true);\n this._input.removeEventListener('focus', this._handleInputFocus);\n this._input.removeEventListener('blur', this._handleInputBlur);\n this._input.removeEventListener('keydown', this._handleInputKeydown);\n }\n\n _handleChipClick = (e: MouseEvent) => {\n const _chip = (<HTMLElement>e.target).closest('.chip');\n // closest, not classList: the close button now wraps an icon span, so a\n // click on the glyph reports the span as the target.\n const clickedClose = !!(<HTMLElement>e.target).closest('.close');\n if (_chip) {\n // Index into the chip list, not into the container's children: the\n // container also holds the label and the input, so counting children\n // gave an index that did not line up with chipsData.\n const index = this._chips.indexOf(_chip as HTMLElement);\n if (index < 0) return;\n if (clickedClose) {\n this._deleteChip(index, 'input');\n } else {\n this.selectChip(index);\n }\n // Default handle click to focus on input\n } else {\n this._input.focus();\n }\n };\n\n static _handleChipsKeydown(e: KeyboardEvent) {\n Chips._keydown = true;\n const chips = (<HTMLElement>e.target).closest('.chips');\n const chipsKeydown = e.target && chips;\n\n // Don't handle keydown inputs on input and textarea\n const tag = (<HTMLElement>e.target).tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || !chipsKeydown) return;\n\n const currChips: Chips = chips['Expressive_Chips'];\n if (!currChips) return; // .chips markup without an instance behind it\n\n if (e.key === Utils.keys.BACKSPACE || e.key === Utils.keys.DELETE) {\n const index = currChips._chips.indexOf((e.target as HTMLElement).closest('.chip'));\n if (index < 0) return;\n e.preventDefault();\n currChips._deleteChip(index, 'previous');\n } else if (e.key === Utils.keys.ARROW_LEFT) {\n if (currChips._selectedChip) {\n const selectIndex = currChips._chips.indexOf(currChips._selectedChip) - 1;\n if (selectIndex < 0) return;\n currChips.selectChip(selectIndex);\n }\n } else if (e.key === Utils.keys.ARROW_RIGHT) {\n if (currChips._selectedChip) {\n const selectIndex = currChips._chips.indexOf(currChips._selectedChip) + 1;\n if (selectIndex >= currChips.chipsData.length) {\n // Walking off the end returns to the input, so nothing is selected\n // any more - without this the last chip kept the class.\n currChips._setSelected(null);\n currChips._input.focus();\n }\n else currChips.selectChip(selectIndex);\n }\n }\n }\n\n static _handleChipsKeyup() {\n Chips._keydown = false;\n }\n\n static _handleChipsBlur(e: Event) {\n if (!Chips._keydown && document.hidden) {\n const chips = (<HTMLElement>e.target).closest('.chips');\n const currChips: Chips = chips?.['Expressive_Chips'];\n if (currChips) currChips._setSelected(null);\n }\n }\n\n _handleInputFocus = () => {\n this.el.classList.add('focus');\n };\n\n _handleInputBlur = () => {\n this.el.classList.remove('focus');\n };\n\n _handleInputKeydown = (e: KeyboardEvent) => {\n Chips._keydown = true;\n if (e.key === Utils.keys.ENTER) {\n // Override enter if autocompleting.\n if (this.hasAutocomplete && this.autocomplete?.isOpen &&\n this.autocomplete.container.querySelector('[role=\"option\"]')) {\n return;\n }\n e.preventDefault();\n if (!this.hasAutocomplete || (this.hasAutocomplete && !this.options.autocompleteOnly)) {\n this.addChip({ id: this._input.value });\n }\n this._input.value = '';\n } else if (\n (e.key === Utils.keys.BACKSPACE || e.key === Utils.keys.ARROW_LEFT) &&\n this._input.value === '' &&\n this.chipsData.length\n ) {\n e.preventDefault();\n this.selectChip(this.chipsData.length - 1);\n }\n };\n\n _renderChip(chip: ChipData): HTMLElement {\n if (!chip.id && chip.id !== 0) return;\n const label = chip.text || <string>chip.id;\n // <span>, not <div>: a chip is inline, and the container itself is not a\n // control. It used to be a <div tabindex=\"0\"> with no role - focusable,\n // and announcing nothing.\n const renderedChip = document.createElement('span');\n renderedChip.classList.add('chip');\n renderedChip.innerText = label;\n // attach image if needed\n if (chip.image) {\n const img = document.createElement('img');\n img.setAttribute('src', chip.image);\n renderedChip.insertBefore(img, renderedChip.firstChild);\n }\n if (this.options.allowUserInput) {\n // The delete affordance is the control, so it is the <button> and it\n // carries the name. `type` is explicit because a bare button inside a\n // form submits it.\n const closeButton = document.createElement('button');\n closeButton.type = 'button';\n closeButton.classList.add('close');\n closeButton.setAttribute('aria-label', `${this.options.i18n.remove} ${label}`);\n // The ligature is text and is read out, so the glyph is hidden and the\n // button's own label is what gets announced.\n const closeIcon = document.createElement('span');\n closeIcon.classList.add(this.options.closeIconClass);\n closeIcon.setAttribute('aria-hidden', 'true');\n closeIcon.innerText = 'close';\n closeButton.appendChild(closeIcon);\n renderedChip.appendChild(closeButton);\n }\n return renderedChip;\n }\n\n _renderChips() {\n this._chips = []; //.remove();\n for (let i = 0; i < this.chipsData.length; i++) {\n const chipElem = this._renderChip(this.chipsData[i]);\n this.el.appendChild(chipElem);\n this._chips.push(chipElem);\n }\n }\n\n _setupAutocomplete() {\n this.options.autocompleteOptions.onAutocomplete = (items) => {\n if (Chips.getInstance(this.el) !== this) return;\n if (items.length > 0) {\n this.addChip({\n id: items[0].id,\n text: items[0].text,\n image: items[0].image\n });\n this._input.value = '';\n this._input.focus();\n }\n };\n this.autocomplete = Autocomplete.init(this._input, this.options.autocompleteOptions);\n }\n\n _setupInput() {\n this._input = this.el.querySelector('input');\n if (!this._input) {\n this._input = document.createElement('input');\n this.el.append(this._input);\n }\n this._input.classList.add('input');\n this.hasAutocomplete = Object.keys(this.options.autocompleteOptions).length > 0;\n // Setup autocomplete if needed\n if (this.hasAutocomplete) this._setupAutocomplete();\n this._setPlaceholder();\n // Set input id\n if (!this._input.getAttribute('id')) this._input.setAttribute('id', Utils.guid());\n }\n\n _setupLabel() {\n this._label = this.el.querySelector('label');\n // No input to point at when allowUserInput is off.\n if (this._label && this._input) this._label.setAttribute('for', this._input.getAttribute('id'));\n }\n\n _setPlaceholder() {\n if (!this._input) return;\n if (this.chipsData !== undefined && !this.chipsData.length && this.options.placeholder) {\n this._input.placeholder = this.options.placeholder;\n } else if (\n (this.chipsData === undefined || !!this.chipsData.length) &&\n this.options.secondaryPlaceholder\n ) {\n this._input.placeholder = this.options.secondaryPlaceholder;\n }\n }\n\n _isValidAndNotExist(chip: ChipData) {\n const isValid = !!chip.id || chip.id === 0;\n const doesNotExist = !this.chipsData.some((item) => item.id == chip.id);\n return isValid && doesNotExist;\n }\n\n /**\n * Add chip to input.\n * @param chip Chip data object\n */\n addChip(chip: ChipData) {\n if (!this._isValidAndNotExist(chip) || this.chipsData.length >= this.options.limit) return;\n const renderedChip = this._renderChip(chip);\n this._chips.push(renderedChip);\n this.chipsData.push(chip);\n if (this._input) this._input.before(renderedChip);\n else this.el.append(renderedChip);\n this._setPlaceholder();\n // fire chipAdd callback\n if (typeof this.options.onChipAdd === 'function') {\n this.options.onChipAdd(this.el, renderedChip);\n }\n }\n\n /**\n * Delete nth chip.\n * @param chipIndex Index of chip\n */\n deleteChip(chipIndex: number) {\n const root = this.el.getRootNode() as Document | ShadowRoot;\n this._deleteChip(chipIndex, this._chips[chipIndex]?.contains(root.activeElement) ? 'input' : null);\n }\n\n private _deleteChip(chipIndex: number, focus: 'input' | 'previous' | null) {\n const chip = this._chips[chipIndex];\n if (!chip) return;\n if (this._selectedChip === chip) this._setSelected(null);\n chip.remove();\n this._chips.splice(chipIndex, 1);\n this.chipsData.splice(chipIndex, 1);\n this._setPlaceholder();\n const focusPath: { root: Document | ShadowRoot; element: Element | null }[] = [];\n let root = this.el.getRootNode() as Document | ShadowRoot;\n while (root) {\n focusPath.push({ root, element: root.activeElement });\n root = 'host' in root ? root.host.getRootNode() as Document | ShadowRoot : null;\n }\n // fire chipDelete callback\n if (typeof this.options.onChipDelete === 'function') {\n this.options.onChipDelete(this.el, chip);\n }\n if (!focus || focusPath.some(({ root, element }) => root.activeElement !== element) || this.el['Expressive_Chips'] !== this) return;\n if (focus === 'previous' && this._chips.length) this.selectChip(Math.max(chipIndex - 1, 0));\n else {\n this._setSelected(null);\n this._input?.focus();\n }\n }\n\n /**\n * Select nth chip.\n * @param chipIndex Index of chip\n */\n selectChip(chipIndex: number) {\n const chip = this._chips[chipIndex];\n if (!chip) return;\n this._setSelected(chip);\n // The chip is not a control any more, so focus goes to the one thing in it\n // that is - the delete button.\n (chip.querySelector('.close') as HTMLElement | null)?.focus();\n // fire chipSelect callback\n if (typeof this.options.onChipSelect === 'function') {\n this.options.onChipSelect(this.el, chip);\n }\n }\n\n static Init() {\n // Handle removal of static chips - markup written by hand, with no Chips\n // instance behind it. Where there *is* an instance, _handleChipClick owns\n // the close button: removing the node here as well left chipsData holding\n // an entry whose element was gone.\n Utils.onDocumentReady(() => {\n const chips = document.querySelectorAll('.chips');\n chips.forEach((el) => {\n el.addEventListener('click', (e) => {\n if (el['Expressive_Chips']) return;\n // closest: the close button wraps an icon span, so a click on the\n // glyph reports the span.\n if ((<HTMLElement>e.target).closest('.close')) {\n const chip = (<HTMLElement>e.target).closest('.chip');\n if (chip) chip.remove();\n }\n });\n });\n });\n }\n\n static {\n Chips._keydown = false;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["root"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/components/tooltip.ts"],
|
|
4
|
-
"sourcesContent": ["import { Utils } from '../core/utils';\nimport { Component, BaseOptions, InitElements, InitElement } from '../core/component';\n\nexport type TooltipPosition = 'top' | 'right' | 'bottom' | 'left';\n\nexport interface TooltipOptions extends BaseOptions {\n /**\n * Delay time before tooltip disappears.\n * @default 200\n */\n exitDelay: number;\n /**\n * Delay time before tooltip appears.\n * @default 0\n */\n enterDelay: number;\n /**\n * Element Id for the tooltip.\n * @default \"\"\n */\n tooltipId?: string;\n /**\n * Text string for the tooltip.\n * @default \"\"\n */\n text: string;\n /**\n * Set distance tooltip appears away from its activator\n * excluding transitionMovement.\n * @default 4\n */\n margin: number;\n /**\n * Enter transition duration.\n * @default 300\n */\n inDuration: number;\n /**\n * Opacity of the tooltip.\n * @default 1\n */\n opacity: number;\n /**\n * Exit transition duration.\n * @default 250\n */\n outDuration: number;\n /**\n * Set the direction of the tooltip.\n * @default 'bottom'\n */\n position: TooltipPosition;\n /**\n * Amount in px that the tooltip moves during its transition.\n * @default 10\n */\n transitionMovement: number;\n}\n\nconst _defaults: TooltipOptions = {\n exitDelay: 200,\n enterDelay: 0,\n text: '',\n margin: 4,\n inDuration: 250,\n outDuration: 200,\n position: 'bottom' as TooltipPosition,\n transitionMovement: 10,\n opacity: 1\n};\n\nexport class Tooltip extends Component<TooltipOptions> {\n /**\n * If tooltip is open.\n */\n isOpen: boolean;\n /**\n * If tooltip is hovered.\n */\n isHovered: boolean;\n /**\n * If tooltip is focused.\n */\n isFocused: boolean;\n tooltipEl: HTMLElement;\n private _exitDelayTimeout: ReturnType<typeof setTimeout>;\n private _enterDelayTimeout: ReturnType<typeof setTimeout>;\n private _animationTimeout: ReturnType<typeof setTimeout>;\n private _originalContent: {\n el: HTMLElement;\n marker: Comment;\n display: string;\n priority: string;\n hidden: string | null;\n contentClass: boolean;\n };\n xMovement: number;\n yMovement: number;\n\n constructor(el: HTMLElement, options: Partial<TooltipOptions>) {\n super(el, options, Tooltip);\n this.el['Expressive_Tooltip'] = this;\n\n this.options = {\n ...Tooltip.defaults,\n ...this._getAttributeOptions(),\n ...options\n };\n\n this.isOpen = false;\n this.isHovered = false;\n this.isFocused = false;\n this._appendTooltipEl();\n this._setupEventHandlers();\n }\n\n static get defaults(): TooltipOptions {\n return _defaults;\n }\n\n /**\n * Initializes instance of Tooltip.\n * @param el HTML element.\n * @param options Component options.\n */\n static init(el: HTMLElement, options?: Partial<TooltipOptions>): Tooltip;\n /**\n * Initializes instances of Tooltip.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(els: InitElements<InitElement>, options?: Partial<TooltipOptions>): Tooltip[];\n /**\n * Initializes instances of Tooltip.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<TooltipOptions> = {}\n ): Tooltip | Tooltip[] {\n return super.init(els, options, Tooltip);\n }\n\n static getInstance(el: HTMLElement): Tooltip {\n return el['Expressive_Tooltip'];\n }\n\n destroy() {\n clearTimeout(this._enterDelayTimeout);\n clearTimeout(this._exitDelayTimeout);\n clearTimeout(this._animationTimeout);\n this.isOpen = false;\n this.isHovered = false;\n this.isFocused = false;\n const descriptions = this.el.getAttribute('aria-describedby')?.split(/\\s+/);\n if (descriptions?.includes(this.tooltipEl.id)) {\n const remaining = descriptions.filter(id => id && id !== this.tooltipEl.id).join(' ');\n if (remaining) this.el.setAttribute('aria-describedby', remaining);\n else this.el.removeAttribute('aria-describedby');\n }\n if (this._originalContent) {\n const { el, marker, display, priority, hidden, contentClass } = this._originalContent;\n el.style.setProperty('display', display, priority);\n if (hidden === null) el.removeAttribute('hidden');\n else el.setAttribute('hidden', hidden);\n el.classList.toggle('tooltip-content', contentClass);\n if (!el.className) el.removeAttribute('class');\n marker.replaceWith(el);\n this._originalContent = null;\n }\n this.tooltipEl.remove();\n this._removeEventHandlers();\n this.el['Expressive_Tooltip'] = undefined;\n }\n\n _appendTooltipEl() {\n this.tooltipEl = document.createElement('div');\n this.tooltipEl.classList.add('tooltip');\n this.tooltipEl.id = `tooltip-${Utils.guid()}`;\n this.tooltipEl.setAttribute('role', 'tooltip');\n this.el.setAttribute('aria-describedby', [this.el.getAttribute('aria-describedby'), this.tooltipEl.id].filter(Boolean).join(' '));\n\n const tooltipContentEl = this.options.tooltipId\n ? Utils.getElementById(this.el, this.options.tooltipId)\n : document.createElement('div');\n if (this.options.tooltipId) {\n this.tooltipEl.classList.add('rich');\n const marker = document.createComment('');\n tooltipContentEl.before(marker);\n this._originalContent = {\n el: tooltipContentEl, marker,\n display: tooltipContentEl.style.display,\n priority: tooltipContentEl.style.getPropertyPriority('display'),\n hidden: tooltipContentEl.getAttribute('hidden'),\n contentClass: tooltipContentEl.classList.contains('tooltip-content')\n };\n tooltipContentEl.removeAttribute('hidden');\n }\n tooltipContentEl.style.display = '';\n tooltipContentEl.classList.add('tooltip-content');\n this._setTooltipContent(tooltipContentEl);\n this.tooltipEl.appendChild(tooltipContentEl);\n Utils.portalRoot(this.el).appendChild(this.tooltipEl);\n }\n\n _setTooltipContent(tooltipContentEl: HTMLElement) {\n if (this.options.tooltipId) return;\n tooltipContentEl.innerText = this.options.text;\n }\n\n _updateTooltipContent() {\n this._setTooltipContent(this.tooltipEl.querySelector('.tooltip-content'));\n }\n\n _setupEventHandlers() {\n for (const el of [this.el, this.tooltipEl]) {\n el.addEventListener('mouseenter', this._handleMouseEnter);\n el.addEventListener('mouseleave', this._handleMouseLeave);\n el.addEventListener('focus', this._handleFocus, true);\n el.addEventListener('blur', this._handleBlur, true);\n }\n }\n\n _removeEventHandlers() {\n for (const el of [this.el, this.tooltipEl]) {\n el.removeEventListener('mouseenter', this._handleMouseEnter);\n el.removeEventListener('mouseleave', this._handleMouseLeave);\n el.removeEventListener('focus', this._handleFocus, true);\n el.removeEventListener('blur', this._handleBlur, true);\n }\n // Escape is only listened for while open; see open() and close().\n this.el.ownerDocument.removeEventListener('keydown', this._handleKeydown, true);\n }\n\n /**\n * Show tooltip.\n */\n open = (isManual: boolean = true) => {\n if (this.isOpen) return;\n clearTimeout(this._exitDelayTimeout);\n clearTimeout(this._animationTimeout);\n this.isOpen = true;\n this.el.ownerDocument.addEventListener('keydown', this._handleKeydown, true);\n // Update tooltip content with HTML attribute options\n this.options = { ...this.options, ...this._getAttributeOptions() };\n this._updateTooltipContent();\n this._setEnterDelayTimeout(isManual);\n };\n\n /**\n * Hide tooltip.\n */\n close = () => {\n if (!this.isOpen) return;\n this.isHovered = false;\n this.isFocused = false;\n this.isOpen = false;\n this.el.ownerDocument.removeEventListener('keydown', this._handleKeydown, true);\n clearTimeout(this._enterDelayTimeout);\n this._setExitDelayTimeout();\n };\n\n _setExitDelayTimeout() {\n clearTimeout(this._exitDelayTimeout);\n this._exitDelayTimeout = setTimeout(() => {\n if (this.isHovered || this.isFocused) return;\n this._animateOut();\n }, this.options.exitDelay);\n }\n\n _setEnterDelayTimeout(isManual) {\n clearTimeout(this._enterDelayTimeout);\n this._enterDelayTimeout = setTimeout(() => {\n if (!this.isHovered && !this.isFocused && !isManual) return;\n this._animateIn();\n }, this.options.enterDelay);\n }\n\n _positionTooltip() {\n const tooltip: HTMLElement = this.tooltipEl;\n const origin = this.el as HTMLElement,\n originHeight = origin.offsetHeight,\n originWidth = origin.offsetWidth,\n tooltipHeight = tooltip.offsetHeight,\n tooltipWidth = tooltip.offsetWidth,\n margin = this.options.margin;\n\n this.xMovement = 0;\n this.yMovement = 0;\n\n const originRect = origin.getBoundingClientRect();\n let targetTop = originRect.top + Utils.getDocumentScrollTop();\n let targetLeft = originRect.left + Utils.getDocumentScrollLeft();\n if (this.options.position === 'top') {\n targetTop += -tooltipHeight - margin;\n targetLeft += originWidth / 2 - tooltipWidth / 2;\n this.yMovement = -this.options.transitionMovement;\n } else if (this.options.position === 'right') {\n targetTop += originHeight / 2 - tooltipHeight / 2;\n targetLeft += originWidth + margin;\n this.xMovement = this.options.transitionMovement;\n } else if (this.options.position === 'left') {\n targetTop += originHeight / 2 - tooltipHeight / 2;\n targetLeft += -tooltipWidth - margin;\n this.xMovement = -this.options.transitionMovement;\n } else {\n targetTop += originHeight + margin;\n targetLeft += originWidth / 2 - tooltipWidth / 2;\n this.yMovement = this.options.transitionMovement;\n }\n\n const newCoordinates = this._repositionWithinScreen(\n targetLeft,\n targetTop,\n tooltipWidth,\n tooltipHeight\n );\n\n tooltip.style.setProperty('--md-comp-tooltip-anchor-gap', `${Math.max(0, margin) + Math.abs(this.options.transitionMovement)}px`);\n tooltip.style.top = newCoordinates.y + 'px';\n tooltip.style.left = newCoordinates.x + 'px';\n }\n\n _repositionWithinScreen(x: number, y: number, width: number, height: number) {\n return Utils._repositionWithinScreen(\n x, y, width, height, this.options.margin, this.options.transitionMovement, 'center'\n );\n }\n\n _animateIn() { this._animate(true); }\n\n _animateOut() { this._animate(false); }\n\n _animate(show: boolean) {\n const style = this.tooltipEl.style;\n const reduce = this.el.ownerDocument.defaultView.matchMedia('(prefers-reduced-motion: reduce)').matches;\n const duration = reduce ? 0 : show ? this.options.inDuration : this.options.outDuration;\n if (show) {\n this._positionTooltip();\n style.visibility = 'visible';\n style.overflow = 'visible';\n }\n style.transition = `transform ${duration}ms ease-out, opacity ${duration}ms ease-out`;\n clearTimeout(this._animationTimeout);\n this._animationTimeout = setTimeout(() => {\n style.transform = show && !reduce ? `translateX(${this.xMovement}px) translateY(${this.yMovement}px)` : 'none';\n style.opacity = show ? (this.options.opacity || 1).toString() : '0';\n if (!show) this._animationTimeout = setTimeout(() => {\n style.visibility = 'hidden';\n style.overflow = '';\n }, duration);\n }, 1);\n }\n\n _handleMouseEnter = () => {\n this.isHovered = true;\n this.open(false);\n };\n\n _handleMouseLeave = (event: MouseEvent) => {\n const next = event.relatedTarget as Node | null;\n if (next && (this.el.contains(next) || this.tooltipEl.contains(next))) return;\n this.isHovered = false;\n if (!this.isFocused) this.close();\n };\n\n _handleKeydown = (event: KeyboardEvent) => {\n if (event.key !== 'Escape' || !this.isOpen) return;\n event.preventDefault();\n event.stopPropagation();\n this.close();\n clearTimeout(this._exitDelayTimeout);\n this._animateOut();\n };\n\n // Focus opens the tooltip only when it arrived by keyboard: a pointer press\n // on the trigger also focuses it, and _handleMouseEnter already covers that.\n _handleFocus = (event: FocusEvent) => {\n if ((event.target as HTMLElement).matches(':focus-visible')) {\n this.isFocused = true;\n this.open(false);\n }\n };\n\n _handleBlur = (event: FocusEvent) => {\n const next = event.relatedTarget as Node | null;\n if (next && (this.el.contains(next) || this.tooltipEl.contains(next))) return;\n this.isFocused = false;\n if (!this.isHovered) this.close();\n };\n\n _getAttributeOptions(): Partial<TooltipOptions> {\n const attributeOptions: Partial<TooltipOptions> = {};\n const tooltipTextOption = this.el.getAttribute('data-tooltip');\n const tooltipId = this.el.getAttribute('data-tooltip-id');\n const positionOption = this.el.getAttribute('data-position');\n if (tooltipTextOption) {\n attributeOptions.text = tooltipTextOption;\n }\n if (positionOption) {\n attributeOptions.position = positionOption as TooltipPosition;\n }\n if (tooltipId) {\n attributeOptions.tooltipId = tooltipId;\n }\n\n return attributeOptions;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/core/component.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Base options for component initialization.\n */\nexport interface BaseOptions {}\n\nexport type InitElement = HTMLElement | Element;\nexport type InitElements<T extends InitElement> = NodeListOf<T> | HTMLCollectionOf<T>;\ntype ComponentConstructor<T extends Component<O>, O extends BaseOptions> = {\n new (el: HTMLElement, options: Partial<O>): T;\n};\ntype ComponentType<C extends Component<O>, O extends BaseOptions> = ComponentConstructor<C, O> &\n typeof Component<O>;\n\nexport interface I18nOptions {\n cancel: string;\n clear: string;\n done: string;\n}\n\nexport interface Openable {\n isOpen: boolean;\n open(): void;\n close(): void;\n}\n\n/**\n * Base class implementation for Expressive components.\n */\nexport class Component<O extends BaseOptions> {\n /**\n * The DOM element the plugin was initialized with.\n */\n el: HTMLElement;\n /**\n * The options the instance was initialized with.\n */\n options: O;\n\n /**\n * Constructs component instance and set everything up.\n */\n constructor(el: HTMLElement, options: Partial<O>, classDef: ComponentType<Component<O>, O>) {\n // Display error if el is not a valid HTML Element\n if (!(el instanceof HTMLElement)) {\n console.error(Error(el + ' is not an HTML Element'));\n }\n // If exists, destroy and reinitialize in child\n const ins = classDef.getInstance(el);\n if (!!ins) {\n ins.destroy();\n }\n this.el = el;\n }\n\n /**\n * Initializes component instance.\n * @param el HTML element.\n * @param options Component options.\n * @param classDef Class definition.\n */\n protected static init<I extends HTMLElement, O extends BaseOptions, C extends Component<O>>(\n el: I,\n options: O,\n classDef: ComponentType<C, O>\n ): C;\n /**\n * Initializes component instances.\n * @param els HTML elements.\n * @param options Component options.\n * @param classDef Class definition.\n */\n protected static init<I extends InitElement, O extends BaseOptions, C extends Component<O>>(\n els: InitElements<I>,\n options: Partial<O>,\n classDef: ComponentType<C, O>\n ): C[];\n /**\n * Initializes component instances.\n * @param els HTML elements.\n * @param options Component options.\n * @param classDef Class definition.\n */\n protected static init<I extends InitElement, O extends BaseOptions, C extends Component<O>>(\n els: I | InitElements<I>,\n options: Partial<O>,\n classDef: ComponentType<C, O>\n ): C | C[];\n /**\n * Initializes component instances.\n * @param els HTML elements.\n * @param options Component options.\n * @param classDef Class definition.\n */\n protected static init<I extends InitElement, O extends BaseOptions, C extends Component<O>>(\n els: I | InitElements<I>,\n options: Partial<O>,\n classDef: ComponentType<C, O>\n ): C | C[] {\n let instances = null;\n if (els instanceof Element) {\n instances = new classDef(<HTMLElement>els, options);\n } else if (els) {\n instances = [];\n for (let i = 0; i < els.length; i++) {\n instances.push(new classDef(<HTMLElement>els[i], options));\n }\n }\n return instances;\n }\n\n /**\n * @returns default options for component instance.\n */\n static get defaults(): BaseOptions {\n return {};\n }\n\n /**\n * Retrieves component instance for the given element.\n * @param el Associated HTML Element.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static getInstance(el: HTMLElement): Component<BaseOptions> {\n throw new Error('This method must be implemented.');\n }\n\n /**\n * Destroy plugin instance and teardown.\n */\n destroy(): void {\n throw new Error('This method must be implemented.');\n }\n}\n"],
|
|
5
|
-
"mappings": ";AA4BO,IAAM,YAAN,MAAuC;AAAA;AAAA;AAAA;AAAA,EAa5C,YAAY,IAAiB,SAAqB,UAA0C;AAE1F,QAAI,EAAE,cAAc,cAAc;AAChC,cAAQ,MAAM,MAAM,KAAK,yBAAyB,CAAC;AAAA,IACrD;AAEA,UAAM,MAAM,SAAS,YAAY,EAAE;AACnC,QAAI,CAAC,CAAC,KAAK;AACT,UAAI,QAAQ;AAAA,IACd;AACA,SAAK,KAAK;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyCA,OAAiB,KACf,KACA,SACA,UACS;AACT,QAAI,YAAY;AAChB,QAAI,eAAe,SAAS;AAC1B,kBAAY,IAAI,SAAsB,KAAK,OAAO;AAAA,IACpD,WAAW,KAAK;AACd,kBAAY,CAAC;AACb,eAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,kBAAU,KAAK,IAAI,SAAsB,IAAI,CAAC,GAAG,OAAO,CAAC;AAAA,MAC3D;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,WAAwB;AACjC,WAAO,CAAC;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,YAAY,IAAyC;AAC1D,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/ts/core/utils.ts"],
|
|
4
|
-
"sourcesContent": ["/** The part of a `DOMRect` the positioning helpers below actually read. */\ntype Bounding = Pick<DOMRect, 'left' | 'top' | 'width' | 'height'>;\n\n/** Which edges of a container a box has crossed. */\ntype Edges = { top: boolean; right: boolean; bottom: boolean; left: boolean };\n\n/**\n * Class with utilitary functions for global usage.\n */\nexport class Utils {\n /**\n * Key maps. One `KeyboardEvent.key` value each: the second entries these used\n * to carry (`Esc`, `Up`, `Del`, ...) were IE and Edge Legacy spellings, and\n * the support baseline excludes both.\n */\n static keys = {\n TAB: 'Tab',\n ENTER: 'Enter',\n ESC: 'Escape',\n BACKSPACE: 'Backspace',\n ARROW_UP: 'ArrowUp',\n ARROW_DOWN: 'ArrowDown',\n ARROW_LEFT: 'ArrowLeft',\n ARROW_RIGHT: 'ArrowRight',\n DELETE: 'Delete'\n };\n\n /**\n * Run `callback` once the document is parsed.\n *\n * The document-level behaviors all used a bare DOMContentLoaded listener,\n * which never fires if the bundle is loaded after that event - an async or\n * deferred script tag, or a dynamic import. Checking readyState first covers\n * both orders.\n */\n static onDocumentReady(callback: () => void): void {\n if (typeof document === 'undefined') return;\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', callback, { once: true });\n } else {\n callback();\n }\n }\n\n /**\n * Generates a unique string identifier. Every caller prefixes the result and\n * uses it as an element id, and a UUID is valid in that position.\n *\n * `randomUUID` is exposed only in secure contexts, and a dev server on a\n * plain-HTTP LAN address - the usual way a page is opened on a phone - is\n * not one. Without the fallback every component that stamps an id would\n * throw there. The ids only have to be unique within one document, so the\n * fallback does not need to be cryptographic.\n */\n static guid(): string {\n return (\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`\n );\n }\n\n /**\n * Where an element created at runtime has to be appended to stay in the same\n * tree as `el`. A stylesheet adopted into a shadow root cannot match a node\n * in the document, so a portal that lands on `document.body` is unstyled\n * whenever its origin lives in a shadow root (adr/0002).\n *\n * Light-DOM elements still get `document.body`, which is what escapes an\n * ancestor's `overflow: hidden` and stacking context. Inside a shadow root\n * both hazards come back: the host's own ancestors still form the containing\n * block, so a transformed ancestor re-anchors `position: fixed` and a\n * positioned one re-anchors `position: absolute`.\n */\n static portalRoot(el: Node): HTMLElement | ShadowRoot {\n const root = el.getRootNode() as ShadowRoot;\n // Only a ShadowRoot has a host; a Document or a detached subtree does not.\n return root.host ? root : document.body;\n }\n\n /**\n * `getElementById` against the tree `el` lives in. The mirror of\n * `portalRoot`: an id in a shadow root is invisible to\n * `document.getElementById`, so a trigger and its target inside the same\n * root could not find each other at all.\n *\n * Falls back to the document for a detached `el`, whose root is a plain\n * element with no lookup of its own.\n */\n static getElementById(el: Node, id: string): HTMLElement {\n const root = el.getRootNode() as Document | ShadowRoot;\n return (root.getElementById ? root.getElementById(id) : document.getElementById(id)) as HTMLElement;\n }\n\n /**\n * Checks for exceeded edges\n * @param container Container element.\n * @param bounding Bounding rect.\n * @param offset Element offset.\n */\n static checkWithinContainer(container: HTMLElement, bounding: Bounding, offset: number): Edges {\n const edges = {\n top: false,\n right: false,\n bottom: false,\n left: false\n };\n\n const containerRect = container.getBoundingClientRect();\n // If body element is smaller than viewport, use viewport height instead.\n const containerBottom =\n container === document.body\n ? Math.max(containerRect.bottom, window.innerHeight)\n : containerRect.bottom;\n\n const scrollLeft = container.scrollLeft;\n const scrollTop = container.scrollTop;\n\n const scrolledX = bounding.left - scrollLeft;\n const scrolledY = bounding.top - scrollTop;\n\n // Check for container and viewport for each edge\n if (scrolledX < containerRect.left + offset || scrolledX < offset) {\n edges.left = true;\n }\n\n if (\n scrolledX + bounding.width > containerRect.right - offset ||\n scrolledX + bounding.width > window.innerWidth - offset\n ) {\n edges.right = true;\n }\n\n if (scrolledY < containerRect.top + offset || scrolledY < offset) {\n edges.top = true;\n }\n\n if (\n scrolledY + bounding.height > containerBottom - offset ||\n scrolledY + bounding.height > window.innerHeight - offset\n ) {\n edges.bottom = true;\n }\n\n return edges;\n }\n\n /**\n * Checks if element can be aligned in multiple directions.\n * @param el Element to be inspected.\n * @param container Container element.\n * @param bounding Bounding rect.\n * @param offset Element offset.\n */\n static checkPossibleAlignments(\n el: HTMLElement,\n container: HTMLElement,\n bounding: Bounding,\n offset: number\n ) {\n const canAlign: {\n top: boolean;\n right: boolean;\n bottom: boolean;\n left: boolean;\n spaceOnTop: number;\n spaceOnRight: number;\n spaceOnBottom: number;\n spaceOnLeft: number;\n } = {\n top: true,\n right: true,\n bottom: true,\n left: true,\n spaceOnTop: null,\n spaceOnRight: null,\n spaceOnBottom: null,\n spaceOnLeft: null\n };\n\n const containerAllowsOverflow = getComputedStyle(container).overflow === 'visible';\n const containerRect = container.getBoundingClientRect();\n const containerHeight = Math.min(containerRect.height, window.innerHeight);\n const containerWidth = Math.min(containerRect.width, window.innerWidth);\n const elOffsetRect = el.getBoundingClientRect();\n\n const scrollLeft = container.scrollLeft;\n const scrollTop = container.scrollTop;\n\n const scrolledX = bounding.left - scrollLeft;\n const scrolledYTopEdge = bounding.top - scrollTop;\n const scrolledYBottomEdge = bounding.top + elOffsetRect.height - scrollTop;\n\n // Check for container and viewport for left\n canAlign.spaceOnRight = !containerAllowsOverflow\n ? containerWidth - (scrolledX + bounding.width)\n : window.innerWidth - (elOffsetRect.left + bounding.width);\n if (canAlign.spaceOnRight < 0) {\n canAlign.left = false;\n }\n\n // Check for container and viewport for Right\n canAlign.spaceOnLeft = !containerAllowsOverflow\n ? scrolledX - bounding.width + elOffsetRect.width\n : elOffsetRect.right - bounding.width;\n if (canAlign.spaceOnLeft < 0) {\n canAlign.right = false;\n }\n\n // Check for container and viewport for Top\n canAlign.spaceOnBottom = !containerAllowsOverflow\n ? containerHeight - (scrolledYTopEdge + bounding.height + offset)\n : window.innerHeight - (elOffsetRect.top + bounding.height + offset);\n if (canAlign.spaceOnBottom < 0) {\n canAlign.top = false;\n }\n\n // Check for container and viewport for Bottom\n canAlign.spaceOnTop = !containerAllowsOverflow\n ? scrolledYBottomEdge - (bounding.height - offset)\n : elOffsetRect.bottom - (bounding.height + offset);\n if (canAlign.spaceOnTop < 0) {\n canAlign.bottom = false;\n }\n\n return canAlign;\n }\n\n /**\n * Retrieves target element id from trigger.\n * @param trigger Trigger element.\n */\n static getIdFromTrigger(trigger: HTMLElement): string {\n let id = trigger.dataset.target;\n if (!id) {\n id = trigger.getAttribute('href');\n return id ? id.slice(1) : '';\n }\n return id;\n }\n\n /**\n * Retrieves document scroll postion from top.\n */\n static getDocumentScrollTop(): number {\n return window.scrollY;\n }\n\n /**\n * Retrieves document scroll postion from left.\n */\n static getDocumentScrollLeft(): number {\n return window.scrollX;\n }\n\n /**\n * Trailing-edge throttle: run `func` now, then at most once per `wait` ms\n * with the most recent arguments.\n *\n * This used to carry its underscore ancestor's whole configuration - leading\n * and trailing switches, a result passthrough - and both call sites are\n * resize handlers passing nothing but a function and a delay.\n *\n * Assign the return value once. `x = Utils.throttle(fn, 200)` is right;\n * wrapping it in an arrow builds a fresh closure per event and never calls\n * it, which is how resize handling was dead in three components.\n */\n static throttle(func: (...args: unknown[]) => void, wait: number) {\n let timeout: ReturnType<typeof setTimeout> = null;\n let lastArgs: unknown[] = null;\n let previous = -Infinity;\n\n return (...args: unknown[]) => {\n // performance.now() is monotonic; Date.now() follows the system clock\n // and a backward jump would hold the trailing call for as long as it jumped.\n const now = performance.now();\n const remaining = wait - (now - previous);\n if (remaining <= 0) {\n clearTimeout(timeout);\n timeout = null;\n previous = now;\n lastArgs = null;\n func(...args);\n } else if (!timeout) {\n // The trailing call replays the most recent arguments; without this it\n // used to fire with none at all.\n lastArgs = args;\n timeout = setTimeout(() => {\n previous = performance.now();\n timeout = null;\n func(...(lastArgs ?? []));\n lastArgs = null;\n }, remaining);\n } else {\n lastArgs = args;\n }\n };\n }\n\n /**\n * Renders confirm/close buttons with callback function\n */\n static createConfirmationContainer(\n container: HTMLElement,\n confirmText: string,\n cancelText: string,\n onConfirm: (Function: object) => void,\n onCancel: (Function: object) => void\n ): void {\n const confirmationButtonsContainer = document.createElement('div');\n confirmationButtonsContainer.classList.add('confirmation-btns');\n container.append(confirmationButtonsContainer);\n\n this.createButton(confirmationButtonsContainer, cancelText, ['btn-cancel'], true, onCancel);\n this.createButton(confirmationButtonsContainer, confirmText, ['btn-confirm'], true, onConfirm);\n }\n\n /**\n * Renders a button with optional callback function\n */\n static createButton(\n container: HTMLElement,\n text: string,\n className: string[] = [],\n visibility: boolean = true,\n callback: (Function: object) => void = null\n ): void {\n className = className.concat(['text']);\n const button = document.createElement('button');\n button.className = className.join(' ');\n button.style.visibility = visibility ? 'visible' : 'hidden';\n button.type = 'button';\n button.tabIndex = !!visibility ? 0 : -1;\n button.innerText = text;\n if (typeof callback === 'function') button.addEventListener('click', callback);\n container.append(button);\n }\n\n static _setAbsolutePosition(\n origin: HTMLElement,\n container: HTMLElement,\n position: string,\n margin: number,\n transitionMovement: number,\n align: string = 'center'\n ) {\n const originHeight = origin.offsetHeight,\n originWidth = origin.offsetWidth,\n containerHeight = container.offsetHeight,\n containerWidth = container.offsetWidth,\n originRect = origin.getBoundingClientRect(); // one rect, read twice below\n let xMovement = 0,\n yMovement = 0,\n targetTop = originRect.top + Utils.getDocumentScrollTop(),\n targetLeft = originRect.left + Utils.getDocumentScrollLeft();\n\n if (position === 'top') {\n targetTop += -containerHeight - margin;\n if (align === 'center') {\n targetLeft += originWidth / 2 - containerWidth / 2; // This is center align\n }\n yMovement = -transitionMovement;\n } else if (position === 'right') {\n targetTop += originHeight / 2 - containerHeight / 2;\n targetLeft = originWidth + margin;\n xMovement = transitionMovement;\n } else if (position === 'left') {\n targetTop += originHeight / 2 - containerHeight / 2;\n targetLeft = -containerWidth - margin;\n xMovement = -transitionMovement;\n } else {\n targetTop += originHeight + margin;\n if (align === 'center') {\n targetLeft += originWidth / 2 - containerWidth / 2; // This is center align\n }\n yMovement = transitionMovement;\n }\n if (align === 'right') {\n targetLeft += originWidth - containerWidth - margin;\n }\n\n const newCoordinates = Utils._repositionWithinScreen(\n targetLeft,\n targetTop,\n containerWidth,\n containerHeight,\n margin,\n transitionMovement,\n align\n );\n\n const parent = container.offsetParent as HTMLElement;\n // A static body uses document coordinates; positioned parents use their\n // padding edge, including borders and local scrolling.\n if (parent && (parent !== document.body || getComputedStyle(parent).position !== 'static')) {\n const rect = parent.getBoundingClientRect();\n const root = parent === document.scrollingElement;\n newCoordinates.x -= rect.left + Utils.getDocumentScrollLeft() + parent.clientLeft - (root ? 0 : parent.scrollLeft);\n newCoordinates.y -= rect.top + Utils.getDocumentScrollTop() + parent.clientTop - (root ? 0 : parent.scrollTop);\n }\n\n container.style.top = newCoordinates.y + 'px';\n container.style.left = newCoordinates.x + 'px';\n\n return {x: xMovement, y: yMovement};\n }\n\n static _repositionWithinScreen(\n x: number,\n y: number,\n width: number,\n height: number,\n margin: number,\n transitionMovement: number,\n align: string\n ) {\n const scrollLeft = Utils.getDocumentScrollLeft();\n const scrollTop = Utils.getDocumentScrollTop();\n let newX = x - scrollLeft;\n let newY = y - scrollTop;\n\n const bounding: Bounding = {\n left: newX,\n top: newY,\n width: width,\n height: height\n };\n let offset: number;\n if (align === 'left' || align == 'center') {\n offset = margin + transitionMovement;\n } else if (align === 'right') {\n offset = margin - transitionMovement;\n }\n const edges = Utils.checkWithinContainer(document.body, bounding, offset);\n\n if (edges.left) {\n newX = offset;\n } else if (edges.right) {\n newX -= newX + width - window.innerWidth;\n }\n if (edges.top) {\n newY = offset;\n } else if (edges.bottom) {\n newY -= newY + height - window.innerHeight;\n }\n return {\n x: newX + scrollLeft,\n y: newY + scrollTop\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/lineChart.ts"],
|
|
4
|
-
"sourcesContent": ["import { Component, BaseOptions, InitElements, InitElement } from '../core/component';\n\nexport interface LineChartOptions extends BaseOptions {\n /**\n * Lowest value on the y axis. Defaults to the data minimum less 10% of\n * the range; a stacked chart starts at zero or its lowest total, and a\n * column chart always includes zero. Overridden by `data-min` on the chart.\n */\n min: number | null;\n /**\n * Highest value on the y axis. Defaults to the data maximum plus 10% of\n * the range. Overridden by `data-max` on the chart.\n */\n max: number | null;\n}\n\nconst _defaults: LineChartOptions = {\n min: null,\n max: null\n};\n\nconst SVG = 'http://www.w3.org/2000/svg';\nexport const COLORS = 4;\n\n/** An SVG element with its attributes. */\nexport function svgNode(name: string, attributes: Record<string, string> = {}): SVGElement {\n const element = document.createElementNS(SVG, name);\n for (const key in attributes) element.setAttribute(key, attributes[key]);\n return element;\n}\nlet _gradientId = 0;\n\nexport interface Series {\n name: string;\n /** Header cell classes, such as `dashed`. */\n className: string;\n /** Cell text, shown in the tooltip as the author formatted it. */\n text: string[];\n values: (number | null)[];\n /**\n * Where each value is drawn: the value, or in a stacked chart the running\n * total, which is unknown (null) above a gap.\n */\n tops: (number | null)[];\n /** In a stacked chart, the total of the series below, which this area fills down to. */\n base?: (number | null)[];\n /** The series' y scale: a value's distance down the plot, in percent. */\n y: (value: number) => number;\n}\n\n/**\n * Reads a cell as a number. `data-value` wins over the text, which may carry\n * currency or percent signs, grouping commas and a typographic minus around\n * one number. Anything else, such as \"(1,200)\" or \"3\u20135\", is a gap rather\n * than a guess.\n */\nfunction cellValue(cell: Element | undefined): number | null {\n if (!cell) return null;\n const raw = (cell as HTMLElement).dataset.value ?? cell.textContent;\n const text = raw.replace(/\\u2212/g, '-').replace(/[\\s%\\p{Sc}]/gu, '');\n if (!/^[+-]?(\\d{1,3}(,\\d{3})+|\\d+)?(\\.\\d+)?(e[+-]?\\d+)?$/i.test(text) || !/\\d/.test(text)) return null;\n return parseFloat(text.replace(/,/g, ''));\n}\n\n/**\n * A monotone cubic through the points (Fritsch-Butland tangents), so the\n * curve never overshoots a data point. Bezier curves keep their shape under\n * the plot's non-uniform scaling, so this can be drawn in a 0-100 box.\n */\nfunction monotonePath(points: [number, number][]): string {\n const n = points.length;\n if (n === 0) return '';\n if (n === 1) return `M${points[0][0]},${points[0][1]}h0`;\n const slopes: number[] = [];\n for (let i = 0; i < n - 1; i++) {\n slopes.push((points[i + 1][1] - points[i][1]) / (points[i + 1][0] - points[i][0]));\n }\n const tangents = points.map((_, i) => {\n if (i === 0) return slopes[0];\n if (i === n - 1) return slopes[n - 2];\n const [a, b] = [slopes[i - 1], slopes[i]];\n return a * b <= 0 ? 0 : 2 / (1 / a + 1 / b);\n });\n let d = `M${points[0][0]},${points[0][1]}`;\n for (let i = 0; i < n - 1; i++) {\n const [[x0, y0], [x1, y1]] = [points[i], points[i + 1]];\n const h = (x1 - x0) / 3;\n d += `C${x0 + h},${y0 + tangents[i] * h} ${x1 - h},${y1 - tangents[i + 1] * h} ${x1},${y1}`;\n }\n return d;\n}\n\n/**\n * Line chart. The data is the chart's <table>; this class draws it as an SVG\n * with x labels, a legend for more than one series, and a cursor and tooltip\n * that follow the pointer or the arrow keys. Styling is CSS.\n *\n * Re-run `LineChart.init(el)` after changing the table.\n */\nexport class LineChart extends Component<LineChartOptions> {\n /** The values' x positions and series, read from the table. */\n labels: string[] = [];\n series: Series[] = [];\n /** The highlighted row, or -1. */\n activeIndex = -1;\n private _generated: Element[] = [];\n /** The table's header cells and body rows, as read. */\n protected _header: HTMLTableCellElement[] = [];\n protected _rows: HTMLTableRowElement[] = [];\n protected _plot: HTMLElement;\n protected _cursor: HTMLElement;\n protected _tooltip: HTMLElement;\n protected _y: (value: number) => number;\n /**\n * Whether the rows run right to left: a horizontal row axis in a\n * right-to-left context, like the labels. Bar chart rows keep their order.\n */\n protected _reversed = false;\n\n /** The class prefix of the generated parts; ColumnChart reuses this class. */\n protected get _type() {\n return 'line-chart';\n }\n\n /** Whether the y axis always includes zero, as columns grow from it. */\n protected get _fromZero() {\n return false;\n }\n\n /**\n * Whether the rows run down the plot and the values across it, as in a\n * bar chart. The rows then keep their order in a right-to-left context.\n */\n protected get _horizontal() {\n return false;\n }\n\n /**\n * Whether the rows go round a circle, as in a pie or radar chart. The\n * arrows then step round it, wrapping from the last row to the first.\n */\n protected get _circular() {\n return false;\n }\n\n /** Whether the cursor marks each series with a point. */\n protected get _points() {\n return true;\n }\n\n protected get _key() {\n return 'Expressive_LineChart';\n }\n\n constructor(el: HTMLElement, options: Partial<LineChartOptions>) {\n super(el, options, new.target);\n this.el[this._key] = this;\n\n this.options = {\n ...new.target.defaults,\n ...options\n };\n\n this._read();\n if (!this.labels.length || !this.series.length) return;\n this._reversed = !this._horizontal && getComputedStyle(this.el).direction === 'rtl';\n this._render();\n if (!this.el.classList.contains('sparkline')) {\n this._plot.tabIndex = 0;\n // A tap has no move before it, so the press picks the row too.\n this._plot.addEventListener('pointerdown', this._onPointerMove);\n this._plot.addEventListener('pointermove', this._onPointerMove);\n this._plot.addEventListener('pointerleave', this._onLeave);\n this._plot.addEventListener('pointercancel', this._onCancel);\n this._plot.addEventListener('keydown', this._onKeyDown);\n this._plot.addEventListener('focus', this._onFocus);\n this._plot.addEventListener('blur', this._onLeave);\n }\n }\n\n static get defaults(): LineChartOptions {\n return _defaults;\n }\n\n static init(el: HTMLElement, options?: Partial<LineChartOptions>): LineChart;\n static init(els: InitElements<InitElement>, options?: Partial<LineChartOptions>): LineChart[];\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<LineChartOptions> = {}\n ): LineChart | LineChart[] {\n return super.init(els, options, this);\n }\n\n static getInstance(el: HTMLElement): LineChart {\n return el['Expressive_LineChart'];\n }\n\n destroy() {\n // The listeners live on the plot, which goes with the generated nodes.\n this._generated.forEach((node) => node.remove());\n this._generated = [];\n this.el[this._key] = undefined;\n }\n\n /**\n * Highlights one row: moves the cursor and fills the tooltip.\n * Pass -1 to hide them. Does nothing for a chart without data.\n */\n show(index: number) {\n // Skipping a repeat also keeps the live tooltip from re-announcing.\n if (!this._tooltip || index === this.activeIndex) return;\n this.activeIndex = index;\n const hidden = index < 0 || index >= this.labels.length;\n this._cursor.hidden = this._tooltip.hidden = hidden;\n if (hidden) return;\n\n this._cursor.replaceChildren();\n const title = document.createElement('strong');\n title.textContent = this.labels[index];\n this._tooltip.replaceChildren(title);\n\n this.series.forEach((series, i) => {\n const value = series.values[index];\n if (value === null) return;\n const color = String((i % COLORS) + 1);\n const top = series.tops[index];\n if (top !== null && this._points) {\n const dot = document.createElement('span');\n dot.className = series.className;\n dot.dataset.series = color;\n dot.style.top = `${series.y(top)}%`;\n this._cursor.append(dot);\n }\n const name = document.createElement('span');\n name.dataset.series = color;\n name.textContent = series.name;\n const text = document.createElement('span');\n text.textContent = series.text[index];\n this._tooltip.append(name, text);\n });\n this._place(index);\n }\n\n /**\n * Moves the filled cursor and tooltip to a row: beside its band, with the\n * tooltip opening back over the plot past the middle.\n */\n protected _place(index: number) {\n const x = this._x(index);\n const side = this._horizontal ? 'top' : 'left';\n this._cursor.style[side] = this._tooltip.style[side] = `${x}%`;\n this._tooltip.classList.toggle('end', x > 50);\n }\n\n private _read() {\n const table = this.el.querySelector<HTMLTableElement>(':scope > table');\n if (!table) return;\n // Without a <thead> the parser puts the header row in the first <tbody>.\n const headerRow = table.tHead?.rows[0] ?? table.rows[0];\n const header = Array.from(headerRow?.cells ?? []);\n const rows = Array.from(table.tBodies)\n .flatMap((body) => Array.from(body.rows))\n .filter((row) => row !== headerRow);\n [this._header, this._rows] = [header, rows];\n this.labels = rows.map((row) => row.cells[0]?.textContent.trim() ?? '');\n this.series = header.slice(1).map((cell, i) => {\n const values = rows.map((row) => cellValue(row.cells[i + 1]));\n return {\n name: cell.textContent.trim(),\n className: cell.className,\n text: rows.map((row) => row.cells[i + 1]?.textContent.trim() ?? ''),\n values,\n tops: values,\n y: undefined\n };\n });\n const stacked = this.el.classList.contains('stacked');\n if (stacked) {\n // A gap leaves the total unknown, so the series above break there too.\n // ponytail: negative values overlap the band below; diverging stacks if needed.\n const totals: (number | null)[] = this.labels.map(() => 0);\n for (const series of this.series) {\n series.base = [...totals];\n series.tops = series.values.map((value, i) =>\n (totals[i] = value === null || totals[i] === null ? null : totals[i] + value));\n }\n }\n\n if (this.series.every((series) => series.tops.every((value) => value === null))) this.series = [];\n const option = (name: 'min' | 'max') => this._number(name) ?? this.options[name];\n this._y = this._scale(this.series, option('min'), option('max'));\n }\n\n /** A number from one of the chart's data attributes, or null. */\n protected _number(name: string) {\n const value = parseFloat(this.el.dataset[name] ?? '');\n return Number.isFinite(value) ? value : null;\n }\n\n /**\n * Fits a y scale to the series' tops, between `min` and `max` where they\n * are set, and gives it to each series.\n */\n protected _scale(series: Series[], min: number | null, max: number | null, fromZero = this._fromZero) {\n const stacked = this.el.classList.contains('stacked');\n let [low, high] = [Infinity, -Infinity];\n for (const { tops } of series) {\n for (const value of tops) {\n if (value === null) continue;\n low = Math.min(low, value);\n high = Math.max(high, value);\n }\n }\n if (low > high) low = high = 0;\n if (fromZero) {\n // Zero is on the scale, with 10% of the span to spare on each side\n // that has data.\n const [bottom, top] = [Math.min(0, low), Math.max(0, high)];\n const room = (top - (min ?? bottom)) * 0.1 || 1;\n min ??= bottom < 0 ? bottom - room : 0;\n max ??= top + room;\n } else {\n const pad = (high - low) * 0.1 || 1;\n // Stacked areas are read against zero, with the headroom of that span.\n min ??= stacked ? Math.min(0, low) : low - pad;\n max ??= high + (stacked ? (high - min) * 0.1 || 1 : pad);\n }\n const y = (value: number) => 100 - ((value - min) / (max - min || 1)) * 100;\n for (const each of series) each.y = y;\n return y;\n }\n\n /** Each row sits in the middle of an equal band, beside its label. */\n private _x(index: number) {\n const x = ((index + 0.5) / this.labels.length) * 100;\n return this._reversed ? 100 - x : x;\n }\n\n private _render() {\n const type = this._type;\n this._plot = document.createElement('div');\n this._plot.className = `${type}-plot`;\n const caption = this.el.querySelector(':scope > figcaption')?.textContent.trim();\n this._plot.setAttribute('role', 'group');\n this._plot.setAttribute('aria-roledescription', type.replace(/-/g, ' '));\n if (caption) this._plot.setAttribute('aria-label', caption);\n\n this._cursor = document.createElement('div');\n this._cursor.className = `${type}-cursor`;\n this._cursor.hidden = true;\n this._tooltip = document.createElement('div');\n this._tooltip.className = `${type}-tooltip`;\n this._tooltip.hidden = true;\n this._tooltip.setAttribute('aria-live', 'polite');\n this._plot.append(this._draw(), this._cursor, this._tooltip);\n\n this._generated = [this._plot, ...this._guides()];\n this.el.append(...this._generated);\n }\n\n /**\n * The <tfoot> row as a total to show over the plot, its value over its\n * label, or null without one.\n */\n protected _total(className: string): HTMLElement | null {\n const footer = this.el.querySelector<HTMLTableElement>(':scope > table')?.tFoot?.rows[0];\n if (!footer) return null;\n const total = document.createElement('div');\n total.className = className;\n const [label, value] = [document.createElement('span'), document.createElement('strong')];\n label.textContent = footer.cells[0]?.textContent.trim() ?? '';\n value.textContent = footer.cells[1]?.textContent.trim() ?? '';\n total.append(value, label);\n return total;\n }\n\n /** The parts below the plot: the row labels and the legend. */\n protected _guides(): Element[] {\n const labels = document.createElement('ol');\n labels.className = `${this._type}-labels`;\n labels.setAttribute('aria-hidden', 'true');\n // A loop rather than a spread: a spread of every row overflows the stack.\n for (const text of this.labels) {\n const li = document.createElement('li');\n li.textContent = text;\n labels.append(li);\n }\n return [labels, ...this._legend()];\n }\n\n /** The series legend, for more than one series. */\n protected _legend(): Element[] {\n if (this.series.length < 2) return [];\n const legend = document.createElement('ul');\n legend.className = `${this._type}-legend`;\n legend.setAttribute('aria-hidden', 'true');\n legend.append(...this.series.map((series, i) => {\n const li = document.createElement('li');\n li.dataset.series = String((i % COLORS) + 1);\n li.textContent = series.name;\n return li;\n }));\n return [legend];\n }\n\n /** Draws the series, which fill the plot. */\n protected _draw(drawn = this.series): Element {\n const svg = document.createElementNS(SVG, 'svg');\n svg.setAttribute('viewBox', '0 0 100 100');\n svg.setAttribute('preserveAspectRatio', 'none');\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('focusable', 'false');\n\n for (const series of drawn) {\n const group = document.createElementNS(SVG, 'g');\n group.setAttribute('class', `${this._type}-series ${series.className}`.trim());\n group.dataset.series = String((this.series.indexOf(series) % COLORS) + 1);\n\n // A gap in the data breaks the line into runs of row indexes.\n const runs: number[][] = [[]];\n series.tops.forEach((value, index) => {\n if (value === null) runs.push([]);\n else runs[runs.length - 1].push(index);\n });\n const filled = runs.filter((run) => run.length);\n const points = (run: number[], values: (number | null)[]) =>\n run.map((index): [number, number] => [this._x(index), series.y(values[index]!)]);\n const tops = filled.map((run) => monotonePath(points(run, series.tops)));\n\n const id = `line-chart-gradient-${++_gradientId}`;\n const gradient = document.createElementNS(SVG, 'linearGradient');\n gradient.id = id;\n gradient.setAttribute('x2', '0');\n gradient.setAttribute('y2', '1');\n gradient.append(document.createElementNS(SVG, 'stop'), document.createElementNS(SVG, 'stop'));\n gradient.lastElementChild.setAttribute('offset', '1');\n\n const area = document.createElementNS(SVG, 'path');\n area.setAttribute('class', `${this._type}-area`);\n area.setAttribute('fill', `url(#${id})`);\n // A stacked area runs back along the series below; the reversed curve\n // is the same curve. Its base stops at the plot bottom when the y axis\n // starts above zero.\n area.setAttribute('d', filled\n .map((run, r) => {\n if (!series.base) return `${tops[r]}V100H${this._x(run[0])}Z`;\n const base = points(run, series.base).map(([x, y]): [number, number] => [x, Math.min(100, y)]);\n return `${tops[r]}L${monotonePath(base.reverse()).slice(1)}Z`;\n })\n .join(''));\n\n const line = document.createElementNS(SVG, 'path');\n line.setAttribute('class', `${this._type}-line`);\n line.setAttribute('d', tops.join(''));\n\n group.append(gradient, area, line);\n svg.append(group);\n }\n return svg;\n }\n\n private _onPointerMove = (e: PointerEvent) => {\n this.show(this._indexAt(e));\n };\n\n /** The row under the pointer, or -1. */\n protected _indexAt(e: PointerEvent) {\n const box = this._plot.getBoundingClientRect();\n const fraction = this._horizontal\n ? (e.clientY - box.top) / box.height\n : (e.clientX - box.left) / box.width;\n const index = Math.floor((this._reversed ? 1 - fraction : fraction) * this.labels.length);\n return Math.min(this.labels.length - 1, Math.max(0, index));\n }\n\n /**\n * For a circular chart, the pointer's position from the plot's middle: a\n * fraction of a turn clockwise from the top, and its distance as a share\n * of the plot's width.\n */\n protected _polarAt(e: PointerEvent): [turn: number, distance: number] {\n const box = this._plot.getBoundingClientRect();\n const [x, y] = [e.clientX - box.left - box.width / 2, e.clientY - box.top - box.height / 2];\n return [(Math.atan2(x, -y) / (2 * Math.PI) + 1) % 1, Math.hypot(x, y) / box.width];\n }\n\n /** The keys that move to the next row and to the one before. */\n protected get _arrows(): [string[], string[]] {\n // Round a circle both pairs work. The rows run clockwise in RTL too, so\n // right still moves the way the top row turns.\n if (this._circular) return [['ArrowRight', 'ArrowDown'], ['ArrowLeft', 'ArrowUp']];\n // Arrows move the cursor the way they point, so they swap in RTL.\n if (this._horizontal) return [['ArrowDown'], ['ArrowUp']];\n return this._reversed ? [['ArrowLeft'], ['ArrowRight']] : [['ArrowRight'], ['ArrowLeft']];\n }\n\n private _onFocus = () => {\n // Only keyboard focus picks the first row; a press off the marks, which\n // focuses the plot too, leaves the tooltip hidden.\n if (this.activeIndex < 0 && this._plot.matches(':focus-visible')) this.show(0);\n };\n\n private _onLeave = (e: Event) => {\n // A touch leaves as it lifts; the tapped row stays until the plot blurs.\n if ((e as PointerEvent).pointerType === 'touch' || this._plot.matches(':focus-visible')) return;\n this.show(-1);\n };\n\n /** The browser took the touch to scroll the page. */\n private _onCancel = () => {\n this.show(-1);\n };\n\n /** The index a key moves to, or undefined for a key the chart ignores. */\n protected _keyTarget(key: string): number | undefined {\n const last = this.labels.length - 1;\n const [forward, back] = this._arrows;\n const step = (by: number) => {\n if (!this._circular) return Math.min(last, Math.max(0, this.activeIndex + by));\n // Round a circle the ends meet; from no row, back starts at the last.\n if (this.activeIndex < 0) return by > 0 ? 0 : last;\n return (this.activeIndex + by + last + 1) % (last + 1);\n };\n // With nothing shown, Escape is left to a dialog or sheet around the chart.\n if (key === 'Escape') return this.activeIndex < 0 ? undefined : -1;\n return forward.includes(key) ? step(1)\n : back.includes(key) ? step(-1)\n : { Home: 0, End: last }[key];\n }\n\n private _onKeyDown = (e: KeyboardEvent) => {\n const next = this._keyTarget(e.key);\n if (next === undefined) return;\n e.preventDefault();\n this.show(next);\n };\n}\n"],
|
|
5
|
-
"mappings": ";;;;;AAgBA,IAAM,YAA8B;AAAA,EAClC,KAAK;AAAA,EACL,KAAK;AACP;AAEA,IAAM,MAAM;AACL,IAAM,SAAS;AAGf,SAAS,QAAQ,MAAc,aAAqC,CAAC,GAAe;AACzF,QAAM,UAAU,SAAS,gBAAgB,KAAK,IAAI;AAClD,aAAW,OAAO,WAAY,SAAQ,aAAa,KAAK,WAAW,GAAG,CAAC;AACvE,SAAO;AACT;AACA,IAAI,cAAc;AA0BlB,SAAS,UAAU,MAA0C;AAC3D,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,MAAO,KAAqB,QAAQ,SAAS,KAAK;AACxD,QAAM,OAAO,IAAI,QAAQ,WAAW,GAAG,EAAE,QAAQ,iBAAiB,EAAE;AACpE,MAAI,CAAC,sDAAsD,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,EAAG,QAAO;AAClG,SAAO,WAAW,KAAK,QAAQ,MAAM,EAAE,CAAC;AAC1C;AAOA,SAAS,aAAa,QAAoC;AACxD,QAAM,IAAI,OAAO;AACjB,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,MAAM,EAAG,QAAO,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC;AACpD,QAAM,SAAmB,CAAC;AAC1B,WAAS,IAAI,GAAG,IAAI,IAAI,GAAG,KAAK;AAC9B,WAAO,MAAM,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC,MAAM,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC,EAAE;AAAA,EACnF;AACA,QAAM,WAAW,OAAO,IAAI,CAAC,GAAG,MAAM;AACpC,QAAI,MAAM,EAAG,QAAO,OAAO,CAAC;AAC5B,QAAI,MAAM,IAAI,EAAG,QAAO,OAAO,IAAI,CAAC;AACpC,UAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;AACxC,WAAO,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAAA,EAC3C,CAAC;AACD,MAAI,IAAI,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC;AACxC,WAAS,IAAI,GAAG,IAAI,IAAI,GAAG,KAAK;AAC9B,UAAM,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;AACtD,UAAM,KAAK,KAAK,MAAM;AACtB,SAAK,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE;AAAA,EAC3F;AACA,SAAO;AACT;AASO,IAAM,YAAN,cAAwB,UAA4B;AAAA,EAuDzD,YAAY,IAAiB,SAAoC;AAC/D,UAAM,IAAI,SAAS,UAAU;AAtD/B;AAAA,kBAAmB,CAAC;AACpB,kBAAmB,CAAC;AAEpB;AAAA,uBAAc;AACd,SAAQ,aAAwB,CAAC;AAEjC;AAAA,SAAU,UAAkC,CAAC;AAC7C,SAAU,QAA+B,CAAC;AAS1C;AAAA;AAAA;AAAA;AAAA,SAAU,YAAY;AAwVtB,SAAQ,iBAAiB,CAAC,MAAoB;AAC5C,WAAK,KAAK,KAAK,SAAS,CAAC,CAAC;AAAA,IAC5B;AAiCA,SAAQ,WAAW,MAAM;AAGvB,UAAI,KAAK,cAAc,KAAK,KAAK,MAAM,QAAQ,gBAAgB,EAAG,MAAK,KAAK,CAAC;AAAA,IAC/E;AAEA,SAAQ,WAAW,CAAC,MAAa;AAE/B,UAAK,EAAmB,gBAAgB,WAAW,KAAK,MAAM,QAAQ,gBAAgB,EAAG;AACzF,WAAK,KAAK,EAAE;AAAA,IACd;AAGA;AAAA,SAAQ,YAAY,MAAM;AACxB,WAAK,KAAK,EAAE;AAAA,IACd;AAmBA,SAAQ,aAAa,CAAC,MAAqB;AACzC,YAAM,OAAO,KAAK,WAAW,EAAE,GAAG;AAClC,UAAI,SAAS,OAAW;AACxB,QAAE,eAAe;AACjB,WAAK,KAAK,IAAI;AAAA,IAChB;AA3XE,SAAK,GAAG,KAAK,IAAI,IAAI;AAErB,SAAK,UAAU;AAAA,MACb,GAAG,WAAW;AAAA,MACd,GAAG;AAAA,IACL;AAEA,SAAK,MAAM;AACX,QAAI,CAAC,KAAK,OAAO,UAAU,CAAC,KAAK,OAAO,OAAQ;AAChD,SAAK,YAAY,CAAC,KAAK,eAAe,iBAAiB,KAAK,EAAE,EAAE,cAAc;AAC9E,SAAK,QAAQ;AACb,QAAI,CAAC,KAAK,GAAG,UAAU,SAAS,WAAW,GAAG;AAC5C,WAAK,MAAM,WAAW;AAEtB,WAAK,MAAM,iBAAiB,eAAe,KAAK,cAAc;AAC9D,WAAK,MAAM,iBAAiB,eAAe,KAAK,cAAc;AAC9D,WAAK,MAAM,iBAAiB,gBAAgB,KAAK,QAAQ;AACzD,WAAK,MAAM,iBAAiB,iBAAiB,KAAK,SAAS;AAC3D,WAAK,MAAM,iBAAiB,WAAW,KAAK,UAAU;AACtD,WAAK,MAAM,iBAAiB,SAAS,KAAK,QAAQ;AAClD,WAAK,MAAM,iBAAiB,QAAQ,KAAK,QAAQ;AAAA,IACnD;AAAA,EACF;AAAA;AAAA,EA1DA,IAAc,QAAQ;AACpB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAc,YAAY;AACxB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAc,cAAc;AAC1B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAc,YAAY;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAc,UAAU;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,IAAc,OAAO;AACnB,WAAO;AAAA,EACT;AAAA,EA4BA,WAAW,WAA6B;AACtC,WAAO;AAAA,EACT;AAAA,EAIA,OAAO,KACL,KACA,UAAqC,CAAC,GACb;AACzB,WAAO,MAAM,KAAK,KAAK,SAAS,IAAI;AAAA,EACtC;AAAA,EAEA,OAAO,YAAY,IAA4B;AAC7C,WAAO,GAAG,sBAAsB;AAAA,EAClC;AAAA,EAEA,UAAU;AAER,SAAK,WAAW,QAAQ,CAAC,SAAS,KAAK,OAAO,CAAC;AAC/C,SAAK,aAAa,CAAC;AACnB,SAAK,GAAG,KAAK,IAAI,IAAI;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,OAAe;AAElB,QAAI,CAAC,KAAK,YAAY,UAAU,KAAK,YAAa;AAClD,SAAK,cAAc;AACnB,UAAM,SAAS,QAAQ,KAAK,SAAS,KAAK,OAAO;AACjD,SAAK,QAAQ,SAAS,KAAK,SAAS,SAAS;AAC7C,QAAI,OAAQ;AAEZ,SAAK,QAAQ,gBAAgB;AAC7B,UAAM,QAAQ,SAAS,cAAc,QAAQ;AAC7C,UAAM,cAAc,KAAK,OAAO,KAAK;AACrC,SAAK,SAAS,gBAAgB,KAAK;AAEnC,SAAK,OAAO,QAAQ,CAAC,QAAQ,MAAM;AACjC,YAAM,QAAQ,OAAO,OAAO,KAAK;AACjC,UAAI,UAAU,KAAM;AACpB,YAAM,QAAQ,OAAQ,IAAI,SAAU,CAAC;AACrC,YAAM,MAAM,OAAO,KAAK,KAAK;AAC7B,UAAI,QAAQ,QAAQ,KAAK,SAAS;AAChC,cAAM,MAAM,SAAS,cAAc,MAAM;AACzC,YAAI,YAAY,OAAO;AACvB,YAAI,QAAQ,SAAS;AACrB,YAAI,MAAM,MAAM,GAAG,OAAO,EAAE,GAAG,CAAC;AAChC,aAAK,QAAQ,OAAO,GAAG;AAAA,MACzB;AACA,YAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,WAAK,QAAQ,SAAS;AACtB,WAAK,cAAc,OAAO;AAC1B,YAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,WAAK,cAAc,OAAO,KAAK,KAAK;AACpC,WAAK,SAAS,OAAO,MAAM,IAAI;AAAA,IACjC,CAAC;AACD,SAAK,OAAO,KAAK;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,OAAO,OAAe;AAC9B,UAAM,IAAI,KAAK,GAAG,KAAK;AACvB,UAAM,OAAO,KAAK,cAAc,QAAQ;AACxC,SAAK,QAAQ,MAAM,IAAI,IAAI,KAAK,SAAS,MAAM,IAAI,IAAI,GAAG,CAAC;AAC3D,SAAK,SAAS,UAAU,OAAO,OAAO,IAAI,EAAE;AAAA,EAC9C;AAAA,EAEQ,QAAQ;AACd,UAAM,QAAQ,KAAK,GAAG,cAAgC,gBAAgB;AACtE,QAAI,CAAC,MAAO;AAEZ,UAAM,YAAY,MAAM,OAAO,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC;AACtD,UAAM,SAAS,MAAM,KAAK,WAAW,SAAS,CAAC,CAAC;AAChD,UAAM,OAAO,MAAM,KAAK,MAAM,OAAO,EAClC,QAAQ,CAAC,SAAS,MAAM,KAAK,KAAK,IAAI,CAAC,EACvC,OAAO,CAAC,QAAQ,QAAQ,SAAS;AACpC,KAAC,KAAK,SAAS,KAAK,KAAK,IAAI,CAAC,QAAQ,IAAI;AAC1C,SAAK,SAAS,KAAK,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,GAAG,YAAY,KAAK,KAAK,EAAE;AACtE,SAAK,SAAS,OAAO,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,MAAM;AAC7C,YAAM,SAAS,KAAK,IAAI,CAAC,QAAQ,UAAU,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC;AAC5D,aAAO;AAAA,QACL,MAAM,KAAK,YAAY,KAAK;AAAA,QAC5B,WAAW,KAAK;AAAA,QAChB,MAAM,KAAK,IAAI,CAAC,QAAQ,IAAI,MAAM,IAAI,CAAC,GAAG,YAAY,KAAK,KAAK,EAAE;AAAA,QAClE;AAAA,QACA,MAAM;AAAA,QACN,GAAG;AAAA,MACL;AAAA,IACF,CAAC;AACD,UAAM,UAAU,KAAK,GAAG,UAAU,SAAS,SAAS;AACpD,QAAI,SAAS;AAGX,YAAM,SAA4B,KAAK,OAAO,IAAI,MAAM,CAAC;AACzD,iBAAW,UAAU,KAAK,QAAQ;AAChC,eAAO,OAAO,CAAC,GAAG,MAAM;AACxB,eAAO,OAAO,OAAO,OAAO,IAAI,CAAC,OAAO,MACrC,OAAO,CAAC,IAAI,UAAU,QAAQ,OAAO,CAAC,MAAM,OAAO,OAAO,OAAO,CAAC,IAAI,KAAM;AAAA,MACjF;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,MAAM,CAAC,WAAW,OAAO,KAAK,MAAM,CAAC,UAAU,UAAU,IAAI,CAAC,EAAG,MAAK,SAAS,CAAC;AAChG,UAAM,SAAS,CAAC,SAAwB,KAAK,QAAQ,IAAI,KAAK,KAAK,QAAQ,IAAI;AAC/E,SAAK,KAAK,KAAK,OAAO,KAAK,QAAQ,OAAO,KAAK,GAAG,OAAO,KAAK,CAAC;AAAA,EACjE;AAAA;AAAA,EAGU,QAAQ,MAAc;AAC9B,UAAM,QAAQ,WAAW,KAAK,GAAG,QAAQ,IAAI,KAAK,EAAE;AACpD,WAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,OAAO,QAAkB,KAAoB,KAAoB,WAAW,KAAK,WAAW;AACpG,UAAM,UAAU,KAAK,GAAG,UAAU,SAAS,SAAS;AACpD,QAAI,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,SAAS;AACtC,eAAW,EAAE,KAAK,KAAK,QAAQ;AAC7B,iBAAW,SAAS,MAAM;AACxB,YAAI,UAAU,KAAM;AACpB,cAAM,KAAK,IAAI,KAAK,KAAK;AACzB,eAAO,KAAK,IAAI,MAAM,KAAK;AAAA,MAC7B;AAAA,IACF;AACA,QAAI,MAAM,KAAM,OAAM,OAAO;AAC7B,QAAI,UAAU;AAGZ,YAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;AAC1D,YAAM,QAAQ,OAAO,OAAO,WAAW,OAAO;AAC9C,oBAAQ,SAAS,IAAI,SAAS,OAAO;AACrC,oBAAQ,MAAM;AAAA,IAChB,OAAO;AACL,YAAM,OAAO,OAAO,OAAO,OAAO;AAElC,oBAAQ,UAAU,KAAK,IAAI,GAAG,GAAG,IAAI,MAAM;AAC3C,oBAAQ,QAAQ,WAAW,OAAO,OAAO,OAAO,IAAI;AAAA,IACtD;AACA,UAAM,IAAI,CAAC,UAAkB,OAAQ,QAAQ,QAAQ,MAAM,OAAO,KAAM;AACxE,eAAW,QAAQ,OAAQ,MAAK,IAAI;AACpC,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,GAAG,OAAe;AACxB,UAAM,KAAM,QAAQ,OAAO,KAAK,OAAO,SAAU;AACjD,WAAO,KAAK,YAAY,MAAM,IAAI;AAAA,EACpC;AAAA,EAEQ,UAAU;AAChB,UAAM,OAAO,KAAK;AAClB,SAAK,QAAQ,SAAS,cAAc,KAAK;AACzC,SAAK,MAAM,YAAY,GAAG,IAAI;AAC9B,UAAM,UAAU,KAAK,GAAG,cAAc,qBAAqB,GAAG,YAAY,KAAK;AAC/E,SAAK,MAAM,aAAa,QAAQ,OAAO;AACvC,SAAK,MAAM,aAAa,wBAAwB,KAAK,QAAQ,MAAM,GAAG,CAAC;AACvE,QAAI,QAAS,MAAK,MAAM,aAAa,cAAc,OAAO;AAE1D,SAAK,UAAU,SAAS,cAAc,KAAK;AAC3C,SAAK,QAAQ,YAAY,GAAG,IAAI;AAChC,SAAK,QAAQ,SAAS;AACtB,SAAK,WAAW,SAAS,cAAc,KAAK;AAC5C,SAAK,SAAS,YAAY,GAAG,IAAI;AACjC,SAAK,SAAS,SAAS;AACvB,SAAK,SAAS,aAAa,aAAa,QAAQ;AAChD,SAAK,MAAM,OAAO,KAAK,MAAM,GAAG,KAAK,SAAS,KAAK,QAAQ;AAE3D,SAAK,aAAa,CAAC,KAAK,OAAO,GAAG,KAAK,QAAQ,CAAC;AAChD,SAAK,GAAG,OAAO,GAAG,KAAK,UAAU;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,OAAO,WAAuC;AACtD,UAAM,SAAS,KAAK,GAAG,cAAgC,gBAAgB,GAAG,OAAO,KAAK,CAAC;AACvF,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAClB,UAAM,CAAC,OAAO,KAAK,IAAI,CAAC,SAAS,cAAc,MAAM,GAAG,SAAS,cAAc,QAAQ,CAAC;AACxF,UAAM,cAAc,OAAO,MAAM,CAAC,GAAG,YAAY,KAAK,KAAK;AAC3D,UAAM,cAAc,OAAO,MAAM,CAAC,GAAG,YAAY,KAAK,KAAK;AAC3D,UAAM,OAAO,OAAO,KAAK;AACzB,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,UAAqB;AAC7B,UAAM,SAAS,SAAS,cAAc,IAAI;AAC1C,WAAO,YAAY,GAAG,KAAK,KAAK;AAChC,WAAO,aAAa,eAAe,MAAM;AAEzC,eAAW,QAAQ,KAAK,QAAQ;AAC9B,YAAM,KAAK,SAAS,cAAc,IAAI;AACtC,SAAG,cAAc;AACjB,aAAO,OAAO,EAAE;AAAA,IAClB;AACA,WAAO,CAAC,QAAQ,GAAG,KAAK,QAAQ,CAAC;AAAA,EACnC;AAAA;AAAA,EAGU,UAAqB;AAC7B,QAAI,KAAK,OAAO,SAAS,EAAG,QAAO,CAAC;AACpC,UAAM,SAAS,SAAS,cAAc,IAAI;AAC1C,WAAO,YAAY,GAAG,KAAK,KAAK;AAChC,WAAO,aAAa,eAAe,MAAM;AACzC,WAAO,OAAO,GAAG,KAAK,OAAO,IAAI,CAAC,QAAQ,MAAM;AAC9C,YAAM,KAAK,SAAS,cAAc,IAAI;AACtC,SAAG,QAAQ,SAAS,OAAQ,IAAI,SAAU,CAAC;AAC3C,SAAG,cAAc,OAAO;AACxB,aAAO;AAAA,IACT,CAAC,CAAC;AACF,WAAO,CAAC,MAAM;AAAA,EAChB;AAAA;AAAA,EAGU,MAAM,QAAQ,KAAK,QAAiB;AAC5C,UAAM,MAAM,SAAS,gBAAgB,KAAK,KAAK;AAC/C,QAAI,aAAa,WAAW,aAAa;AACzC,QAAI,aAAa,uBAAuB,MAAM;AAC9C,QAAI,aAAa,eAAe,MAAM;AACtC,QAAI,aAAa,aAAa,OAAO;AAErC,eAAW,UAAU,OAAO;AAC1B,YAAM,QAAQ,SAAS,gBAAgB,KAAK,GAAG;AAC/C,YAAM,aAAa,SAAS,GAAG,KAAK,KAAK,WAAW,OAAO,SAAS,GAAG,KAAK,CAAC;AAC7E,YAAM,QAAQ,SAAS,OAAQ,KAAK,OAAO,QAAQ,MAAM,IAAI,SAAU,CAAC;AAGxE,YAAM,OAAmB,CAAC,CAAC,CAAC;AAC5B,aAAO,KAAK,QAAQ,CAAC,OAAO,UAAU;AACpC,YAAI,UAAU,KAAM,MAAK,KAAK,CAAC,CAAC;AAAA,YAC3B,MAAK,KAAK,SAAS,CAAC,EAAE,KAAK,KAAK;AAAA,MACvC,CAAC;AACD,YAAM,SAAS,KAAK,OAAO,CAAC,QAAQ,IAAI,MAAM;AAC9C,YAAM,SAAS,CAAC,KAAe,WAC7B,IAAI,IAAI,CAAC,UAA4B,CAAC,KAAK,GAAG,KAAK,GAAG,OAAO,EAAE,OAAO,KAAK,CAAE,CAAC,CAAC;AACjF,YAAM,OAAO,OAAO,IAAI,CAAC,QAAQ,aAAa,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC;AAEvE,YAAM,KAAK,uBAAuB,EAAE,WAAW;AAC/C,YAAM,WAAW,SAAS,gBAAgB,KAAK,gBAAgB;AAC/D,eAAS,KAAK;AACd,eAAS,aAAa,MAAM,GAAG;AAC/B,eAAS,aAAa,MAAM,GAAG;AAC/B,eAAS,OAAO,SAAS,gBAAgB,KAAK,MAAM,GAAG,SAAS,gBAAgB,KAAK,MAAM,CAAC;AAC5F,eAAS,iBAAiB,aAAa,UAAU,GAAG;AAEpD,YAAM,OAAO,SAAS,gBAAgB,KAAK,MAAM;AACjD,WAAK,aAAa,SAAS,GAAG,KAAK,KAAK,OAAO;AAC/C,WAAK,aAAa,QAAQ,QAAQ,EAAE,GAAG;AAIvC,WAAK,aAAa,KAAK,OACpB,IAAI,CAAC,KAAK,MAAM;AACf,YAAI,CAAC,OAAO,KAAM,QAAO,GAAG,KAAK,CAAC,CAAC,QAAQ,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;AAC1D,cAAM,OAAO,OAAO,KAAK,OAAO,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAwB,CAAC,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC;AAC7F,eAAO,GAAG,KAAK,CAAC,CAAC,IAAI,aAAa,KAAK,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;AAAA,MAC5D,CAAC,EACA,KAAK,EAAE,CAAC;AAEX,YAAM,OAAO,SAAS,gBAAgB,KAAK,MAAM;AACjD,WAAK,aAAa,SAAS,GAAG,KAAK,KAAK,OAAO;AAC/C,WAAK,aAAa,KAAK,KAAK,KAAK,EAAE,CAAC;AAEpC,YAAM,OAAO,UAAU,MAAM,IAAI;AACjC,UAAI,OAAO,KAAK;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAOU,SAAS,GAAiB;AAClC,UAAM,MAAM,KAAK,MAAM,sBAAsB;AAC7C,UAAM,WAAW,KAAK,eACjB,EAAE,UAAU,IAAI,OAAO,IAAI,UAC3B,EAAE,UAAU,IAAI,QAAQ,IAAI;AACjC,UAAM,QAAQ,KAAK,OAAO,KAAK,YAAY,IAAI,WAAW,YAAY,KAAK,OAAO,MAAM;AACxF,WAAO,KAAK,IAAI,KAAK,OAAO,SAAS,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,SAAS,GAAmD;AACpE,UAAM,MAAM,KAAK,MAAM,sBAAsB;AAC7C,UAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,IAAI,OAAO,IAAI,QAAQ,GAAG,EAAE,UAAU,IAAI,MAAM,IAAI,SAAS,CAAC;AAC1F,WAAO,EAAE,KAAK,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG,KAAK,MAAM,GAAG,CAAC,IAAI,IAAI,KAAK;AAAA,EACnF;AAAA;AAAA,EAGA,IAAc,UAAgC;AAG5C,QAAI,KAAK,UAAW,QAAO,CAAC,CAAC,cAAc,WAAW,GAAG,CAAC,aAAa,SAAS,CAAC;AAEjF,QAAI,KAAK,YAAa,QAAO,CAAC,CAAC,WAAW,GAAG,CAAC,SAAS,CAAC;AACxD,WAAO,KAAK,YAAY,CAAC,CAAC,WAAW,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,YAAY,GAAG,CAAC,WAAW,CAAC;AAAA,EAC1F;AAAA;AAAA,EAoBU,WAAW,KAAiC;AACpD,UAAM,OAAO,KAAK,OAAO,SAAS;AAClC,UAAM,CAAC,SAAS,IAAI,IAAI,KAAK;AAC7B,UAAM,OAAO,CAAC,OAAe;AAC3B,UAAI,CAAC,KAAK,UAAW,QAAO,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG,KAAK,cAAc,EAAE,CAAC;AAE7E,UAAI,KAAK,cAAc,EAAG,QAAO,KAAK,IAAI,IAAI;AAC9C,cAAQ,KAAK,cAAc,KAAK,OAAO,MAAM,OAAO;AAAA,IACtD;AAEA,QAAI,QAAQ,SAAU,QAAO,KAAK,cAAc,IAAI,SAAY;AAChE,WAAO,QAAQ,SAAS,GAAG,IAAI,KAAK,CAAC,IACjC,KAAK,SAAS,GAAG,IAAI,KAAK,EAAE,IAC5B,EAAE,MAAM,GAAG,KAAK,KAAK,EAAE,GAAG;AAAA,EAChC;AAQF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|