@sondor-technology/sondor-components 1.0.8 → 1.0.10
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/dist/components/accordion/accordion.constants.d.ts +5 -0
- package/dist/components/accordion/accordion.constants.d.ts.map +1 -0
- package/dist/components/accordion/accordion.constants.js +3 -0
- package/dist/components/accordion/accordion.constants.js.map +1 -0
- package/dist/components/accordion/accordion.d.ts +29 -0
- package/dist/components/accordion/accordion.d.ts.map +1 -0
- package/dist/components/accordion/accordion.js +226 -0
- package/dist/components/accordion/accordion.js.map +1 -0
- package/dist/components/alert/alert.constants.d.ts +2 -0
- package/dist/components/alert/alert.constants.d.ts.map +1 -1
- package/dist/components/alert/alert.d.ts +50 -2
- package/dist/components/alert/alert.d.ts.map +1 -1
- package/dist/components/alert/alert.js +285 -16
- package/dist/components/alert/alert.js.map +1 -1
- package/dist/components/avatar/avatar.d.ts +20 -0
- package/dist/components/avatar/avatar.d.ts.map +1 -0
- package/dist/components/avatar/avatar.js +100 -0
- package/dist/components/avatar/avatar.js.map +1 -0
- package/dist/components/back-to-top/back-to-top.d.ts +29 -0
- package/dist/components/back-to-top/back-to-top.d.ts.map +1 -0
- package/dist/components/back-to-top/back-to-top.js +149 -0
- package/dist/components/back-to-top/back-to-top.js.map +1 -0
- package/dist/components/bar-chart/bar-chart.d.ts +42 -0
- package/dist/components/bar-chart/bar-chart.d.ts.map +1 -0
- package/dist/components/bar-chart/bar-chart.js +298 -0
- package/dist/components/bar-chart/bar-chart.js.map +1 -0
- package/dist/components/breadcrumb/breadcrumb.js +2 -2
- package/dist/components/button/button.d.ts +1 -0
- package/dist/components/button/button.d.ts.map +1 -1
- package/dist/components/button/button.js +8 -8
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/button-group/button-group.js +4 -4
- package/dist/components/calendar/calendar.d.ts.map +1 -1
- package/dist/components/calendar/calendar.js +21 -9
- package/dist/components/calendar/calendar.js.map +1 -1
- package/dist/components/chart/chart-base.d.ts +59 -0
- package/dist/components/chart/chart-base.d.ts.map +1 -0
- package/dist/components/chart/chart-base.js +261 -0
- package/dist/components/chart/chart-base.js.map +1 -0
- package/dist/components/chart/chart.utils.d.ts +27 -0
- package/dist/components/chart/chart.utils.d.ts.map +1 -0
- package/dist/components/chart/chart.utils.js +117 -0
- package/dist/components/chart/chart.utils.js.map +1 -0
- package/dist/components/code-block/code-block.d.ts +5 -0
- package/dist/components/code-block/code-block.d.ts.map +1 -1
- package/dist/components/code-block/code-block.js +34 -24
- package/dist/components/code-block/code-block.js.map +1 -1
- package/dist/components/consent/consent.d.ts +63 -0
- package/dist/components/consent/consent.d.ts.map +1 -0
- package/dist/components/consent/consent.js +327 -0
- package/dist/components/consent/consent.js.map +1 -0
- package/dist/components/consent/consent.utils.d.ts +36 -0
- package/dist/components/consent/consent.utils.d.ts.map +1 -0
- package/dist/components/consent/consent.utils.js +82 -0
- package/dist/components/consent/consent.utils.js.map +1 -0
- package/dist/components/contact/contact.d.ts +22 -0
- package/dist/components/contact/contact.d.ts.map +1 -0
- package/dist/components/contact/contact.js +83 -0
- package/dist/components/contact/contact.js.map +1 -0
- package/dist/components/container/container.d.ts +20 -0
- package/dist/components/container/container.d.ts.map +1 -0
- package/dist/components/container/container.js +68 -0
- package/dist/components/container/container.js.map +1 -0
- package/dist/components/content-card/content-card.js +4 -4
- package/dist/components/context-menu/context-menu.d.ts +89 -0
- package/dist/components/context-menu/context-menu.d.ts.map +1 -0
- package/dist/components/context-menu/context-menu.js +414 -0
- package/dist/components/context-menu/context-menu.js.map +1 -0
- package/dist/components/cron-builder/cron-builder.d.ts +5 -2
- package/dist/components/cron-builder/cron-builder.d.ts.map +1 -1
- package/dist/components/cron-builder/cron-builder.js +83 -15
- package/dist/components/cron-builder/cron-builder.js.map +1 -1
- package/dist/components/cta/cta.d.ts +20 -0
- package/dist/components/cta/cta.d.ts.map +1 -0
- package/dist/components/cta/cta.js +64 -0
- package/dist/components/cta/cta.js.map +1 -0
- package/dist/components/drawer/drawer.js +6 -6
- package/dist/components/faq/faq-item.d.ts +22 -0
- package/dist/components/faq/faq-item.d.ts.map +1 -0
- package/dist/components/faq/faq-item.js +117 -0
- package/dist/components/faq/faq-item.js.map +1 -0
- package/dist/components/faq/faq.d.ts +18 -0
- package/dist/components/faq/faq.d.ts.map +1 -0
- package/dist/components/faq/faq.js +38 -0
- package/dist/components/faq/faq.js.map +1 -0
- package/dist/components/feature-grid/feature-grid.d.ts +22 -0
- package/dist/components/feature-grid/feature-grid.d.ts.map +1 -0
- package/dist/components/feature-grid/feature-grid.js +55 -0
- package/dist/components/feature-grid/feature-grid.js.map +1 -0
- package/dist/components/feature-grid/feature.d.ts +18 -0
- package/dist/components/feature-grid/feature.d.ts.map +1 -0
- package/dist/components/feature-grid/feature.js +91 -0
- package/dist/components/feature-grid/feature.js.map +1 -0
- package/dist/components/field/field.js +2 -2
- package/dist/components/footer/footer.js +4 -4
- package/dist/components/form/form-reset.d.ts +7 -0
- package/dist/components/form/form-reset.d.ts.map +1 -0
- package/dist/components/form/form-reset.js +47 -0
- package/dist/components/form/form-reset.js.map +1 -0
- package/dist/components/form/form.d.ts +5 -0
- package/dist/components/form/form.d.ts.map +1 -1
- package/dist/components/form/form.js +17 -3
- package/dist/components/form/form.js.map +1 -1
- package/dist/components/grid/grid.d.ts +5 -0
- package/dist/components/grid/grid.d.ts.map +1 -1
- package/dist/components/grid/grid.js +86 -4
- package/dist/components/grid/grid.js.map +1 -1
- package/dist/components/heat-map/heat-map.d.ts +39 -0
- package/dist/components/heat-map/heat-map.d.ts.map +1 -0
- package/dist/components/heat-map/heat-map.js +306 -0
- package/dist/components/heat-map/heat-map.js.map +1 -0
- package/dist/components/hero/hero.d.ts +26 -0
- package/dist/components/hero/hero.d.ts.map +1 -0
- package/dist/components/hero/hero.js +132 -0
- package/dist/components/hero/hero.js.map +1 -0
- package/dist/components/icon/icon-paths.d.ts +84 -0
- package/dist/components/icon/icon-paths.d.ts.map +1 -1
- package/dist/components/icon/icon-paths.js +89 -0
- package/dist/components/icon/icon-paths.js.map +1 -1
- package/dist/components/icon/icon.d.ts +2 -0
- package/dist/components/icon/icon.d.ts.map +1 -1
- package/dist/components/icon/icon.js +10 -1
- package/dist/components/icon/icon.js.map +1 -1
- package/dist/components/image/image.d.ts +31 -0
- package/dist/components/image/image.d.ts.map +1 -0
- package/dist/components/image/image.js +179 -0
- package/dist/components/image/image.js.map +1 -0
- package/dist/components/input/input.js +4 -4
- package/dist/components/lazy/lazy.d.ts +34 -0
- package/dist/components/lazy/lazy.d.ts.map +1 -0
- package/dist/components/lazy/lazy.js +104 -0
- package/dist/components/lazy/lazy.js.map +1 -0
- package/dist/components/line-chart/line-chart.d.ts +37 -0
- package/dist/components/line-chart/line-chart.d.ts.map +1 -0
- package/dist/components/line-chart/line-chart.js +271 -0
- package/dist/components/line-chart/line-chart.js.map +1 -0
- package/dist/components/list/list-item.d.ts +45 -0
- package/dist/components/list/list-item.d.ts.map +1 -0
- package/dist/components/list/list-item.js +263 -0
- package/dist/components/list/list-item.js.map +1 -0
- package/dist/components/list/list.d.ts +50 -0
- package/dist/components/list/list.d.ts.map +1 -0
- package/dist/components/list/list.js +161 -0
- package/dist/components/list/list.js.map +1 -0
- package/dist/components/logo-cloud/logo-cloud.d.ts +19 -0
- package/dist/components/logo-cloud/logo-cloud.d.ts.map +1 -0
- package/dist/components/logo-cloud/logo-cloud.js +66 -0
- package/dist/components/logo-cloud/logo-cloud.js.map +1 -0
- package/dist/components/modal/modal.d.ts +12 -0
- package/dist/components/modal/modal.d.ts.map +1 -1
- package/dist/components/modal/modal.js +40 -11
- package/dist/components/modal/modal.js.map +1 -1
- package/dist/components/page-layout/page-layout.js +8 -8
- package/dist/components/pagination/pagination.d.ts +15 -0
- package/dist/components/pagination/pagination.d.ts.map +1 -0
- package/dist/components/pagination/pagination.js +126 -0
- package/dist/components/pagination/pagination.js.map +1 -0
- package/dist/components/pagination/pagination.utils.d.ts +3 -0
- package/dist/components/pagination/pagination.utils.d.ts.map +1 -0
- package/dist/components/pagination/pagination.utils.js +19 -0
- package/dist/components/pagination/pagination.utils.js.map +1 -0
- package/dist/components/pie-chart/pie-chart.d.ts +33 -0
- package/dist/components/pie-chart/pie-chart.d.ts.map +1 -0
- package/dist/components/pie-chart/pie-chart.js +233 -0
- package/dist/components/pie-chart/pie-chart.js.map +1 -0
- package/dist/components/pin-input/pin-input.js +4 -4
- package/dist/components/popover/popover.d.ts.map +1 -1
- package/dist/components/popover/popover.js +1 -3
- package/dist/components/popover/popover.js.map +1 -1
- package/dist/components/post-list/post-card.d.ts +16 -0
- package/dist/components/post-list/post-card.d.ts.map +1 -0
- package/dist/components/post-list/post-card.js +22 -0
- package/dist/components/post-list/post-card.js.map +1 -0
- package/dist/components/post-list/post-list.d.ts +17 -0
- package/dist/components/post-list/post-list.d.ts.map +1 -0
- package/dist/components/post-list/post-list.js +23 -0
- package/dist/components/post-list/post-list.js.map +1 -0
- package/dist/components/pricing/pricing-tier.d.ts +23 -0
- package/dist/components/pricing/pricing-tier.d.ts.map +1 -0
- package/dist/components/pricing/pricing-tier.js +144 -0
- package/dist/components/pricing/pricing-tier.js.map +1 -0
- package/dist/components/pricing/pricing.d.ts +18 -0
- package/dist/components/pricing/pricing.d.ts.map +1 -0
- package/dist/components/pricing/pricing.js +38 -0
- package/dist/components/pricing/pricing.js.map +1 -0
- package/dist/components/progress/progress.d.ts +17 -0
- package/dist/components/progress/progress.d.ts.map +1 -0
- package/dist/components/progress/progress.js +109 -0
- package/dist/components/progress/progress.js.map +1 -0
- package/dist/components/project-grid/project-card.d.ts +17 -0
- package/dist/components/project-grid/project-card.d.ts.map +1 -0
- package/dist/components/project-grid/project-card.js +23 -0
- package/dist/components/project-grid/project-card.js.map +1 -0
- package/dist/components/project-grid/project-grid.d.ts +17 -0
- package/dist/components/project-grid/project-grid.d.ts.map +1 -0
- package/dist/components/project-grid/project-grid.js +23 -0
- package/dist/components/project-grid/project-grid.js.map +1 -0
- package/dist/components/radio/radio.js +1 -1
- package/dist/components/reveal/reveal.constants.d.ts +10 -0
- package/dist/components/reveal/reveal.constants.d.ts.map +1 -0
- package/dist/components/reveal/reveal.constants.js +11 -0
- package/dist/components/reveal/reveal.constants.js.map +1 -0
- package/dist/components/reveal/reveal.d.ts +64 -0
- package/dist/components/reveal/reveal.d.ts.map +1 -0
- package/dist/components/reveal/reveal.js +352 -0
- package/dist/components/reveal/reveal.js.map +1 -0
- package/dist/components/scroll-progress/scroll-progress.d.ts +32 -0
- package/dist/components/scroll-progress/scroll-progress.d.ts.map +1 -0
- package/dist/components/scroll-progress/scroll-progress.js +120 -0
- package/dist/components/scroll-progress/scroll-progress.js.map +1 -0
- package/dist/components/section/card-row.d.ts +30 -0
- package/dist/components/section/card-row.d.ts.map +1 -0
- package/dist/components/section/card-row.js +174 -0
- package/dist/components/section/card-row.js.map +1 -0
- package/dist/components/section/card.d.ts +27 -0
- package/dist/components/section/card.d.ts.map +1 -0
- package/dist/components/section/card.js +205 -0
- package/dist/components/section/card.js.map +1 -0
- package/dist/components/section/row-item.d.ts +22 -0
- package/dist/components/section/row-item.d.ts.map +1 -0
- package/dist/components/section/row-item.js +53 -0
- package/dist/components/section/row-item.js.map +1 -0
- package/dist/components/section/section.d.ts +70 -0
- package/dist/components/section/section.d.ts.map +1 -0
- package/dist/components/section/section.js +240 -0
- package/dist/components/section/section.js.map +1 -0
- package/dist/components/select/select.js +3 -3
- package/dist/components/series-nav/series-nav.d.ts +29 -0
- package/dist/components/series-nav/series-nav.d.ts.map +1 -0
- package/dist/components/series-nav/series-nav.js +178 -0
- package/dist/components/series-nav/series-nav.js.map +1 -0
- package/dist/components/site-header/site-header.d.ts +51 -0
- package/dist/components/site-header/site-header.d.ts.map +1 -0
- package/dist/components/site-header/site-header.js +296 -0
- package/dist/components/site-header/site-header.js.map +1 -0
- package/dist/components/skeleton/skeleton.js +7 -7
- package/dist/components/sparkline/sparkline.d.ts +19 -0
- package/dist/components/sparkline/sparkline.d.ts.map +1 -0
- package/dist/components/sparkline/sparkline.js +99 -0
- package/dist/components/sparkline/sparkline.js.map +1 -0
- package/dist/components/spinner/spinner.d.ts +13 -0
- package/dist/components/spinner/spinner.d.ts.map +1 -0
- package/dist/components/spinner/spinner.js +65 -0
- package/dist/components/spinner/spinner.js.map +1 -0
- package/dist/components/split/split.d.ts +23 -0
- package/dist/components/split/split.d.ts.map +1 -0
- package/dist/components/split/split.js +104 -0
- package/dist/components/split/split.js.map +1 -0
- package/dist/components/stack/stack.d.ts +21 -0
- package/dist/components/stack/stack.d.ts.map +1 -0
- package/dist/components/stack/stack.js +102 -0
- package/dist/components/stack/stack.js.map +1 -0
- package/dist/components/stat-card/stat-card.d.ts +35 -0
- package/dist/components/stat-card/stat-card.d.ts.map +1 -0
- package/dist/components/stat-card/stat-card.js +199 -0
- package/dist/components/stat-card/stat-card.js.map +1 -0
- package/dist/components/stats/stat.d.ts +16 -0
- package/dist/components/stats/stat.d.ts.map +1 -0
- package/dist/components/stats/stat.js +51 -0
- package/dist/components/stats/stat.js.map +1 -0
- package/dist/components/stats/stats.d.ts +19 -0
- package/dist/components/stats/stats.d.ts.map +1 -0
- package/dist/components/stats/stats.js +45 -0
- package/dist/components/stats/stats.js.map +1 -0
- package/dist/components/switch/switch.js +2 -2
- package/dist/components/table/data-table.d.ts +115 -27
- package/dist/components/table/data-table.d.ts.map +1 -1
- package/dist/components/table/data-table.js +1012 -411
- package/dist/components/table/data-table.js.map +1 -1
- package/dist/components/table/data-table.utils.d.ts +81 -0
- package/dist/components/table/data-table.utils.d.ts.map +1 -0
- package/dist/components/table/data-table.utils.js +208 -0
- package/dist/components/table/data-table.utils.js.map +1 -0
- package/dist/components/table/table.d.ts +28 -0
- package/dist/components/table/table.d.ts.map +1 -1
- package/dist/components/table/table.js +161 -33
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/team/person.d.ts +19 -0
- package/dist/components/team/person.d.ts.map +1 -0
- package/dist/components/team/person.js +123 -0
- package/dist/components/team/person.js.map +1 -0
- package/dist/components/team/team.d.ts +18 -0
- package/dist/components/team/team.d.ts.map +1 -0
- package/dist/components/team/team.js +36 -0
- package/dist/components/team/team.js.map +1 -0
- package/dist/components/testimonials/testimonial.d.ts +18 -0
- package/dist/components/testimonials/testimonial.d.ts.map +1 -0
- package/dist/components/testimonials/testimonial.js +115 -0
- package/dist/components/testimonials/testimonial.js.map +1 -0
- package/dist/components/testimonials/testimonials.d.ts +18 -0
- package/dist/components/testimonials/testimonials.d.ts.map +1 -0
- package/dist/components/testimonials/testimonials.js +36 -0
- package/dist/components/testimonials/testimonials.js.map +1 -0
- package/dist/components/textarea/textarea.js +3 -3
- package/dist/components/theme-toggle/theme-toggle.js +1 -1
- package/dist/components/time-picker/time-picker.d.ts.map +1 -1
- package/dist/components/time-picker/time-picker.js +13 -3
- package/dist/components/time-picker/time-picker.js.map +1 -1
- package/dist/components/timeline/timeline-item.d.ts +18 -0
- package/dist/components/timeline/timeline-item.d.ts.map +1 -0
- package/dist/components/timeline/timeline-item.js +102 -0
- package/dist/components/timeline/timeline-item.js.map +1 -0
- package/dist/components/timeline/timeline.d.ts +18 -0
- package/dist/components/timeline/timeline.d.ts.map +1 -0
- package/dist/components/timeline/timeline.js +30 -0
- package/dist/components/timeline/timeline.js.map +1 -0
- package/dist/components/toast/toast.d.ts +33 -0
- package/dist/components/toast/toast.d.ts.map +1 -0
- package/dist/components/toast/toast.js +147 -0
- package/dist/components/toast/toast.js.map +1 -0
- package/dist/components/toggle-group/toggle-button.d.ts +2 -0
- package/dist/components/toggle-group/toggle-button.d.ts.map +1 -1
- package/dist/components/toggle-group/toggle-button.js +12 -5
- package/dist/components/toggle-group/toggle-button.js.map +1 -1
- package/dist/components/toggle-group/toggle-group.d.ts +6 -0
- package/dist/components/toggle-group/toggle-group.d.ts.map +1 -1
- package/dist/components/toggle-group/toggle-group.js +141 -21
- package/dist/components/toggle-group/toggle-group.js.map +1 -1
- package/dist/components/tooltip/tooltip.js +21 -21
- package/dist/components/vertical-nav/vertical-nav-group.js +3 -3
- package/dist/components/vertical-nav/vertical-nav-item.js +4 -4
- package/dist/components/video-embed/video-embed.d.ts +37 -0
- package/dist/components/video-embed/video-embed.d.ts.map +1 -0
- package/dist/components/video-embed/video-embed.js +183 -0
- package/dist/components/video-embed/video-embed.js.map +1 -0
- package/dist/index.d.ts +107 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +104 -0
- package/dist/index.js.map +1 -0
- package/dist/styles/index.css +205 -1
- package/dist/styles/reset.d.ts.map +1 -1
- package/dist/styles/reset.js +5 -0
- package/dist/styles/reset.js.map +1 -1
- package/package.json +214 -7
- package/src/components/accordion/accordion.constants.ts +5 -0
- package/src/components/accordion/accordion.ts +209 -0
- package/src/components/alert/alert.constants.ts +3 -0
- package/src/components/alert/alert.ts +284 -17
- package/src/components/avatar/avatar.ts +84 -0
- package/src/components/back-to-top/back-to-top.ts +140 -0
- package/src/components/bar-chart/bar-chart.ts +295 -0
- package/src/components/breadcrumb/breadcrumb.ts +2 -2
- package/src/components/button/button.ts +9 -8
- package/src/components/button-group/button-group.ts +4 -4
- package/src/components/calendar/calendar.ts +26 -9
- package/src/components/chart/chart-base.ts +275 -0
- package/src/components/chart/chart.utils.ts +140 -0
- package/src/components/code-block/code-block.ts +35 -24
- package/src/components/consent/consent.ts +312 -0
- package/src/components/consent/consent.utils.ts +110 -0
- package/src/components/contact/contact.ts +83 -0
- package/src/components/container/container.ts +60 -0
- package/src/components/content-card/content-card.ts +4 -4
- package/src/components/context-menu/context-menu.ts +426 -0
- package/src/components/cron-builder/cron-builder.ts +102 -22
- package/src/components/cta/cta.ts +64 -0
- package/src/components/drawer/drawer.ts +6 -6
- package/src/components/faq/faq-item.ts +110 -0
- package/src/components/faq/faq.ts +40 -0
- package/src/components/feature-grid/feature-grid.ts +52 -0
- package/src/components/feature-grid/feature.ts +84 -0
- package/src/components/field/field.ts +2 -2
- package/src/components/footer/footer.ts +4 -4
- package/src/components/form/form-reset.ts +45 -0
- package/src/components/form/form.ts +17 -3
- package/src/components/grid/grid.ts +73 -4
- package/src/components/heat-map/heat-map.ts +292 -0
- package/src/components/hero/hero.ts +132 -0
- package/src/components/icon/icon-paths.ts +92 -1
- package/src/components/icon/icon.ts +8 -1
- package/src/components/image/image.ts +165 -0
- package/src/components/input/input.ts +4 -4
- package/src/components/lazy/lazy.ts +94 -0
- package/src/components/line-chart/line-chart.ts +271 -0
- package/src/components/list/list-item.ts +225 -0
- package/src/components/list/list.ts +157 -0
- package/src/components/logo-cloud/logo-cloud.ts +65 -0
- package/src/components/modal/modal.ts +37 -11
- package/src/components/page-layout/page-layout.ts +8 -8
- package/src/components/pagination/pagination.ts +120 -0
- package/src/components/pagination/pagination.utils.ts +14 -0
- package/src/components/pie-chart/pie-chart.ts +230 -0
- package/src/components/pin-input/pin-input.ts +4 -4
- package/src/components/popover/popover.ts +1 -3
- package/src/components/post-list/post-card.ts +18 -0
- package/src/components/post-list/post-list.ts +19 -0
- package/src/components/pricing/pricing-tier.ts +132 -0
- package/src/components/pricing/pricing.ts +39 -0
- package/src/components/progress/progress.ts +95 -0
- package/src/components/project-grid/project-card.ts +19 -0
- package/src/components/project-grid/project-grid.ts +19 -0
- package/src/components/radio/radio.ts +1 -1
- package/src/components/reveal/reveal.constants.ts +20 -0
- package/src/components/reveal/reveal.ts +344 -0
- package/src/components/scroll-progress/scroll-progress.ts +119 -0
- package/src/components/section/card-row.ts +152 -0
- package/src/components/section/card.ts +197 -0
- package/src/components/section/row-item.ts +38 -0
- package/src/components/section/section.ts +232 -0
- package/src/components/select/select.ts +3 -3
- package/src/components/series-nav/series-nav.ts +164 -0
- package/src/components/site-header/site-header.ts +276 -0
- package/src/components/skeleton/skeleton.ts +7 -7
- package/src/components/sparkline/sparkline.ts +83 -0
- package/src/components/spinner/spinner.ts +55 -0
- package/src/components/split/split.ts +106 -0
- package/src/components/stack/stack.ts +88 -0
- package/src/components/stat-card/stat-card.ts +179 -0
- package/src/components/stats/stat.ts +49 -0
- package/src/components/stats/stats.ts +47 -0
- package/src/components/switch/switch.ts +2 -2
- package/src/components/table/data-table.ts +1015 -425
- package/src/components/table/data-table.utils.ts +276 -0
- package/src/components/table/table.ts +168 -38
- package/src/components/team/person.ts +113 -0
- package/src/components/team/team.ts +37 -0
- package/src/components/testimonials/testimonial.ts +108 -0
- package/src/components/testimonials/testimonials.ts +37 -0
- package/src/components/textarea/textarea.ts +3 -3
- package/src/components/theme-toggle/theme-toggle.ts +1 -1
- package/src/components/time-picker/time-picker.ts +17 -3
- package/src/components/timeline/timeline-item.ts +100 -0
- package/src/components/timeline/timeline.ts +31 -0
- package/src/components/toast/toast.ts +153 -0
- package/src/components/toggle-group/toggle-button.ts +9 -5
- package/src/components/toggle-group/toggle-group.ts +158 -42
- package/src/components/tooltip/tooltip.ts +21 -21
- package/src/components/vertical-nav/vertical-nav-group.ts +3 -3
- package/src/components/vertical-nav/vertical-nav-item.ts +4 -4
- package/src/components/video-embed/video-embed.ts +162 -0
- package/src/index.ts +108 -0
- package/src/styles/globals.css +63 -0
- package/src/styles/index.css +3 -1
- package/src/styles/prose.css +154 -0
- package/src/styles/reset.ts +5 -0
- package/src/styles/theme.css +53 -0
- package/src/styles/typography.css +1 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
import {LitElement, html, css, nothing} from "lit";
|
|
2
|
+
import {customElement, property, query, state} from "lit/decorators.js";
|
|
3
|
+
import {resetStyles} from "../../styles/reset.js";
|
|
4
|
+
import "../icon/icon.js";
|
|
5
|
+
|
|
6
|
+
export interface MenuItem {
|
|
7
|
+
/** Text shown for the item. Omit for a separator. */
|
|
8
|
+
label?: string;
|
|
9
|
+
/** Identifier returned in `st-menu-select`. Defaults to the label. */
|
|
10
|
+
value?: string;
|
|
11
|
+
icon?: string;
|
|
12
|
+
/** Right-aligned hint such as "Ctrl+C" (display only). */
|
|
13
|
+
shortcut?: string;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
/** Styles the item as destructive, e.g. Delete. */
|
|
16
|
+
danger?: boolean;
|
|
17
|
+
/** Turns the item into a checkbox item. Update `items` in response to `st-menu-select`. */
|
|
18
|
+
checked?: boolean;
|
|
19
|
+
/** Keeps the menu open after selecting, e.g. for toggles. */
|
|
20
|
+
keepOpen?: boolean;
|
|
21
|
+
/** Renders a divider line instead of an item. */
|
|
22
|
+
separator?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type MenuTrigger = "contextmenu" | "click" | "manual";
|
|
26
|
+
|
|
27
|
+
const VIEWPORT_MARGIN = 8;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A reusable menu styled like a native right-click menu. It renders in the top layer, so it is
|
|
31
|
+
* never clipped by scrolling containers, flips to stay on screen, and is fully keyboard
|
|
32
|
+
* operable (arrows, Home/End, type-ahead, Enter/Space, Escape).
|
|
33
|
+
*
|
|
34
|
+
* Opening: wrap an element in it (default trigger is right-click, which also covers the
|
|
35
|
+
* keyboard Menu key and Shift+F10), or call `show(x, y, context)` / `showAt(element, context)`
|
|
36
|
+
* with `trigger="manual"`.
|
|
37
|
+
*
|
|
38
|
+
* Events (bubble, composed): `st-menu-open`, `st-menu-close`, and `st-menu-select` with
|
|
39
|
+
* `{ item, value, context }`.
|
|
40
|
+
*/
|
|
41
|
+
@customElement("st-context-menu")
|
|
42
|
+
export class StContextMenu extends LitElement {
|
|
43
|
+
@property({type: Array}) items: MenuItem[] = [];
|
|
44
|
+
@property({type: String}) trigger: MenuTrigger = "contextmenu";
|
|
45
|
+
/** Accessible name of the menu. */
|
|
46
|
+
@property({type: String}) label = "Actions";
|
|
47
|
+
@property({type: Boolean, reflect: true}) disabled = false;
|
|
48
|
+
|
|
49
|
+
@state() private _open = false;
|
|
50
|
+
@state() private _active = -1;
|
|
51
|
+
|
|
52
|
+
@query("[popover]") private _menu!: HTMLElement;
|
|
53
|
+
|
|
54
|
+
private _context: unknown;
|
|
55
|
+
private _returnFocus: HTMLElement | null = null;
|
|
56
|
+
private _clicked: HTMLElement | null = null;
|
|
57
|
+
private _typeahead = "";
|
|
58
|
+
private _typeaheadTimer?: number;
|
|
59
|
+
|
|
60
|
+
static styles = [
|
|
61
|
+
resetStyles,
|
|
62
|
+
css`
|
|
63
|
+
:host {
|
|
64
|
+
display: contents;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
[popover] {
|
|
68
|
+
position: fixed;
|
|
69
|
+
inset: auto;
|
|
70
|
+
margin: 0;
|
|
71
|
+
min-width: 12rem;
|
|
72
|
+
max-width: min(24rem, calc(100vw - 16px));
|
|
73
|
+
max-height: calc(100vh - 16px);
|
|
74
|
+
overflow-y: auto;
|
|
75
|
+
padding: var(--st-spacing-xs);
|
|
76
|
+
border: 1px solid var(--st-color-border);
|
|
77
|
+
border-radius: var(--st-radius-md);
|
|
78
|
+
background: var(--st-color-surface);
|
|
79
|
+
color: var(--st-color-text);
|
|
80
|
+
box-shadow: var(--st-shadow-lg);
|
|
81
|
+
font-size: var(--st-font-size-sm);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
85
|
+
[popover]:popover-open {
|
|
86
|
+
animation: st-menu-in 0.1s ease-out;
|
|
87
|
+
}
|
|
88
|
+
@keyframes st-menu-in {
|
|
89
|
+
from {
|
|
90
|
+
opacity: 0;
|
|
91
|
+
transform: scale(0.97);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.item {
|
|
97
|
+
display: flex;
|
|
98
|
+
align-items: center;
|
|
99
|
+
gap: var(--st-spacing-sm);
|
|
100
|
+
width: 100%;
|
|
101
|
+
padding: var(--st-spacing-xs) var(--st-spacing-sm);
|
|
102
|
+
border: 0;
|
|
103
|
+
border-radius: var(--st-radius-sm);
|
|
104
|
+
background: none;
|
|
105
|
+
color: inherit;
|
|
106
|
+
font: inherit;
|
|
107
|
+
text-align: left;
|
|
108
|
+
cursor: default;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.item:hover:not(:disabled),
|
|
112
|
+
.item:focus-visible {
|
|
113
|
+
outline: none;
|
|
114
|
+
background: var(--st-color-primary-bg);
|
|
115
|
+
color: var(--st-color-primary-text);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.item:disabled {
|
|
119
|
+
opacity: 0.5;
|
|
120
|
+
cursor: not-allowed;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.item.danger {
|
|
124
|
+
color: var(--st-color-error-text);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.item.danger:hover:not(:disabled),
|
|
128
|
+
.item.danger:focus-visible {
|
|
129
|
+
background: var(--st-color-error-bg);
|
|
130
|
+
color: var(--st-color-error-text);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.lead {
|
|
134
|
+
display: inline-flex;
|
|
135
|
+
flex-shrink: 0;
|
|
136
|
+
width: 1.25rem;
|
|
137
|
+
justify-content: center;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.label {
|
|
141
|
+
flex: 1;
|
|
142
|
+
white-space: nowrap;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.shortcut {
|
|
146
|
+
padding-left: var(--st-spacing-lg);
|
|
147
|
+
color: var(--st-color-text-muted);
|
|
148
|
+
font-size: var(--st-font-size-xs);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.separator {
|
|
152
|
+
height: 1px;
|
|
153
|
+
margin: var(--st-spacing-xs) calc(var(--st-spacing-xs) * -1);
|
|
154
|
+
background: var(--st-color-border);
|
|
155
|
+
}
|
|
156
|
+
`,
|
|
157
|
+
];
|
|
158
|
+
|
|
159
|
+
connectedCallback() {
|
|
160
|
+
super.connectedCallback();
|
|
161
|
+
this.addEventListener("contextmenu", this._onContextMenu);
|
|
162
|
+
this.addEventListener("click", this._onTriggerClick);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
disconnectedCallback() {
|
|
166
|
+
this.removeEventListener("contextmenu", this._onContextMenu);
|
|
167
|
+
this.removeEventListener("click", this._onTriggerClick);
|
|
168
|
+
this._listen(false);
|
|
169
|
+
super.disconnectedCallback();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** True while the menu is showing. */
|
|
173
|
+
get isOpen() {
|
|
174
|
+
return this._open;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private _onContextMenu = (e: MouseEvent) => {
|
|
178
|
+
if (this.trigger !== "contextmenu" || this.disabled) return;
|
|
179
|
+
// Let the native menu through on text inputs so users keep copy/paste.
|
|
180
|
+
const target = e.composedPath()[0] as HTMLElement;
|
|
181
|
+
if (target?.closest?.("input, textarea, [contenteditable]")) return;
|
|
182
|
+
e.preventDefault();
|
|
183
|
+
// Some browsers don't focus a button on right-click, so remember what was clicked.
|
|
184
|
+
this._clicked = (target?.closest?.("button, a[href], [tabindex]") as HTMLElement | null) ?? null;
|
|
185
|
+
this.show(e.clientX, e.clientY);
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
private _onTriggerClick = (e: MouseEvent) => {
|
|
189
|
+
if (this.trigger !== "click" || this.disabled || this._menu?.contains(e.target as Node)) return;
|
|
190
|
+
this.showAt(this);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/** Opens the menu at viewport coordinates. `context` is echoed back in `st-menu-select`. */
|
|
194
|
+
show(x: number, y: number, context?: unknown) {
|
|
195
|
+
this._show(x, y, context);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private _show(x: number, y: number, context?: unknown, flipY?: number) {
|
|
199
|
+
if (!this.items.length || this.disabled) return;
|
|
200
|
+
this._context = context;
|
|
201
|
+
const focused = this._activeElement();
|
|
202
|
+
this._returnFocus = focused && focused !== document.body ? focused : this._clicked;
|
|
203
|
+
this._clicked = null;
|
|
204
|
+
this._open = true;
|
|
205
|
+
this.updateComplete.then(() => {
|
|
206
|
+
const menu = this._menu;
|
|
207
|
+
if (!menu) return;
|
|
208
|
+
if (!menu.matches(":popover-open")) menu.showPopover();
|
|
209
|
+
this._place(x, y, flipY);
|
|
210
|
+
this._listen(true);
|
|
211
|
+
this._focusItem(this._nextEnabled(-1, 1));
|
|
212
|
+
this.dispatchEvent(
|
|
213
|
+
new CustomEvent("st-menu-open", {detail: {context}, bubbles: true, composed: true}),
|
|
214
|
+
);
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** Opens the menu below (or above, if there is no room) an element, e.g. a "more" button. */
|
|
219
|
+
showAt(anchor: HTMLElement, context?: unknown) {
|
|
220
|
+
const rect = anchor.getBoundingClientRect();
|
|
221
|
+
// Opens below the anchor, or above it when there is no room.
|
|
222
|
+
this._show(rect.left, rect.bottom + 4, context, rect.top - 4);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** Closes the menu and restores focus to where it was before opening. */
|
|
226
|
+
hide() {
|
|
227
|
+
if (this._menu?.matches(":popover-open")) this._menu.hidePopover();
|
|
228
|
+
else this._afterClose();
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
private _activeElement(): HTMLElement | null {
|
|
232
|
+
let el = document.activeElement as HTMLElement | null;
|
|
233
|
+
while (el?.shadowRoot?.activeElement) el = el.shadowRoot.activeElement as HTMLElement;
|
|
234
|
+
return el;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private _place(x: number, y: number, flipY?: number) {
|
|
238
|
+
const menu = this._menu;
|
|
239
|
+
if (!menu) return;
|
|
240
|
+
// Layout size, so the opening scale animation does not skew the measurement.
|
|
241
|
+
const {offsetWidth: width, offsetHeight: height} = menu;
|
|
242
|
+
const maxLeft = window.innerWidth - width - VIEWPORT_MARGIN;
|
|
243
|
+
const maxTop = window.innerHeight - height - VIEWPORT_MARGIN;
|
|
244
|
+
const left = x > maxLeft ? Math.max(VIEWPORT_MARGIN, x - width) : x;
|
|
245
|
+
let top = y;
|
|
246
|
+
if (y > maxTop) top = flipY !== undefined ? flipY - height : y - height;
|
|
247
|
+
top = Math.min(Math.max(VIEWPORT_MARGIN, top), Math.max(VIEWPORT_MARGIN, maxTop));
|
|
248
|
+
menu.style.left = `${Math.max(VIEWPORT_MARGIN, left)}px`;
|
|
249
|
+
menu.style.top = `${top}px`;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Light dismiss is handled here rather than by popover="auto", because browsers that fire
|
|
254
|
+
* contextmenu on mouse-down (macOS, Linux) would close an auto popover on the mouse-up.
|
|
255
|
+
*/
|
|
256
|
+
private _listen(on: boolean) {
|
|
257
|
+
const method = on ? "addEventListener" : "removeEventListener";
|
|
258
|
+
window[method]("resize", this._closeOnLayoutChange);
|
|
259
|
+
window[method]("scroll", this._closeOnLayoutChange, true);
|
|
260
|
+
window[method]("blur", this._dismiss);
|
|
261
|
+
document[method]("pointerdown", this._onOutsidePointer as EventListener, true);
|
|
262
|
+
document[method]("keydown", this._onEscape as EventListener, true);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
private _dismiss = () => this.hide();
|
|
266
|
+
|
|
267
|
+
private _onOutsidePointer = (e: PointerEvent) => {
|
|
268
|
+
if (!e.composedPath().includes(this._menu)) this.hide();
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
private _onEscape = (e: KeyboardEvent) => {
|
|
272
|
+
if (e.key !== "Escape") return;
|
|
273
|
+
e.stopPropagation();
|
|
274
|
+
this.hide();
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
private _closeOnLayoutChange = (e: Event) => {
|
|
278
|
+
// Scrolling inside the menu itself must not dismiss it.
|
|
279
|
+
if (e.target instanceof Node && this._menu?.contains(e.target)) return;
|
|
280
|
+
this.hide();
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
private _onToggle = (e: Event) => {
|
|
284
|
+
const state = (e as ToggleEvent).newState;
|
|
285
|
+
if (state === "closed") this._afterClose();
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
private _afterClose() {
|
|
289
|
+
if (!this._open) return;
|
|
290
|
+
this._open = false;
|
|
291
|
+
this._active = -1;
|
|
292
|
+
this._listen(false);
|
|
293
|
+
this._returnFocus?.focus?.();
|
|
294
|
+
this._returnFocus = null;
|
|
295
|
+
this.dispatchEvent(
|
|
296
|
+
new CustomEvent("st-menu-close", {detail: {context: this._context}, bubbles: true, composed: true}),
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
private _isFocusable(item: MenuItem) {
|
|
301
|
+
return !item.separator && !item.disabled;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
private _nextEnabled(from: number, step: 1 | -1): number {
|
|
305
|
+
const n = this.items.length;
|
|
306
|
+
for (let i = 1; i <= n; i++) {
|
|
307
|
+
const index = (((from + step * i) % n) + n) % n;
|
|
308
|
+
if (this._isFocusable(this.items[index])) return index;
|
|
309
|
+
}
|
|
310
|
+
return -1;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
private _focusItem(index: number) {
|
|
314
|
+
if (index < 0) return;
|
|
315
|
+
this._active = index;
|
|
316
|
+
this.updateComplete.then(() => {
|
|
317
|
+
this.renderRoot.querySelector<HTMLElement>(`[data-index="${index}"]`)?.focus();
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
private _onKeydown(e: KeyboardEvent) {
|
|
322
|
+
const last = this.items.length - 1;
|
|
323
|
+
switch (e.key) {
|
|
324
|
+
case "ArrowDown":
|
|
325
|
+
e.preventDefault();
|
|
326
|
+
this._focusItem(this._nextEnabled(this._active, 1));
|
|
327
|
+
break;
|
|
328
|
+
case "ArrowUp":
|
|
329
|
+
e.preventDefault();
|
|
330
|
+
this._focusItem(this._nextEnabled(this._active < 0 ? 0 : this._active, -1));
|
|
331
|
+
break;
|
|
332
|
+
case "Home":
|
|
333
|
+
e.preventDefault();
|
|
334
|
+
this._focusItem(this._nextEnabled(-1, 1));
|
|
335
|
+
break;
|
|
336
|
+
case "End":
|
|
337
|
+
e.preventDefault();
|
|
338
|
+
this._focusItem(this._nextEnabled(last + 1, -1));
|
|
339
|
+
break;
|
|
340
|
+
case "Tab":
|
|
341
|
+
this.hide();
|
|
342
|
+
break;
|
|
343
|
+
default:
|
|
344
|
+
if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) this._typeaheadSearch(e.key);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
private _typeaheadSearch(char: string) {
|
|
349
|
+
window.clearTimeout(this._typeaheadTimer);
|
|
350
|
+
this._typeahead += char.toLowerCase();
|
|
351
|
+
this._typeaheadTimer = window.setTimeout(() => (this._typeahead = ""), 600);
|
|
352
|
+
const start = this._typeahead.length === 1 ? this._active : this._active - 1;
|
|
353
|
+
const n = this.items.length;
|
|
354
|
+
for (let i = 1; i <= n; i++) {
|
|
355
|
+
const index = (((start + i) % n) + n) % n;
|
|
356
|
+
const item = this.items[index];
|
|
357
|
+
if (this._isFocusable(item) && item.label?.toLowerCase().startsWith(this._typeahead)) {
|
|
358
|
+
this._focusItem(index);
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
private _select(item: MenuItem) {
|
|
365
|
+
if (!this._isFocusable(item)) return;
|
|
366
|
+
this.dispatchEvent(
|
|
367
|
+
new CustomEvent("st-menu-select", {
|
|
368
|
+
detail: {item, value: item.value ?? item.label, context: this._context},
|
|
369
|
+
bubbles: true,
|
|
370
|
+
composed: true,
|
|
371
|
+
}),
|
|
372
|
+
);
|
|
373
|
+
if (!item.keepOpen) this.hide();
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
private _renderItem(item: MenuItem, index: number) {
|
|
377
|
+
if (item.separator) return html`<div class="separator" role="separator"></div>`;
|
|
378
|
+
const checkable = item.checked !== undefined;
|
|
379
|
+
return html`
|
|
380
|
+
<button
|
|
381
|
+
class="item ${item.danger ? "danger" : ""}"
|
|
382
|
+
type="button"
|
|
383
|
+
role=${checkable ? "menuitemcheckbox" : "menuitem"}
|
|
384
|
+
aria-checked=${checkable ? String(item.checked) : nothing}
|
|
385
|
+
?disabled=${item.disabled}
|
|
386
|
+
tabindex=${index === this._active ? "0" : "-1"}
|
|
387
|
+
data-index=${index}
|
|
388
|
+
@click=${() => this._select(item)}
|
|
389
|
+
@pointerenter=${(e: PointerEvent) => !item.disabled && (e.currentTarget as HTMLElement).focus()}
|
|
390
|
+
>
|
|
391
|
+
<span class="lead" aria-hidden="true">
|
|
392
|
+
${checkable
|
|
393
|
+
? item.checked
|
|
394
|
+
? html`<st-icon name="check" size="sm"></st-icon>`
|
|
395
|
+
: nothing
|
|
396
|
+
: item.icon
|
|
397
|
+
? html`<st-icon name=${item.icon} size="sm"></st-icon>`
|
|
398
|
+
: nothing}
|
|
399
|
+
</span>
|
|
400
|
+
<span class="label">${item.label}</span>
|
|
401
|
+
${item.shortcut ? html`<span class="shortcut" aria-hidden="true">${item.shortcut}</span>` : nothing}
|
|
402
|
+
</button>
|
|
403
|
+
`;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
render() {
|
|
407
|
+
return html`
|
|
408
|
+
<slot></slot>
|
|
409
|
+
<div
|
|
410
|
+
popover="manual"
|
|
411
|
+
role="menu"
|
|
412
|
+
aria-label=${this.label}
|
|
413
|
+
@toggle=${this._onToggle}
|
|
414
|
+
@keydown=${this._onKeydown}
|
|
415
|
+
>
|
|
416
|
+
${this._open ? this.items.map((item, index) => this._renderItem(item, index)) : nothing}
|
|
417
|
+
</div>
|
|
418
|
+
`;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
declare global {
|
|
423
|
+
interface HTMLElementTagNameMap {
|
|
424
|
+
"st-context-menu": StContextMenu;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
@@ -2,6 +2,9 @@ import {LitElement, html, css, PropertyValues} from "lit";
|
|
|
2
2
|
import {customElement, property, state} from "lit/decorators.js";
|
|
3
3
|
import {resetStyles} from "../../styles/reset";
|
|
4
4
|
|
|
5
|
+
/** Reads `.value` from a custom form element event target. */
|
|
6
|
+
const targetValue = <T = string>(e: Event) => (e.target as unknown as {value: T}).value;
|
|
7
|
+
|
|
5
8
|
@customElement("st-cron-builder")
|
|
6
9
|
export class StCronBuilder extends LitElement {
|
|
7
10
|
static formAssociated = true;
|
|
@@ -22,6 +25,7 @@ export class StCronBuilder extends LitElement {
|
|
|
22
25
|
@state() private _customCronText = "";
|
|
23
26
|
|
|
24
27
|
private _defaultValue = "";
|
|
28
|
+
private _lastGeneratedOutput = "";
|
|
25
29
|
|
|
26
30
|
constructor() {
|
|
27
31
|
super();
|
|
@@ -41,7 +45,7 @@ export class StCronBuilder extends LitElement {
|
|
|
41
45
|
border: 1px solid var(--st-color-border);
|
|
42
46
|
border-radius: var(--st-radius-lg);
|
|
43
47
|
padding: var(--st-spacing-lg);
|
|
44
|
-
box-shadow:
|
|
48
|
+
box-shadow: var(--st-shadow-sm);
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
.builder-grid {
|
|
@@ -80,7 +84,7 @@ export class StCronBuilder extends LitElement {
|
|
|
80
84
|
text-align: center;
|
|
81
85
|
font-size: 11px;
|
|
82
86
|
padding: 4px;
|
|
83
|
-
background: var(--st-color-surface-muted
|
|
87
|
+
background: var(--st-color-surface-muted);
|
|
84
88
|
border-radius: var(--st-radius-sm);
|
|
85
89
|
color: var(--st-color-text-muted);
|
|
86
90
|
border: 1px solid var(--st-color-border);
|
|
@@ -88,25 +92,25 @@ export class StCronBuilder extends LitElement {
|
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
.segment-badge.active {
|
|
91
|
-
background: var(--st-color-primary
|
|
95
|
+
background: var(--st-color-primary);
|
|
92
96
|
color: var(--st-color-surface);
|
|
93
97
|
border-color: var(--st-color-primary);
|
|
94
98
|
font-weight: 600;
|
|
95
99
|
}
|
|
96
100
|
|
|
97
101
|
.success-text {
|
|
98
|
-
color: var(--st-color-success
|
|
102
|
+
color: var(--st-color-success);
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
.error-text {
|
|
102
|
-
color: var(--st-color-danger
|
|
106
|
+
color: var(--st-color-danger);
|
|
103
107
|
font-weight: 500;
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
.output-preview {
|
|
107
111
|
margin-top: var(--st-spacing-md);
|
|
108
112
|
padding: var(--st-spacing-md);
|
|
109
|
-
background: var(--st-color-surface-muted
|
|
113
|
+
background: var(--st-color-surface-muted);
|
|
110
114
|
border-radius: var(--st-radius-md);
|
|
111
115
|
border: 1px dashed var(--st-color-border);
|
|
112
116
|
}
|
|
@@ -120,11 +124,82 @@ export class StCronBuilder extends LitElement {
|
|
|
120
124
|
`,
|
|
121
125
|
];
|
|
122
126
|
|
|
123
|
-
override
|
|
124
|
-
|
|
127
|
+
override willUpdate(changedProperties: PropertyValues) {
|
|
128
|
+
super.willUpdate(changedProperties);
|
|
129
|
+
|
|
130
|
+
// Check if value changed, is truthy (not ""), and wasn't generated by the component itself
|
|
131
|
+
if (changedProperties.has("value") && this.value && this.value !== this._lastGeneratedOutput) {
|
|
132
|
+
this._parseIncomingValue(this.value);
|
|
133
|
+
this._generateOutput(true); // true = silent (don't dispatch 'change' event)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
override firstUpdated(changedProperties: PropertyValues) {
|
|
138
|
+
super.firstUpdated(changedProperties);
|
|
139
|
+
|
|
140
|
+
// If the component mounted without an external value, generate the default cron string
|
|
141
|
+
if (!this.value) {
|
|
142
|
+
this._generateOutput(true);
|
|
143
|
+
}
|
|
144
|
+
|
|
125
145
|
this._defaultValue = this.value;
|
|
126
146
|
}
|
|
127
147
|
|
|
148
|
+
private _parseIncomingValue(val: string) {
|
|
149
|
+
if (!val) return;
|
|
150
|
+
|
|
151
|
+
// 1. One-Off Checks
|
|
152
|
+
if (val.includes("T")) {
|
|
153
|
+
this._frequency = "one-off";
|
|
154
|
+
const [dateStr, timeStr] = val.split("T");
|
|
155
|
+
this._date = dateStr;
|
|
156
|
+
this._time = timeStr;
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const parts = val.trim().split(/\s+/);
|
|
161
|
+
if (parts.length !== 5) {
|
|
162
|
+
this._frequency = "custom";
|
|
163
|
+
this._customCron = val;
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// 🚀 THE FIX: Check mathematical validity FIRST.
|
|
168
|
+
// If it's broken (like DOW 15), force it to Custom so the error UI displays.
|
|
169
|
+
const analysis = this._translateCron(val);
|
|
170
|
+
if (!analysis.valid) {
|
|
171
|
+
this._frequency = "custom";
|
|
172
|
+
this._customCron = val;
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// 2. Safe mapping for valid cron strings
|
|
177
|
+
const [min, hour, dom, mon, dow] = parts;
|
|
178
|
+
|
|
179
|
+
if (/^\d+$/.test(min) && /^\d+$/.test(hour)) {
|
|
180
|
+
this._time = `${hour.padStart(2, "0")}:${min.padStart(2, "0")}`;
|
|
181
|
+
|
|
182
|
+
if (dom === "*" && mon === "*" && dow === "*") {
|
|
183
|
+
this._frequency = "daily";
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// Ensure weekly is only triggered for simple lists (e.g. "1,3,5" or "1"), not steps/ranges
|
|
187
|
+
else if (dom === "*" && mon === "*" && /^[0-7](,[0-7])*$/.test(dow)) {
|
|
188
|
+
this._frequency = "weekly";
|
|
189
|
+
this._days = dow;
|
|
190
|
+
return;
|
|
191
|
+
} else if (/^\d+$/.test(dom) && mon === "*" && dow === "*") {
|
|
192
|
+
this._frequency = "monthly";
|
|
193
|
+
this._monthDay = dom;
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// 3. Fallback for valid but complex expressions (e.g., */15 * * * *)
|
|
199
|
+
this._frequency = "custom";
|
|
200
|
+
this._customCron = val;
|
|
201
|
+
}
|
|
202
|
+
|
|
128
203
|
private _translateCron(cron: string): {valid: boolean; text: string} {
|
|
129
204
|
const parts = cron.trim().split(/\s+/);
|
|
130
205
|
|
|
@@ -238,7 +313,7 @@ export class StCronBuilder extends LitElement {
|
|
|
238
313
|
return {valid: true, text: desc + "."};
|
|
239
314
|
}
|
|
240
315
|
|
|
241
|
-
private _generateOutput() {
|
|
316
|
+
private _generateOutput(silent = false) {
|
|
242
317
|
let output = "";
|
|
243
318
|
this._customCronError = "";
|
|
244
319
|
this._customCronText = "";
|
|
@@ -275,13 +350,18 @@ export class StCronBuilder extends LitElement {
|
|
|
275
350
|
}
|
|
276
351
|
}
|
|
277
352
|
|
|
353
|
+
this._lastGeneratedOutput = output;
|
|
278
354
|
this.value = output;
|
|
279
355
|
this._internals.setFormValue(output);
|
|
280
|
-
|
|
356
|
+
|
|
357
|
+
// Only dispatch if the user actually clicked/typed something
|
|
358
|
+
if (!silent) {
|
|
359
|
+
this.dispatchEvent(new Event("change", {bubbles: true, composed: true}));
|
|
360
|
+
}
|
|
281
361
|
}
|
|
282
362
|
|
|
283
|
-
private _handleCustomCronInput(e:
|
|
284
|
-
const inputEl = e.target;
|
|
363
|
+
private _handleCustomCronInput(e: Event) {
|
|
364
|
+
const inputEl = e.target as HTMLInputElement;
|
|
285
365
|
const sanitized = inputEl.value.replace(/[^0-9A-Za-z\s\*\/\-\,]/g, "");
|
|
286
366
|
|
|
287
367
|
if (inputEl.value !== sanitized) {
|
|
@@ -292,8 +372,8 @@ export class StCronBuilder extends LitElement {
|
|
|
292
372
|
this._generateOutput();
|
|
293
373
|
}
|
|
294
374
|
|
|
295
|
-
private _handleFrequencyChange(e:
|
|
296
|
-
this._frequency = e
|
|
375
|
+
private _handleFrequencyChange(e: Event) {
|
|
376
|
+
this._frequency = targetValue(e);
|
|
297
377
|
this._generateOutput();
|
|
298
378
|
}
|
|
299
379
|
|
|
@@ -345,8 +425,8 @@ export class StCronBuilder extends LitElement {
|
|
|
345
425
|
<st-toggle-group
|
|
346
426
|
multiple
|
|
347
427
|
.value=${this._days}
|
|
348
|
-
@change=${(e:
|
|
349
|
-
this._days = e
|
|
428
|
+
@change=${(e: Event) => {
|
|
429
|
+
this._days = targetValue(e);
|
|
350
430
|
this._generateOutput();
|
|
351
431
|
}}
|
|
352
432
|
>
|
|
@@ -368,8 +448,8 @@ export class StCronBuilder extends LitElement {
|
|
|
368
448
|
label="Run on day of month"
|
|
369
449
|
.options=${monthDayOptions}
|
|
370
450
|
.value=${this._monthDay}
|
|
371
|
-
@change=${(e:
|
|
372
|
-
this._monthDay = e
|
|
451
|
+
@change=${(e: Event) => {
|
|
452
|
+
this._monthDay = targetValue(e);
|
|
373
453
|
this._generateOutput();
|
|
374
454
|
}}
|
|
375
455
|
></st-select>
|
|
@@ -382,8 +462,8 @@ export class StCronBuilder extends LitElement {
|
|
|
382
462
|
<label>Execution Date</label>
|
|
383
463
|
<st-calendar
|
|
384
464
|
.value=${this._date}
|
|
385
|
-
@change=${(e:
|
|
386
|
-
this._date = e
|
|
465
|
+
@change=${(e: Event) => {
|
|
466
|
+
this._date = targetValue(e);
|
|
387
467
|
this._generateOutput();
|
|
388
468
|
}}
|
|
389
469
|
></st-calendar>
|
|
@@ -427,8 +507,8 @@ export class StCronBuilder extends LitElement {
|
|
|
427
507
|
<st-time-picker
|
|
428
508
|
label="Execution Time"
|
|
429
509
|
.value=${this._time}
|
|
430
|
-
@change=${(e:
|
|
431
|
-
this._time = e
|
|
510
|
+
@change=${(e: Event) => {
|
|
511
|
+
this._time = targetValue(e);
|
|
432
512
|
this._generateOutput();
|
|
433
513
|
}}
|
|
434
514
|
></st-time-picker>
|