@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
|
@@ -0,0 +1,7 @@
|
|
|
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 return trigger.dataset.target || (trigger.getAttribute('href')?.slice(1) ?? '');\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 const button = document.createElement('button');\n button.className = className.concat(['text']).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,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Utils
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-M372EDXD.mjs";
|
|
4
4
|
|
|
5
5
|
// src/ts/plugins/dockedDisplayPlugin.ts
|
|
6
6
|
var _defaults = {
|
|
@@ -12,9 +12,9 @@ var _defaults = {
|
|
|
12
12
|
var DockedDisplayPlugin = class _DockedDisplayPlugin {
|
|
13
13
|
constructor(el, container, options) {
|
|
14
14
|
this._handleDocumentClick = (e) => {
|
|
15
|
-
if (this.visible
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
if (!this.visible) return;
|
|
16
|
+
const path = e.composedPath();
|
|
17
|
+
if (!path.includes(this.el) && !path.includes(this.container)) this.hide();
|
|
18
18
|
};
|
|
19
19
|
/**
|
|
20
20
|
* Tears the plugin down. While shown, the document listener holds a
|
|
@@ -31,12 +31,10 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
|
|
|
31
31
|
document.addEventListener("click", this._handleDocumentClick);
|
|
32
32
|
const coordinates = Utils._setAbsolutePosition(this.el, this.container, "bottom", this.options.margin, this.options.transition, this.options.align);
|
|
33
33
|
this.container.style.visibility = "visible";
|
|
34
|
-
this.container.style.transition =
|
|
35
|
-
transform ${this.options.duration}ms ease-out,
|
|
36
|
-
opacity ${this.options.duration}ms ease-out`;
|
|
34
|
+
this.container.style.transition = this._transition;
|
|
37
35
|
setTimeout(() => {
|
|
38
36
|
this.container.style.transform = `translateX(${coordinates.x}px) translateY(${coordinates.y}px)`;
|
|
39
|
-
this.container.style.opacity = 1
|
|
37
|
+
this.container.style.opacity = "1";
|
|
40
38
|
}, 1);
|
|
41
39
|
};
|
|
42
40
|
this.hide = () => {
|
|
@@ -44,9 +42,7 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
|
|
|
44
42
|
this.visible = false;
|
|
45
43
|
document.removeEventListener("click", this._handleDocumentClick);
|
|
46
44
|
this.container.removeAttribute("style");
|
|
47
|
-
this.container.style.transition =
|
|
48
|
-
transform ${this.options.duration}ms ease-out,
|
|
49
|
-
opacity ${this.options.duration}ms ease-out`;
|
|
45
|
+
this.container.style.transition = this._transition;
|
|
50
46
|
setTimeout(() => {
|
|
51
47
|
this.container.style.transform = `translateX(0px) translateY(0px)`;
|
|
52
48
|
this.container.style.opacity = "0";
|
|
@@ -62,6 +58,13 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
|
|
|
62
58
|
this.container.append(container);
|
|
63
59
|
el.parentElement.append(this.container);
|
|
64
60
|
}
|
|
61
|
+
// @todo move to Util? -> duplicate code fragment with tooltip
|
|
62
|
+
// easeOutCubic
|
|
63
|
+
get _transition() {
|
|
64
|
+
return `
|
|
65
|
+
transform ${this.options.duration}ms ease-out,
|
|
66
|
+
opacity ${this.options.duration}ms ease-out`;
|
|
67
|
+
}
|
|
65
68
|
/**
|
|
66
69
|
* Initializes instance of DockedDisplayPlugin
|
|
67
70
|
* @param el HTMLElement to position to
|
|
@@ -76,4 +79,4 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
|
|
|
76
79
|
export {
|
|
77
80
|
DockedDisplayPlugin
|
|
78
81
|
};
|
|
79
|
-
//# sourceMappingURL=chunk-
|
|
82
|
+
//# sourceMappingURL=chunk-M3MURWMB.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ts/plugins/dockedDisplayPlugin.ts"],
|
|
4
|
-
"sourcesContent": ["import { Utils } from '../core/utils';\n\nexport interface DockedDisplayPluginOptions {\n /**\n * Margin between element and docked container\n */\n margin: number,\n /**\n * Transition movement\n */\n transition: number,\n /**\n * Transition duration\n */\n duration: number,\n /**\n * The alignment of the docked container\n */\n align: string\n}\n\nconst _defaults: DockedDisplayPluginOptions = {\n margin: 5,\n transition: 10,\n duration: 250,\n align: 'left'\n}\n\nexport class DockedDisplayPlugin {\n private readonly el: HTMLElement;\n private readonly container: HTMLDivElement;\n private options: Partial<DockedDisplayPluginOptions>;\n private visible: boolean;\n\n constructor(el: HTMLElement, container: HTMLElement, options: Partial<DockedDisplayPluginOptions>) {\n this.el = el;\n this.options = {\n ..._defaults,\n ...options\n };\n\n this.container = document.createElement('div');\n this.container.classList.add('display-docked');\n this.container.append(container);\n el.parentElement.append(this.container);\n }\n\n private _handleDocumentClick = (e: MouseEvent) => {\n if (this.visible
|
|
5
|
-
"mappings": ";;;;;AAqBA,IAAM,YAAwC;AAAA,EAC5C,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,OAAO;AACT;AAEO,IAAM,sBAAN,MAAM,qBAAoB;AAAA,EAM/B,YAAY,IAAiB,WAAwB,SAA8C;AAanG,SAAQ,uBAAuB,CAAC,MAAkB;AAChD,UAAI,KAAK,
|
|
4
|
+
"sourcesContent": ["import { Utils } from '../core/utils';\n\nexport interface DockedDisplayPluginOptions {\n /**\n * Margin between element and docked container\n */\n margin: number,\n /**\n * Transition movement\n */\n transition: number,\n /**\n * Transition duration\n */\n duration: number,\n /**\n * The alignment of the docked container\n */\n align: string\n}\n\nconst _defaults: DockedDisplayPluginOptions = {\n margin: 5,\n transition: 10,\n duration: 250,\n align: 'left'\n}\n\nexport class DockedDisplayPlugin {\n private readonly el: HTMLElement;\n private readonly container: HTMLDivElement;\n private options: Partial<DockedDisplayPluginOptions>;\n private visible: boolean;\n\n constructor(el: HTMLElement, container: HTMLElement, options: Partial<DockedDisplayPluginOptions>) {\n this.el = el;\n this.options = {\n ..._defaults,\n ...options\n };\n\n this.container = document.createElement('div');\n this.container.classList.add('display-docked');\n this.container.append(container);\n el.parentElement.append(this.container);\n }\n\n private _handleDocumentClick = (e: MouseEvent) => {\n if (!this.visible) return;\n const path = e.composedPath();\n if (!path.includes(this.el) && !path.includes(this.container)) this.hide();\n };\n\n // @todo move to Util? -> duplicate code fragment with tooltip\n // easeOutCubic\n private get _transition() {\n return `\n transform ${this.options.duration}ms ease-out,\n opacity ${this.options.duration}ms ease-out`;\n }\n\n /**\n * Tears the plugin down. While shown, the document listener holds a\n * reference to this instance - and through it the whole picker subtree - so\n * the owning component must call this from its own destroy().\n */\n destroy = () => {\n document.removeEventListener('click', this._handleDocumentClick);\n this.container.remove();\n };\n\n /**\n * Initializes instance of DockedDisplayPlugin\n * @param el HTMLElement to position to\n * @param container HTMLElement to be positioned\n * @param options Plugin options\n */\n static init(el: HTMLElement, container: HTMLElement, options?: Partial<DockedDisplayPluginOptions>): DockedDisplayPlugin {\n return new DockedDisplayPlugin(el, container, options);\n }\n\n show = () => {\n if (this.visible) return;\n this.visible = true;\n document.addEventListener('click', this._handleDocumentClick);\n const coordinates = Utils._setAbsolutePosition(this.el, this.container, 'bottom', this.options.margin, this.options.transition, this.options.align);\n\n this.container.style.visibility = 'visible';\n this.container.style.transition = this._transition;\n setTimeout(() => {\n this.container.style.transform = `translateX(${coordinates.x}px) translateY(${coordinates.y}px)`;\n this.container.style.opacity = '1';\n }, 1);\n };\n\n hide = () => {\n if (!this.visible) return;\n this.visible = false;\n document.removeEventListener('click', this._handleDocumentClick);\n this.container.removeAttribute('style');\n this.container.style.transition = this._transition;\n setTimeout(() => {\n this.container.style.transform = `translateX(0px) translateY(0px)`;\n this.container.style.opacity = '0';\n }, 1);\n };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AAqBA,IAAM,YAAwC;AAAA,EAC5C,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,OAAO;AACT;AAEO,IAAM,sBAAN,MAAM,qBAAoB;AAAA,EAM/B,YAAY,IAAiB,WAAwB,SAA8C;AAanG,SAAQ,uBAAuB,CAAC,MAAkB;AAChD,UAAI,CAAC,KAAK,QAAS;AACnB,YAAM,OAAO,EAAE,aAAa;AAC5B,UAAI,CAAC,KAAK,SAAS,KAAK,EAAE,KAAK,CAAC,KAAK,SAAS,KAAK,SAAS,EAAG,MAAK,KAAK;AAAA,IAC3E;AAeA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAU,MAAM;AACd,eAAS,oBAAoB,SAAS,KAAK,oBAAoB;AAC/D,WAAK,UAAU,OAAO;AAAA,IACxB;AAYA,gBAAO,MAAM;AACX,UAAI,KAAK,QAAS;AAClB,WAAK,UAAU;AACf,eAAS,iBAAiB,SAAS,KAAK,oBAAoB;AAC5D,YAAM,cAAc,MAAM,qBAAqB,KAAK,IAAI,KAAK,WAAW,UAAU,KAAK,QAAQ,QAAQ,KAAK,QAAQ,YAAY,KAAK,QAAQ,KAAK;AAElJ,WAAK,UAAU,MAAM,aAAa;AAClC,WAAK,UAAU,MAAM,aAAa,KAAK;AACvC,iBAAW,MAAM;AACf,aAAK,UAAU,MAAM,YAAY,cAAc,YAAY,CAAC,kBAAkB,YAAY,CAAC;AAC3F,aAAK,UAAU,MAAM,UAAU;AAAA,MACjC,GAAG,CAAC;AAAA,IACN;AAEA,gBAAO,MAAM;AACX,UAAI,CAAC,KAAK,QAAS;AACnB,WAAK,UAAU;AACf,eAAS,oBAAoB,SAAS,KAAK,oBAAoB;AAC/D,WAAK,UAAU,gBAAgB,OAAO;AACtC,WAAK,UAAU,MAAM,aAAa,KAAK;AACvC,iBAAW,MAAM;AACf,aAAK,UAAU,MAAM,YAAY;AACjC,aAAK,UAAU,MAAM,UAAU;AAAA,MACjC,GAAG,CAAC;AAAA,IACN;AAtEE,SAAK,KAAK;AACV,SAAK,UAAU;AAAA,MACb,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAEA,SAAK,YAAY,SAAS,cAAc,KAAK;AAC7C,SAAK,UAAU,UAAU,IAAI,gBAAgB;AAC7C,SAAK,UAAU,OAAO,SAAS;AAC/B,OAAG,cAAc,OAAO,KAAK,SAAS;AAAA,EACxC;AAAA;AAAA;AAAA,EAUA,IAAY,cAAc;AACxB,WAAO;AAAA,kBACO,KAAK,QAAQ,QAAQ;AAAA,gBACvB,KAAK,QAAQ,QAAQ;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,OAAO,KAAK,IAAiB,WAAwB,SAAoE;AACvH,WAAO,IAAI,qBAAoB,IAAI,WAAW,OAAO;AAAA,EACvD;AA2BF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Utils
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-M372EDXD.mjs";
|
|
4
4
|
import {
|
|
5
5
|
Component
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PD6HYHAE.mjs";
|
|
7
7
|
|
|
8
8
|
// src/ts/components/menu.ts
|
|
9
9
|
var MIN_SURFACE_WIDTH = 112;
|
|
@@ -83,15 +83,8 @@ var _Menu = class _Menu extends Component {
|
|
|
83
83
|
this.close();
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
const closestTrigger = toEl.closest(".menu-trigger");
|
|
89
|
-
if (closestTrigger && !!closestTrigger["Expressive_Menu"] && closestTrigger["Expressive_Menu"].isOpen) {
|
|
90
|
-
leaveToActiveMenuTrigger = true;
|
|
91
|
-
}
|
|
92
|
-
if (!leaveToActiveMenuTrigger && !leaveToMenuContent) {
|
|
93
|
-
this.close();
|
|
94
|
-
}
|
|
86
|
+
const leaveToActiveMenuTrigger = toEl.closest(".menu-trigger")?.["Expressive_Menu"]?.isOpen;
|
|
87
|
+
if (!leaveToActiveMenuTrigger && !this.menuEl?.contains(toEl)) this.close();
|
|
95
88
|
};
|
|
96
89
|
this._handleDocumentClick = (e) => {
|
|
97
90
|
const path = e.composedPath();
|
|
@@ -103,11 +96,7 @@ var _Menu = class _Menu extends Component {
|
|
|
103
96
|
if (this.options.closeOnClick && inside && !this.isTouchMoving) {
|
|
104
97
|
this.close();
|
|
105
98
|
} else if (!inside) {
|
|
106
|
-
this._schedule(() =>
|
|
107
|
-
if (this.isOpen) {
|
|
108
|
-
this.close();
|
|
109
|
-
}
|
|
110
|
-
}, 0);
|
|
99
|
+
this._schedule(() => this.close(), 0);
|
|
111
100
|
}
|
|
112
101
|
this.isTouchMoving = false;
|
|
113
102
|
};
|
|
@@ -183,11 +172,10 @@ var _Menu = class _Menu extends Component {
|
|
|
183
172
|
if (submenu) {
|
|
184
173
|
e.preventDefault();
|
|
185
174
|
const parentLi = submenu.parentElement;
|
|
186
|
-
|
|
187
|
-
this._syncSubmenuAria(parentLi, false);
|
|
175
|
+
this._closeSubmenu(parentLi);
|
|
188
176
|
this._focusRow(parentLi);
|
|
189
177
|
}
|
|
190
|
-
} else if (arrowUpOrDown
|
|
178
|
+
} else if (arrowUpOrDown) {
|
|
191
179
|
e.preventDefault();
|
|
192
180
|
const direction = e.key === Utils.keys.ARROW_DOWN ? 1 : -1;
|
|
193
181
|
const row = this._focusedRow(e);
|
|
@@ -206,7 +194,7 @@ var _Menu = class _Menu extends Component {
|
|
|
206
194
|
item.classList.add("active");
|
|
207
195
|
this._focusRow(item);
|
|
208
196
|
}
|
|
209
|
-
} else if (
|
|
197
|
+
} else if (e.key === Utils.keys.ENTER || e.key === SPACE) {
|
|
210
198
|
const li = this._focusedRow(e);
|
|
211
199
|
e.preventDefault();
|
|
212
200
|
if (li?.matches('.disabled, [aria-disabled="true"]')) return;
|
|
@@ -221,19 +209,18 @@ var _Menu = class _Menu extends Component {
|
|
|
221
209
|
} else if (focusedElement instanceof HTMLElement) {
|
|
222
210
|
focusedElement.click();
|
|
223
211
|
}
|
|
224
|
-
} else if (e.key === Utils.keys.ESC
|
|
212
|
+
} else if (e.key === Utils.keys.ESC) {
|
|
225
213
|
e.preventDefault();
|
|
226
214
|
const openSub = this._containingSubmenu(e)?.parentElement ?? Array.from(this.menuEl.querySelectorAll("li.open")).reverse()[0];
|
|
227
215
|
if (openSub) {
|
|
228
|
-
|
|
229
|
-
this._syncSubmenuAria(openSub, false);
|
|
216
|
+
this._closeSubmenu(openSub);
|
|
230
217
|
this._focusRow(openSub);
|
|
231
218
|
} else {
|
|
232
219
|
this.close();
|
|
233
220
|
}
|
|
234
221
|
}
|
|
235
222
|
const keyText = e.key.toLowerCase();
|
|
236
|
-
if (e.key.length === 1 && e.key !== SPACE
|
|
223
|
+
if (e.key.length === 1 && e.key !== SPACE) {
|
|
237
224
|
this.filterQuery.push(keyText);
|
|
238
225
|
const string = this.filterQuery.join("");
|
|
239
226
|
const newOptionEl = Array.from(list.querySelectorAll(":scope > li")).find(
|
|
@@ -458,10 +445,7 @@ var _Menu = class _Menu extends Component {
|
|
|
458
445
|
_toggleSubmenu(li) {
|
|
459
446
|
const open = !li.classList.contains("open");
|
|
460
447
|
li.parentElement?.querySelectorAll(":scope > li.open").forEach((other) => {
|
|
461
|
-
if (other !== li)
|
|
462
|
-
other.classList.remove("open", "submenu-start");
|
|
463
|
-
this._syncSubmenuAria(other, false);
|
|
464
|
-
}
|
|
448
|
+
if (other !== li) this._closeSubmenu(other);
|
|
465
449
|
});
|
|
466
450
|
li.classList.toggle("open", open);
|
|
467
451
|
if (open) this._alignSubmenu(li);
|
|
@@ -478,11 +462,12 @@ var _Menu = class _Menu extends Component {
|
|
|
478
462
|
const rect = menu.getBoundingClientRect();
|
|
479
463
|
if (rect.left < 8 || rect.right > window.innerWidth - 8) li.classList.add("submenu-start");
|
|
480
464
|
}
|
|
465
|
+
_closeSubmenu(li) {
|
|
466
|
+
li.classList.remove("open", "submenu-start");
|
|
467
|
+
this._syncSubmenuAria(li, false);
|
|
468
|
+
}
|
|
481
469
|
_closeSubmenus() {
|
|
482
|
-
this.menuEl?.querySelectorAll("li.open").forEach((li) =>
|
|
483
|
-
li.classList.remove("open", "submenu-start");
|
|
484
|
-
this._syncSubmenuAria(li, false);
|
|
485
|
-
});
|
|
470
|
+
this.menuEl?.querySelectorAll("li.open").forEach((li) => this._closeSubmenu(li));
|
|
486
471
|
}
|
|
487
472
|
_containingSubmenu(e) {
|
|
488
473
|
const target = e.target;
|
|
@@ -773,4 +758,4 @@ var Menu = _Menu;
|
|
|
773
758
|
export {
|
|
774
759
|
Menu
|
|
775
760
|
};
|
|
776
|
-
//# sourceMappingURL=chunk-
|
|
761
|
+
//# sourceMappingURL=chunk-NUHMOAOY.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
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 if (this.isOpen) {\n this.close();\n } else {\n this.open();\n }\n };\n\n _handleMouseEnter = () => {\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 // Close hover menu if mouse did not leave to either active menu-trigger or menu-content\n const leaveToActiveMenuTrigger = toEl.closest('.menu-trigger')?.['Expressive_Menu']?.isOpen;\n if (!leaveToActiveMenuTrigger && !this.menuEl?.contains(toEl)) this.close();\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(() => this.close(), 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) this._closeSubmenu(other as HTMLElement);\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 _closeSubmenu(li: HTMLElement) {\n li.classList.remove('open', 'submenu-start');\n this._syncSubmenuAria(li, false);\n }\n\n private _closeSubmenus() {\n this.menuEl?.querySelectorAll('li.open').forEach((li) => this._closeSubmenu(li as HTMLElement));\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 this._closeSubmenu(parentLi);\n this._focusRow(parentLi);\n }\n }\n // Navigate down menu list\n else if (arrowUpOrDown) {\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) {\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) {\n e.preventDefault();\n const openSub = this._containingSubmenu(e)?.parentElement ??\n Array.from(this.menuEl.querySelectorAll('li.open')).reverse()[0];\n if (openSub) {\n this._closeSubmenu(openSub as HTMLElement);\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) {\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 // 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 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LineChart,
|
|
3
|
+
polarPoint,
|
|
3
4
|
svgNode
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-TCCA2HDG.mjs";
|
|
5
6
|
|
|
6
7
|
// src/ts/components/pieChart.ts
|
|
7
8
|
var COLORS = 6;
|
|
@@ -105,17 +106,13 @@ var PieChart = class extends LineChart {
|
|
|
105
106
|
const total = values.reduce((sum, value) => sum + value, 0);
|
|
106
107
|
let turn = 0;
|
|
107
108
|
this._turns = values.map((value) => [turn, turn += total ? value / total : 0]);
|
|
108
|
-
const drawn = this._turns.filter(([start, end]) => end > start)
|
|
109
|
+
const drawn = this._turns.filter(([start, end]) => end > start);
|
|
109
110
|
let slice = 0;
|
|
110
111
|
this._colors = this._turns.map(([start, end]) => {
|
|
111
112
|
if (end <= start) return void 0;
|
|
112
113
|
const index = slice++;
|
|
113
|
-
return String(index === drawn - 1 && index > 0 && index % COLORS === 0 ? 2 : index % COLORS + 1);
|
|
114
|
+
return String(index === drawn.length - 1 && index > 0 && index % COLORS === 0 ? 2 : index % COLORS + 1);
|
|
114
115
|
});
|
|
115
|
-
const at = (t, r = RADIUS) => {
|
|
116
|
-
const angle = t * 2 * Math.PI;
|
|
117
|
-
return `${(r * Math.sin(angle)).toFixed(3)},${(-r * Math.cos(angle)).toFixed(3)}`;
|
|
118
|
-
};
|
|
119
116
|
const pie = document.createElement("div");
|
|
120
117
|
pie.className = "pie-chart-pie";
|
|
121
118
|
pie.setAttribute("aria-hidden", "true");
|
|
@@ -123,13 +120,12 @@ var PieChart = class extends LineChart {
|
|
|
123
120
|
const id = `pie-chart-mask-${++_maskId}`;
|
|
124
121
|
const area = { x: "-50", y: "-50", width: "100", height: "100" };
|
|
125
122
|
const mask = svgNode("mask", { id, maskUnits: "userSpaceOnUse", ...area });
|
|
126
|
-
const edges = this._turns.filter(([start, end]) => end > start);
|
|
127
123
|
mask.append(
|
|
128
124
|
svgNode("rect", { ...area, fill: "white" }),
|
|
129
125
|
svgNode("path", {
|
|
130
126
|
class: "pie-chart-gaps",
|
|
131
127
|
stroke: "black",
|
|
132
|
-
d:
|
|
128
|
+
d: drawn.length > 1 ? drawn.map(([start]) => `M0,0L${polarPoint(start, 50)}`).join("") : ""
|
|
133
129
|
}),
|
|
134
130
|
svgNode("circle", { class: "pie-chart-hole", r: String(RADIUS), fill: "black" })
|
|
135
131
|
);
|
|
@@ -141,7 +137,7 @@ var PieChart = class extends LineChart {
|
|
|
141
137
|
class: "pie-chart-slice",
|
|
142
138
|
"data-series": this._colors[i],
|
|
143
139
|
// A whole circle is two half arcs; one arc cannot end where it starts.
|
|
144
|
-
d: end - start >= 1 ? `M0,${-RADIUS}${arc} 1 1 0,${RADIUS}${arc} 1 1 0,${-RADIUS}Z` : `M0,0L${
|
|
140
|
+
d: end - start >= 1 ? `M0,${-RADIUS}${arc} 1 1 0,${RADIUS}${arc} 1 1 0,${-RADIUS}Z` : `M0,0L${polarPoint(start, RADIUS)}${arc} ${end - start > 0.5 ? 1 : 0} 1 ${polarPoint(end, RADIUS)}Z`
|
|
145
141
|
});
|
|
146
142
|
slices.append(slice2);
|
|
147
143
|
return slice2;
|
|
@@ -170,4 +166,4 @@ var PieChart = class extends LineChart {
|
|
|
170
166
|
export {
|
|
171
167
|
PieChart
|
|
172
168
|
};
|
|
173
|
-
//# sourceMappingURL=chunk-
|
|
169
|
+
//# sourceMappingURL=chunk-OWG3LMUL.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ts/components/pieChart.ts"],
|
|
4
|
+
"sourcesContent": ["import { InitElements, InitElement } from '../core/component';\nimport { LineChart, LineChartOptions, polarPoint as at, svgNode as node } from './lineChart';\n\nexport type PieChartOptions = LineChartOptions;\n\n// ponytail: rows past six repeat the colors; group small parts as \"Other\".\nconst COLORS = 6;\n/** The pie's radius in a 100-unit box, leaving room for the active slice to grow. */\nconst RADIUS = 46;\n/** The active slice's scale, as in _pie-chart.scss. */\nconst GROWN = 1.06;\n/** Slices smaller than this share get no .values label. */\nconst LABEL_SHARE = 0.05;\nlet _maskId = 0;\n\n/**\n * Pie chart. It reads its <table> like LineChart, but draws each row of the\n * first value column as a slice of the whole, clockwise from the top, with\n * a legend of every row and its share. With `.donut`, a <tfoot> row is the\n * total in the middle. Further columns show in the tooltip.\n *\n * Re-run `PieChart.init(el)` after changing the table.\n */\nexport class PieChart extends LineChart {\n // No initializers: LineChart's constructor draws before they would run.\n /** Each row's start and end, as fractions of a turn clockwise from the top. */\n private _turns: [number, number][];\n /** Each row's color, or undefined for a row with no slice. */\n private _colors: (string | undefined)[];\n private _slices: (SVGPathElement | null)[];\n /** Percent formatters by fraction digits, rebuilt once per legend. */\n private _percents: Intl.NumberFormat[];\n\n protected get _type() {\n return 'pie-chart';\n }\n\n protected get _key() {\n return 'Expressive_PieChart';\n }\n\n protected get _points() {\n return false;\n }\n\n protected get _circular() {\n return true;\n }\n\n static init(el: HTMLElement, options?: Partial<PieChartOptions>): PieChart;\n static init(els: InitElements<InitElement>, options?: Partial<PieChartOptions>): PieChart[];\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<PieChartOptions> = {}\n ): PieChart | PieChart[] {\n return super.init(els as HTMLElement, options) as PieChart | PieChart[];\n }\n\n static getInstance(el: HTMLElement): PieChart {\n return el['Expressive_PieChart'];\n }\n\n show(index: number) {\n if (!this._tooltip || index === this.activeIndex) return;\n super.show(index);\n this._slices.forEach((slice, i) => slice?.classList.toggle('active', i === index));\n // LineChart hides the tooltip for -1 and for an index past the last row.\n if (this._tooltip.hidden) return;\n\n const color = this._colors[index];\n this._tooltip.querySelectorAll<HTMLElement>('[data-series]').forEach((span) => {\n if (color) span.dataset.series = color;\n else delete span.dataset.series;\n });\n const share = this._share(index);\n const value = this._tooltip.querySelector('span:nth-of-type(2)');\n if (share && value) value.textContent += ` (${share})`;\n }\n\n /** CSS places the tooltip on the slice's middle from --turn. */\n protected _place(index: number) {\n const middle = (this._turns[index][0] + this._turns[index][1]) / 2;\n this._tooltip.style.setProperty('--turn', String(middle));\n // On the right half it opens leftwards, over the pie.\n this._tooltip.classList.toggle('end', middle < 0.5);\n }\n\n /** The row's share of the whole as a percentage, or '' for none. */\n private _share(index: number) {\n const [start, end] = this._turns[index];\n if (end <= start) return '';\n const share = end - start;\n // Whole percentages, with a tenth below 10% so a small part is not 0%.\n const digits = share < 0.1 ? 1 : 0;\n (this._percents ??= [])[digits] ??= this._percent(digits);\n return this._percents[digits].format(share);\n }\n\n private _percent(digits: number) {\n const options = { style: 'percent', maximumFractionDigits: digits } as const;\n try {\n return new Intl.NumberFormat(this.el.closest<HTMLElement>('[lang]')?.lang || undefined, options);\n } catch {\n // An invalid lang attribute.\n return new Intl.NumberFormat(undefined, options);\n }\n }\n\n /** The legend: every row with its color, its cell and its share. */\n protected _guides(): Element[] {\n // A redraw picks up a changed lang attribute.\n this._percents = [];\n const legend = document.createElement('ul');\n legend.className = 'pie-chart-legend';\n legend.setAttribute('aria-hidden', 'true');\n const text = this.series[0].text;\n legend.append(...this.labels.map((label, i) => {\n const li = document.createElement('li');\n if (this._colors[i]) li.dataset.series = this._colors[i];\n const [name, value, share] = [label, text[i], this._share(i)].map((content) => {\n const span = document.createElement('span');\n span.textContent = content;\n return span;\n });\n li.append(name, value, share);\n return li;\n }));\n return [legend];\n }\n\n /** The row under the pointer by its angle from the middle, or -1 off the slices. */\n protected _indexAt(e: PointerEvent) {\n const [turn, share] = this._polarAt(e);\n // The distance in the SVG's 100-unit box.\n const distance = share * 100;\n const hole = this.el.classList.contains('donut')\n ? parseFloat(getComputedStyle(this.el).getPropertyValue('--md-comp-pie-chart-hole')) || 0\n : 0;\n if (distance < RADIUS * hole) return -1;\n const index = this._turns.findIndex(([start, end]) => start <= turn && turn < end);\n // The active slice is drawn larger, so the pointer stays on it to its edge.\n return distance > RADIUS * (index === this.activeIndex ? GROWN : 1) ? -1 : index;\n }\n\n /**\n * An SVG of slices in a -50 to 50 box, under a mask that cuts the gaps\n * between them and the donut's hole, which CSS sizes. The values and the\n * total are HTML over it.\n */\n protected _draw(): Element {\n const values = this.series[0].values.map((value) => Math.max(0, value ?? 0));\n const total = values.reduce((sum, value) => sum + value, 0);\n let turn = 0;\n this._turns = values.map((value) => [turn, (turn += total ? value / total : 0)]);\n // Colors go round the drawn slices; the last skips the first's color beside it.\n const drawn = this._turns.filter(([start, end]) => end > start);\n let slice = 0;\n this._colors = this._turns.map(([start, end]) => {\n if (end <= start) return undefined;\n const index = slice++;\n return String(index === drawn.length - 1 && index > 0 && index % COLORS === 0 ? 2 : (index % COLORS) + 1);\n });\n\n const pie = document.createElement('div');\n pie.className = 'pie-chart-pie';\n pie.setAttribute('aria-hidden', 'true');\n const svg = node('svg', { viewBox: '-50 -50 100 100', focusable: 'false' });\n const id = `pie-chart-mask-${++_maskId}`;\n const area = { x: '-50', y: '-50', width: '100', height: '100' };\n const mask = node('mask', { id, maskUnits: 'userSpaceOnUse', ...area });\n mask.append(\n node('rect', { ...area, fill: 'white' }),\n node('path', {\n class: 'pie-chart-gaps',\n stroke: 'black',\n d: drawn.length > 1 ? drawn.map(([start]) => `M0,0L${at(start, 50)}`).join('') : ''\n }),\n node('circle', { class: 'pie-chart-hole', r: String(RADIUS), fill: 'black' })\n );\n\n const slices = node('g', { mask: `url(#${id})` });\n const arc = `A${RADIUS},${RADIUS} 0`;\n this._slices = this._turns.map(([start, end], i) => {\n if (end <= start) return null;\n const slice = node('path', {\n class: 'pie-chart-slice',\n 'data-series': this._colors[i],\n // A whole circle is two half arcs; one arc cannot end where it starts.\n d: end - start >= 1\n ? `M0,${-RADIUS}${arc} 1 1 0,${RADIUS}${arc} 1 1 0,${-RADIUS}Z`\n : `M0,0L${at(start, RADIUS)}${arc} ${end - start > 0.5 ? 1 : 0} 1 ${at(end, RADIUS)}Z`\n }) as SVGPathElement;\n slices.append(slice);\n return slice;\n });\n svg.append(mask, slices);\n pie.append(svg);\n\n if (this.el.classList.contains('values')) {\n const labels = document.createElement('div');\n labels.className = 'pie-chart-values';\n this._turns.forEach(([start, end], i) => {\n if (end - start < LABEL_SHARE) return;\n const label = document.createElement('span');\n label.dataset.series = this._colors[i];\n label.style.setProperty('--turn', String((start + end) / 2));\n label.textContent = this._share(i);\n labels.append(label);\n });\n pie.append(labels);\n }\n\n const middle = this._total('pie-chart-total');\n if (middle) pie.append(middle);\n return pie;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["slice"]
|
|
7
|
+
}
|
|
@@ -7,10 +7,7 @@ var Component = class {
|
|
|
7
7
|
if (!(el instanceof HTMLElement)) {
|
|
8
8
|
console.error(Error(el + " is not an HTML Element"));
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
if (!!ins) {
|
|
12
|
-
ins.destroy();
|
|
13
|
-
}
|
|
10
|
+
classDef.getInstance(el)?.destroy();
|
|
14
11
|
this.el = el;
|
|
15
12
|
}
|
|
16
13
|
/**
|
|
@@ -20,16 +17,8 @@ var Component = class {
|
|
|
20
17
|
* @param classDef Class definition.
|
|
21
18
|
*/
|
|
22
19
|
static init(els, options, classDef) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
instances = new classDef(els, options);
|
|
26
|
-
} else if (els) {
|
|
27
|
-
instances = [];
|
|
28
|
-
for (let i = 0; i < els.length; i++) {
|
|
29
|
-
instances.push(new classDef(els[i], options));
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return instances;
|
|
20
|
+
if (els instanceof Element) return new classDef(els, options);
|
|
21
|
+
return els ? Array.from(els, (el) => new classDef(el, options)) : null;
|
|
33
22
|
}
|
|
34
23
|
/**
|
|
35
24
|
* @returns default options for component instance.
|
|
@@ -56,4 +45,4 @@ var Component = class {
|
|
|
56
45
|
export {
|
|
57
46
|
Component
|
|
58
47
|
};
|
|
59
|
-
//# sourceMappingURL=chunk-
|
|
48
|
+
//# sourceMappingURL=chunk-PD6HYHAE.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
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 classDef.getInstance(el)?.destroy();\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 if (els instanceof Element) return new classDef(<HTMLElement>els, options);\n return els ? Array.from(els, (el) => new classDef(<HTMLElement>el, options)) : null;\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,aAAS,YAAY,EAAE,GAAG,QAAQ;AAClC,SAAK,KAAK;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyCA,OAAiB,KACf,KACA,SACA,UACS;AACT,QAAI,eAAe,QAAS,QAAO,IAAI,SAAsB,KAAK,OAAO;AACzE,WAAO,MAAM,MAAM,KAAK,KAAK,CAAC,OAAO,IAAI,SAAsB,IAAI,OAAO,CAAC,IAAI;AAAA,EACjF;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,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Utils
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-M372EDXD.mjs";
|
|
4
4
|
import {
|
|
5
5
|
Component
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PD6HYHAE.mjs";
|
|
7
7
|
|
|
8
8
|
// src/ts/components/buttons.ts
|
|
9
9
|
var _defaults = {};
|
|
@@ -91,4 +91,4 @@ var FloatingActionButton = class _FloatingActionButton extends Component {
|
|
|
91
91
|
export {
|
|
92
92
|
FloatingActionButton
|
|
93
93
|
};
|
|
94
|
-
//# sourceMappingURL=chunk-
|
|
94
|
+
//# sourceMappingURL=chunk-PDG64UHF.mjs.map
|