@expressivecss/expressive 0.13.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 +196 -1
- package/README.md +2 -1
- package/dist/css/expressive.css +432 -311
- 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-DTKR54I6.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-WJXDBPXQ.mjs → chunk-5CEAOLUA.mjs} +17 -20
- package/dist/js/chunks/chunk-5CEAOLUA.mjs.map +7 -0
- package/dist/js/chunks/{chunk-CKQP6P76.mjs → chunk-6VATUZC6.mjs} +12 -7
- 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-DLWYKFEI.mjs → chunk-AIURVCG6.mjs} +3 -3
- package/dist/js/chunks/{chunk-NNYP33NB.mjs → chunk-BGZLF6JZ.mjs} +19 -18
- package/dist/js/chunks/chunk-BGZLF6JZ.mjs.map +7 -0
- package/dist/js/chunks/chunk-C6CHEWYP.mjs +154 -0
- package/dist/js/chunks/chunk-C6CHEWYP.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GVGT6MIU.mjs → chunk-CK2XCICY.mjs} +2 -2
- package/dist/js/chunks/{chunk-XGHORT7J.mjs → chunk-CXXM2L4F.mjs} +8 -9
- package/dist/js/chunks/chunk-CXXM2L4F.mjs.map +7 -0
- package/dist/js/chunks/{chunk-QVVEWBOF.mjs → chunk-DXGRXYYL.mjs} +25 -37
- package/dist/js/chunks/chunk-DXGRXYYL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-QV2JAWIZ.mjs → chunk-FM5CZOUB.mjs} +5 -8
- package/dist/js/chunks/{chunk-QV2JAWIZ.mjs.map → chunk-FM5CZOUB.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-PLYXLSH3.mjs → chunk-GJL6GCIU.mjs} +46 -58
- 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-KHXZ2A4K.mjs +395 -0
- package/dist/js/chunks/chunk-KHXZ2A4K.mjs.map +7 -0
- package/dist/js/chunks/chunk-KQACNQ22.mjs +7 -0
- package/dist/js/chunks/{chunk-4PWAPV6F.mjs.map → chunk-KQACNQ22.mjs.map} +1 -1
- package/dist/js/chunks/chunk-KUFHW3DS.mjs +214 -0
- package/dist/js/chunks/chunk-KUFHW3DS.mjs.map +7 -0
- package/dist/js/chunks/{chunk-LWBQIX5J.mjs → chunk-KVJAVDBC.mjs} +46 -57
- 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-CCWDV5CR.mjs → chunk-LQWUDNHZ.mjs} +3 -3
- package/dist/js/chunks/{chunk-6OMRGML6.mjs → chunk-M372EDXD.mjs} +7 -13
- package/dist/js/chunks/{chunk-6OMRGML6.mjs.map → chunk-M372EDXD.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-EC63CHXU.mjs → chunk-M3MURWMB.mjs} +20 -16
- package/dist/js/chunks/chunk-M3MURWMB.mjs.map +7 -0
- package/dist/js/chunks/{chunk-U2OTHOTI.mjs → chunk-NUHMOAOY.mjs} +19 -33
- package/dist/js/chunks/chunk-NUHMOAOY.mjs.map +7 -0
- package/dist/js/chunks/{chunk-P3G3QHII.mjs → chunk-OWG3LMUL.mjs} +17 -14
- 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-PIJ2TAR3.mjs → chunk-PDG64UHF.mjs} +3 -3
- package/dist/js/chunks/{chunk-IFXVDDDH.mjs → chunk-PO3AXVR3.mjs} +38 -64
- package/dist/js/chunks/chunk-PO3AXVR3.mjs.map +7 -0
- package/dist/js/chunks/{chunk-QKWPQK5N.mjs → chunk-QYGK36OG.mjs} +16 -14
- package/dist/js/chunks/chunk-QYGK36OG.mjs.map +7 -0
- package/dist/js/chunks/{chunk-UNEMYWEW.mjs → chunk-SFI2U4YW.mjs} +28 -44
- package/dist/js/chunks/chunk-SFI2U4YW.mjs.map +7 -0
- package/dist/js/chunks/{chunk-VTLBW7QS.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-UBLRRJ7N.mjs → chunk-TSZYSW7F.mjs} +4 -4
- package/dist/js/chunks/{chunk-UBLRRJ7N.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-3VOK6J7U.mjs → chunk-UCOE7ZDL.mjs} +47 -45
- package/dist/js/chunks/chunk-UCOE7ZDL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-K4CJCRGE.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-LNCCYGPC.mjs → chunk-VGNYF6FB.mjs} +8 -10
- package/dist/js/chunks/chunk-VGNYF6FB.mjs.map +7 -0
- package/dist/js/chunks/{chunk-UAEAQBRC.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-55IA2XUC.mjs → chunk-WDK4T63U.mjs} +8 -11
- package/dist/js/chunks/chunk-WDK4T63U.mjs.map +7 -0
- package/dist/js/chunks/{chunk-XH6BEEMY.mjs → chunk-WOCCTVUF.mjs} +51 -39
- package/dist/js/chunks/chunk-WOCCTVUF.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GZWPXXY6.mjs → chunk-WQYN5L4E.mjs} +14 -16
- package/dist/js/chunks/chunk-WQYN5L4E.mjs.map +7 -0
- package/dist/js/chunks/{chunk-6WLSDZ4O.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-3CLXLPYS.mjs → chunk-ZX6M7SWO.mjs} +43 -29
- package/dist/js/chunks/chunk-ZX6M7SWO.mjs.map +7 -0
- package/dist/js/expressive.cjs +1337 -572
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +1337 -572
- 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 +71 -55
- 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 +8 -0
- package/dist/js/internal/components/confetti.mjs.map +7 -0
- 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 +64 -48
- 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 +9 -0
- package/dist/js/internal/components/mapView.mjs.map +7 -0
- 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 +8 -0
- package/dist/js/internal/components/particles.mjs.map +7 -0
- 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 -37
- 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 +71 -55
- package/dist/types/behaviors/forms.d.ts +5 -0
- package/dist/types/components/autocomplete.d.ts +1 -0
- package/dist/types/components/carousel.d.ts +2 -0
- package/dist/types/components/confetti.d.ts +103 -0
- package/dist/types/components/datepicker.d.ts +5 -4
- package/dist/types/components/expandingCard.d.ts +2 -0
- package/dist/types/components/index.d.ts +4 -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/mapView.d.ts +151 -0
- package/dist/types/components/menu.d.ts +1 -0
- package/dist/types/components/particles.d.ts +72 -0
- package/dist/types/components/pieChart.d.ts +3 -0
- package/dist/types/components/radialChart.d.ts +0 -1
- package/dist/types/components/registry.d.ts +12 -0
- package/dist/types/components/slider.d.ts +3 -1
- package/dist/types/components/snackbar.d.ts +3 -0
- package/dist/types/components/tabs.d.ts +5 -1
- package/dist/types/components/timepicker.d.ts +2 -0
- package/dist/types/modular.d.ts +1 -1
- package/dist/types/plugins/dockedDisplayPlugin.d.ts +4 -3
- package/package.json +2 -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/_buttons.scss +1 -1
- 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/_confetti.scss +14 -0
- 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 +4 -0
- package/src/sass/components/_keypad.scss +162 -0
- package/src/sass/components/_lightbox.scss +3 -8
- package/src/sass/components/_map.scss +188 -0
- 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/_particles.scss +14 -0
- 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/_table_of_contents.scss +3 -1
- package/src/sass/components/_timepicker.scss +4 -36
- package/src/sass/components/_toolbar.scss +0 -4
- package/src/sass/components/forms/_checkboxes.scss +44 -67
- 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-3CLXLPYS.mjs.map +0 -7
- package/dist/js/chunks/chunk-3DHK5CZU.mjs.map +0 -7
- package/dist/js/chunks/chunk-3VOK6J7U.mjs.map +0 -7
- package/dist/js/chunks/chunk-4PWAPV6F.mjs +0 -7
- package/dist/js/chunks/chunk-55IA2XUC.mjs.map +0 -7
- package/dist/js/chunks/chunk-6N2XAEFK.mjs.map +0 -7
- package/dist/js/chunks/chunk-CKQP6P76.mjs.map +0 -7
- package/dist/js/chunks/chunk-EC63CHXU.mjs.map +0 -7
- package/dist/js/chunks/chunk-GZWPXXY6.mjs.map +0 -7
- package/dist/js/chunks/chunk-IFXVDDDH.mjs.map +0 -7
- package/dist/js/chunks/chunk-LNCCYGPC.mjs.map +0 -7
- package/dist/js/chunks/chunk-LTWPGFBR.mjs.map +0 -7
- package/dist/js/chunks/chunk-LWBQIX5J.mjs.map +0 -7
- package/dist/js/chunks/chunk-NNYP33NB.mjs.map +0 -7
- package/dist/js/chunks/chunk-NQLC3YMW.mjs +0 -1
- package/dist/js/chunks/chunk-O5XPWXIQ.mjs.map +0 -7
- package/dist/js/chunks/chunk-P3G3QHII.mjs.map +0 -7
- package/dist/js/chunks/chunk-PLYXLSH3.mjs.map +0 -7
- package/dist/js/chunks/chunk-QKWPQK5N.mjs.map +0 -7
- package/dist/js/chunks/chunk-QVVEWBOF.mjs.map +0 -7
- package/dist/js/chunks/chunk-RHRQKTTX.mjs.map +0 -7
- package/dist/js/chunks/chunk-SPETGK25.mjs.map +0 -7
- package/dist/js/chunks/chunk-U2OTHOTI.mjs.map +0 -7
- package/dist/js/chunks/chunk-UAEAQBRC.mjs.map +0 -7
- package/dist/js/chunks/chunk-UNEMYWEW.mjs.map +0 -7
- package/dist/js/chunks/chunk-WJXDBPXQ.mjs.map +0 -7
- package/dist/js/chunks/chunk-XGHORT7J.mjs.map +0 -7
- package/dist/js/chunks/chunk-XH6BEEMY.mjs.map +0 -7
- /package/dist/js/chunks/{chunk-DTKR54I6.mjs.map → chunk-33QVDDGR.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-DLWYKFEI.mjs.map → chunk-AIURVCG6.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-GVGT6MIU.mjs.map → chunk-CK2XCICY.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-YDCS5S3J.mjs.map → chunk-L27Q6ZMI.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-CCWDV5CR.mjs.map → chunk-LQWUDNHZ.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-PIJ2TAR3.mjs.map → chunk-PDG64UHF.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-VTLBW7QS.mjs.map → chunk-SMY7GJSS.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-K4CJCRGE.mjs.map → chunk-UETTGDLI.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-NQLC3YMW.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-6WLSDZ4O.mjs.map → chunk-X4ISMKE2.mjs.map} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ts/components/chips.ts"],
|
|
4
|
+
"sourcesContent": ["import { Utils } from '../core/utils';\nimport { Autocomplete, AutocompleteOptions } from './autocomplete';\nimport { Component, BaseOptions, InitElements, InitElement } from '../core/component';\n\nexport interface ChipData {\n /**\n * Unique identifier.\n */\n id: number | string;\n /**\n * Chip text. If not specified, \"id\" will be used.\n */\n text?: string;\n /**\n * Chip image (URL).\n */\n image?: string;\n}\n\nexport interface ChipsI18nOptions {\n /** Prefix for the delete button's accessible name. */\n remove: string;\n}\n\nexport interface ChipsOptions extends BaseOptions {\n /**\n * Set the chip data.\n * @default []\n */\n data: ChipData[];\n /**\n * Set first placeholder when there are no tags.\n * @default \"\"\n */\n placeholder: string;\n /**\n * Set second placeholder when adding additional tags.\n * @default \"\"\n */\n secondaryPlaceholder: string;\n /**\n * Set autocomplete options.\n * @default {}\n */\n autocompleteOptions: Partial<AutocompleteOptions>;\n /**\n * Toggles abililty to add custom value not in autocomplete list.\n * @default false\n */\n autocompleteOnly: boolean;\n /**\n * Set chips limit.\n * @default Infinity\n */\n limit: number;\n /**\n * Specifies class to be used in \"close\" button.\n * @default 'material-symbols'\n */\n closeIconClass: string;\n /**\n * Specifies option to render user input field\n * @default false;\n */\n allowUserInput: boolean;\n /**\n * Strings the component generates. `remove` prefixes the delete button's\n * accessible name, giving \"Remove Apple\".\n * @default { remove: 'Remove' }\n */\n i18n: Partial<ChipsI18nOptions>;\n /**\n * Callback for chip add.\n * @default null\n */\n onChipAdd: (element: HTMLElement, chip: HTMLElement) => void;\n /**\n * Callback for chip select.\n * @default null\n */\n onChipSelect: (element: HTMLElement, chip: HTMLElement) => void;\n /**\n * Callback for chip delete.\n * @default null\n */\n onChipDelete: (element: HTMLElement, chip: HTMLElement) => void;\n}\n\nconst _defaults: ChipsOptions = {\n data: [],\n placeholder: '',\n secondaryPlaceholder: '',\n closeIconClass: 'material-symbols',\n autocompleteOptions: {},\n autocompleteOnly: false,\n limit: Infinity,\n allowUserInput: false,\n i18n: { remove: 'Remove' },\n onChipAdd: null,\n onChipSelect: null,\n onChipDelete: null\n};\n\nexport class Chips extends Component<ChipsOptions> {\n /** Array of the current chips data. */\n chipsData: ChipData[];\n /** If the chips has autocomplete enabled. */\n hasAutocomplete: boolean;\n /** Autocomplete instance, if any. */\n autocomplete: Autocomplete;\n _input: HTMLInputElement;\n _label: HTMLLabelElement;\n _chips: HTMLElement[];\n static _keydown: boolean;\n private _selectedChip: HTMLElement;\n\n /**\n * Selection is drawn by a class now, not by `:focus`, so it does not clear\n * itself when focus moves - every path that changes the selection has to go\n * through here or the class and the field drift apart.\n *\n * Deliberately no `aria-selected`: the chip is not an option in a listbox,\n * and putting the attribute on an element with no such role is the same\n * defect the semantics standard exists to remove.\n */\n private _setSelected(chip: HTMLElement | null) {\n this._selectedChip?.classList.remove('selected');\n this._selectedChip = chip;\n chip?.classList.add('selected');\n }\n\n constructor(el: HTMLElement, options: Partial<ChipsOptions>) {\n super(el, options, Chips);\n this.el['Expressive_Chips'] = this;\n\n this.options = {\n ...Chips.defaults,\n ...options\n };\n // Spreading options over the defaults replaces the i18n object wholesale,\n // so passing one string would drop the rest. Same fix as Datepicker.\n if (options?.i18n) this.options.i18n = { ...Chips.defaults.i18n, ...options.i18n };\n\n this.el.classList.add('chips');\n this.chipsData = [];\n this._chips = [];\n\n // Render initial chips\n if (this.options.data.length) {\n this.chipsData = this.options.data;\n this._renderChips();\n }\n\n // Render input element, setup event handlers\n if (this.options.allowUserInput) {\n this.el.classList.add('field');\n this._setupInput();\n this._setupEventHandlers();\n // move input to end\n this.el.append(this._input);\n }\n // After _setupInput: the label points at the input's id, which is only\n // assigned there. Running this first threw on any .chips with a <label>.\n this._setupLabel();\n }\n\n static get defaults() {\n return _defaults;\n }\n\n /**\n * Initializes instance of Chips.\n * @param el HTML element.\n * @param options Component options.\n */\n static init(el: HTMLElement, options?: Partial<ChipsOptions>): Chips;\n /**\n * Initializes instances of Chips.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(els: InitElements<InitElement>, options?: Partial<ChipsOptions>): Chips[];\n /**\n * Initializes instances of Chips.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<ChipsOptions> = {}\n ): Chips | Chips[] {\n return super.init(els, options, Chips);\n }\n\n static getInstance(el: HTMLElement): Chips {\n return el['Expressive_Chips'];\n }\n\n getData() {\n return this.chipsData;\n }\n\n destroy() {\n if (this.autocomplete && Autocomplete.getInstance(this._input) === this.autocomplete) {\n this.autocomplete.destroy();\n }\n if (this.options.allowUserInput) {\n this._removeEventHandlers();\n }\n this._chips.forEach((c) => c.remove());\n this._chips = [];\n this.el['Expressive_Chips'] = undefined;\n }\n\n _setupEventHandlers() {\n this.el.addEventListener('click', this._handleChipClick);\n this.el.addEventListener('keydown', Chips._handleChipsKeydown);\n this.el.addEventListener('keyup', Chips._handleChipsKeyup);\n this.el.addEventListener('blur', Chips._handleChipsBlur, true);\n this._input.addEventListener('focus', this._handleInputFocus);\n this._input.addEventListener('blur', this._handleInputBlur);\n this._input.addEventListener('keydown', this._handleInputKeydown);\n }\n\n _removeEventHandlers() {\n this.el.removeEventListener('click', this._handleChipClick);\n this.el.removeEventListener('keydown', Chips._handleChipsKeydown);\n this.el.removeEventListener('keyup', Chips._handleChipsKeyup);\n this.el.removeEventListener('blur', Chips._handleChipsBlur, true);\n this._input.removeEventListener('focus', this._handleInputFocus);\n this._input.removeEventListener('blur', this._handleInputBlur);\n this._input.removeEventListener('keydown', this._handleInputKeydown);\n }\n\n _handleChipClick = (e: MouseEvent) => {\n const _chip = (<HTMLElement>e.target).closest('.chip');\n // closest, not classList: the close button now wraps an icon span, so a\n // click on the glyph reports the span as the target.\n const clickedClose = !!(<HTMLElement>e.target).closest('.close');\n if (_chip) {\n // Index into the chip list, not into the container's children: the\n // container also holds the label and the input, so counting children\n // gave an index that did not line up with chipsData.\n const index = this._chips.indexOf(_chip as HTMLElement);\n if (index < 0) return;\n if (clickedClose) {\n this._deleteChip(index, 'input');\n } else {\n this.selectChip(index);\n }\n // Default handle click to focus on input\n } else {\n this._input.focus();\n }\n };\n\n static _handleChipsKeydown(e: KeyboardEvent) {\n Chips._keydown = true;\n const chips = (<HTMLElement>e.target).closest('.chips');\n\n // Don't handle keydown inputs on input and textarea\n const tag = (<HTMLElement>e.target).tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || !chips) return;\n\n const currChips: Chips = chips['Expressive_Chips'];\n if (!currChips) return; // .chips markup without an instance behind it\n\n if (e.key === Utils.keys.BACKSPACE || e.key === Utils.keys.DELETE) {\n const index = currChips._chips.indexOf((e.target as HTMLElement).closest('.chip'));\n if (index < 0) return;\n e.preventDefault();\n currChips._deleteChip(index, 'previous');\n } else if (e.key === Utils.keys.ARROW_LEFT) {\n if (currChips._selectedChip) {\n const selectIndex = currChips._chips.indexOf(currChips._selectedChip) - 1;\n if (selectIndex < 0) return;\n currChips.selectChip(selectIndex);\n }\n } else if (e.key === Utils.keys.ARROW_RIGHT) {\n if (currChips._selectedChip) {\n const selectIndex = currChips._chips.indexOf(currChips._selectedChip) + 1;\n if (selectIndex >= currChips.chipsData.length) {\n // Walking off the end returns to the input, so nothing is selected\n // any more - without this the last chip kept the class.\n currChips._setSelected(null);\n currChips._input.focus();\n }\n else currChips.selectChip(selectIndex);\n }\n }\n }\n\n static _handleChipsKeyup() {\n Chips._keydown = false;\n }\n\n static _handleChipsBlur(e: Event) {\n if (!Chips._keydown && document.hidden) {\n const chips = (<HTMLElement>e.target).closest('.chips');\n const currChips: Chips = chips?.['Expressive_Chips'];\n if (currChips) currChips._setSelected(null);\n }\n }\n\n _handleInputFocus = () => {\n this.el.classList.add('focus');\n };\n\n _handleInputBlur = () => {\n this.el.classList.remove('focus');\n };\n\n _handleInputKeydown = (e: KeyboardEvent) => {\n Chips._keydown = true;\n if (e.key === Utils.keys.ENTER) {\n // Override enter if autocompleting.\n if (this.hasAutocomplete && this.autocomplete?.isOpen &&\n this.autocomplete.container.querySelector('[role=\"option\"]')) {\n return;\n }\n e.preventDefault();\n if (!this.hasAutocomplete || !this.options.autocompleteOnly) {\n this.addChip({ id: this._input.value });\n }\n this._input.value = '';\n } else if (\n (e.key === Utils.keys.BACKSPACE || e.key === Utils.keys.ARROW_LEFT) &&\n this._input.value === '' &&\n this.chipsData.length\n ) {\n e.preventDefault();\n this.selectChip(this.chipsData.length - 1);\n }\n };\n\n _renderChip(chip: ChipData): HTMLElement {\n if (!chip.id && chip.id !== 0) return;\n const label = chip.text || <string>chip.id;\n // <span>, not <div>: a chip is inline, and the container itself is not a\n // control. It used to be a <div tabindex=\"0\"> with no role - focusable,\n // and announcing nothing.\n const renderedChip = document.createElement('span');\n renderedChip.classList.add('chip');\n renderedChip.innerText = label;\n // attach image if needed\n if (chip.image) {\n const img = document.createElement('img');\n img.setAttribute('src', chip.image);\n renderedChip.insertBefore(img, renderedChip.firstChild);\n }\n if (this.options.allowUserInput) {\n // The delete affordance is the control, so it is the <button> and it\n // carries the name. `type` is explicit because a bare button inside a\n // form submits it.\n const closeButton = document.createElement('button');\n closeButton.type = 'button';\n closeButton.classList.add('close');\n closeButton.setAttribute('aria-label', `${this.options.i18n.remove} ${label}`);\n // The ligature is text and is read out, so the glyph is hidden and the\n // button's own label is what gets announced.\n const closeIcon = document.createElement('span');\n closeIcon.classList.add(this.options.closeIconClass);\n closeIcon.setAttribute('aria-hidden', 'true');\n closeIcon.innerText = 'close';\n closeButton.appendChild(closeIcon);\n renderedChip.appendChild(closeButton);\n }\n return renderedChip;\n }\n\n _renderChips() {\n this._chips = []; //.remove();\n for (let i = 0; i < this.chipsData.length; i++) {\n const chipElem = this._renderChip(this.chipsData[i]);\n this.el.appendChild(chipElem);\n this._chips.push(chipElem);\n }\n }\n\n _setupAutocomplete() {\n this.options.autocompleteOptions.onAutocomplete = (items) => {\n if (Chips.getInstance(this.el) !== this) return;\n if (items.length > 0) {\n this.addChip({\n id: items[0].id,\n text: items[0].text,\n image: items[0].image\n });\n this._input.value = '';\n this._input.focus();\n }\n };\n this.autocomplete = Autocomplete.init(this._input, this.options.autocompleteOptions);\n }\n\n _setupInput() {\n this._input = this.el.querySelector('input');\n if (!this._input) {\n this._input = document.createElement('input');\n this.el.append(this._input);\n }\n this._input.classList.add('input');\n this.hasAutocomplete = Object.keys(this.options.autocompleteOptions).length > 0;\n // Setup autocomplete if needed\n if (this.hasAutocomplete) this._setupAutocomplete();\n this._setPlaceholder();\n // Set input id\n if (!this._input.getAttribute('id')) this._input.setAttribute('id', Utils.guid());\n }\n\n _setupLabel() {\n this._label = this.el.querySelector('label');\n // No input to point at when allowUserInput is off.\n if (this._label && this._input) this._label.setAttribute('for', this._input.getAttribute('id'));\n }\n\n _setPlaceholder() {\n if (!this._input) return;\n if (!this.chipsData.length && this.options.placeholder) {\n this._input.placeholder = this.options.placeholder;\n } else if (this.chipsData.length && this.options.secondaryPlaceholder) {\n this._input.placeholder = this.options.secondaryPlaceholder;\n }\n }\n\n _isValidAndNotExist(chip: ChipData) {\n const isValid = !!chip.id || chip.id === 0;\n const doesNotExist = !this.chipsData.some((item) => item.id == chip.id);\n return isValid && doesNotExist;\n }\n\n /**\n * Add chip to input.\n * @param chip Chip data object\n */\n addChip(chip: ChipData) {\n if (!this._isValidAndNotExist(chip) || this.chipsData.length >= this.options.limit) return;\n const renderedChip = this._renderChip(chip);\n this._chips.push(renderedChip);\n this.chipsData.push(chip);\n if (this._input) this._input.before(renderedChip);\n else this.el.append(renderedChip);\n this._setPlaceholder();\n // fire chipAdd callback\n if (typeof this.options.onChipAdd === 'function') {\n this.options.onChipAdd(this.el, renderedChip);\n }\n }\n\n /**\n * Delete nth chip.\n * @param chipIndex Index of chip\n */\n deleteChip(chipIndex: number) {\n const root = this.el.getRootNode() as Document | ShadowRoot;\n this._deleteChip(chipIndex, this._chips[chipIndex]?.contains(root.activeElement) ? 'input' : null);\n }\n\n private _deleteChip(chipIndex: number, focus: 'input' | 'previous' | null) {\n const chip = this._chips[chipIndex];\n if (!chip) return;\n if (this._selectedChip === chip) this._setSelected(null);\n chip.remove();\n this._chips.splice(chipIndex, 1);\n this.chipsData.splice(chipIndex, 1);\n this._setPlaceholder();\n const focusPath: { root: Document | ShadowRoot; element: Element | null }[] = [];\n let root = this.el.getRootNode() as Document | ShadowRoot;\n while (root) {\n focusPath.push({ root, element: root.activeElement });\n root = 'host' in root ? root.host.getRootNode() as Document | ShadowRoot : null;\n }\n // fire chipDelete callback\n if (typeof this.options.onChipDelete === 'function') {\n this.options.onChipDelete(this.el, chip);\n }\n if (!focus || focusPath.some(({ root, element }) => root.activeElement !== element) || this.el['Expressive_Chips'] !== this) return;\n if (focus === 'previous' && this._chips.length) this.selectChip(Math.max(chipIndex - 1, 0));\n else {\n this._setSelected(null);\n this._input?.focus();\n }\n }\n\n /**\n * Select nth chip.\n * @param chipIndex Index of chip\n */\n selectChip(chipIndex: number) {\n const chip = this._chips[chipIndex];\n if (!chip) return;\n this._setSelected(chip);\n // The chip is not a control any more, so focus goes to the one thing in it\n // that is - the delete button.\n (chip.querySelector('.close') as HTMLElement | null)?.focus();\n // fire chipSelect callback\n if (typeof this.options.onChipSelect === 'function') {\n this.options.onChipSelect(this.el, chip);\n }\n }\n\n static Init() {\n // Handle removal of static chips - markup written by hand, with no Chips\n // instance behind it. Where there *is* an instance, _handleChipClick owns\n // the close button: removing the node here as well left chipsData holding\n // an entry whose element was gone.\n Utils.onDocumentReady(() => {\n const chips = document.querySelectorAll('.chips');\n chips.forEach((el) => {\n el.addEventListener('click', (e) => {\n if (el['Expressive_Chips']) return;\n // closest: the close button wraps an icon span, so a click on the\n // glyph reports the span.\n if ((<HTMLElement>e.target).closest('.close')) {\n const chip = (<HTMLElement>e.target).closest('.chip');\n if (chip) chip.remove();\n }\n });\n });\n });\n }\n\n static {\n Chips._keydown = false;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["root"]
|
|
7
|
+
}
|
|
@@ -1,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/expandingCard.ts
|
|
9
9
|
var _defaults = {
|
|
@@ -42,11 +42,7 @@ var ExpandingCard = class _ExpandingCard extends Component {
|
|
|
42
42
|
};
|
|
43
43
|
this._handleNativeClose = () => {
|
|
44
44
|
if (this.dialog.open) return;
|
|
45
|
-
this.
|
|
46
|
-
this.isOpen = false;
|
|
47
|
-
this.trigger.ariaExpanded = "false";
|
|
48
|
-
this.dialog.ariaExpanded = "false";
|
|
49
|
-
this.dialog.classList.remove("expanded");
|
|
45
|
+
this._collapse();
|
|
50
46
|
};
|
|
51
47
|
this._setTransitionOrigin = () => {
|
|
52
48
|
if (!this.dialog) return;
|
|
@@ -55,26 +51,15 @@ var ExpandingCard = class _ExpandingCard extends Component {
|
|
|
55
51
|
":scope > figure, :scope > img"
|
|
56
52
|
);
|
|
57
53
|
const mediaRect = media?.getBoundingClientRect();
|
|
58
|
-
this.dialog.style.setProperty(
|
|
59
|
-
|
|
60
|
-
`${Math.max(0,
|
|
61
|
-
);
|
|
62
|
-
this.dialog.style.setProperty(
|
|
63
|
-
"--md-comp-expanding-card-from-right",
|
|
64
|
-
`${Math.max(0, window.innerWidth - card.right)}px`
|
|
65
|
-
);
|
|
66
|
-
this.dialog.style.setProperty(
|
|
67
|
-
"--md-comp-expanding-card-from-bottom",
|
|
68
|
-
`${Math.max(0, window.innerHeight - card.bottom)}px`
|
|
69
|
-
);
|
|
70
|
-
this.dialog.style.setProperty(
|
|
71
|
-
"--md-comp-expanding-card-from-left",
|
|
72
|
-
`${Math.max(0, card.left)}px`
|
|
73
|
-
);
|
|
74
|
-
this.dialog.style.setProperty(
|
|
75
|
-
"--md-comp-expanding-card-from-media-height",
|
|
76
|
-
`${Math.max(0, mediaRect?.height ?? 0)}px`
|
|
54
|
+
const set = (side, px) => this.dialog.style.setProperty(
|
|
55
|
+
`--md-comp-expanding-card-from-${side}`,
|
|
56
|
+
`${Math.max(0, px)}px`
|
|
77
57
|
);
|
|
58
|
+
set("top", card.top);
|
|
59
|
+
set("right", window.innerWidth - card.right);
|
|
60
|
+
set("bottom", window.innerHeight - card.bottom);
|
|
61
|
+
set("left", card.left);
|
|
62
|
+
set("media-height", mediaRect?.height ?? 0);
|
|
78
63
|
};
|
|
79
64
|
this.open = () => {
|
|
80
65
|
if (this.isOpen || !this.dialog || !this.trigger) return;
|
|
@@ -93,12 +78,9 @@ var ExpandingCard = class _ExpandingCard extends Component {
|
|
|
93
78
|
};
|
|
94
79
|
this.close = () => {
|
|
95
80
|
if (!this.isOpen || !this.dialog || !this.trigger) return;
|
|
96
|
-
const generation = ++this.closeGeneration;
|
|
97
81
|
this._setTransitionOrigin();
|
|
98
|
-
this.
|
|
99
|
-
|
|
100
|
-
this.dialog.ariaExpanded = "false";
|
|
101
|
-
this.dialog.classList.remove("expanded");
|
|
82
|
+
this._collapse();
|
|
83
|
+
const generation = this.closeGeneration;
|
|
102
84
|
if (typeof this.options.onClose === "function") {
|
|
103
85
|
this.options.onClose.call(this, this.el);
|
|
104
86
|
}
|
|
@@ -149,18 +131,24 @@ var ExpandingCard = class _ExpandingCard extends Component {
|
|
|
149
131
|
}
|
|
150
132
|
destroy() {
|
|
151
133
|
this._removeEventHandlers();
|
|
134
|
+
this._collapse();
|
|
135
|
+
if (this.dialog?.open) this.dialog.close();
|
|
136
|
+
this.el["Expressive_ExpandingCard"] = void 0;
|
|
137
|
+
}
|
|
138
|
+
/** Marks the card closed and invalidates any pending close. */
|
|
139
|
+
_collapse() {
|
|
152
140
|
this.closeGeneration++;
|
|
153
141
|
this.isOpen = false;
|
|
154
142
|
if (this.trigger) this.trigger.ariaExpanded = "false";
|
|
155
|
-
if (this.dialog)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
143
|
+
if (this.dialog) {
|
|
144
|
+
this.dialog.ariaExpanded = "false";
|
|
145
|
+
this.dialog.classList.remove("expanded");
|
|
146
|
+
}
|
|
159
147
|
}
|
|
160
148
|
static Init() {
|
|
161
149
|
Utils.onDocumentReady(() => {
|
|
162
150
|
document.querySelectorAll(EXPANDING_CARD_SELECTOR).forEach((el) => {
|
|
163
|
-
if (el
|
|
151
|
+
if (el["Expressive_ExpandingCard"] == void 0) {
|
|
164
152
|
this.init(el);
|
|
165
153
|
}
|
|
166
154
|
});
|
|
@@ -172,4 +160,4 @@ export {
|
|
|
172
160
|
EXPANDING_CARD_SELECTOR,
|
|
173
161
|
ExpandingCard
|
|
174
162
|
};
|
|
175
|
-
//# sourceMappingURL=chunk-
|
|
163
|
+
//# sourceMappingURL=chunk-DXGRXYYL.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ts/components/expandingCard.ts"],
|
|
4
|
+
"sourcesContent": ["import { Utils } from \"../core/utils\";\nimport {\n Component,\n BaseOptions,\n InitElements,\n InitElement,\n Openable,\n} from \"../core/component\";\n\nexport interface ExpandingCardOptions extends BaseOptions {\n onOpen: (el: Element) => void;\n onClose: (el: Element) => void;\n}\n\nconst _defaults: ExpandingCardOptions = {\n onOpen: null,\n onClose: null,\n};\n\nexport const EXPANDING_CARD_SELECTOR =\n \"article.expanding-card:has(> dialog.expanding-card-dialog)\";\n\n/**\n * Morphs a compact card into a full-screen modal detail surface.\n */\nexport class ExpandingCard\n extends Component<ExpandingCardOptions>\n implements Openable\n{\n isOpen: boolean = false;\n private readonly trigger: HTMLElement | null;\n private readonly dialog: HTMLDialogElement | null;\n private readonly closeButton: HTMLElement | null;\n private closeGeneration = 0;\n\n constructor(el: HTMLElement, options: Partial<ExpandingCardOptions>) {\n super(el, options, ExpandingCard);\n this.el[\"Expressive_ExpandingCard\"] = this;\n\n this.options = {\n ...ExpandingCard.defaults,\n ...options,\n };\n\n this.dialog = this.el.querySelector(\n \":scope > dialog.expanding-card-dialog\",\n );\n this.trigger = this.el.querySelector(\n \":scope > .expanding-card-trigger, :scope > figure > .expanding-card-trigger\",\n );\n this.closeButton =\n this.dialog?.querySelector(\".expanding-card-close\") ?? null;\n\n if (this.trigger && this.dialog) {\n this.trigger.ariaExpanded = \"false\";\n if (this.dialog.id)\n this.trigger.setAttribute(\"aria-controls\", this.dialog.id);\n if (!this.trigger.matches(\"a[href], button, input, select, textarea\")) {\n this.trigger.tabIndex = 0;\n this.trigger.setAttribute(\"role\", \"button\");\n }\n this.dialog.ariaExpanded = \"false\";\n this._setupEventHandlers();\n }\n }\n\n static get defaults(): ExpandingCardOptions {\n return _defaults;\n }\n\n static init(\n el: HTMLElement,\n options?: Partial<ExpandingCardOptions>,\n ): ExpandingCard;\n static init(\n els: InitElements<InitElement>,\n options?: Partial<ExpandingCardOptions>,\n ): ExpandingCard[];\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options?: Partial<ExpandingCardOptions>,\n ): ExpandingCard | ExpandingCard[] {\n return super.init(els, options, ExpandingCard);\n }\n\n static getInstance(el: HTMLElement): ExpandingCard {\n return el[\"Expressive_ExpandingCard\"];\n }\n\n destroy() {\n this._removeEventHandlers();\n this._collapse();\n if (this.dialog?.open) this.dialog.close();\n this.el[\"Expressive_ExpandingCard\"] = undefined;\n }\n\n private _setupEventHandlers = () => {\n this.trigger?.addEventListener(\"click\", this.open);\n this.trigger?.addEventListener(\"keypress\", this._handleTriggerKeypress);\n this.closeButton?.addEventListener(\"click\", this.close);\n this.dialog?.addEventListener(\"cancel\", this._handleCancel);\n this.dialog?.addEventListener(\"close\", this._handleNativeClose);\n };\n\n private _removeEventHandlers = () => {\n this.trigger?.removeEventListener(\"click\", this.open);\n this.trigger?.removeEventListener(\"keypress\", this._handleTriggerKeypress);\n this.closeButton?.removeEventListener(\"click\", this.close);\n this.dialog?.removeEventListener(\"cancel\", this._handleCancel);\n this.dialog?.removeEventListener(\"close\", this._handleNativeClose);\n };\n\n private _handleTriggerKeypress = (event: KeyboardEvent) => {\n if (event.key === Utils.keys.ENTER || event.key === \" \") {\n event.preventDefault();\n this.open();\n }\n };\n\n private _handleCancel = (event: Event) => {\n event.preventDefault();\n this.close();\n };\n\n private _handleNativeClose = () => {\n // A queued close event can arrive after a caller has reopened the dialog.\n if (this.dialog.open) return;\n this._collapse();\n };\n\n /** Marks the card closed and invalidates any pending close. */\n private _collapse() {\n this.closeGeneration++;\n this.isOpen = false;\n if (this.trigger) this.trigger.ariaExpanded = \"false\";\n if (this.dialog) {\n this.dialog.ariaExpanded = \"false\";\n this.dialog.classList.remove(\"expanded\");\n }\n }\n\n private _setTransitionOrigin = () => {\n if (!this.dialog) return;\n const card = this.el.getBoundingClientRect();\n const media = this.el.querySelector<HTMLElement>(\n \":scope > figure, :scope > img\",\n );\n const mediaRect = media?.getBoundingClientRect();\n const set = (side: string, px: number) =>\n this.dialog.style.setProperty(\n `--md-comp-expanding-card-from-${side}`,\n `${Math.max(0, px)}px`,\n );\n\n set(\"top\", card.top);\n set(\"right\", window.innerWidth - card.right);\n set(\"bottom\", window.innerHeight - card.bottom);\n set(\"left\", card.left);\n set(\"media-height\", mediaRect?.height ?? 0);\n };\n\n open: () => void = () => {\n if (this.isOpen || !this.dialog || !this.trigger) return;\n this.closeGeneration++;\n\n this._setTransitionOrigin();\n this.isOpen = true;\n this.trigger.ariaExpanded = \"true\";\n this.dialog.ariaExpanded = \"true\";\n this.dialog.showModal();\n // Commit the clipped start frame before asking CSS to expand it.\n void this.dialog.offsetWidth;\n this.dialog.classList.add(\"expanded\");\n this.closeButton?.focus();\n\n if (typeof this.options.onOpen === \"function\") {\n this.options.onOpen.call(this, this.el);\n }\n };\n\n close: () => void = () => {\n if (!this.isOpen || !this.dialog || !this.trigger) return;\n this._setTransitionOrigin();\n this._collapse();\n const generation = this.closeGeneration;\n\n if (typeof this.options.onClose === \"function\") {\n this.options.onClose.call(this, this.el);\n }\n\n const finish = () => {\n if (generation !== this.closeGeneration || this.isOpen || !this.dialog.open) return;\n this.dialog.close();\n if (this.dialog.isConnected && this.trigger.isConnected) this.trigger.focus();\n };\n const reducedMotion = window.matchMedia(\n \"(prefers-reduced-motion: reduce)\",\n ).matches;\n // Wait only for the container's actual clip transition, not arbitrary\n // animations in consumer content. Cancellation also completes cleanup.\n const transitions = reducedMotion ? [] : (this.dialog.getAnimations?.() ?? [])\n .filter((animation) => (animation as CSSTransition).transitionProperty === \"clip-path\");\n if (transitions.length === 0) finish();\n else void Promise.allSettled(transitions.map((animation) => animation.finished)).then(finish);\n };\n\n static Init() {\n Utils.onDocumentReady(() => {\n document.querySelectorAll(EXPANDING_CARD_SELECTOR).forEach((el) => {\n if (el[\"Expressive_ExpandingCard\"] == undefined) {\n this.init(el as HTMLElement);\n }\n });\n });\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;AAcA,IAAM,YAAkC;AAAA,EACtC,QAAQ;AAAA,EACR,SAAS;AACX;AAEO,IAAM,0BACX;AAKK,IAAM,gBAAN,MAAM,uBACH,UAEV;AAAA,EAOE,YAAY,IAAiB,SAAwC;AACnE,UAAM,IAAI,SAAS,cAAa;AAPlC,kBAAkB;AAIlB,SAAQ,kBAAkB;AA+D1B,SAAQ,sBAAsB,MAAM;AAClC,WAAK,SAAS,iBAAiB,SAAS,KAAK,IAAI;AACjD,WAAK,SAAS,iBAAiB,YAAY,KAAK,sBAAsB;AACtE,WAAK,aAAa,iBAAiB,SAAS,KAAK,KAAK;AACtD,WAAK,QAAQ,iBAAiB,UAAU,KAAK,aAAa;AAC1D,WAAK,QAAQ,iBAAiB,SAAS,KAAK,kBAAkB;AAAA,IAChE;AAEA,SAAQ,uBAAuB,MAAM;AACnC,WAAK,SAAS,oBAAoB,SAAS,KAAK,IAAI;AACpD,WAAK,SAAS,oBAAoB,YAAY,KAAK,sBAAsB;AACzE,WAAK,aAAa,oBAAoB,SAAS,KAAK,KAAK;AACzD,WAAK,QAAQ,oBAAoB,UAAU,KAAK,aAAa;AAC7D,WAAK,QAAQ,oBAAoB,SAAS,KAAK,kBAAkB;AAAA,IACnE;AAEA,SAAQ,yBAAyB,CAAC,UAAyB;AACzD,UAAI,MAAM,QAAQ,MAAM,KAAK,SAAS,MAAM,QAAQ,KAAK;AACvD,cAAM,eAAe;AACrB,aAAK,KAAK;AAAA,MACZ;AAAA,IACF;AAEA,SAAQ,gBAAgB,CAAC,UAAiB;AACxC,YAAM,eAAe;AACrB,WAAK,MAAM;AAAA,IACb;AAEA,SAAQ,qBAAqB,MAAM;AAEjC,UAAI,KAAK,OAAO,KAAM;AACtB,WAAK,UAAU;AAAA,IACjB;AAaA,SAAQ,uBAAuB,MAAM;AACnC,UAAI,CAAC,KAAK,OAAQ;AAClB,YAAM,OAAO,KAAK,GAAG,sBAAsB;AAC3C,YAAM,QAAQ,KAAK,GAAG;AAAA,QACpB;AAAA,MACF;AACA,YAAM,YAAY,OAAO,sBAAsB;AAC/C,YAAM,MAAM,CAAC,MAAc,OACzB,KAAK,OAAO,MAAM;AAAA,QAChB,iCAAiC,IAAI;AAAA,QACrC,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC;AAAA,MACpB;AAEF,UAAI,OAAO,KAAK,GAAG;AACnB,UAAI,SAAS,OAAO,aAAa,KAAK,KAAK;AAC3C,UAAI,UAAU,OAAO,cAAc,KAAK,MAAM;AAC9C,UAAI,QAAQ,KAAK,IAAI;AACrB,UAAI,gBAAgB,WAAW,UAAU,CAAC;AAAA,IAC5C;AAEA,gBAAmB,MAAM;AACvB,UAAI,KAAK,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK,QAAS;AAClD,WAAK;AAEL,WAAK,qBAAqB;AAC1B,WAAK,SAAS;AACd,WAAK,QAAQ,eAAe;AAC5B,WAAK,OAAO,eAAe;AAC3B,WAAK,OAAO,UAAU;AAEtB,WAAK,KAAK,OAAO;AACjB,WAAK,OAAO,UAAU,IAAI,UAAU;AACpC,WAAK,aAAa,MAAM;AAExB,UAAI,OAAO,KAAK,QAAQ,WAAW,YAAY;AAC7C,aAAK,QAAQ,OAAO,KAAK,MAAM,KAAK,EAAE;AAAA,MACxC;AAAA,IACF;AAEA,iBAAoB,MAAM;AACxB,UAAI,CAAC,KAAK,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK,QAAS;AACnD,WAAK,qBAAqB;AAC1B,WAAK,UAAU;AACf,YAAM,aAAa,KAAK;AAExB,UAAI,OAAO,KAAK,QAAQ,YAAY,YAAY;AAC9C,aAAK,QAAQ,QAAQ,KAAK,MAAM,KAAK,EAAE;AAAA,MACzC;AAEA,YAAM,SAAS,MAAM;AACnB,YAAI,eAAe,KAAK,mBAAmB,KAAK,UAAU,CAAC,KAAK,OAAO,KAAM;AAC7E,aAAK,OAAO,MAAM;AAClB,YAAI,KAAK,OAAO,eAAe,KAAK,QAAQ,YAAa,MAAK,QAAQ,MAAM;AAAA,MAC9E;AACA,YAAM,gBAAgB,OAAO;AAAA,QAC3B;AAAA,MACF,EAAE;AAGF,YAAM,cAAc,gBAAgB,CAAC,KAAK,KAAK,OAAO,gBAAgB,KAAK,CAAC,GACzE,OAAO,CAAC,cAAe,UAA4B,uBAAuB,WAAW;AACxF,UAAI,YAAY,WAAW,EAAG,QAAO;AAAA,UAChC,MAAK,QAAQ,WAAW,YAAY,IAAI,CAAC,cAAc,UAAU,QAAQ,CAAC,EAAE,KAAK,MAAM;AAAA,IAC9F;AAvKE,SAAK,GAAG,0BAA0B,IAAI;AAEtC,SAAK,UAAU;AAAA,MACb,GAAG,eAAc;AAAA,MACjB,GAAG;AAAA,IACL;AAEA,SAAK,SAAS,KAAK,GAAG;AAAA,MACpB;AAAA,IACF;AACA,SAAK,UAAU,KAAK,GAAG;AAAA,MACrB;AAAA,IACF;AACA,SAAK,cACH,KAAK,QAAQ,cAAc,uBAAuB,KAAK;AAEzD,QAAI,KAAK,WAAW,KAAK,QAAQ;AAC/B,WAAK,QAAQ,eAAe;AAC5B,UAAI,KAAK,OAAO;AACd,aAAK,QAAQ,aAAa,iBAAiB,KAAK,OAAO,EAAE;AAC3D,UAAI,CAAC,KAAK,QAAQ,QAAQ,0CAA0C,GAAG;AACrE,aAAK,QAAQ,WAAW;AACxB,aAAK,QAAQ,aAAa,QAAQ,QAAQ;AAAA,MAC5C;AACA,WAAK,OAAO,eAAe;AAC3B,WAAK,oBAAoB;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,WAAW,WAAiC;AAC1C,WAAO;AAAA,EACT;AAAA,EAUA,OAAO,KACL,KACA,SACiC;AACjC,WAAO,MAAM,KAAK,KAAK,SAAS,cAAa;AAAA,EAC/C;AAAA,EAEA,OAAO,YAAY,IAAgC;AACjD,WAAO,GAAG,0BAA0B;AAAA,EACtC;AAAA,EAEA,UAAU;AACR,SAAK,qBAAqB;AAC1B,SAAK,UAAU;AACf,QAAI,KAAK,QAAQ,KAAM,MAAK,OAAO,MAAM;AACzC,SAAK,GAAG,0BAA0B,IAAI;AAAA,EACxC;AAAA;AAAA,EAqCQ,YAAY;AAClB,SAAK;AACL,SAAK,SAAS;AACd,QAAI,KAAK,QAAS,MAAK,QAAQ,eAAe;AAC9C,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,eAAe;AAC3B,WAAK,OAAO,UAAU,OAAO,UAAU;AAAA,IACzC;AAAA,EACF;AAAA,EAmEA,OAAO,OAAO;AACZ,UAAM,gBAAgB,MAAM;AAC1B,eAAS,iBAAiB,uBAAuB,EAAE,QAAQ,CAAC,OAAO;AACjE,YAAI,GAAG,0BAA0B,KAAK,QAAW;AAC/C,eAAK,KAAK,EAAiB;AAAA,QAC7B;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Component
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PD6HYHAE.mjs";
|
|
4
4
|
|
|
5
5
|
// src/ts/components/scrollspy.ts
|
|
6
6
|
var _defaultGetActiveElement = (id) => `a[href="#${id}"]`;
|
|
@@ -74,8 +74,9 @@ var _ScrollSpy = class _ScrollSpy extends Component {
|
|
|
74
74
|
const retained = elements.filter((spy) => spy.options.keepTopElementActive);
|
|
75
75
|
best = _ScrollSpy._nearestAbove(retained) ?? retained[0];
|
|
76
76
|
}
|
|
77
|
-
const next = best ? _ScrollSpy._linkFor(best.el.id, best.options) : null;
|
|
78
77
|
const active = _ScrollSpy._active.get(resolver);
|
|
78
|
+
if (best && active === best && best._link?.isConnected) return;
|
|
79
|
+
const next = best ? _ScrollSpy._linkFor(best.el.id, best.options) : null;
|
|
79
80
|
if (active === best && active?._link === next) return;
|
|
80
81
|
_ScrollSpy._clearActive(resolver);
|
|
81
82
|
if (!next) return;
|
|
@@ -118,11 +119,7 @@ var _ScrollSpy = class _ScrollSpy extends Component {
|
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
const href = `#${id}`;
|
|
121
|
-
|
|
122
|
-
for (let i = 0; i < links.length; i++) {
|
|
123
|
-
if (links[i].getAttribute("href") === href) return links[i];
|
|
124
|
-
}
|
|
125
|
-
return null;
|
|
122
|
+
return Array.from(document.querySelectorAll('a[href^="#"]')).find((link) => link.getAttribute("href") === href) ?? null;
|
|
126
123
|
}
|
|
127
124
|
};
|
|
128
125
|
_ScrollSpy._elements = [];
|
|
@@ -132,4 +129,4 @@ var ScrollSpy = _ScrollSpy;
|
|
|
132
129
|
export {
|
|
133
130
|
ScrollSpy
|
|
134
131
|
};
|
|
135
|
-
//# sourceMappingURL=chunk-
|
|
132
|
+
//# sourceMappingURL=chunk-FM5CZOUB.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ts/components/scrollspy.ts"],
|
|
4
|
-
"sourcesContent": ["import { Component, BaseOptions, InitElements, InitElement } from '../core/component';\n\nexport interface ScrollSpyOptions extends BaseOptions {\n /**\n * Offset used as IntersectionObserver rootMargin and as\n * `--md-comp-scrollspy-offset` (scroll-margin on the section).\n * @default 200\n */\n scrollOffset: number;\n /**\n * Class applied to active elements.\n * @default 'active'\n */\n activeClass: string;\n /**\n * Returns a CSS selector for the TOC link. The default is unused: links\n * are found by comparing `a[href^=\"#\"]` to `#id`. A custom function\n * still runs through `querySelector` (escape any author id yourself).\n * @default id => 'a[href=\"#' + id + '\"]'\n */\n getActiveElement: (id: string) => string;\n /**\n * If true, keep the last section above the viewport active when nothing\n * intersects. If there is no such section, the first one stays active.\n * @default false\n */\n keepTopElementActive: boolean;\n}\n\nconst _defaultGetActiveElement = (id: string): string => `a[href=\"#${id}\"]`;\n\nconst _defaults: ScrollSpyOptions = {\n scrollOffset: 200,\n activeClass: 'active',\n getActiveElement: _defaultGetActiveElement,\n keepTopElementActive: false\n};\n\n/**\n * ScrollSpy. IntersectionObserver decides which section is current.\n * Hash links are left to the browser (`scroll-margin` + `scroll-behavior`).\n */\nexport class ScrollSpy extends Component<ScrollSpyOptions> {\n static _elements: ScrollSpy[] = [];\n private static _active = new Map<ScrollSpyOptions['getActiveElement'], ScrollSpy>();\n private _observer: IntersectionObserver;\n private _ratio = 0;\n private _link: Element | null = null;\n private _offset: string;\n private _offsetPriority: string;\n\n constructor(el: HTMLElement, options: Partial<ScrollSpyOptions>) {\n super(el, options, ScrollSpy);\n this.el['Expressive_ScrollSpy'] = this;\n\n this.options = {\n ...ScrollSpy.defaults,\n ...options\n };\n\n this._offset = this.el.style.getPropertyValue('--md-comp-scrollspy-offset');\n this._offsetPriority = this.el.style.getPropertyPriority('--md-comp-scrollspy-offset');\n this.el.style.setProperty(\n '--md-comp-scrollspy-offset',\n `${this.options.scrollOffset}px`\n );\n\n ScrollSpy._elements.push(this);\n if (typeof IntersectionObserver !== 'undefined') {\n this._observer = new IntersectionObserver((entries) => {\n if (ScrollSpy.getInstance(this.el) !== this) return;\n for (const entry of entries) this._ratio = entry.isIntersecting ? entry.intersectionRatio : 0;\n ScrollSpy._syncActive(this.options.getActiveElement);\n }, {\n rootMargin: `-${this.options.scrollOffset}px 0px -45% 0px`,\n threshold: [0, 0.1, 0.25, 0.5, 0.75, 1]\n });\n this._observer.observe(this.el);\n }\n }\n\n static get defaults(): ScrollSpyOptions {\n return _defaults;\n }\n\n static init(el: HTMLElement, options?: Partial<ScrollSpyOptions>): ScrollSpy;\n static init(els: InitElements<InitElement>, options?: Partial<ScrollSpyOptions>): ScrollSpy[];\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<ScrollSpyOptions> = {}\n ): ScrollSpy | ScrollSpy[] {\n return super.init(els, options, ScrollSpy);\n }\n\n static getInstance(el: HTMLElement): ScrollSpy {\n return el['Expressive_ScrollSpy'];\n }\n\n destroy() {\n const index = ScrollSpy._elements.indexOf(this);\n if (index < 0) return;\n ScrollSpy._elements.splice(index, 1);\n this._observer?.disconnect();\n const resolver = this.options.getActiveElement;\n if (ScrollSpy._active.get(resolver) === this) ScrollSpy._clearActive(resolver);\n this.el.style.setProperty('--md-comp-scrollspy-offset', this._offset, this._offsetPriority);\n this.el['Expressive_ScrollSpy'] = undefined;\n ScrollSpy._syncActive(resolver);\n }\n\n private static _syncActive(resolver: ScrollSpyOptions['getActiveElement']) {\n const elements = ScrollSpy._elements.filter(spy => spy.options.getActiveElement === resolver);\n\n let best: ScrollSpy | null = null;\n let bestRatio = 0;\n for (const spy of elements) {\n const ratio = spy._ratio;\n if (ratio > bestRatio) {\n bestRatio = ratio;\n best = spy;\n }\n }\n\n if (!best) {\n const retained = elements.filter(spy => spy.options.keepTopElementActive);\n best = ScrollSpy._nearestAbove(retained) ?? retained[0];\n }\n\n const next = best ? ScrollSpy._linkFor(best.el.id, best.options) : null;\n
|
|
5
|
-
"mappings": ";;;;;AA6BA,IAAM,2BAA2B,CAAC,OAAuB,YAAY,EAAE;AAEvE,IAAM,YAA8B;AAAA,EAClC,cAAc;AAAA,EACd,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,sBAAsB;AACxB;AAMO,IAAM,aAAN,MAAM,mBAAkB,UAA4B;AAAA,EASzD,YAAY,IAAiB,SAAoC;AAC/D,UAAM,IAAI,SAAS,UAAS;AAN9B,SAAQ,SAAS;AACjB,SAAQ,QAAwB;AAM9B,SAAK,GAAG,sBAAsB,IAAI;AAElC,SAAK,UAAU;AAAA,MACb,GAAG,WAAU;AAAA,MACb,GAAG;AAAA,IACL;AAEA,SAAK,UAAU,KAAK,GAAG,MAAM,iBAAiB,4BAA4B;AAC1E,SAAK,kBAAkB,KAAK,GAAG,MAAM,oBAAoB,4BAA4B;AACrF,SAAK,GAAG,MAAM;AAAA,MACZ;AAAA,MACA,GAAG,KAAK,QAAQ,YAAY;AAAA,IAC9B;AAEA,eAAU,UAAU,KAAK,IAAI;AAC7B,QAAI,OAAO,yBAAyB,aAAa;AAC/C,WAAK,YAAY,IAAI,qBAAqB,CAAC,YAAY;AACrD,YAAI,WAAU,YAAY,KAAK,EAAE,MAAM,KAAM;AAC7C,mBAAW,SAAS,QAAS,MAAK,SAAS,MAAM,iBAAiB,MAAM,oBAAoB;AAC5F,mBAAU,YAAY,KAAK,QAAQ,gBAAgB;AAAA,MACrD,GAAG;AAAA,QACD,YAAY,IAAI,KAAK,QAAQ,YAAY;AAAA,QACzC,WAAW,CAAC,GAAG,KAAK,MAAM,KAAK,MAAM,CAAC;AAAA,MACxC,CAAC;AACD,WAAK,UAAU,QAAQ,KAAK,EAAE;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,WAAW,WAA6B;AACtC,WAAO;AAAA,EACT;AAAA,EAIA,OAAO,KACL,KACA,UAAqC,CAAC,GACb;AACzB,WAAO,MAAM,KAAK,KAAK,SAAS,UAAS;AAAA,EAC3C;AAAA,EAEA,OAAO,YAAY,IAA4B;AAC7C,WAAO,GAAG,sBAAsB;AAAA,EAClC;AAAA,EAEA,UAAU;AACR,UAAM,QAAQ,WAAU,UAAU,QAAQ,IAAI;AAC9C,QAAI,QAAQ,EAAG;AACf,eAAU,UAAU,OAAO,OAAO,CAAC;AACnC,SAAK,WAAW,WAAW;AAC3B,UAAM,WAAW,KAAK,QAAQ;AAC9B,QAAI,WAAU,QAAQ,IAAI,QAAQ,MAAM,KAAM,YAAU,aAAa,QAAQ;AAC7E,SAAK,GAAG,MAAM,YAAY,8BAA8B,KAAK,SAAS,KAAK,eAAe;AAC1F,SAAK,GAAG,sBAAsB,IAAI;AAClC,eAAU,YAAY,QAAQ;AAAA,EAChC;AAAA,EAEA,OAAe,YAAY,UAAgD;AACzE,UAAM,WAAW,WAAU,UAAU,OAAO,SAAO,IAAI,QAAQ,qBAAqB,QAAQ;AAE5F,QAAI,OAAyB;AAC7B,QAAI,YAAY;AAChB,eAAW,OAAO,UAAU;AAC1B,YAAM,QAAQ,IAAI;AAClB,UAAI,QAAQ,WAAW;AACrB,oBAAY;AACZ,eAAO;AAAA,MACT;AAAA,IACF;AAEA,QAAI,CAAC,MAAM;AACT,YAAM,WAAW,SAAS,OAAO,SAAO,IAAI,QAAQ,oBAAoB;AACxE,aAAO,WAAU,cAAc,QAAQ,KAAK,SAAS,CAAC;AAAA,IACxD;AAEA,UAAM,
|
|
4
|
+
"sourcesContent": ["import { Component, BaseOptions, InitElements, InitElement } from '../core/component';\n\nexport interface ScrollSpyOptions extends BaseOptions {\n /**\n * Offset used as IntersectionObserver rootMargin and as\n * `--md-comp-scrollspy-offset` (scroll-margin on the section).\n * @default 200\n */\n scrollOffset: number;\n /**\n * Class applied to active elements.\n * @default 'active'\n */\n activeClass: string;\n /**\n * Returns a CSS selector for the TOC link. The default is unused: links\n * are found by comparing `a[href^=\"#\"]` to `#id`. A custom function\n * still runs through `querySelector` (escape any author id yourself).\n * @default id => 'a[href=\"#' + id + '\"]'\n */\n getActiveElement: (id: string) => string;\n /**\n * If true, keep the last section above the viewport active when nothing\n * intersects. If there is no such section, the first one stays active.\n * @default false\n */\n keepTopElementActive: boolean;\n}\n\nconst _defaultGetActiveElement = (id: string): string => `a[href=\"#${id}\"]`;\n\nconst _defaults: ScrollSpyOptions = {\n scrollOffset: 200,\n activeClass: 'active',\n getActiveElement: _defaultGetActiveElement,\n keepTopElementActive: false\n};\n\n/**\n * ScrollSpy. IntersectionObserver decides which section is current.\n * Hash links are left to the browser (`scroll-margin` + `scroll-behavior`).\n */\nexport class ScrollSpy extends Component<ScrollSpyOptions> {\n static _elements: ScrollSpy[] = [];\n private static _active = new Map<ScrollSpyOptions['getActiveElement'], ScrollSpy>();\n private _observer: IntersectionObserver;\n private _ratio = 0;\n private _link: Element | null = null;\n private _offset: string;\n private _offsetPriority: string;\n\n constructor(el: HTMLElement, options: Partial<ScrollSpyOptions>) {\n super(el, options, ScrollSpy);\n this.el['Expressive_ScrollSpy'] = this;\n\n this.options = {\n ...ScrollSpy.defaults,\n ...options\n };\n\n this._offset = this.el.style.getPropertyValue('--md-comp-scrollspy-offset');\n this._offsetPriority = this.el.style.getPropertyPriority('--md-comp-scrollspy-offset');\n this.el.style.setProperty(\n '--md-comp-scrollspy-offset',\n `${this.options.scrollOffset}px`\n );\n\n ScrollSpy._elements.push(this);\n if (typeof IntersectionObserver !== 'undefined') {\n this._observer = new IntersectionObserver((entries) => {\n if (ScrollSpy.getInstance(this.el) !== this) return;\n for (const entry of entries) this._ratio = entry.isIntersecting ? entry.intersectionRatio : 0;\n ScrollSpy._syncActive(this.options.getActiveElement);\n }, {\n rootMargin: `-${this.options.scrollOffset}px 0px -45% 0px`,\n threshold: [0, 0.1, 0.25, 0.5, 0.75, 1]\n });\n this._observer.observe(this.el);\n }\n }\n\n static get defaults(): ScrollSpyOptions {\n return _defaults;\n }\n\n static init(el: HTMLElement, options?: Partial<ScrollSpyOptions>): ScrollSpy;\n static init(els: InitElements<InitElement>, options?: Partial<ScrollSpyOptions>): ScrollSpy[];\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<ScrollSpyOptions> = {}\n ): ScrollSpy | ScrollSpy[] {\n return super.init(els, options, ScrollSpy);\n }\n\n static getInstance(el: HTMLElement): ScrollSpy {\n return el['Expressive_ScrollSpy'];\n }\n\n destroy() {\n const index = ScrollSpy._elements.indexOf(this);\n if (index < 0) return;\n ScrollSpy._elements.splice(index, 1);\n this._observer?.disconnect();\n const resolver = this.options.getActiveElement;\n if (ScrollSpy._active.get(resolver) === this) ScrollSpy._clearActive(resolver);\n this.el.style.setProperty('--md-comp-scrollspy-offset', this._offset, this._offsetPriority);\n this.el['Expressive_ScrollSpy'] = undefined;\n ScrollSpy._syncActive(resolver);\n }\n\n private static _syncActive(resolver: ScrollSpyOptions['getActiveElement']) {\n const elements = ScrollSpy._elements.filter(spy => spy.options.getActiveElement === resolver);\n\n let best: ScrollSpy | null = null;\n let bestRatio = 0;\n for (const spy of elements) {\n const ratio = spy._ratio;\n if (ratio > bestRatio) {\n bestRatio = ratio;\n best = spy;\n }\n }\n\n if (!best) {\n const retained = elements.filter(spy => spy.options.keepTopElementActive);\n best = ScrollSpy._nearestAbove(retained) ?? retained[0];\n }\n\n const active = ScrollSpy._active.get(resolver);\n // Most callbacks only move a ratio within the same section. Its link is\n // already marked, so skip the document-wide lookup.\n if (best && active === best && best._link?.isConnected) return;\n const next = best ? ScrollSpy._linkFor(best.el.id, best.options) : null;\n if (active === best && active?._link === next) return;\n ScrollSpy._clearActive(resolver);\n if (!next) return;\n next.classList.add(best.options.activeClass);\n next.setAttribute('aria-current', 'true');\n best._link = next;\n ScrollSpy._active.set(resolver, best);\n }\n\n private static _nearestAbove(elements: ScrollSpy[]): ScrollSpy | null {\n let best: ScrollSpy | null = null;\n let bestTop = -Infinity;\n for (const spy of elements) {\n const top = spy.el.getBoundingClientRect().top;\n if (top <= 0 && top >= bestTop) {\n bestTop = top;\n best = spy;\n }\n }\n return best;\n }\n\n private static _clearActive(resolver: ScrollSpyOptions['getActiveElement']) {\n const active = ScrollSpy._active.get(resolver);\n if (!active) return;\n active._link?.classList.remove(active.options.activeClass);\n active._link?.removeAttribute('aria-current');\n active._link = null;\n ScrollSpy._active.delete(resolver);\n }\n\n /**\n * Default lookup compares href attributes (no interpolated selector).\n * A custom getActiveElement still returns a selector.\n */\n static _linkFor(id: string, options: ScrollSpyOptions): Element | null {\n if (!id) return null;\n if (options.getActiveElement !== _defaultGetActiveElement) {\n try {\n return document.querySelector(options.getActiveElement(id));\n } catch {\n return null;\n }\n }\n const href = `#${id}`;\n return Array.from(document.querySelectorAll('a[href^=\"#\"]')).find(link => link.getAttribute('href') === href) ?? null;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
FormSelect
|
|
3
|
-
} from "./chunk-55IA2XUC.mjs";
|
|
4
1
|
import {
|
|
5
2
|
DockedDisplayPlugin
|
|
6
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-M3MURWMB.mjs";
|
|
4
|
+
import {
|
|
5
|
+
FormSelect
|
|
6
|
+
} from "./chunk-WDK4T63U.mjs";
|
|
7
7
|
import {
|
|
8
8
|
Utils
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-M372EDXD.mjs";
|
|
10
10
|
import {
|
|
11
11
|
Component
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-PD6HYHAE.mjs";
|
|
13
13
|
|
|
14
14
|
// src/ts/components/datepicker.ts
|
|
15
15
|
var _defaults = {
|
|
@@ -116,6 +116,10 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
116
116
|
constructor(el, options) {
|
|
117
117
|
super(el, options, _Datepicker);
|
|
118
118
|
this.multiple = false;
|
|
119
|
+
/** What setInputValue last wrote, so reading it back does not depend on the parser. */
|
|
120
|
+
this._writtenInputs = /* @__PURE__ */ new WeakMap();
|
|
121
|
+
/** Rows renderRow has already checked, so renderBody does not parse them again. */
|
|
122
|
+
this._checkedRows = /* @__PURE__ */ new Set();
|
|
119
123
|
/** Nesting depth of {@link _batchDraws}; > 0 means draws are being collected. */
|
|
120
124
|
this._drawDepth = 0;
|
|
121
125
|
/** Whether a draw was requested while batching. */
|
|
@@ -182,7 +186,9 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
182
186
|
if (maxDate && date > maxDate) date.setTime(maxDate.getTime());
|
|
183
187
|
if (date.getFullYear() < minYear || date.getFullYear() > maxYear || date.getFullYear() === minYear && date.getMonth() < (minMonth ?? 0) || date.getFullYear() === maxYear && date.getMonth() > (maxMonth ?? 11)) return;
|
|
184
188
|
this._focusedDate = date;
|
|
185
|
-
this.
|
|
189
|
+
const { year, month } = this.calendars[0];
|
|
190
|
+
if (date.getFullYear() === year && date.getMonth() === month) this._syncCalendarFocus(true);
|
|
191
|
+
else this.gotoDate(date);
|
|
186
192
|
};
|
|
187
193
|
this._handleCalendarClick = (e) => {
|
|
188
194
|
const target = e.target;
|
|
@@ -194,7 +200,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
194
200
|
e.target.getAttribute("data-month"),
|
|
195
201
|
e.target.getAttribute("data-day")
|
|
196
202
|
);
|
|
197
|
-
if (!this.multiple || this.
|
|
203
|
+
if (!this.multiple || this.options.isMultipleSelection) {
|
|
198
204
|
this.setDate(selectedDate);
|
|
199
205
|
}
|
|
200
206
|
if (this.options.isDateRange) {
|
|
@@ -292,8 +298,8 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
292
298
|
}
|
|
293
299
|
}
|
|
294
300
|
}
|
|
295
|
-
if (this.options.displayPlugin) {
|
|
296
|
-
|
|
301
|
+
if (this.options.displayPlugin === "docked") {
|
|
302
|
+
this.displayPlugin = DockedDisplayPlugin.init(this.el, this.containerEl, this.options.displayPluginOptions);
|
|
297
303
|
}
|
|
298
304
|
}
|
|
299
305
|
static get defaults() {
|
|
@@ -450,7 +456,8 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
450
456
|
this.draw();
|
|
451
457
|
return;
|
|
452
458
|
}
|
|
453
|
-
const
|
|
459
|
+
const written = !this.options.parse && this._writtenInputs.get(el);
|
|
460
|
+
const parsedDate = written && written.value === el.value ? written.date : this._parseInput(el.value);
|
|
454
461
|
if (!_Datepicker._isDate(parsedDate)) return;
|
|
455
462
|
const date = new Date(parsedDate.getTime());
|
|
456
463
|
_Datepicker._setToStartOfDay(date);
|
|
@@ -508,7 +515,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
508
515
|
setSingleDate(date, isEndDate) {
|
|
509
516
|
if (!isEndDate) {
|
|
510
517
|
this.date = date;
|
|
511
|
-
} else
|
|
518
|
+
} else {
|
|
512
519
|
this.endDate = date;
|
|
513
520
|
}
|
|
514
521
|
}
|
|
@@ -517,13 +524,11 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
517
524
|
* @param date Date to set on the datepicker.
|
|
518
525
|
*/
|
|
519
526
|
setMultiDate(date) {
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
});
|
|
523
|
-
if (!selectedDate) {
|
|
527
|
+
const index = this.dates.findIndex((item) => item.getTime() === date.getTime());
|
|
528
|
+
if (index === -1) {
|
|
524
529
|
this.dates.push(date);
|
|
525
530
|
} else {
|
|
526
|
-
this.dates.splice(
|
|
531
|
+
this.dates.splice(index, 1);
|
|
527
532
|
}
|
|
528
533
|
this.dates.sort((a, b) => a.getTime() < b.getTime() ? -1 : 0);
|
|
529
534
|
}
|
|
@@ -565,6 +570,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
565
570
|
} else {
|
|
566
571
|
el.value = this.toString(date);
|
|
567
572
|
}
|
|
573
|
+
this._writtenInputs.set(el, { value: el.value, date: _Datepicker._isDate(date) ? new Date(date.getTime()) : null });
|
|
568
574
|
el.dispatchEvent(
|
|
569
575
|
new CustomEvent("change", {
|
|
570
576
|
bubbles: true,
|
|
@@ -649,12 +655,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
649
655
|
}
|
|
650
656
|
}
|
|
651
657
|
const previousMonth = month === 0 ? 11 : month - 1, nextMonth = month === 11 ? 0 : month + 1, yearOfPreviousMonth = month === 0 ? year - 1 : year, yearOfNextMonth = month === 11 ? year + 1 : year, daysInPreviousMonth = _Datepicker._getDaysInMonth(yearOfPreviousMonth, previousMonth);
|
|
652
|
-
|
|
653
|
-
while (after > 7) {
|
|
654
|
-
after -= 7;
|
|
655
|
-
}
|
|
656
|
-
cells += 7 - after;
|
|
657
|
-
let isWeekSelected = false;
|
|
658
|
+
const cells = Math.ceil((days + before) / 7) * 7;
|
|
658
659
|
for (let i = 0, r = 0; i < cells; i++) {
|
|
659
660
|
const day = new Date(year, month, 1 + (i - before)), isToday = _Datepicker._compareDates(day, now), hasEvent = this.options.events.indexOf(day.toDateString()) !== -1, isEmpty = i < before || i >= days + before, isStartRange = this.options.startRange && _Datepicker._compareDates(this.options.startRange, day), isEndRange = this.options.endRange && _Datepicker._compareDates(this.options.endRange, day), isInRange = this.options.startRange && this.options.endRange && this.options.startRange < day && day < this.options.endRange, isDisabled = this.options.minDate && day < this.options.minDate || this.options.maxDate && day > this.options.maxDate || this.options.disableWeekends && _Datepicker._isWeekend(day) || this.options.disableDayFn && this.options.disableDayFn(day), isDateRangeStart = this.options.isDateRange && this.date && this.endDate && _Datepicker._compareDates(this.date, day), isDateRangeEnd = this.options.isDateRange && this.endDate && _Datepicker._compareDates(this.endDate, day), isDateRange = this.options.isDateRange && _Datepicker._isDate(this.date) && _Datepicker._isDate(this.endDate) && _Datepicker._compareWithinRange(day, this.date, this.endDate);
|
|
660
661
|
let dayNumber = 1 + (i - before), monthNumber = month, yearNumber = year;
|
|
@@ -698,10 +699,9 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
698
699
|
};
|
|
699
700
|
row.push(this.renderDay(dayConfig));
|
|
700
701
|
if (++r === 7) {
|
|
701
|
-
data.push(this.renderRow(row, this.options.isRTL,
|
|
702
|
+
data.push(this.renderRow(row, this.options.isRTL, false));
|
|
702
703
|
row = [];
|
|
703
704
|
r = 0;
|
|
704
|
-
isWeekSelected = false;
|
|
705
705
|
}
|
|
706
706
|
}
|
|
707
707
|
return this.renderTable(this.options, data, randId);
|
|
@@ -718,7 +718,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
718
718
|
isDateRangeStart: "is-daterange-start",
|
|
719
719
|
isDateRangeEnd: "is-daterange-end",
|
|
720
720
|
isDateRange: "is-daterange"
|
|
721
|
-
}, ariaSelected =
|
|
721
|
+
}, ariaSelected = opts.isSelected === true || opts.isDateRange === true, arr = ["datepicker-day"];
|
|
722
722
|
if (opts.isEmpty) {
|
|
723
723
|
if (opts.showDaysInNextAndPreviousMonths) {
|
|
724
724
|
arr.push("is-outside-current-month");
|
|
@@ -739,7 +739,9 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
739
739
|
}
|
|
740
740
|
/** Assemble calendar cells; reject unsupported elements and attributes. */
|
|
741
741
|
renderRow(days, isRTL, isRowSelected) {
|
|
742
|
-
|
|
742
|
+
const row = '<tr class="datepicker-row' + (isRowSelected ? " is-selected" : "") + '">' + _Datepicker._calendarMarkup((isRTL ? days.reverse() : days).join(""), "tr") + "</tr>";
|
|
743
|
+
this._checkedRows.add(row);
|
|
744
|
+
return row;
|
|
743
745
|
}
|
|
744
746
|
/** Assemble calendar rows; reject unsupported elements and attributes. */
|
|
745
747
|
renderTable(opts, data, randId) {
|
|
@@ -757,11 +759,15 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
757
759
|
}
|
|
758
760
|
/** Wrap calendar rows after validating and encoding their contents. */
|
|
759
761
|
renderBody(rows) {
|
|
760
|
-
|
|
762
|
+
const html = rows.join("");
|
|
763
|
+
const safeHtml = _Datepicker._calendarMarkup(html, "tbody");
|
|
764
|
+
this._checkedRows.clear();
|
|
765
|
+
return "<tbody>" + safeHtml + "</tbody>";
|
|
761
766
|
}
|
|
762
767
|
static _calendarMarkup(html, parent) {
|
|
763
768
|
const template = document.createElement("template");
|
|
764
769
|
template.innerHTML = html;
|
|
770
|
+
const childOf = { tbody: "tr", tr: "td", td: "button" };
|
|
765
771
|
const attributes = {
|
|
766
772
|
tr: ["class"],
|
|
767
773
|
td: ["class", "data-day", "aria-selected"],
|
|
@@ -775,8 +781,8 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
775
781
|
return _Datepicker._escape(node.textContent);
|
|
776
782
|
}
|
|
777
783
|
if (!(node instanceof HTMLElement)) throw new TypeError("Unsupported calendar row content");
|
|
778
|
-
const tag =
|
|
779
|
-
if (!tag ||
|
|
784
|
+
const tag = childOf[container];
|
|
785
|
+
if (!tag || node.localName !== tag) {
|
|
780
786
|
throw new TypeError("Unsupported calendar row element");
|
|
781
787
|
}
|
|
782
788
|
if ([...node.attributes].some((attr) => !attributes[tag].includes(attr.name))) {
|
|
@@ -900,26 +906,9 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
900
906
|
const active = this.calendarEl.getRootNode().activeElement;
|
|
901
907
|
const restoreDayFocus = active?.matches(".datepicker-day-button") && this.calendarEl.contains(active);
|
|
902
908
|
const restoreArrow = this.calendarEl.contains(active) && active?.matches(".month-prev, .month-next") ? active.classList.contains("month-prev") ? ".month-prev" : ".month-next" : null;
|
|
903
|
-
const opts = this.options, minYear = opts.minYear, maxYear = opts.maxYear, minMonth = opts.minMonth, maxMonth = opts.maxMonth;
|
|
904
|
-
if (this._y <= minYear) {
|
|
905
|
-
this._y = minYear;
|
|
906
|
-
if (!isNaN(minMonth) && this._m < minMonth) {
|
|
907
|
-
this._m = minMonth;
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
if (this._y >= maxYear) {
|
|
911
|
-
this._y = maxYear;
|
|
912
|
-
if (!isNaN(maxMonth) && this._m > maxMonth) {
|
|
913
|
-
this._m = maxMonth;
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
909
|
const year = this.calendars[0].year;
|
|
917
910
|
const month = this.calendars[0].month;
|
|
918
|
-
|
|
919
|
-
this._renderDateDisplay(this.date);
|
|
920
|
-
} else {
|
|
921
|
-
this._renderDateDisplay(this.date, this.endDate);
|
|
922
|
-
}
|
|
911
|
+
this._renderDateDisplay(this.date, this.endDate);
|
|
923
912
|
const key = this._controlsCacheKey(year);
|
|
924
913
|
if (key === this._controlsKey && this.calendarEl.querySelector(".datepicker-controls")) {
|
|
925
914
|
this._reuseControls(year, month);
|
|
@@ -974,12 +963,8 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
974
963
|
else this.calendarEl.insertAdjacentHTML("beforeend", html);
|
|
975
964
|
}
|
|
976
965
|
_setupEventHandlers() {
|
|
977
|
-
this.
|
|
978
|
-
this.
|
|
979
|
-
this.el.addEventListener("change", this._handleInputChange);
|
|
980
|
-
this.endDateEl?.addEventListener("click", this._handleInputClick);
|
|
981
|
-
this.endDateEl?.addEventListener("keydown", this._handleInputKeydown);
|
|
982
|
-
this.endDateEl?.addEventListener("change", this._handleInputChange);
|
|
966
|
+
this._addInputEventHandlers(this.el);
|
|
967
|
+
if (this.endDateEl) this._addInputEventHandlers(this.endDateEl);
|
|
983
968
|
this.calendarEl.addEventListener("click", this._handleCalendarClick);
|
|
984
969
|
this.calendarEl.addEventListener("keydown", this._handleCalendarKeydown);
|
|
985
970
|
this.calendarEl.addEventListener("focusin", this._handleCalendarFocus);
|
|
@@ -1036,6 +1021,11 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
1036
1021
|
this._removeInputEventHandlers(this.endDateEl);
|
|
1037
1022
|
}
|
|
1038
1023
|
}
|
|
1024
|
+
_addInputEventHandlers(input) {
|
|
1025
|
+
input.addEventListener("click", this._handleInputClick);
|
|
1026
|
+
input.addEventListener("keydown", this._handleInputKeydown);
|
|
1027
|
+
input.addEventListener("change", this._handleInputChange);
|
|
1028
|
+
}
|
|
1039
1029
|
_removeInputEventHandlers(input) {
|
|
1040
1030
|
input.removeEventListener("click", this._handleInputClick);
|
|
1041
1031
|
input.removeEventListener("keydown", this._handleInputKeydown);
|
|
@@ -1092,9 +1082,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
1092
1082
|
const dateInput = this.el.cloneNode(true);
|
|
1093
1083
|
dateInput.removeAttribute("id");
|
|
1094
1084
|
dateInput.classList.add("no-autoinit");
|
|
1095
|
-
|
|
1096
|
-
dateInput.addEventListener("keydown", this._handleInputKeydown);
|
|
1097
|
-
dateInput.addEventListener("change", this._handleInputChange);
|
|
1085
|
+
this._addInputEventHandlers(dateInput);
|
|
1098
1086
|
this.el.parentElement.appendChild(dateInput);
|
|
1099
1087
|
return dateInput;
|
|
1100
1088
|
}
|
|
@@ -1115,4 +1103,4 @@ var Datepicker = _Datepicker;
|
|
|
1115
1103
|
export {
|
|
1116
1104
|
Datepicker
|
|
1117
1105
|
};
|
|
1118
|
-
//# sourceMappingURL=chunk-
|
|
1106
|
+
//# sourceMappingURL=chunk-GJL6GCIU.mjs.map
|