@expressivecss/expressive 0.14.1 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +88 -1
- package/README.md +1 -1
- package/dist/css/expressive.css +200 -241
- package/dist/css/expressive.css.map +1 -1
- package/dist/css/expressive.min.css +1 -1
- package/dist/css/expressive.min.css.map +1 -1
- package/dist/js/chunks/{chunk-4KMNFIFZ.mjs → chunk-33QVDDGR.mjs} +3 -3
- package/dist/js/chunks/{chunk-SPETGK25.mjs → chunk-45FER6RI.mjs} +5 -5
- package/dist/js/chunks/chunk-45FER6RI.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GIW4K4SE.mjs → chunk-5CEAOLUA.mjs} +11 -10
- package/dist/js/chunks/{chunk-GIW4K4SE.mjs.map → chunk-5CEAOLUA.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-LRZMJZ3T.mjs → chunk-6VATUZC6.mjs} +10 -6
- package/dist/js/chunks/chunk-6VATUZC6.mjs.map +7 -0
- package/dist/js/chunks/{chunk-QDAL4IYN.mjs → chunk-74MXKKLN.mjs} +2 -2
- package/dist/js/chunks/{chunk-QDAL4IYN.mjs.map → chunk-74MXKKLN.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-CUQPB25U.mjs → chunk-AIURVCG6.mjs} +3 -3
- package/dist/js/chunks/{chunk-KHV6DZXX.mjs → chunk-BGZLF6JZ.mjs} +16 -16
- package/dist/js/chunks/chunk-BGZLF6JZ.mjs.map +7 -0
- package/dist/js/chunks/{chunk-BG6ZRB5H.mjs → chunk-C6CHEWYP.mjs} +2 -2
- package/dist/js/chunks/{chunk-GVGT6MIU.mjs → chunk-CK2XCICY.mjs} +2 -2
- package/dist/js/chunks/{chunk-KY6U46SM.mjs → chunk-CXXM2L4F.mjs} +8 -9
- package/dist/js/chunks/chunk-CXXM2L4F.mjs.map +7 -0
- package/dist/js/chunks/{chunk-Z2NRKI7R.mjs → chunk-DXGRXYYL.mjs} +25 -37
- package/dist/js/chunks/chunk-DXGRXYYL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-MZ6Z24BX.mjs → chunk-FM5CZOUB.mjs} +3 -7
- package/dist/js/chunks/{chunk-MZ6Z24BX.mjs.map → chunk-FM5CZOUB.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-5HQSGDZ5.mjs → chunk-GJL6GCIU.mjs} +34 -55
- package/dist/js/chunks/chunk-GJL6GCIU.mjs.map +7 -0
- package/dist/js/chunks/chunk-K3HZMFMD.mjs +135 -0
- package/dist/js/chunks/chunk-K3HZMFMD.mjs.map +7 -0
- package/dist/js/chunks/{chunk-TBM3FT7G.mjs → chunk-KHXZ2A4K.mjs} +12 -15
- package/dist/js/chunks/{chunk-TBM3FT7G.mjs.map → chunk-KHXZ2A4K.mjs.map} +2 -2
- package/dist/js/chunks/chunk-KQACNQ22.mjs +7 -0
- package/dist/js/chunks/{chunk-KBNN3QDH.mjs.map → chunk-KQACNQ22.mjs.map} +1 -1
- package/dist/js/chunks/{chunk-UEXCIMJZ.mjs → chunk-KUFHW3DS.mjs} +2 -2
- package/dist/js/chunks/{chunk-A7ALMYUR.mjs → chunk-KVJAVDBC.mjs} +7 -15
- package/dist/js/chunks/chunk-KVJAVDBC.mjs.map +7 -0
- package/dist/js/chunks/{chunk-YDCS5S3J.mjs → chunk-L27Q6ZMI.mjs} +2 -2
- package/dist/js/chunks/{chunk-NS2UMNZV.mjs → chunk-LQWUDNHZ.mjs} +3 -3
- package/dist/js/chunks/{chunk-MNPROCZF.mjs → chunk-M372EDXD.mjs} +4 -10
- package/dist/js/chunks/chunk-M372EDXD.mjs.map +7 -0
- package/dist/js/chunks/{chunk-YMSXJON6.mjs → chunk-M3MURWMB.mjs} +15 -12
- package/dist/js/chunks/{chunk-YMSXJON6.mjs.map → chunk-M3MURWMB.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-JIDMQGK6.mjs → chunk-NUHMOAOY.mjs} +18 -33
- package/dist/js/chunks/chunk-NUHMOAOY.mjs.map +7 -0
- package/dist/js/chunks/{chunk-VGZSAFTX.mjs → chunk-OWG3LMUL.mjs} +7 -11
- package/dist/js/chunks/chunk-OWG3LMUL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-LTWPGFBR.mjs → chunk-PD6HYHAE.mjs} +4 -15
- package/dist/js/chunks/chunk-PD6HYHAE.mjs.map +7 -0
- package/dist/js/chunks/{chunk-ZAS25YFD.mjs → chunk-PDG64UHF.mjs} +3 -3
- package/dist/js/chunks/{chunk-QERLECVU.mjs → chunk-PO3AXVR3.mjs} +38 -64
- package/dist/js/chunks/chunk-PO3AXVR3.mjs.map +7 -0
- package/dist/js/chunks/{chunk-ILP3PDTL.mjs → chunk-QYGK36OG.mjs} +7 -13
- package/dist/js/chunks/chunk-QYGK36OG.mjs.map +7 -0
- package/dist/js/chunks/{chunk-S3XDFGSZ.mjs → chunk-SFI2U4YW.mjs} +28 -44
- package/dist/js/chunks/chunk-SFI2U4YW.mjs.map +7 -0
- package/dist/js/chunks/{chunk-FS7XY3HT.mjs → chunk-SMY7GJSS.mjs} +3 -3
- package/dist/js/chunks/{chunk-O5XPWXIQ.mjs → chunk-TCCA2HDG.mjs} +39 -31
- package/dist/js/chunks/chunk-TCCA2HDG.mjs.map +7 -0
- package/dist/js/chunks/{chunk-PM655FXL.mjs → chunk-TSZYSW7F.mjs} +4 -4
- package/dist/js/chunks/{chunk-PM655FXL.mjs.map → chunk-TSZYSW7F.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-UEZUJQ66.mjs → chunk-UAZSDUVP.mjs} +3 -4
- package/dist/js/chunks/{chunk-UEZUJQ66.mjs.map → chunk-UAZSDUVP.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-6N2XAEFK.mjs → chunk-UBRZZWRA.mjs} +10 -8
- package/dist/js/chunks/chunk-UBRZZWRA.mjs.map +7 -0
- package/dist/js/chunks/{chunk-5BKHWHYY.mjs → chunk-UCOE7ZDL.mjs} +41 -46
- package/dist/js/chunks/chunk-UCOE7ZDL.mjs.map +7 -0
- package/dist/js/chunks/{chunk-4TKTLGEM.mjs → chunk-UETTGDLI.mjs} +3 -3
- package/dist/js/chunks/{chunk-RHRQKTTX.mjs → chunk-UNCRDLP6.mjs} +6 -9
- package/dist/js/chunks/chunk-UNCRDLP6.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GUB3TNO2.mjs → chunk-VGNYF6FB.mjs} +3 -6
- package/dist/js/chunks/{chunk-GUB3TNO2.mjs.map → chunk-VGNYF6FB.mjs.map} +2 -2
- package/dist/js/chunks/{chunk-X7OCHZVF.mjs → chunk-VGPGBNGL.mjs} +4 -12
- package/dist/js/chunks/chunk-VGPGBNGL.mjs.map +7 -0
- package/dist/js/chunks/chunk-VKAUVTQY.mjs +1 -0
- package/dist/js/chunks/{chunk-HKT2S7VM.mjs → chunk-VM4FTS7L.mjs} +3 -3
- package/dist/js/chunks/{chunk-3GVFZ4XO.mjs → chunk-WDK4T63U.mjs} +8 -11
- package/dist/js/chunks/chunk-WDK4T63U.mjs.map +7 -0
- package/dist/js/chunks/{chunk-GZKEFWPM.mjs → chunk-WOCCTVUF.mjs} +38 -34
- package/dist/js/chunks/chunk-WOCCTVUF.mjs.map +7 -0
- package/dist/js/chunks/{chunk-QJABDLSD.mjs → chunk-WQYN5L4E.mjs} +11 -16
- package/dist/js/chunks/chunk-WQYN5L4E.mjs.map +7 -0
- package/dist/js/chunks/{chunk-DAIU5SLG.mjs → chunk-X4ISMKE2.mjs} +2 -2
- package/dist/js/chunks/{chunk-3DHK5CZU.mjs → chunk-XAEAEHIX.mjs} +6 -8
- package/dist/js/chunks/chunk-XAEAEHIX.mjs.map +7 -0
- package/dist/js/chunks/{chunk-4HZMB7LI.mjs → chunk-ZX6M7SWO.mjs} +24 -24
- package/dist/js/chunks/chunk-ZX6M7SWO.mjs.map +7 -0
- package/dist/js/expressive.cjs +484 -507
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +484 -507
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +10 -13
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +54 -50
- package/dist/js/expressive.mjs.map +1 -1
- package/dist/js/internal/behaviors/bottomSheets.mjs +3 -3
- package/dist/js/internal/behaviors/dialogs.mjs +2 -2
- package/dist/js/internal/behaviors/forms.mjs +2 -2
- package/dist/js/internal/behaviors/sheetDrag.mjs +2 -2
- package/dist/js/internal/behaviors/sideSheets.mjs +3 -3
- package/dist/js/internal/components/appBar.mjs +2 -2
- package/dist/js/internal/components/autocomplete.mjs +4 -4
- package/dist/js/internal/components/barChart.mjs +4 -4
- package/dist/js/internal/components/buttonGroup.mjs +2 -2
- package/dist/js/internal/components/buttons.mjs +3 -3
- package/dist/js/internal/components/cards.mjs +3 -3
- package/dist/js/internal/components/carousel.mjs +3 -3
- package/dist/js/internal/components/characterCounter.mjs +2 -2
- package/dist/js/internal/components/chips.mjs +5 -5
- package/dist/js/internal/components/columnChart.mjs +3 -3
- package/dist/js/internal/components/commandPalette.mjs +3 -3
- package/dist/js/internal/components/confetti.mjs +2 -2
- package/dist/js/internal/components/datepicker.mjs +6 -6
- package/dist/js/internal/components/expandingCard.mjs +3 -3
- package/dist/js/internal/components/heatmapChart.mjs +3 -3
- package/dist/js/internal/components/index.mjs +47 -43
- package/dist/js/internal/components/keypad.mjs +9 -0
- package/dist/js/internal/components/keypad.mjs.map +7 -0
- package/dist/js/internal/components/lightbox.mjs +3 -3
- package/dist/js/internal/components/lineChart.mjs +6 -2
- package/dist/js/internal/components/mapView.mjs +3 -3
- package/dist/js/internal/components/menu.mjs +3 -3
- package/dist/js/internal/components/messageScroller.mjs +3 -3
- package/dist/js/internal/components/mixedChart.mjs +4 -4
- package/dist/js/internal/components/navigationRail.mjs +2 -2
- package/dist/js/internal/components/particles.mjs +2 -2
- package/dist/js/internal/components/pieChart.mjs +3 -3
- package/dist/js/internal/components/questionnaire.mjs +3 -3
- package/dist/js/internal/components/radarChart.mjs +3 -3
- package/dist/js/internal/components/radialChart.mjs +3 -3
- package/dist/js/internal/components/registry.mjs +41 -40
- package/dist/js/internal/components/richTextEditor.mjs +3 -3
- package/dist/js/internal/components/scrollspy.mjs +2 -2
- package/dist/js/internal/components/select.mjs +4 -4
- package/dist/js/internal/components/slider.mjs +3 -3
- package/dist/js/internal/components/snackbar.mjs +2 -2
- package/dist/js/internal/components/tabs.mjs +4 -4
- package/dist/js/internal/components/timepicker.mjs +4 -4
- package/dist/js/internal/components/tooltip.mjs +3 -3
- package/dist/js/internal/core/component.mjs +1 -1
- package/dist/js/internal/core/utils.mjs +1 -1
- package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +2 -2
- package/dist/js/modular.mjs +54 -50
- package/dist/types/components/autocomplete.d.ts +1 -0
- package/dist/types/components/datepicker.d.ts +3 -4
- package/dist/types/components/expandingCard.d.ts +2 -0
- package/dist/types/components/index.d.ts +1 -0
- package/dist/types/components/keypad.d.ts +34 -0
- package/dist/types/components/lightbox.d.ts +3 -5
- package/dist/types/components/lineChart.d.ts +4 -0
- package/dist/types/components/menu.d.ts +1 -0
- package/dist/types/components/radialChart.d.ts +0 -1
- package/dist/types/components/registry.d.ts +4 -0
- package/dist/types/components/slider.d.ts +2 -0
- package/dist/types/components/snackbar.d.ts +1 -0
- package/dist/types/components/tabs.d.ts +4 -0
- package/dist/types/components/timepicker.d.ts +2 -0
- package/dist/types/modular.d.ts +1 -1
- package/dist/types/plugins/dockedDisplayPlugin.d.ts +1 -0
- package/package.json +1 -1
- package/src/sass/abstracts/_breakpoints.scss +0 -1
- package/src/sass/abstracts/_elevation.scss +1 -1
- package/src/sass/abstracts/_mixins.scss +20 -60
- package/src/sass/abstracts/_variables.scss +10 -0
- package/src/sass/base/_global.scss +3 -12
- package/src/sass/base/_index.scss +1 -1
- package/src/sass/components/_badges.scss +1 -8
- package/src/sass/components/_bar-chart.scss +1 -1
- package/src/sass/components/_button-groups.scss +31 -66
- package/src/sass/components/_cards.scss +6 -25
- package/src/sass/components/_carousel.scss +16 -55
- package/src/sass/components/_chips.scss +0 -6
- package/src/sass/components/_column-chart.scss +1 -1
- package/src/sass/components/_data-table.scss +1 -3
- package/src/sass/components/_datepicker.scss +3 -22
- package/src/sass/components/_dialog.scss +1 -4
- package/src/sass/components/_heatmap-chart.scss +2 -2
- package/src/sass/components/_icon-buttons.scss +0 -1
- package/src/sass/components/_index.scss +1 -0
- package/src/sass/components/_keypad.scss +162 -0
- package/src/sass/components/_lightbox.scss +3 -8
- package/src/sass/components/_map.scss +2 -2
- package/src/sass/components/_menu.scss +31 -74
- package/src/sass/components/_mixed-chart.scss +1 -1
- package/src/sass/components/_navbar.scss +9 -45
- package/src/sass/components/_navigation-rail.scss +23 -32
- package/src/sass/components/_page-footer.scss +15 -12
- package/src/sass/components/_panes.scss +2 -6
- package/src/sass/components/_progress.scss +6 -4
- package/src/sass/components/_side-sheet.scss +1 -4
- package/src/sass/components/_stepper.scss +0 -4
- package/src/sass/components/_timepicker.scss +4 -36
- package/src/sass/components/_toolbar.scss +0 -4
- package/src/sass/components/forms/_checkboxes.scss +37 -65
- package/src/sass/components/forms/_fieldset.scss +3 -3
- package/src/sass/components/forms/_file-input.scss +0 -1
- package/src/sass/components/forms/_radio-buttons.scss +10 -36
- package/src/sass/components/forms/_select.scss +0 -3
- package/src/sass/components/forms/_slider.scss +72 -259
- package/src/sass/tokens/_state.scss +2 -2
- package/src/sass/tokens/_theme.scss +1 -1
- package/src/sass/utilities/_colors.scss +6 -1
- package/src/sass/utilities/_index.scss +1 -1
- package/dist/js/chunks/chunk-3DHK5CZU.mjs.map +0 -7
- package/dist/js/chunks/chunk-3GVFZ4XO.mjs.map +0 -7
- package/dist/js/chunks/chunk-4HZMB7LI.mjs.map +0 -7
- package/dist/js/chunks/chunk-5BKHWHYY.mjs.map +0 -7
- package/dist/js/chunks/chunk-5HQSGDZ5.mjs.map +0 -7
- package/dist/js/chunks/chunk-6N2XAEFK.mjs.map +0 -7
- package/dist/js/chunks/chunk-A7ALMYUR.mjs.map +0 -7
- package/dist/js/chunks/chunk-GZKEFWPM.mjs.map +0 -7
- package/dist/js/chunks/chunk-ILP3PDTL.mjs.map +0 -7
- package/dist/js/chunks/chunk-JIDMQGK6.mjs.map +0 -7
- package/dist/js/chunks/chunk-KBNN3QDH.mjs +0 -7
- package/dist/js/chunks/chunk-KHV6DZXX.mjs.map +0 -7
- package/dist/js/chunks/chunk-KY6U46SM.mjs.map +0 -7
- package/dist/js/chunks/chunk-LRZMJZ3T.mjs.map +0 -7
- package/dist/js/chunks/chunk-LTWPGFBR.mjs.map +0 -7
- package/dist/js/chunks/chunk-MNPROCZF.mjs.map +0 -7
- package/dist/js/chunks/chunk-O5XPWXIQ.mjs.map +0 -7
- package/dist/js/chunks/chunk-QERLECVU.mjs.map +0 -7
- package/dist/js/chunks/chunk-QJABDLSD.mjs.map +0 -7
- package/dist/js/chunks/chunk-RHRQKTTX.mjs.map +0 -7
- package/dist/js/chunks/chunk-S3XDFGSZ.mjs.map +0 -7
- package/dist/js/chunks/chunk-SPETGK25.mjs.map +0 -7
- package/dist/js/chunks/chunk-VGZSAFTX.mjs.map +0 -7
- package/dist/js/chunks/chunk-X7OCHZVF.mjs.map +0 -7
- package/dist/js/chunks/chunk-Z2NRKI7R.mjs.map +0 -7
- package/dist/js/chunks/chunk-ZKZKNSLC.mjs +0 -1
- /package/dist/js/chunks/{chunk-4KMNFIFZ.mjs.map → chunk-33QVDDGR.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-CUQPB25U.mjs.map → chunk-AIURVCG6.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-BG6ZRB5H.mjs.map → chunk-C6CHEWYP.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-GVGT6MIU.mjs.map → chunk-CK2XCICY.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-UEXCIMJZ.mjs.map → chunk-KUFHW3DS.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-YDCS5S3J.mjs.map → chunk-L27Q6ZMI.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-NS2UMNZV.mjs.map → chunk-LQWUDNHZ.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-ZAS25YFD.mjs.map → chunk-PDG64UHF.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-FS7XY3HT.mjs.map → chunk-SMY7GJSS.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-4TKTLGEM.mjs.map → chunk-UETTGDLI.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-ZKZKNSLC.mjs.map → chunk-VKAUVTQY.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-HKT2S7VM.mjs.map → chunk-VM4FTS7L.mjs.map} +0 -0
- /package/dist/js/chunks/{chunk-DAIU5SLG.mjs.map → chunk-X4ISMKE2.mjs.map} +0 -0
|
@@ -1,7 +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 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
|
|
5
|
-
"mappings": "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
|
|
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
1
|
import {
|
|
2
2
|
DockedDisplayPlugin
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-M3MURWMB.mjs";
|
|
4
4
|
import {
|
|
5
5
|
FormSelect
|
|
6
|
-
} from "./chunk-
|
|
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,8 @@ 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();
|
|
119
121
|
/** Rows renderRow has already checked, so renderBody does not parse them again. */
|
|
120
122
|
this._checkedRows = /* @__PURE__ */ new Set();
|
|
121
123
|
/** Nesting depth of {@link _batchDraws}; > 0 means draws are being collected. */
|
|
@@ -198,7 +200,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
198
200
|
e.target.getAttribute("data-month"),
|
|
199
201
|
e.target.getAttribute("data-day")
|
|
200
202
|
);
|
|
201
|
-
if (!this.multiple || this.
|
|
203
|
+
if (!this.multiple || this.options.isMultipleSelection) {
|
|
202
204
|
this.setDate(selectedDate);
|
|
203
205
|
}
|
|
204
206
|
if (this.options.isDateRange) {
|
|
@@ -296,8 +298,8 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
296
298
|
}
|
|
297
299
|
}
|
|
298
300
|
}
|
|
299
|
-
if (this.options.displayPlugin) {
|
|
300
|
-
|
|
301
|
+
if (this.options.displayPlugin === "docked") {
|
|
302
|
+
this.displayPlugin = DockedDisplayPlugin.init(this.el, this.containerEl, this.options.displayPluginOptions);
|
|
301
303
|
}
|
|
302
304
|
}
|
|
303
305
|
static get defaults() {
|
|
@@ -454,7 +456,8 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
454
456
|
this.draw();
|
|
455
457
|
return;
|
|
456
458
|
}
|
|
457
|
-
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);
|
|
458
461
|
if (!_Datepicker._isDate(parsedDate)) return;
|
|
459
462
|
const date = new Date(parsedDate.getTime());
|
|
460
463
|
_Datepicker._setToStartOfDay(date);
|
|
@@ -512,7 +515,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
512
515
|
setSingleDate(date, isEndDate) {
|
|
513
516
|
if (!isEndDate) {
|
|
514
517
|
this.date = date;
|
|
515
|
-
} else
|
|
518
|
+
} else {
|
|
516
519
|
this.endDate = date;
|
|
517
520
|
}
|
|
518
521
|
}
|
|
@@ -521,13 +524,11 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
521
524
|
* @param date Date to set on the datepicker.
|
|
522
525
|
*/
|
|
523
526
|
setMultiDate(date) {
|
|
524
|
-
const
|
|
525
|
-
|
|
526
|
-
});
|
|
527
|
-
if (!selectedDate) {
|
|
527
|
+
const index = this.dates.findIndex((item) => item.getTime() === date.getTime());
|
|
528
|
+
if (index === -1) {
|
|
528
529
|
this.dates.push(date);
|
|
529
530
|
} else {
|
|
530
|
-
this.dates.splice(
|
|
531
|
+
this.dates.splice(index, 1);
|
|
531
532
|
}
|
|
532
533
|
this.dates.sort((a, b) => a.getTime() < b.getTime() ? -1 : 0);
|
|
533
534
|
}
|
|
@@ -569,6 +570,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
569
570
|
} else {
|
|
570
571
|
el.value = this.toString(date);
|
|
571
572
|
}
|
|
573
|
+
this._writtenInputs.set(el, { value: el.value, date: _Datepicker._isDate(date) ? new Date(date.getTime()) : null });
|
|
572
574
|
el.dispatchEvent(
|
|
573
575
|
new CustomEvent("change", {
|
|
574
576
|
bubbles: true,
|
|
@@ -653,12 +655,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
653
655
|
}
|
|
654
656
|
}
|
|
655
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);
|
|
656
|
-
|
|
657
|
-
while (after > 7) {
|
|
658
|
-
after -= 7;
|
|
659
|
-
}
|
|
660
|
-
cells += 7 - after;
|
|
661
|
-
let isWeekSelected = false;
|
|
658
|
+
const cells = Math.ceil((days + before) / 7) * 7;
|
|
662
659
|
for (let i = 0, r = 0; i < cells; i++) {
|
|
663
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);
|
|
664
661
|
let dayNumber = 1 + (i - before), monthNumber = month, yearNumber = year;
|
|
@@ -702,10 +699,9 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
702
699
|
};
|
|
703
700
|
row.push(this.renderDay(dayConfig));
|
|
704
701
|
if (++r === 7) {
|
|
705
|
-
data.push(this.renderRow(row, this.options.isRTL,
|
|
702
|
+
data.push(this.renderRow(row, this.options.isRTL, false));
|
|
706
703
|
row = [];
|
|
707
704
|
r = 0;
|
|
708
|
-
isWeekSelected = false;
|
|
709
705
|
}
|
|
710
706
|
}
|
|
711
707
|
return this.renderTable(this.options, data, randId);
|
|
@@ -722,7 +718,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
722
718
|
isDateRangeStart: "is-daterange-start",
|
|
723
719
|
isDateRangeEnd: "is-daterange-end",
|
|
724
720
|
isDateRange: "is-daterange"
|
|
725
|
-
}, ariaSelected =
|
|
721
|
+
}, ariaSelected = opts.isSelected === true || opts.isDateRange === true, arr = ["datepicker-day"];
|
|
726
722
|
if (opts.isEmpty) {
|
|
727
723
|
if (opts.showDaysInNextAndPreviousMonths) {
|
|
728
724
|
arr.push("is-outside-current-month");
|
|
@@ -764,13 +760,14 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
764
760
|
/** Wrap calendar rows after validating and encoding their contents. */
|
|
765
761
|
renderBody(rows) {
|
|
766
762
|
const html = rows.join("");
|
|
767
|
-
const
|
|
763
|
+
const safeHtml = _Datepicker._calendarMarkup(html, "tbody");
|
|
768
764
|
this._checkedRows.clear();
|
|
769
|
-
return "<tbody>" +
|
|
765
|
+
return "<tbody>" + safeHtml + "</tbody>";
|
|
770
766
|
}
|
|
771
767
|
static _calendarMarkup(html, parent) {
|
|
772
768
|
const template = document.createElement("template");
|
|
773
769
|
template.innerHTML = html;
|
|
770
|
+
const childOf = { tbody: "tr", tr: "td", td: "button" };
|
|
774
771
|
const attributes = {
|
|
775
772
|
tr: ["class"],
|
|
776
773
|
td: ["class", "data-day", "aria-selected"],
|
|
@@ -784,8 +781,8 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
784
781
|
return _Datepicker._escape(node.textContent);
|
|
785
782
|
}
|
|
786
783
|
if (!(node instanceof HTMLElement)) throw new TypeError("Unsupported calendar row content");
|
|
787
|
-
const tag =
|
|
788
|
-
if (!tag ||
|
|
784
|
+
const tag = childOf[container];
|
|
785
|
+
if (!tag || node.localName !== tag) {
|
|
789
786
|
throw new TypeError("Unsupported calendar row element");
|
|
790
787
|
}
|
|
791
788
|
if ([...node.attributes].some((attr) => !attributes[tag].includes(attr.name))) {
|
|
@@ -909,26 +906,9 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
909
906
|
const active = this.calendarEl.getRootNode().activeElement;
|
|
910
907
|
const restoreDayFocus = active?.matches(".datepicker-day-button") && this.calendarEl.contains(active);
|
|
911
908
|
const restoreArrow = this.calendarEl.contains(active) && active?.matches(".month-prev, .month-next") ? active.classList.contains("month-prev") ? ".month-prev" : ".month-next" : null;
|
|
912
|
-
const opts = this.options, minYear = opts.minYear, maxYear = opts.maxYear, minMonth = opts.minMonth, maxMonth = opts.maxMonth;
|
|
913
|
-
if (this._y <= minYear) {
|
|
914
|
-
this._y = minYear;
|
|
915
|
-
if (!isNaN(minMonth) && this._m < minMonth) {
|
|
916
|
-
this._m = minMonth;
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
if (this._y >= maxYear) {
|
|
920
|
-
this._y = maxYear;
|
|
921
|
-
if (!isNaN(maxMonth) && this._m > maxMonth) {
|
|
922
|
-
this._m = maxMonth;
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
909
|
const year = this.calendars[0].year;
|
|
926
910
|
const month = this.calendars[0].month;
|
|
927
|
-
|
|
928
|
-
this._renderDateDisplay(this.date);
|
|
929
|
-
} else {
|
|
930
|
-
this._renderDateDisplay(this.date, this.endDate);
|
|
931
|
-
}
|
|
911
|
+
this._renderDateDisplay(this.date, this.endDate);
|
|
932
912
|
const key = this._controlsCacheKey(year);
|
|
933
913
|
if (key === this._controlsKey && this.calendarEl.querySelector(".datepicker-controls")) {
|
|
934
914
|
this._reuseControls(year, month);
|
|
@@ -983,12 +963,8 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
983
963
|
else this.calendarEl.insertAdjacentHTML("beforeend", html);
|
|
984
964
|
}
|
|
985
965
|
_setupEventHandlers() {
|
|
986
|
-
this.
|
|
987
|
-
this.
|
|
988
|
-
this.el.addEventListener("change", this._handleInputChange);
|
|
989
|
-
this.endDateEl?.addEventListener("click", this._handleInputClick);
|
|
990
|
-
this.endDateEl?.addEventListener("keydown", this._handleInputKeydown);
|
|
991
|
-
this.endDateEl?.addEventListener("change", this._handleInputChange);
|
|
966
|
+
this._addInputEventHandlers(this.el);
|
|
967
|
+
if (this.endDateEl) this._addInputEventHandlers(this.endDateEl);
|
|
992
968
|
this.calendarEl.addEventListener("click", this._handleCalendarClick);
|
|
993
969
|
this.calendarEl.addEventListener("keydown", this._handleCalendarKeydown);
|
|
994
970
|
this.calendarEl.addEventListener("focusin", this._handleCalendarFocus);
|
|
@@ -1045,6 +1021,11 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
1045
1021
|
this._removeInputEventHandlers(this.endDateEl);
|
|
1046
1022
|
}
|
|
1047
1023
|
}
|
|
1024
|
+
_addInputEventHandlers(input) {
|
|
1025
|
+
input.addEventListener("click", this._handleInputClick);
|
|
1026
|
+
input.addEventListener("keydown", this._handleInputKeydown);
|
|
1027
|
+
input.addEventListener("change", this._handleInputChange);
|
|
1028
|
+
}
|
|
1048
1029
|
_removeInputEventHandlers(input) {
|
|
1049
1030
|
input.removeEventListener("click", this._handleInputClick);
|
|
1050
1031
|
input.removeEventListener("keydown", this._handleInputKeydown);
|
|
@@ -1101,9 +1082,7 @@ var _Datepicker = class _Datepicker extends Component {
|
|
|
1101
1082
|
const dateInput = this.el.cloneNode(true);
|
|
1102
1083
|
dateInput.removeAttribute("id");
|
|
1103
1084
|
dateInput.classList.add("no-autoinit");
|
|
1104
|
-
|
|
1105
|
-
dateInput.addEventListener("keydown", this._handleInputKeydown);
|
|
1106
|
-
dateInput.addEventListener("change", this._handleInputChange);
|
|
1085
|
+
this._addInputEventHandlers(dateInput);
|
|
1107
1086
|
this.el.parentElement.appendChild(dateInput);
|
|
1108
1087
|
return dateInput;
|
|
1109
1088
|
}
|
|
@@ -1124,4 +1103,4 @@ var Datepicker = _Datepicker;
|
|
|
1124
1103
|
export {
|
|
1125
1104
|
Datepicker
|
|
1126
1105
|
};
|
|
1127
|
-
//# sourceMappingURL=chunk-
|
|
1106
|
+
//# sourceMappingURL=chunk-GJL6GCIU.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ts/components/datepicker.ts"],
|
|
4
|
+
"sourcesContent": ["import { Utils } from '../core/utils';\nimport { FormSelect } from './select';\nimport { BaseOptions, Component, I18nOptions, InitElements, InitElement } from '../core/component';\nimport { DockedDisplayPlugin } from '../plugins/dockedDisplayPlugin';\n\nexport interface DateI18nOptions extends I18nOptions {\n previousMonth: string;\n nextMonth: string;\n months: string[];\n monthsShort: string[];\n weekdays: string[];\n weekdaysShort: string[];\n weekdaysAbbrev: string[];\n}\n\nexport interface DatepickerOptions extends BaseOptions {\n /**\n * The date output format for the input field value\n * or a function taking the date and outputting the\n * formatted date string.\n * @default 'mmm dd, yyyy'\n */\n format: string | ((d: Date) => string);\n /**\n * Used to create date object from current input string.\n * Receives the format string, or an empty string when format is a function.\n * Not called for blank input.\n * @default null\n */\n parse: ((value: string, format: string) => Date) | null;\n /**\n * The initial condition if the datepicker is based on date range.\n * @default false\n */\n isDateRange: boolean;\n /**\n * The selector of the user specified date range end element\n */\n dateRangeEndEl: string | null;\n /**\n * The initial condition if the datepicker is based on multiple date selection.\n * @default false\n */\n isMultipleSelection: boolean;\n /**\n * The initial date to view when first opened.\n * @default null\n */\n defaultDate: Date | null;\n /**\n * The initial end date to view when first opened.\n * @default null\n */\n defaultEndDate: Date | null;\n /**\n * Make the `defaultDate` the initial selected value.\n * @default false\n */\n setDefaultDate: boolean;\n /**\n * Make the `defaultEndDate` the initial selected value.\n * @default false\n */\n setDefaultEndDate: boolean;\n /**\n * Prevent selection of any date on the weekend.\n * @default false\n */\n disableWeekends: boolean;\n /**\n * Custom function to disable certain days.\n * @default null\n */\n disableDayFn: ((day: Date) => boolean) | null;\n /**\n * First day of week (0: Sunday, 1: Monday etc).\n * @default 0\n */\n firstDay: number;\n /**\n * The earliest date that can be selected.\n * @default null\n */\n minDate: Date | null;\n /**\n * The latest date that can be selected.\n * @default null\n */\n maxDate: Date | null;\n /**\n * Number of years either side, or array of upper/lower range.\n * @default 10\n */\n yearRange: number | number[];\n /**\n * Sort year range in reverse order.\n * @default false\n */\n yearRangeReverse: boolean;\n /**\n * Changes Datepicker to RTL.\n * @default false\n */\n isRTL: boolean;\n /**\n * Show month after year in Datepicker title.\n * @default false\n */\n showMonthAfterYear: boolean;\n /**\n * Render days of the calendar grid that fall in the next\n * or previous month.\n * @default false\n */\n showDaysInNextAndPreviousMonths: boolean;\n /**\n * Specify if the docked datepicker is in open state by default\n */\n openByDefault: boolean;\n /**\n * Specify a DOM element OR selector for a DOM element to render\n * the calendar in, by default it will be placed before the input.\n * @default null\n */\n container: HTMLElement | string | null;\n /**\n * Show the clear button in the datepicker.\n * @default false\n */\n showClearBtn: boolean;\n /**\n * Autosubmit calendar day select to input field\n * @default true\n */\n autoSubmit: boolean;\n /**\n * Internationalization options.\n */\n i18n: Partial<DateI18nOptions>;\n /**\n * An array of string returned by `Date.toDateString()`,\n * indicating there are events in the specified days.\n * @default []\n */\n events: string[];\n /**\n * Callback function when date is selected,\n * first parameter is the newly selected date.\n * @default null\n */\n onSelect: ((selectedDate: Date) => void) | null;\n /**\n * Callback function when Datepicker HTML is refreshed.\n * @default null\n */\n onDraw: (() => void) | null;\n /**\n * Callback function for interaction with input field.\n * @default null\n */\n onInputInteraction: (() => void) | null;\n /**\n * Callback function for interaction with confirm button.\n * @default null\n */\n onConfirm: (() => void) | null;\n /**\n * Callback function for interaction with close button.\n * @default null\n */\n onCancel: (() => void) | null;\n\n /** Field used for internal calculations DO NOT CHANGE IT */\n minYear?: number;\n /** Field used for internal calculations DO NOT CHANGE IT */\n maxYear?: number;\n /** Field used for internal calculations DO NOT CHANGE IT */\n minMonth?: number;\n /** Field used for internal calculations DO NOT CHANGE IT */\n maxMonth?: number;\n /** Field used for internal calculations DO NOT CHANGE IT */\n startRange?: Date;\n /** Field used for internal calculations DO NOT CHANGE IT */\n endRange?: Date;\n /**\n * Display plugin\n */\n displayPlugin: string;\n /**\n * Configurable display plugin options\n */\n displayPluginOptions: object;\n}\n\nconst _defaults: DatepickerOptions = {\n // the default output format for the input field value\n format: 'mmm dd, yyyy',\n // Used to create date object from current input string\n parse: null,\n // The initial condition if the datepicker is based on date range\n isDateRange: false,\n // The selector of the user specified date range end element\n dateRangeEndEl: null,\n // The initial condition if the datepicker is based on multiple date selection\n isMultipleSelection: false,\n // The initial date to view when first opened\n defaultDate: null,\n // The initial end date to view when first opened\n defaultEndDate: null,\n // Make the `defaultDate` the initial selected value\n setDefaultDate: false,\n // Make the `defaultEndDate` the initial selected value\n setDefaultEndDate: false,\n disableWeekends: false,\n disableDayFn: null,\n // First day of week (0: Sunday, 1: Monday etc)\n firstDay: 0,\n // The earliest date that can be selected\n minDate: null,\n // Thelatest date that can be selected\n maxDate: null,\n // Number of years either side, or array of upper/lower range\n yearRange: 10,\n // used internally (don't config outside)\n minYear: 0,\n maxYear: 9999,\n minMonth: undefined,\n maxMonth: undefined,\n startRange: null,\n endRange: null,\n isRTL: false,\n yearRangeReverse: false,\n // Render the month after year in the calendar title\n showMonthAfterYear: false,\n // Render days of the calendar grid that fall in the next or previous month\n showDaysInNextAndPreviousMonths: false,\n // Specify if docked picker is in open state by default\n openByDefault: false,\n // Specify a DOM element to render the calendar in\n container: null,\n // Show clear button\n showClearBtn: false,\n // Autosubmit\n autoSubmit: true,\n // internationalization\n i18n: {\n cancel: 'Cancel',\n clear: 'Clear',\n done: 'Ok',\n previousMonth: '\u2039',\n nextMonth: '\u203A',\n months: [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December'\n ],\n monthsShort: [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec'\n ],\n weekdays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],\n weekdaysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],\n weekdaysAbbrev: ['S', 'M', 'T', 'W', 'T', 'F', 'S']\n },\n // events array\n events: [],\n // callback function\n onSelect: null,\n onDraw: null,\n onInputInteraction: null,\n displayPlugin: null,\n displayPluginOptions: null,\n onConfirm: null,\n onCancel: null,\n};\n\nexport class Datepicker extends Component<DatepickerOptions> {\n declare el: HTMLInputElement;\n id: string;\n multiple: boolean = false;\n calendarEl: HTMLElement;\n containerEl: HTMLElement;\n yearTextEl: HTMLElement;\n dateTextEl: HTMLElement;\n endDateEl: HTMLInputElement;\n dateEls: HTMLInputElement[];\n /** The selected Date. */\n date: Date;\n endDate: null | Date;\n dates: Date[];\n formats: object;\n calendars: [{ month: number; year: number }];\n private displayPlugin: DockedDisplayPlugin;\n /** What setInputValue last wrote, so reading it back does not depend on the parser. */\n private _writtenInputs = new WeakMap<HTMLInputElement, { value: string; date: Date | null }>();\n /** Rows renderRow has already checked, so renderBody does not parse them again. */\n private _checkedRows = new Set<string>();\n private footer: HTMLElement;\n /** Nesting depth of {@link _batchDraws}; > 0 means draws are being collected. */\n private _drawDepth = 0;\n /** Whether a draw was requested while batching. */\n private _drawDirty = false;\n /** Shape of the currently rendered controls; see {@link _controlsCacheKey}. */\n private _controlsKey: string = null;\n /** id linking the controls element to the table's aria-labelledby. */\n private _randId: string = null;\n private _focusedDate: Date = null;\n static _template: string;\n\n constructor(el: HTMLInputElement, options: Partial<DatepickerOptions>) {\n super(el, options, Datepicker);\n this.el['Expressive_Datepicker'] = this;\n\n this.options = {\n ...Datepicker.defaults,\n ...options\n };\n\n // make sure i18n defaults are not lost when only few i18n option properties are passed\n if (!!options && options.hasOwnProperty('i18n') && typeof options.i18n === 'object') {\n this.options.i18n = { ...Datepicker.defaults.i18n, ...options.i18n };\n }\n\n // Remove time component from minDate and maxDate options\n if (this.options.minDate) this.options.minDate.setHours(0, 0, 0, 0);\n if (this.options.maxDate) this.options.maxDate.setHours(0, 0, 0, 0);\n\n this.id = Utils.guid();\n if (this.options.isMultipleSelection) {\n this.multiple = true;\n this.dates = [];\n this.dateEls = [el];\n }\n\n this._setupVariables();\n this._insertHTMLIntoDOM();\n this._setupEventHandlers();\n\n if (!this.options.defaultDate) {\n this.options.defaultDate = this._parseInput(this.el.value);\n }\n\n const defDate = this.options.defaultDate;\n if (Datepicker._isDate(defDate)) {\n if (this.options.setDefaultDate) {\n this.setDate(defDate, true);\n this.setInputValue(this.el, defDate);\n } else {\n this.gotoDate(defDate);\n }\n } else {\n this.gotoDate(new Date());\n }\n if (this.options.isDateRange) {\n this.multiple = true;\n const defEndDate = this.options.defaultEndDate;\n if (Datepicker._isDate(defEndDate)) {\n if (this.options.setDefaultEndDate) {\n this.setDate(defEndDate, true, true);\n this.setInputValue(this.endDateEl, defEndDate);\n }\n }\n }\n if (this.options.displayPlugin === 'docked') {\n this.displayPlugin = DockedDisplayPlugin.init(this.el, this.containerEl, this.options.displayPluginOptions);\n }\n }\n\n static get defaults() {\n return _defaults;\n }\n\n /**\n * Initializes instance of Datepicker.\n * @param el HTML element.\n * @param options Component options.\n */\n static init(el: HTMLInputElement, options?: Partial<DatepickerOptions>): Datepicker;\n /**\n * Initializes instances of Datepicker.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: InitElements<HTMLInputElement | InitElement>,\n options?: Partial<DatepickerOptions>\n ): Datepicker[];\n /**\n * Initializes instances of Datepicker.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: HTMLInputElement | InitElements<HTMLInputElement | InitElement>,\n options: Partial<DatepickerOptions> = {}\n ): Datepicker | Datepicker[] {\n return super.init(els, options, Datepicker);\n }\n\n /**\n * Escape a value for interpolation into the calendar markup.\n *\n * `draw()` assembles the calendar as an HTML string, so every value that is\n * not a number this class computed itself has to go through here. In\n * practice that means the i18n strings: month and weekday names are the one\n * part of a datepicker that routinely comes from a translation file, and a\n * translation file is as trustworthy as whatever wrote it.\n */\n static _escape(value: unknown): string {\n return String(value ?? '')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n }\n\n static _isDate(obj) {\n return /Date/.test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime());\n }\n\n private static _parseDate(value: string): Date {\n value = value.trim();\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) return new Date(Date.parse(value));\n // An ISO time without an offset is local. Reject days that roll into the next month.\n const date = new Date(value + 'T00:00:00');\n return date.getDate() === Number(value.slice(-2)) ? date : new Date(NaN);\n }\n\n private _parseInput(value: string): Date {\n if (!value.trim() || !this.options.parse) return Datepicker._parseDate(value);\n return this.options.parse(\n value,\n typeof this.options.format === 'string' ? this.options.format : ''\n );\n }\n\n static _isWeekend(date) {\n const day = date.getDay();\n return day === 0 || day === 6;\n }\n\n /**\n * @deprecated as this function has no effect without any return statement or global parameter setter.\n */\n static _setToStartOfDay(date) {\n if (Datepicker._isDate(date)) date.setHours(0, 0, 0, 0);\n }\n\n static _getDaysInMonth(year, month) {\n return [31, Datepicker._isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][\n month\n ];\n }\n\n static _isLeapYear(year) {\n // solution by Matti Virkkunen: http://stackoverflow.com/a/4881951\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n }\n\n static _compareDates(a, b) {\n // weak date comparison (use setToStartOfDay(date) to ensure correct result)\n return a.getTime() === b.getTime();\n }\n\n static _compareWithinRange(day: Date, date: Date, dateEnd: Date) {\n return day.getTime() > date.getTime() && day.getTime() < dateEnd.getTime();\n }\n\n static _comparePastDate(a: Date, b: Date) {\n return a.getTime() < b.getTime();\n }\n\n static getInstance(el: HTMLElement): Datepicker {\n return el['Expressive_Datepicker'];\n }\n\n destroy() {\n this._removeEventHandlers();\n this.dateEls?.slice(1).forEach(input => this._removeDateInput(input));\n if (!this.options.dateRangeEndEl && this.endDateEl) this._removeDateInput(this.endDateEl);\n this.displayPlugin?.destroy();\n this.containerEl.remove();\n this.destroySelects();\n this.el['Expressive_Datepicker'] = undefined;\n }\n\n destroySelects() {\n const oldYearSelect = this.calendarEl.querySelector('.orig-select-year');\n if (oldYearSelect) {\n FormSelect.getInstance(oldYearSelect as HTMLElement).destroy();\n }\n const oldMonthSelect = this.calendarEl.querySelector('.orig-select-month');\n if (oldMonthSelect) {\n FormSelect.getInstance(oldMonthSelect as HTMLElement).destroy();\n }\n }\n\n _insertHTMLIntoDOM() {\n // HTML5 input date field support\n if (this.el.type == 'date') {\n this.el.classList.add('datepicker-date-input');\n }\n\n // `!x === null` is always false, so this never ran; _renderDateInputFormat\n // now no-ops on its own when there is no hint element to fill in.\n this._renderDateInputFormat(this.el);\n\n if (this.options.isDateRange) {\n this.containerEl.classList.add('daterange');\n if (!this.options.dateRangeEndEl) {\n this.endDateEl = this.createDateInput();\n this.endDateEl.classList.add('datepicker-end-date');\n } else {\n // querySelector returns null, never undefined: the old check compared\n // against undefined, so a miss skipped the warning and fell through to\n // dereferencing null.\n this.endDateEl = document.querySelector(this.options.dateRangeEndEl);\n if (!this.endDateEl) {\n console.warn('Specified date range end input element in dateRangeEndEl not found');\n } else {\n this._renderDateInputFormat(this.endDateEl);\n }\n }\n }\n\n Utils.createButton(this.footer, this.options.i18n.clear, ['datepicker-clear'], this.options.showClearBtn, this._handleClearClick);\n\n if (!this.options.autoSubmit) {\n Utils.createConfirmationContainer(this.footer, this.options.i18n.done, this.options.i18n.cancel, this._confirm, this._cancel);\n }\n\n if (this.options.container) {\n const optEl = this.options.container;\n this.options.container =\n optEl instanceof HTMLElement ? optEl : (document.querySelector(optEl) as HTMLElement);\n this.options.container.append(this.containerEl);\n } else {\n const appendTo = !this.endDateEl ? this.el : this.endDateEl;\n if (!this.options.openByDefault) (this.containerEl as HTMLElement).setAttribute('style', 'display: none; visibility: hidden;');\n appendTo.parentElement.after(this.containerEl);\n }\n }\n\n /**\n * Renders the date input format into the optional `.datepicker-format` hint\n * next to the input, if the consumer provided one.\n */\n _renderDateInputFormat(el: HTMLInputElement) {\n const formatEl = el.parentElement?.querySelector('.datepicker-format');\n if (!formatEl) return;\n // textContent, and nothing at all for a function format: this used to be\n // `innerHTML = format.toString()`, which rendered a format string as\n // markup and dumped a function's entire source into the page.\n formatEl.textContent =\n typeof this.options.format === 'function' ? '' : String(this.options.format);\n }\n\n /**\n * Gets a string representation of the given date.\n */\n toString(date: Date = this.date, format: string | ((d: Date) => string) = null): string {\n format = format || this.options.format;\n if (typeof format === 'function') return format(date);\n if (!Datepicker._isDate(date)) return '';\n // String Format\n return this.formatDate(date, format);\n }\n\n /**\n * Returns the formatted date.\n */\n formatDate(date: Date, format: string) {\n const formatArray = format.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g);\n return formatArray\n .map((label) => (this.formats[label] ? this.formats[label](date) : label))\n .join('');\n }\n\n /**\n * Sets date from input field.\n */\n setDateFromInput(el: HTMLInputElement) {\n // The native input's overlay follows edits, including cleared or partial values.\n if (el.type === 'date') this.setDataDate(el, Datepicker._parseDate(el.value));\n if ((this.options.isDateRange || !this.options.isMultipleSelection) && !el.value.trim()) {\n this.setSingleDate(null, el === this.endDateEl);\n this.draw();\n return;\n }\n // Without a custom parser, Date.parse reads \"05/10/2026\" from a dd/mm/yyyy\n // format as 10 May, so reuse the date behind a value the picker wrote.\n const written = !this.options.parse && this._writtenInputs.get(el);\n const parsedDate = written && written.value === el.value ? written.date : this._parseInput(el.value);\n if (!Datepicker._isDate(parsedDate)) return;\n const date = new Date(parsedDate.getTime());\n Datepicker._setToStartOfDay(date);\n const isEndDate = el === this.endDateEl;\n if (this.options.isDateRange && (isEndDate\n ? this.date && date < this.date\n : this.endDate && date > this.endDate)) {\n this.setInputValue(el, isEndDate ? this.endDate : this.date);\n return;\n }\n this.setDate(date, false, isEndDate, true);\n }\n\n /**\n * Set a date on the datepicker.\n * @param date Date to set on the datepicker.\n * @param preventOnSelect Undocumented as of 5 March 2018.\n * @param isEndDate\n * @param fromUserInput\n */\n setDate(\n date: Date = null,\n preventOnSelect: boolean = false,\n isEndDate: boolean = false,\n fromUserInput: boolean = false\n ) {\n const selectedDate = this.validateDate(date);\n if (!selectedDate) {\n return;\n }\n Datepicker._setToStartOfDay(selectedDate);\n if (!this.options.isMultipleSelection) this.setSingleDate(selectedDate, isEndDate);\n else if (!fromUserInput) this.setMultiDate(selectedDate);\n this.gotoDate(selectedDate);\n if (!preventOnSelect && typeof this.options.onSelect === 'function') {\n this.options.onSelect.call(this, selectedDate);\n }\n }\n\n validateDate(date: Date) {\n if (!date) {\n this._renderDateDisplay(date);\n return this.draw();\n }\n if (typeof date === 'string') {\n date = Datepicker._parseDate(date);\n }\n if (!Datepicker._isDate(date)) {\n return;\n }\n const min = this.options.minDate,\n max = this.options.maxDate;\n if (Datepicker._isDate(min) && date < min) {\n date = min;\n } else if (Datepicker._isDate(max) && date > max) {\n date = max;\n }\n return new Date(date.getTime());\n }\n\n /**\n * Set a single date on the datepicker.\n * @param date Date to set on the datepicker.\n * @param isEndDate\n */\n setSingleDate(date: Date, isEndDate: boolean) {\n if (!isEndDate) {\n this.date = date;\n } else {\n this.endDate = date;\n }\n }\n\n /**\n * Set a multi date on the datepicker.\n * @param date Date to set on the datepicker.\n */\n setMultiDate(date: Date) {\n const index = this.dates.findIndex((item) => item.getTime() === date.getTime());\n if (index === -1) {\n this.dates.push(date);\n } else {\n this.dates.splice(index, 1);\n }\n this.dates.sort((a: Date, b: Date) => (a.getTime() < b.getTime() ? -1 : 0));\n }\n\n /**\n * Sets the data-date attribute on the date input field\n */\n setDataDate(el, date) {\n el.setAttribute('data-date', Datepicker._isDate(date) ? this.toString(date) : '');\n }\n\n /**\n * Sets dates on the input values.\n */\n setInputValues() {\n if (!this.options?.isMultipleSelection) {\n this.setInputValue(this.el, this.date);\n if (this.options?.isDateRange) {\n this.setInputValue(this.endDateEl, this.endDate);\n }\n return;\n }\n this.setMultipleSelectionInputValues();\n }\n\n setMultipleSelectionInputValues() {\n const count = Math.max(1, this.dates.length);\n for (const input of this.dateEls.splice(count)) this._removeDateInput(input);\n while (this.dateEls.length < count) this.dateEls.push(this.createDateInput());\n this.dateEls.forEach((input, index) => this.setInputValue(input, this.dates[index] ?? null));\n }\n\n /**\n * Sets given date as the input value on the given element.\n */\n setInputValue(el, date) {\n if (!el) return;\n if (el.type == 'date') this.setDataDate(el, date);\n if (!Datepicker._isDate(date)) {\n el.value = '';\n } else if (el.type == 'date') {\n el.value = this.formatDate(date, 'yyyy-mm-dd');\n } else {\n el.value = this.toString(date);\n }\n this._writtenInputs.set(el, { value: el.value, date: Datepicker._isDate(date) ? new Date(date.getTime()) : null });\n el.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n cancelable: true,\n composed: true,\n detail: { firedBy: this }\n })\n );\n }\n\n /**\n * Renders the date in the modal head section.\n */\n _renderDateDisplay(date: Date, endDate: Date = null) {\n const displayDate = Datepicker._isDate(date) ? date : new Date();\n // @todo should we include an option for date formatting by component options?\n // textContent: formatDate splices i18n month and weekday names in.\n if (!this.options.isDateRange) {\n this.dateTextEl.textContent = this.formatDate(displayDate, 'ddd, mmm d');\n } else {\n const displayEndDate = Datepicker._isDate(endDate) ? endDate : new Date();\n this.dateTextEl.textContent = `${this.formatDate(displayDate, 'mmm d')} - ${this.formatDate(displayEndDate, 'mmm d')}`;\n }\n }\n\n /**\n * Change date view to a specific date on the datepicker.\n * @param date Date to show on the datepicker.\n */\n gotoDate(date: Date) {\n let newCalendar = true;\n if (!Datepicker._isDate(date)) {\n return;\n }\n if (this.calendars) {\n const firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1),\n lastVisibleDate = new Date(\n this.calendars[this.calendars.length - 1].year,\n this.calendars[this.calendars.length - 1].month,\n 1\n ),\n visibleDate = date.getTime();\n // get the end of the month\n lastVisibleDate.setMonth(lastVisibleDate.getMonth() + 1);\n lastVisibleDate.setDate(lastVisibleDate.getDate() - 1);\n newCalendar =\n visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate;\n }\n if (newCalendar) {\n this.calendars = [\n {\n month: date.getMonth(),\n year: date.getFullYear()\n }\n ];\n }\n this.adjustCalendars();\n }\n\n adjustCalendars() {\n this.calendars[0] = this.adjustCalendar(this.calendars[0]);\n this.draw();\n }\n\n adjustCalendar(calendar) {\n if (calendar.month < 0) {\n calendar.year -= Math.ceil(Math.abs(calendar.month) / 12);\n calendar.month += 12;\n }\n if (calendar.month > 11) {\n calendar.year += Math.floor(Math.abs(calendar.month) / 12);\n calendar.month -= 12;\n }\n return calendar;\n }\n\n nextMonth() {\n this.calendars[0].month++;\n this.adjustCalendars();\n }\n\n prevMonth() {\n this.calendars[0].month--;\n this.adjustCalendars();\n }\n\n render(year, month, randId) {\n const now = new Date(),\n days = Datepicker._getDaysInMonth(year, month),\n data = [];\n let before = new Date(year, month, 1).getDay(),\n row = [];\n Datepicker._setToStartOfDay(now);\n if (this.options.firstDay > 0) {\n before -= this.options.firstDay;\n if (before < 0) {\n before += 7;\n }\n }\n const previousMonth = month === 0 ? 11 : month - 1,\n nextMonth = month === 11 ? 0 : month + 1,\n yearOfPreviousMonth = month === 0 ? year - 1 : year,\n yearOfNextMonth = month === 11 ? year + 1 : year,\n daysInPreviousMonth = Datepicker._getDaysInMonth(yearOfPreviousMonth, previousMonth);\n const cells = Math.ceil((days + before) / 7) * 7;\n for (let i = 0, r = 0; i < cells; i++) {\n const day = new Date(year, month, 1 + (i - before)),\n isToday = Datepicker._compareDates(day, now),\n hasEvent = this.options.events.indexOf(day.toDateString()) !== -1,\n isEmpty = i < before || i >= days + before,\n isStartRange =\n this.options.startRange && Datepicker._compareDates(this.options.startRange, day),\n isEndRange = this.options.endRange && Datepicker._compareDates(this.options.endRange, day),\n isInRange =\n this.options.startRange &&\n this.options.endRange &&\n this.options.startRange < day &&\n day < this.options.endRange,\n isDisabled =\n (this.options.minDate && day < this.options.minDate) ||\n (this.options.maxDate && day > this.options.maxDate) ||\n (this.options.disableWeekends && Datepicker._isWeekend(day)) ||\n (this.options.disableDayFn && this.options.disableDayFn(day)),\n isDateRangeStart = this.options.isDateRange && this.date && this.endDate && Datepicker._compareDates(this.date, day),\n isDateRangeEnd = this.options.isDateRange && this.endDate && Datepicker._compareDates(this.endDate, day),\n isDateRange =\n this.options.isDateRange &&\n Datepicker._isDate(this.date) &&\n Datepicker._isDate(this.endDate) &&\n Datepicker._compareWithinRange(day, this.date, this.endDate);\n let dayNumber = 1 + (i - before),\n monthNumber = month,\n yearNumber = year;\n\n let isSelected = false;\n if (Datepicker._isDate(this.date)) {\n isSelected = Datepicker._compareDates(day, this.date);\n }\n\n if (!isSelected && Datepicker._isDate(this.endDate)) {\n isSelected = Datepicker._compareDates(day, this.endDate);\n }\n\n if (\n this.options.isMultipleSelection &&\n this.dates?.some((item) => item.getTime() === day.getTime())\n ) {\n isSelected = true;\n }\n\n if (isEmpty) {\n if (i < before) {\n dayNumber = daysInPreviousMonth + dayNumber;\n monthNumber = previousMonth;\n yearNumber = yearOfPreviousMonth;\n } else {\n dayNumber = dayNumber - days;\n monthNumber = nextMonth;\n yearNumber = yearOfNextMonth;\n }\n }\n\n const dayConfig = {\n day: dayNumber,\n month: monthNumber,\n year: yearNumber,\n hasEvent: hasEvent,\n isSelected: isSelected,\n isToday: isToday,\n isDisabled: isDisabled,\n isEmpty: isEmpty,\n isStartRange: isStartRange,\n isEndRange: isEndRange,\n isInRange: isInRange,\n showDaysInNextAndPreviousMonths: this.options.showDaysInNextAndPreviousMonths,\n isDateRangeStart: isDateRangeStart,\n isDateRangeEnd: isDateRangeEnd,\n isDateRange: isDateRange\n };\n\n row.push(this.renderDay(dayConfig));\n\n if (++r === 7) {\n data.push(this.renderRow(row, this.options.isRTL, false));\n row = [];\n r = 0;\n }\n }\n return this.renderTable(this.options, data, randId);\n }\n\n renderDay(opts) {\n const classMap = {\n isDisabled: 'is-disabled',\n isToday: 'is-today',\n isSelected: 'is-selected',\n hasEvent: 'has-event',\n isInRange: 'is-inrange',\n isStartRange: 'is-startrange',\n isEndRange: 'is-endrange',\n isDateRangeStart: 'is-daterange-start',\n isDateRangeEnd: 'is-daterange-end',\n isDateRange: 'is-daterange'\n },\n ariaSelected = opts.isSelected === true || opts.isDateRange === true,\n arr = ['datepicker-day'];\n\n if (opts.isEmpty) {\n if (opts.showDaysInNextAndPreviousMonths) {\n arr.push('is-outside-current-month');\n arr.push('is-selection-disabled');\n } else {\n return '<td class=\"is-empty\"></td>';\n }\n }\n\n for (const [property, className] of Object.entries(classMap)) {\n if (opts.hasOwnProperty(property) && opts[property]) {\n arr.push(className);\n }\n }\n\n const day = Datepicker._escape(opts.day);\n const month = Datepicker._escape(opts.month);\n const year = Datepicker._escape(opts.year);\n return (\n `<td data-day=\"${day}\" class=\"${arr.join(' ')}\" aria-selected=\"${ariaSelected}\">` +\n `<button class=\"datepicker-day-button\" type=\"button\" data-year=\"${year}\" data-month=\"${month}\" data-day=\"${day}\">${day}</button>` +\n '</td>'\n );\n }\n\n /** Assemble calendar cells; reject unsupported elements and attributes. */\n renderRow(days, isRTL, isRowSelected) {\n const row =\n '<tr class=\"datepicker-row' +\n (isRowSelected ? ' is-selected' : '') +\n '\">' +\n Datepicker._calendarMarkup((isRTL ? days.reverse() : days).join(''), 'tr') +\n '</tr>';\n this._checkedRows.add(row);\n return row;\n }\n\n /** Assemble calendar rows; reject unsupported elements and attributes. */\n renderTable(opts, data, randId) {\n return (\n '<div class=\"datepicker-table-wrapper\"><table cellpadding=\"0\" cellspacing=\"0\" class=\"datepicker-table\" role=\"grid\" aria-labelledby=\"' +\n Datepicker._escape(randId) +\n '\">' +\n this.renderHead(opts) +\n this.renderBody(data) +\n '</table></div>'\n );\n }\n\n renderHead(opts) {\n const arr = [];\n let i;\n for (i = 0; i < 7; i++) {\n const full = Datepicker._escape(this.renderDayName(opts, i));\n const abbrev = Datepicker._escape(this.renderDayName(opts, i, true));\n arr.push(`<th scope=\"col\"><abbr title=\"${full}\">${abbrev}</abbr></th>`);\n }\n return '<thead><tr>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</tr></thead>';\n }\n\n /** Wrap calendar rows after validating and encoding their contents. */\n renderBody(rows) {\n const html = rows.join('');\n // Always sanitize row markup before insertion to avoid propagating unsafe library input.\n const safeHtml = Datepicker._calendarMarkup(html, 'tbody');\n this._checkedRows.clear();\n return '<tbody>' + safeHtml + '</tbody>';\n }\n\n private static _calendarMarkup(html: string, parent: string): string {\n const template = document.createElement('template');\n // Template contents stay inert. Only rebuilt, encoded markup leaves here.\n template.innerHTML = html;\n const childOf: Record<string, 'tr' | 'td' | 'button'> = { tbody: 'tr', tr: 'td', td: 'button' };\n const attributes = {\n tr: ['class'],\n td: ['class', 'data-day', 'aria-selected'],\n button: ['class', 'type', 'data-year', 'data-month', 'data-day', 'aria-label', 'disabled', 'tabindex']\n };\n const render = (node: Node, container: string): string => {\n if (node.nodeType === Node.TEXT_NODE) {\n if (container === 'tbody' || container === 'tr') {\n if (node.textContent.trim()) throw new TypeError('Unsupported calendar row content');\n }\n return Datepicker._escape(node.textContent);\n }\n if (!(node instanceof HTMLElement)) throw new TypeError('Unsupported calendar row content');\n const tag = childOf[container];\n if (!tag || node.localName !== tag) {\n throw new TypeError('Unsupported calendar row element');\n }\n if ([...node.attributes].some(attr => !attributes[tag].includes(attr.name))) {\n throw new TypeError('Unsupported calendar row attribute');\n }\n if (tag === 'button' && node.getAttribute('type') !== 'button') {\n throw new TypeError('Calendar day buttons require type=\"button\"');\n }\n const attrs = attributes[tag].filter(name => node.hasAttribute(name))\n .map(name => ` ${name}=\"${Datepicker._escape(node.getAttribute(name))}\"`).join('');\n return `<${tag}${attrs}>${[...node.childNodes].map(child => render(child, tag)).join('')}</${tag}>`;\n };\n return [...template.content.childNodes].map(node => render(node, parent)).join('');\n }\n\n /**\n * Whether each month arrow is usable at this position in the allowed range.\n *\n * Depends on the month, which is deliberately *not* part of the controls\n * cache key - so the reuse path has to recompute and reapply it.\n */\n private _arrowState(year: number, month: number) {\n const opts = this.options;\n const isMinYear = year === opts.minYear;\n const isMaxYear = year === opts.maxYear;\n return {\n prev: !(isMinYear && (month === 0 || opts.minMonth >= month)),\n next: !(isMaxYear && (month === 11 || opts.maxMonth <= month))\n };\n }\n\n /**\n * Identifies the *shape* of the controls - everything that changes which\n * options the month and year selects contain, as opposed to which one is\n * picked. While this is stable the two FormSelects can be left alone.\n *\n * `year` is in the key because a numeric `yearRange` centres the year list\n * on the displayed year, so paging across a year boundary does change it.\n */\n private _controlsCacheKey(year: number): string {\n const o = this.options;\n return [\n year,\n o.minYear,\n o.maxYear,\n o.minMonth,\n o.maxMonth,\n Array.isArray(o.yearRange) ? o.yearRange.join('-') : o.yearRange,\n o.yearRangeReverse,\n o.showMonthAfterYear\n ].join('|');\n }\n\n renderTitle(instance, c, year, month, refYear, randId) {\n const opts = this.options,\n isMinYear = year === opts.minYear,\n isMaxYear = year === opts.maxYear;\n let i,\n j,\n arr = [],\n html =\n '<div id=\"' +\n Datepicker._escape(randId) +\n '\" class=\"datepicker-controls\" role=\"heading\" aria-live=\"assertive\">';\n\n // Decided up front. These used to be computed *below* the month-prev\n // button that reads `prev`, so the previous arrow was never disabled at\n // the start of the allowed range.\n const { prev, next } = this._arrowState(year, month);\n\n for (i = 0; i < 12; i++) {\n arr.push(\n '<option value=\"' +\n (year === refYear ? i - c : 12 + i - c) +\n '\"' +\n (i === month ? ' selected=\"selected\"' : '') +\n ((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth)\n ? 'disabled=\"disabled\"'\n : '') +\n '>' +\n Datepicker._escape(opts.i18n.months[i]) +\n '</option>'\n );\n }\n\n const monthHtml =\n '<select class=\"datepicker-select orig-select-month\" tabindex=\"-1\">' +\n arr.join('') +\n '</select>';\n\n if (Array.isArray(opts.yearRange)) {\n i = opts.yearRange[0];\n j = opts.yearRange[1] + 1;\n } else {\n i = year - opts.yearRange;\n j = 1 + year + opts.yearRange;\n }\n\n for (arr = []; i < j && i <= opts.maxYear; i++) {\n if (i >= opts.minYear) {\n arr.push(`<option value=\"${i}\" ${i === year ? 'selected=\"selected\"' : ''}>${i}</option>`);\n }\n }\n if (opts.yearRangeReverse) arr.reverse();\n\n const yearHtml = `<select class=\"datepicker-select orig-select-year\" tabindex=\"-1\">${arr.join('')}</select>`;\n\n const leftArrow =\n '<svg height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z\"/><path d=\"M0-.5h24v24H0z\" fill=\"none\"/></svg>';\n html += `<button class=\"month-prev${\n prev ? '' : ' is-disabled'\n // @todo remove button class and add scss mixin, current implementation temporary for focus states\n }\" type=\"button\">${leftArrow}</button>`;\n\n html += '<div class=\"selects-container\">';\n if (opts.showMonthAfterYear) {\n html += yearHtml + monthHtml;\n } else {\n html += monthHtml + yearHtml;\n }\n html += '</div>';\n\n const rightArrow =\n '<svg height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z\"/><path d=\"M0-.25h24v24H0z\" fill=\"none\"/></svg>';\n html += `<button class=\"month-next${\n next ? '' : ' is-disabled'\n // @todo remove button class and add scss mixin, current implementation temporary for focus states\n }\" type=\"button\">${rightArrow}</button>`;\n\n return (html += '</div>');\n }\n\n /**\n * Run `fn`, collapsing every draw it triggers into a single one at the end.\n *\n * A single input click reaches draw() three times - once through\n * setDateFromInput -> setDate -> gotoDate, once directly, and once through\n * the trailing gotoDate - and each one destroys two FormSelect instances,\n * reparses the calendar and builds two fresh FormSelects. The three calls\n * cannot simply be deleted: the direct draw() is what covers an empty input\n * (setDate bails before drawing when the value does not parse), and the\n * trailing gotoDate re-centres on a date validateDate may have clamped to\n * minDate/maxDate. So they are collected instead of removed.\n *\n * Deliberately synchronous: the constructor and callers read calendarEl\n * immediately after init(), which a microtask-deferred draw would leave\n * empty.\n */\n private _batchDraws(fn: () => void) {\n this._drawDepth++;\n try {\n fn();\n } finally {\n this._drawDepth--;\n if (this._drawDepth === 0 && this._drawDirty) {\n this._drawDirty = false;\n this.draw();\n }\n }\n }\n\n // refresh HTML\n draw() {\n // Inside a batch, note that a draw is due and let the batch do it once.\n if (this._drawDepth > 0) {\n this._drawDirty = true;\n return;\n }\n const active = (this.calendarEl.getRootNode() as Document | ShadowRoot).activeElement;\n const restoreDayFocus = active?.matches('.datepicker-day-button') && this.calendarEl.contains(active);\n const restoreArrow = this.calendarEl.contains(active) && active?.matches('.month-prev, .month-next')\n ? active.classList.contains('month-prev') ? '.month-prev' : '.month-next' : null;\n const year = this.calendars[0].year;\n const month = this.calendars[0].month;\n\n this._renderDateDisplay(this.date, this.endDate);\n\n // Only the day grid changes when you page within a year. Rebuilding the\n // controls as well meant tearing down and reconstructing two FormSelects -\n // each with its own <ul> of 12 or 21+ options, an input, a caret and a\n // Menu - on every single draw.\n const key = this._controlsCacheKey(year);\n if (key === this._controlsKey && this.calendarEl.querySelector('.datepicker-controls')) {\n this._reuseControls(year, month);\n } else {\n this._controlsKey = key;\n // Held across table re-renders: the table's aria-labelledby points at\n // the controls element's id.\n this._randId = 'datepicker-title-' + Utils.guid();\n this._rebuildControls(year, month);\n }\n this._renderCalendarTable(year, month);\n this._syncCalendarFocus(!!restoreDayFocus);\n if (restoreArrow) this.calendarEl.querySelector<HTMLButtonElement>(restoreArrow)?.focus();\n\n if (typeof this.options.onDraw === 'function') {\n this.options.onDraw.call(this);\n }\n }\n\n /** Tear down the two FormSelects and render the controls from scratch. */\n private _rebuildControls(year: number, month: number) {\n this.destroySelects();\n this.calendarEl.innerHTML = this.renderTitle(this, 0, year, month, year, this._randId);\n\n const yearSelect = this.calendarEl.querySelector('.orig-select-year') as HTMLSelectElement;\n const monthSelect = this.calendarEl.querySelector('.orig-select-month') as HTMLSelectElement;\n // @todo fix accessibility\n FormSelect.init(yearSelect, {\n classes: 'select-year',\n menuOptions: { container: Utils.portalRoot(this.el), constrainWidth: false }\n });\n FormSelect.init(monthSelect, {\n classes: 'select-month',\n menuOptions: { container: Utils.portalRoot(this.el), constrainWidth: false }\n });\n\n // Add change handlers for select\n yearSelect.addEventListener('change', this._handleYearChange);\n monthSelect.addEventListener('change', this._handleMonthChange);\n }\n\n /**\n * Keep the existing controls and bring them up to date: the selected month,\n * and the arrow states, which depend on the month rather than on the key.\n */\n private _reuseControls(year: number, month: number) {\n const monthSelect = this.calendarEl.querySelector('.orig-select-month') as HTMLSelectElement;\n if (monthSelect && monthSelect.value !== month.toString()) {\n monthSelect.value = month.toString();\n // Assigning .value fires no change event, so the wrapper needs telling.\n FormSelect.getInstance(monthSelect)?.refresh();\n }\n\n const { prev, next } = this._arrowState(year, month);\n this.calendarEl.querySelector('.month-prev')?.classList.toggle('is-disabled', !prev);\n this.calendarEl.querySelector('.month-next')?.classList.toggle('is-disabled', !next);\n }\n\n /** Replace just the day grid, leaving the controls in place. */\n private _renderCalendarTable(year: number, month: number) {\n const html = this.render(year, month, this._randId);\n const existing = this.calendarEl.querySelector('.datepicker-table-wrapper');\n if (existing) existing.outerHTML = html;\n else this.calendarEl.insertAdjacentHTML('beforeend', html);\n }\n\n _setupEventHandlers() {\n this._addInputEventHandlers(this.el);\n if (this.endDateEl) this._addInputEventHandlers(this.endDateEl);\n this.calendarEl.addEventListener('click', this._handleCalendarClick);\n this.calendarEl.addEventListener('keydown', this._handleCalendarKeydown);\n this.calendarEl.addEventListener('focusin', this._handleCalendarFocus);\n }\n\n _setupVariables() {\n const template = document.createElement('template');\n template.innerHTML = Datepicker._template.trim();\n\n this.containerEl = <HTMLElement>template.content.firstChild;\n\n this.calendarEl = this.containerEl.querySelector('.datepicker-calendar');\n this.yearTextEl = this.containerEl.querySelector('.year-text');\n this.dateTextEl = this.containerEl.querySelector('.date-text');\n this.footer = this.containerEl.querySelector('.datepicker-footer');\n\n this.formats = {\n d: (date: Date) => {\n return date.getDate();\n },\n dd: (date: Date) => {\n const d = date.getDate();\n return (d < 10 ? '0' : '') + d;\n },\n ddd: (date: Date) => {\n return this.options.i18n.weekdaysShort[date.getDay()];\n },\n dddd: (date: Date) => {\n return this.options.i18n.weekdays[date.getDay()];\n },\n m: (date: Date) => {\n return date.getMonth() + 1;\n },\n mm: (date: Date) => {\n const m = date.getMonth() + 1;\n return (m < 10 ? '0' : '') + m;\n },\n mmm: (date: Date) => {\n return this.options.i18n.monthsShort[date.getMonth()];\n },\n mmmm: (date: Date) => {\n return this.options.i18n.months[date.getMonth()];\n },\n yy: (date: Date) => {\n return ('' + date.getFullYear()).slice(2);\n },\n yyyy: (date: Date) => {\n return date.getFullYear();\n }\n };\n }\n\n _removeEventHandlers() {\n for (const input of this.dateEls ?? [this.el]) this._removeInputEventHandlers(input);\n this.calendarEl.removeEventListener('click', this._handleCalendarClick);\n this.calendarEl.removeEventListener('keydown', this._handleCalendarKeydown);\n this.calendarEl.removeEventListener('focusin', this._handleCalendarFocus);\n if (this.options.isDateRange && this.endDateEl) {\n this._removeInputEventHandlers(this.endDateEl);\n }\n }\n\n private _addInputEventHandlers(input: HTMLInputElement) {\n input.addEventListener('click', this._handleInputClick);\n input.addEventListener('keydown', this._handleInputKeydown);\n input.addEventListener('change', this._handleInputChange);\n }\n\n private _removeInputEventHandlers(input: HTMLInputElement) {\n input.removeEventListener('click', this._handleInputClick);\n input.removeEventListener('keydown', this._handleInputKeydown);\n input.removeEventListener('change', this._handleInputChange);\n }\n\n private _removeDateInput(input: HTMLInputElement) {\n const focused = (input.getRootNode() as Document | ShadowRoot).activeElement === input;\n this._removeInputEventHandlers(input);\n input.remove();\n if (focused && document.activeElement === document.body) this.el.focus();\n }\n\n _handleInputClick = (e) => {\n // Block the native date picker only when the calendar is shown to replace it.\n if (e.target.type == 'date' && (this.options.openByDefault || this.options.container)) e.preventDefault();\n this._batchDraws(() => {\n this.setDateFromInput(e.target as HTMLInputElement);\n this.draw();\n this.gotoDate(<HTMLElement>e.target === this.el ? this.date : this.endDate);\n });\n if (this.displayPlugin) this.displayPlugin.show();\n if (this.options.onInputInteraction) this.options.onInputInteraction.call(this);\n };\n\n _handleInputKeydown = (e: KeyboardEvent) => {\n if (e.key === Utils.keys.ENTER) {\n e.preventDefault();\n this._batchDraws(() => {\n this.setDateFromInput(e.target as HTMLInputElement);\n this._focusedDate = e.target === this.endDateEl ? this.endDate : this.date;\n this.draw();\n });\n if (this.displayPlugin) this.displayPlugin.show();\n this._syncCalendarFocus(true);\n if (this.options.onInputInteraction) this.options.onInputInteraction.call(this);\n }\n };\n\n private _dayDate(button: HTMLElement) {\n const date = new Date(0);\n date.setFullYear(Number(button.dataset.year), Number(button.dataset.month), Number(button.dataset.day));\n Datepicker._setToStartOfDay(date);\n return date;\n }\n\n private _syncCalendarFocus(restore = false) {\n const buttons = [...this.calendarEl.querySelectorAll<HTMLButtonElement>('.datepicker-day-button')];\n const current = buttons.filter(button => !button.parentElement.classList.contains('is-selection-disabled'));\n const preferred = this._focusedDate || this.date || new Date();\n const target = current.find(button => Datepicker._compareDates(this._dayDate(button), preferred))\n || current.find(button => button.parentElement.classList.contains('is-selected'))\n || current.find(button => !button.parentElement.classList.contains('is-disabled')) || current[0];\n for (const button of buttons) {\n button.tabIndex = button === target ? 0 : -1;\n button.setAttribute('aria-disabled', String(button.parentElement.matches('.is-disabled, .is-selection-disabled')));\n }\n if (target) {\n this._focusedDate = this._dayDate(target);\n if (restore) target.focus();\n }\n }\n\n private _handleCalendarFocus = (event: FocusEvent) => {\n const button = event.target as HTMLElement;\n if (!button.matches('.datepicker-day-button')) return;\n this._focusedDate = this._dayDate(button);\n this._syncCalendarFocus();\n };\n\n private _handleCalendarKeydown = (event: KeyboardEvent) => {\n const button = event.target as HTMLElement;\n if (!button.matches('.datepicker-day-button') || event.altKey || event.ctrlKey || event.metaKey) return;\n const date = this._dayDate(button);\n const weekday = (date.getDay() - this.options.firstDay + 7) % 7;\n const offsets = { ArrowLeft: this.options.isRTL ? 1 : -1, ArrowRight: this.options.isRTL ? -1 : 1,\n ArrowUp: -7, ArrowDown: 7, Home: -weekday, End: 6 - weekday };\n if (Object.hasOwn(offsets, event.key)) date.setDate(date.getDate() + offsets[event.key]);\n else if (event.key === 'PageUp' || event.key === 'PageDown') {\n const day = date.getDate();\n date.setDate(1);\n date.setMonth(date.getMonth() + (event.key === 'PageUp' ? -1 : 1) * (event.shiftKey ? 12 : 1));\n const last = new Date(date.getTime());\n last.setMonth(last.getMonth() + 1, 0);\n date.setDate(Math.min(day, last.getDate()));\n } else return;\n event.preventDefault();\n const { minDate, maxDate, minYear, maxYear, minMonth, maxMonth } = this.options;\n if (minDate && date < minDate) date.setTime(minDate.getTime());\n if (maxDate && date > maxDate) date.setTime(maxDate.getTime());\n if (date.getFullYear() < minYear || date.getFullYear() > maxYear\n || (date.getFullYear() === minYear && date.getMonth() < (minMonth ?? 0))\n || (date.getFullYear() === maxYear && date.getMonth() > (maxMonth ?? 11))) return;\n this._focusedDate = date;\n // Moving within the shown month only moves focus; redrawing the grid on\n // every held arrow key rebuilt 42 cells for nothing.\n const { year, month } = this.calendars[0];\n if (date.getFullYear() === year && date.getMonth() === month) this._syncCalendarFocus(true);\n else this.gotoDate(date);\n };\n\n _handleCalendarClick = (e) => {\n const target = <HTMLElement>e.target;\n if (target.classList.contains('is-disabled')) return;\n\n this._batchDraws(() => {\n if (\n target.classList.contains('datepicker-day-button') &&\n !target.classList.contains('is-empty') &&\n !target.parentElement.classList.contains('is-disabled') &&\n !target.parentElement.classList.contains('is-selection-disabled')\n ) {\n const selectedDate = new Date(\n e.target.getAttribute('data-year'),\n e.target.getAttribute('data-month'),\n e.target.getAttribute('data-day')\n );\n\n if (!this.multiple || this.options.isMultipleSelection) {\n this.setDate(selectedDate);\n }\n\n // Selecting a range end draws a second time on top of setDate's.\n if (this.options.isDateRange) {\n this._handleDateRangeCalendarClick(selectedDate);\n }\n\n if (this.options.autoSubmit) this._finishSelection();\n } else if (target.closest('.month-prev')) {\n this.prevMonth();\n } else if (target.closest('.month-next')) {\n this.nextMonth();\n }\n });\n };\n\n _handleDateRangeCalendarClick = (date: Date) => {\n if (this.endDate == null || !Datepicker._compareDates(date, this.endDate)) {\n if (Datepicker._isDate(this.date) && Datepicker._comparePastDate(date, this.date)) {\n return;\n }\n\n this.setDate(date, false, Datepicker._isDate(this.date));\n return;\n }\n\n this._clearDates();\n this.draw();\n };\n\n _handleClearClick = () => {\n this._clearDates();\n this.setInputValues();\n };\n\n _clearDates = () => {\n this.date = null;\n this.endDate = null;\n this.dates?.splice(0);\n this.draw();\n };\n\n _handleMonthChange = (e) => {\n this.gotoMonth(e.target.value);\n };\n\n _handleYearChange = (e) => {\n this.gotoYear(e.target.value);\n };\n\n // change view to a specific month (zero-index, e.g. 0: January)\n gotoMonth(month) {\n if (!isNaN(month)) {\n this.calendars[0].month = parseInt(month, 10);\n this.adjustCalendars();\n }\n }\n\n // change view to a specific full year (e.g. \"2012\")\n gotoYear(year) {\n if (!isNaN(year)) {\n this.calendars[0].year = parseInt(year, 10);\n this.adjustCalendars();\n }\n }\n\n _handleInputChange = (e: Event) => {\n // Prevent change event from being fired when triggered by the plugin\n if (e['detail']?.firedBy === this) return;\n this.setDateFromInput(e.target as HTMLInputElement);\n };\n\n renderDayName(opts, day, abbr: boolean = false) {\n day += opts.firstDay;\n while (day >= 7) {\n day -= 7;\n }\n return abbr ? opts.i18n.weekdaysAbbrev[day] : opts.i18n.weekdays[day];\n }\n\n createDateInput() {\n const dateInput = <HTMLInputElement>this.el.cloneNode(true);\n // cloneNode copies the id too, and two elements sharing one id break every\n // lookup that goes through it.\n dateInput.removeAttribute('id');\n dateInput.classList.add('no-autoinit');\n this._addInputEventHandlers(dateInput);\n this.el.parentElement.appendChild(dateInput);\n return dateInput;\n }\n\n _finishSelection = () => {\n this.setInputValues();\n };\n\n _confirm = () => {\n this._finishSelection();\n if (typeof this.options.onConfirm === 'function') this.options.onConfirm.call(this);\n }\n\n _cancel = () => {\n if (typeof this.options.onCancel === 'function') this.options.onCancel.call(this);\n };\n\n static {\n Datepicker._template = `\n <div class=\"datepicker-container\">\n <div class=\"datepicker-date-display\">\n <span class=\"year-text\"></span>\n <span class=\"date-text\"></span>\n </div>\n <div class=\"datepicker-calendar-container\">\n <div class=\"datepicker-calendar\"></div>\n <div class=\"datepicker-footer\"></div>\n </div>\n </div>`;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Utils
|
|
3
|
+
} from "./chunk-M372EDXD.mjs";
|
|
4
|
+
import {
|
|
5
|
+
Component
|
|
6
|
+
} from "./chunk-PD6HYHAE.mjs";
|
|
7
|
+
|
|
8
|
+
// src/ts/components/keypad.ts
|
|
9
|
+
var _defaults = {
|
|
10
|
+
onKey: null
|
|
11
|
+
};
|
|
12
|
+
var isField = (el) => el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement;
|
|
13
|
+
var instances = /* @__PURE__ */ new Set();
|
|
14
|
+
var touched = /* @__PURE__ */ new WeakSet();
|
|
15
|
+
var segmenter;
|
|
16
|
+
function keyFor(e) {
|
|
17
|
+
const key = e.target.closest?.("button");
|
|
18
|
+
if (!key) return null;
|
|
19
|
+
const keypad = key.closest(".keypad, .keyboard")?.["Expressive_Keypad"];
|
|
20
|
+
if (keypad) return [keypad, key];
|
|
21
|
+
const wrapper = key.dataset.key && key.closest(".field");
|
|
22
|
+
if (!wrapper) return null;
|
|
23
|
+
for (const other of instances) {
|
|
24
|
+
const field = other.target;
|
|
25
|
+
if (field && wrapper.contains(field)) return [other, key];
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
var rootListeners = [
|
|
30
|
+
// A pointer press on a key would move focus off the field and hide its
|
|
31
|
+
// caret. Keep focus where it is while the field has it.
|
|
32
|
+
["mousedown", (e) => {
|
|
33
|
+
const hit = keyFor(e);
|
|
34
|
+
if (hit && hit[0]._root?.activeElement === hit[0].target) e.preventDefault();
|
|
35
|
+
}],
|
|
36
|
+
["click", (e) => {
|
|
37
|
+
const hit = keyFor(e);
|
|
38
|
+
if (hit) hit[0]._press(hit[1]);
|
|
39
|
+
}],
|
|
40
|
+
["focusin", (e) => {
|
|
41
|
+
if (isField(e.target)) touched.add(e.target);
|
|
42
|
+
}]
|
|
43
|
+
];
|
|
44
|
+
var Keypad = class _Keypad extends Component {
|
|
45
|
+
constructor(el, options) {
|
|
46
|
+
super(el, options, _Keypad);
|
|
47
|
+
this.el["Expressive_Keypad"] = this;
|
|
48
|
+
this.options = { ..._Keypad.defaults, ...options };
|
|
49
|
+
const root = this.el.getRootNode();
|
|
50
|
+
this._root = root.nodeType === 9 || root.nodeType === 11 ? root : null;
|
|
51
|
+
if (this._root && !this._shared()) {
|
|
52
|
+
for (const [type, listener] of rootListeners) this._root.addEventListener(type, listener);
|
|
53
|
+
}
|
|
54
|
+
instances.add(this);
|
|
55
|
+
const active = this._root?.activeElement;
|
|
56
|
+
if (isField(active)) touched.add(active);
|
|
57
|
+
}
|
|
58
|
+
static get defaults() {
|
|
59
|
+
return _defaults;
|
|
60
|
+
}
|
|
61
|
+
static init(els, options = {}) {
|
|
62
|
+
return super.init(els, options, _Keypad);
|
|
63
|
+
}
|
|
64
|
+
static getInstance(el) {
|
|
65
|
+
return el["Expressive_Keypad"];
|
|
66
|
+
}
|
|
67
|
+
destroy() {
|
|
68
|
+
instances.delete(this);
|
|
69
|
+
if (this._root && !this._shared()) {
|
|
70
|
+
for (const [type, listener] of rootListeners) this._root.removeEventListener(type, listener);
|
|
71
|
+
}
|
|
72
|
+
this.el["Expressive_Keypad"] = void 0;
|
|
73
|
+
}
|
|
74
|
+
/** The text field named by `aria-controls`, if there is one. */
|
|
75
|
+
get target() {
|
|
76
|
+
const id = this.el.getAttribute("aria-controls");
|
|
77
|
+
const field = id ? Utils.getElementById(this.el, id) : null;
|
|
78
|
+
return isField(field) ? field : null;
|
|
79
|
+
}
|
|
80
|
+
// Whether another keypad already listens on this one's root.
|
|
81
|
+
_shared() {
|
|
82
|
+
for (const other of instances) if (other !== this && other._root === this._root) return true;
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
/** @internal */
|
|
86
|
+
_press(key) {
|
|
87
|
+
const name = key.dataset.key;
|
|
88
|
+
if (key.disabled || !name && !key.hasAttribute("value")) return;
|
|
89
|
+
if (name === "Shift") {
|
|
90
|
+
key.setAttribute("aria-pressed", String(key.getAttribute("aria-pressed") !== "true"));
|
|
91
|
+
this.options.onKey?.(name);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
let text = name ? "" : key.value;
|
|
95
|
+
const shift = text && this.el.querySelector('[data-key="Shift"][aria-pressed="true"]');
|
|
96
|
+
if (shift) {
|
|
97
|
+
text = text.toUpperCase();
|
|
98
|
+
shift.setAttribute("aria-pressed", "false");
|
|
99
|
+
}
|
|
100
|
+
const field = this.target;
|
|
101
|
+
if (field && !field.matches(":disabled") && !field.readOnly) {
|
|
102
|
+
if (name === "Enter" && field instanceof HTMLInputElement) field.form?.requestSubmit();
|
|
103
|
+
else if (name === "Enter") this._edit(field, "\n", "insertLineBreak");
|
|
104
|
+
else if (name === "Backspace") this._edit(field, "", "deleteContentBackward");
|
|
105
|
+
else if (text) this._edit(field, text, "insertText");
|
|
106
|
+
}
|
|
107
|
+
this.options.onKey?.(name ?? text);
|
|
108
|
+
}
|
|
109
|
+
_edit(field, text, inputType) {
|
|
110
|
+
const { value } = field;
|
|
111
|
+
let start = field.selectionStart ?? value.length;
|
|
112
|
+
let end = field.selectionEnd ?? value.length;
|
|
113
|
+
if (start === 0 && end === 0 && !touched.has(field)) start = end = value.length;
|
|
114
|
+
if (inputType === "deleteContentBackward" && start === end && start) {
|
|
115
|
+
const tail = value.slice(Math.max(0, start - 64), start);
|
|
116
|
+
start -= (segmenter ?? (segmenter = new Intl.Segmenter())).segment(tail).containing(tail.length - 1).segment.length;
|
|
117
|
+
}
|
|
118
|
+
if (start === end && !text) return;
|
|
119
|
+
if (text && field.maxLength >= 0 && value.length - (end - start) + text.length > field.maxLength) return;
|
|
120
|
+
const next = value.slice(0, start) + text + value.slice(end);
|
|
121
|
+
field.value = next;
|
|
122
|
+
if (next && !field.value) {
|
|
123
|
+
field.value = value;
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (field.selectionStart !== null) field.setSelectionRange(start + text.length, start + text.length);
|
|
127
|
+
touched.add(field);
|
|
128
|
+
field.dispatchEvent(new InputEvent("input", { bubbles: true, composed: true, inputType, data: text || null }));
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export {
|
|
133
|
+
Keypad
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=chunk-K3HZMFMD.mjs.map
|