@fusion.dev/helix-headless 0.0.0-dev
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/LICENSE +21 -0
- package/custom-elements.json +75202 -0
- package/dist/accordion/index.d.ts +2 -0
- package/dist/accordion/index.js +2 -0
- package/dist/accordion/item/accordion-item.d.ts +141 -0
- package/dist/accordion/item/accordion-item.js +214 -0
- package/dist/accordion/root/accordion-root.d.ts +57 -0
- package/dist/accordion/root/accordion-root.js +96 -0
- package/dist/announcement/index.d.ts +1 -0
- package/dist/announcement/index.js +1 -0
- package/dist/announcement/root/announcement-root.d.ts +106 -0
- package/dist/announcement/root/announcement-root.js +144 -0
- package/dist/app-header/index.d.ts +1 -0
- package/dist/app-header/index.js +1 -0
- package/dist/app-header/root/app-header-root.d.ts +113 -0
- package/dist/app-header/root/app-header-root.js +147 -0
- package/dist/avatar/group/avatar-group.d.ts +116 -0
- package/dist/avatar/group/avatar-group.js +136 -0
- package/dist/avatar/index.d.ts +2 -0
- package/dist/avatar/index.js +2 -0
- package/dist/avatar/root/avatar-root.d.ts +71 -0
- package/dist/avatar/root/avatar-root.js +147 -0
- package/dist/badge/index.d.ts +1 -0
- package/dist/badge/index.js +1 -0
- package/dist/badge/root/badge-root.d.ts +61 -0
- package/dist/badge/root/badge-root.js +121 -0
- package/dist/bar-chart/index.d.ts +1 -0
- package/dist/bar-chart/index.js +1 -0
- package/dist/bar-chart/root/bar-chart-root.d.ts +266 -0
- package/dist/bar-chart/root/bar-chart-root.js +515 -0
- package/dist/blockquote/index.d.ts +1 -0
- package/dist/blockquote/index.js +1 -0
- package/dist/blockquote/root/blockquote-root.d.ts +51 -0
- package/dist/blockquote/root/blockquote-root.js +84 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +104 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +137 -0
- package/dist/breadcrumbs/index.d.ts +2 -0
- package/dist/breadcrumbs/index.js +2 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +77 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.js +94 -0
- package/dist/button/index.d.ts +1 -0
- package/dist/button/index.js +1 -0
- package/dist/button/root/button-root.d.ts +251 -0
- package/dist/button/root/button-root.js +401 -0
- package/dist/button-group/index.d.ts +1 -0
- package/dist/button-group/index.js +1 -0
- package/dist/button-group/root/button-group-root.d.ts +62 -0
- package/dist/button-group/root/button-group-root.js +62 -0
- package/dist/callout/index.d.ts +1 -0
- package/dist/callout/index.js +1 -0
- package/dist/callout/root/callout-root.d.ts +72 -0
- package/dist/callout/root/callout-root.js +90 -0
- package/dist/card/index.d.ts +1 -0
- package/dist/card/index.js +1 -0
- package/dist/card/root/card-root.d.ts +54 -0
- package/dist/card/root/card-root.js +71 -0
- package/dist/carousel/index.d.ts +1 -0
- package/dist/carousel/index.js +1 -0
- package/dist/carousel/root/carousel-root.d.ts +399 -0
- package/dist/carousel/root/carousel-root.js +723 -0
- package/dist/chat/composer/chat-composer.d.ts +160 -0
- package/dist/chat/composer/chat-composer.js +273 -0
- package/dist/chat/index.d.ts +3 -0
- package/dist/chat/index.js +3 -0
- package/dist/chat/message/chat-message.d.ts +170 -0
- package/dist/chat/message/chat-message.js +271 -0
- package/dist/chat/root/chat-root.d.ts +216 -0
- package/dist/chat/root/chat-root.js +389 -0
- package/dist/checkbox/index.d.ts +1 -0
- package/dist/checkbox/index.js +1 -0
- package/dist/checkbox/root/checkbox-root.d.ts +108 -0
- package/dist/checkbox/root/checkbox-root.js +207 -0
- package/dist/checkbox-group/index.d.ts +1 -0
- package/dist/checkbox-group/index.js +1 -0
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +155 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +293 -0
- package/dist/code/index.d.ts +1 -0
- package/dist/code/index.js +1 -0
- package/dist/code/root/code-root.d.ts +36 -0
- package/dist/code/root/code-root.js +43 -0
- package/dist/code-block/index.d.ts +1 -0
- package/dist/code-block/index.js +1 -0
- package/dist/code-block/root/code-block-root.d.ts +112 -0
- package/dist/code-block/root/code-block-root.js +155 -0
- package/dist/color-input/index.d.ts +1 -0
- package/dist/color-input/index.js +1 -0
- package/dist/color-input/root/color-input-root.d.ts +227 -0
- package/dist/color-input/root/color-input-root.js +456 -0
- package/dist/color-picker/color.d.ts +74 -0
- package/dist/color-picker/color.js +238 -0
- package/dist/color-picker/index.d.ts +2 -0
- package/dist/color-picker/index.js +2 -0
- package/dist/color-picker/root/color-picker-root.d.ts +303 -0
- package/dist/color-picker/root/color-picker-root.js +576 -0
- package/dist/combobox/index.d.ts +1 -0
- package/dist/combobox/index.js +1 -0
- package/dist/combobox/root/combobox-root.d.ts +396 -0
- package/dist/combobox/root/combobox-root.js +808 -0
- package/dist/command/index.d.ts +1 -0
- package/dist/command/index.js +1 -0
- package/dist/command/root/command-root.d.ts +166 -0
- package/dist/command/root/command-root.js +353 -0
- package/dist/copy-button/index.d.ts +1 -0
- package/dist/copy-button/index.js +1 -0
- package/dist/copy-button/root/copy-button-root.d.ts +154 -0
- package/dist/copy-button/root/copy-button-root.js +225 -0
- package/dist/data-table/index.d.ts +2 -0
- package/dist/data-table/index.js +2 -0
- package/dist/data-table/root/data-table-root.d.ts +392 -0
- package/dist/data-table/root/data-table-root.js +729 -0
- package/dist/data-table/root/order.d.ts +116 -0
- package/dist/data-table/root/order.js +175 -0
- package/dist/date-input/index.d.ts +1 -0
- package/dist/date-input/index.js +1 -0
- package/dist/date-input/root/date-input-root.d.ts +361 -0
- package/dist/date-input/root/date-input-root.js +791 -0
- package/dist/date-picker/index.d.ts +1 -0
- package/dist/date-picker/index.js +1 -0
- package/dist/date-picker/root/date-picker-root.d.ts +361 -0
- package/dist/date-picker/root/date-picker-root.js +837 -0
- package/dist/dialog/index.d.ts +1 -0
- package/dist/dialog/index.js +1 -0
- package/dist/dialog/root/dialog-root.d.ts +185 -0
- package/dist/dialog/root/dialog-root.js +319 -0
- package/dist/divider/index.d.ts +1 -0
- package/dist/divider/index.js +1 -0
- package/dist/divider/root/divider-root.d.ts +68 -0
- package/dist/divider/root/divider-root.js +116 -0
- package/dist/donut-chart/index.d.ts +1 -0
- package/dist/donut-chart/index.js +1 -0
- package/dist/donut-chart/root/donut-chart-root.d.ts +209 -0
- package/dist/donut-chart/root/donut-chart-root.js +395 -0
- package/dist/drawer/index.d.ts +1 -0
- package/dist/drawer/index.js +1 -0
- package/dist/drawer/root/drawer-root.d.ts +144 -0
- package/dist/drawer/root/drawer-root.js +222 -0
- package/dist/drilldown/index.d.ts +2 -0
- package/dist/drilldown/index.js +2 -0
- package/dist/drilldown/item/drilldown-item.d.ts +87 -0
- package/dist/drilldown/item/drilldown-item.js +152 -0
- package/dist/drilldown/root/drilldown-root.d.ts +115 -0
- package/dist/drilldown/root/drilldown-root.js +263 -0
- package/dist/element-events.generated.d.ts +1 -0
- package/dist/element-events.generated.js +125 -0
- package/dist/empty/index.d.ts +1 -0
- package/dist/empty/index.js +1 -0
- package/dist/empty/root/empty-root.d.ts +47 -0
- package/dist/empty/root/empty-root.js +68 -0
- package/dist/file-input/index.d.ts +1 -0
- package/dist/file-input/index.js +1 -0
- package/dist/file-input/root/file-input-root.d.ts +196 -0
- package/dist/file-input/root/file-input-root.js +488 -0
- package/dist/format-date/index.d.ts +1 -0
- package/dist/format-date/index.js +1 -0
- package/dist/format-date/root/format-date-root.d.ts +151 -0
- package/dist/format-date/root/format-date-root.js +266 -0
- package/dist/heatmap/index.d.ts +2 -0
- package/dist/heatmap/index.js +2 -0
- package/dist/heatmap/root/buckets.d.ts +62 -0
- package/dist/heatmap/root/buckets.js +85 -0
- package/dist/heatmap/root/heatmap-root.d.ts +330 -0
- package/dist/heatmap/root/heatmap-root.js +526 -0
- package/dist/icon/index.d.ts +1 -0
- package/dist/icon/index.js +1 -0
- package/dist/icon/root/icon-root.d.ts +53 -0
- package/dist/icon/root/icon-root.js +93 -0
- package/dist/icon-button/index.d.ts +1 -0
- package/dist/icon-button/index.js +1 -0
- package/dist/icon-button/root/icon-button-root.d.ts +40 -0
- package/dist/icon-button/root/icon-button-root.js +46 -0
- package/dist/image/index.d.ts +1 -0
- package/dist/image/index.js +1 -0
- package/dist/image/root/image-root.d.ts +213 -0
- package/dist/image/root/image-root.js +335 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.js +99 -0
- package/dist/input/index.d.ts +1 -0
- package/dist/input/index.js +1 -0
- package/dist/input/root/input-root.d.ts +281 -0
- package/dist/input/root/input-root.js +472 -0
- package/dist/kbd/index.d.ts +1 -0
- package/dist/kbd/index.js +1 -0
- package/dist/kbd/root/kbd-root.d.ts +98 -0
- package/dist/kbd/root/kbd-root.js +230 -0
- package/dist/legend/index.d.ts +1 -0
- package/dist/legend/index.js +1 -0
- package/dist/legend/root/legend-root.d.ts +83 -0
- package/dist/legend/root/legend-root.js +125 -0
- package/dist/line-chart/index.d.ts +1 -0
- package/dist/line-chart/index.js +1 -0
- package/dist/line-chart/root/line-chart-root.d.ts +238 -0
- package/dist/line-chart/root/line-chart-root.js +365 -0
- package/dist/list/index.d.ts +2 -0
- package/dist/list/index.js +2 -0
- package/dist/list/item/list-item.d.ts +95 -0
- package/dist/list/item/list-item.js +148 -0
- package/dist/list/root/list-root.d.ts +72 -0
- package/dist/list/root/list-root.js +61 -0
- package/dist/listbox/index.d.ts +1 -0
- package/dist/listbox/index.js +1 -0
- package/dist/listbox/root/listbox-root.d.ts +357 -0
- package/dist/listbox/root/listbox-root.js +890 -0
- package/dist/loader/index.d.ts +1 -0
- package/dist/loader/index.js +1 -0
- package/dist/loader/root/loader-root.d.ts +52 -0
- package/dist/loader/root/loader-root.js +74 -0
- package/dist/megamenu/index.d.ts +1 -0
- package/dist/megamenu/index.js +1 -0
- package/dist/megamenu/root/megamenu-root.d.ts +254 -0
- package/dist/megamenu/root/megamenu-root.js +526 -0
- package/dist/menu/index.d.ts +2 -0
- package/dist/menu/index.js +2 -0
- package/dist/menu/item/menu-item.d.ts +231 -0
- package/dist/menu/item/menu-item.js +405 -0
- package/dist/menu/root/menu-root.d.ts +158 -0
- package/dist/menu/root/menu-root.js +422 -0
- package/dist/meter/index.d.ts +1 -0
- package/dist/meter/index.js +1 -0
- package/dist/meter/root/meter-root.d.ts +234 -0
- package/dist/meter/root/meter-root.js +316 -0
- package/dist/navigation/index.d.ts +1 -0
- package/dist/navigation/index.js +1 -0
- package/dist/navigation/root/navigation-root.d.ts +55 -0
- package/dist/navigation/root/navigation-root.js +130 -0
- package/dist/notifications/index.d.ts +2 -0
- package/dist/notifications/index.js +2 -0
- package/dist/notifications/notification/notification.d.ts +181 -0
- package/dist/notifications/notification/notification.js +305 -0
- package/dist/notifications/root/notifications-root.d.ts +168 -0
- package/dist/notifications/root/notifications-root.js +291 -0
- package/dist/number-input/index.d.ts +1 -0
- package/dist/number-input/index.js +1 -0
- package/dist/number-input/root/number-input-root.d.ts +282 -0
- package/dist/number-input/root/number-input-root.js +592 -0
- package/dist/option/group/option-group.d.ts +38 -0
- package/dist/option/group/option-group.js +58 -0
- package/dist/option/index.d.ts +2 -0
- package/dist/option/index.js +2 -0
- package/dist/option/root/option-root.d.ts +194 -0
- package/dist/option/root/option-root.js +247 -0
- package/dist/outline/index.d.ts +1 -0
- package/dist/outline/index.js +1 -0
- package/dist/outline/root/outline-root.d.ts +237 -0
- package/dist/outline/root/outline-root.js +519 -0
- package/dist/pagination/index.d.ts +3 -0
- package/dist/pagination/index.js +3 -0
- package/dist/pagination/root/pagination-root.d.ts +390 -0
- package/dist/pagination/root/pagination-root.js +695 -0
- package/dist/pagination/size/pagination-size.d.ts +127 -0
- package/dist/pagination/size/pagination-size.js +232 -0
- package/dist/pagination/summary/pagination-summary.d.ts +90 -0
- package/dist/pagination/summary/pagination-summary.js +145 -0
- package/dist/pin-input/index.d.ts +1 -0
- package/dist/pin-input/index.js +1 -0
- package/dist/pin-input/root/pin-input-root.d.ts +292 -0
- package/dist/pin-input/root/pin-input-root.js +553 -0
- package/dist/popover/index.d.ts +1 -0
- package/dist/popover/index.js +1 -0
- package/dist/popover/root/popover-root.d.ts +108 -0
- package/dist/popover/root/popover-root.js +231 -0
- package/dist/progress/index.d.ts +1 -0
- package/dist/progress/index.js +1 -0
- package/dist/progress/root/progress-root.d.ts +125 -0
- package/dist/progress/root/progress-root.js +212 -0
- package/dist/qr-code/index.d.ts +1 -0
- package/dist/qr-code/index.js +1 -0
- package/dist/qr-code/root/qr-code-root.d.ts +93 -0
- package/dist/qr-code/root/qr-code-root.js +233 -0
- package/dist/quote/index.d.ts +1 -0
- package/dist/quote/index.js +1 -0
- package/dist/quote/root/quote-root.d.ts +36 -0
- package/dist/quote/root/quote-root.js +50 -0
- package/dist/radio/group/radio-group.d.ts +84 -0
- package/dist/radio/group/radio-group.js +170 -0
- package/dist/radio/index.d.ts +2 -0
- package/dist/radio/index.js +2 -0
- package/dist/radio/root/radio-root.d.ts +102 -0
- package/dist/radio/root/radio-root.js +151 -0
- package/dist/rating/index.d.ts +1 -0
- package/dist/rating/index.js +1 -0
- package/dist/rating/root/rating-root.d.ts +242 -0
- package/dist/rating/root/rating-root.js +484 -0
- package/dist/scroll-area/index.d.ts +1 -0
- package/dist/scroll-area/index.js +1 -0
- package/dist/scroll-area/root/scroll-area-root.d.ts +96 -0
- package/dist/scroll-area/root/scroll-area-root.js +215 -0
- package/dist/select/index.d.ts +1 -0
- package/dist/select/index.js +1 -0
- package/dist/select/root/select-root.d.ts +170 -0
- package/dist/select/root/select-root.js +419 -0
- package/dist/skeleton/index.d.ts +1 -0
- package/dist/skeleton/index.js +1 -0
- package/dist/skeleton/root/skeleton-root.d.ts +31 -0
- package/dist/skeleton/root/skeleton-root.js +42 -0
- package/dist/slider/index.d.ts +1 -0
- package/dist/slider/index.js +1 -0
- package/dist/slider/root/slider-root.d.ts +235 -0
- package/dist/slider/root/slider-root.js +488 -0
- package/dist/sparkline/index.d.ts +1 -0
- package/dist/sparkline/index.js +1 -0
- package/dist/sparkline/root/sparkline-root.d.ts +147 -0
- package/dist/sparkline/root/sparkline-root.js +278 -0
- package/dist/speed-dial/index.d.ts +2 -0
- package/dist/speed-dial/index.js +2 -0
- package/dist/speed-dial/item/speed-dial-item.d.ts +71 -0
- package/dist/speed-dial/item/speed-dial-item.js +113 -0
- package/dist/speed-dial/root/speed-dial-root.d.ts +122 -0
- package/dist/speed-dial/root/speed-dial-root.js +251 -0
- package/dist/splitter/index.d.ts +1 -0
- package/dist/splitter/index.js +1 -0
- package/dist/splitter/root/splitter-root.d.ts +491 -0
- package/dist/splitter/root/splitter-root.js +1030 -0
- package/dist/stat/group/stat-group.d.ts +30 -0
- package/dist/stat/group/stat-group.js +47 -0
- package/dist/stat/index.d.ts +2 -0
- package/dist/stat/index.js +2 -0
- package/dist/stat/root/stat-root.d.ts +62 -0
- package/dist/stat/root/stat-root.js +51 -0
- package/dist/steps/index.d.ts +2 -0
- package/dist/steps/index.js +2 -0
- package/dist/steps/root/steps-root.d.ts +110 -0
- package/dist/steps/root/steps-root.js +130 -0
- package/dist/steps/step/step.d.ts +139 -0
- package/dist/steps/step/step.js +215 -0
- package/dist/switch/index.d.ts +1 -0
- package/dist/switch/index.js +1 -0
- package/dist/switch/root/switch-root.d.ts +74 -0
- package/dist/switch/root/switch-root.js +153 -0
- package/dist/table/cell/table-cell.d.ts +34 -0
- package/dist/table/cell/table-cell.js +52 -0
- package/dist/table/column/table-column.d.ts +165 -0
- package/dist/table/column/table-column.js +222 -0
- package/dist/table/index.d.ts +4 -0
- package/dist/table/index.js +4 -0
- package/dist/table/root/table-root.d.ts +98 -0
- package/dist/table/root/table-root.js +161 -0
- package/dist/table/row/table-row.d.ts +27 -0
- package/dist/table/row/table-row.js +42 -0
- package/dist/tabs/index.d.ts +3 -0
- package/dist/tabs/index.js +3 -0
- package/dist/tabs/panel/tab-panel.d.ts +67 -0
- package/dist/tabs/panel/tab-panel.js +98 -0
- package/dist/tabs/root/tabs-root.d.ts +123 -0
- package/dist/tabs/root/tabs-root.js +217 -0
- package/dist/tabs/tab/tab.d.ts +64 -0
- package/dist/tabs/tab/tab.js +116 -0
- package/dist/tag/index.d.ts +1 -0
- package/dist/tag/index.js +1 -0
- package/dist/tag/root/tag-root.d.ts +41 -0
- package/dist/tag/root/tag-root.js +67 -0
- package/dist/textarea/index.d.ts +1 -0
- package/dist/textarea/index.js +1 -0
- package/dist/textarea/root/textarea-root.d.ts +215 -0
- package/dist/textarea/root/textarea-root.js +380 -0
- package/dist/time-input/index.d.ts +1 -0
- package/dist/time-input/index.js +1 -0
- package/dist/time-input/root/time-input-root.d.ts +322 -0
- package/dist/time-input/root/time-input-root.js +661 -0
- package/dist/time-picker/index.d.ts +1 -0
- package/dist/time-picker/index.js +1 -0
- package/dist/time-picker/root/time-picker-root.d.ts +380 -0
- package/dist/time-picker/root/time-picker-root.js +669 -0
- package/dist/timeline/index.d.ts +2 -0
- package/dist/timeline/index.js +2 -0
- package/dist/timeline/item/timeline-item.d.ts +81 -0
- package/dist/timeline/item/timeline-item.js +128 -0
- package/dist/timeline/root/timeline-root.d.ts +52 -0
- package/dist/timeline/root/timeline-root.js +72 -0
- package/dist/toast/index.d.ts +2 -0
- package/dist/toast/index.js +2 -0
- package/dist/toast/item/toast-item.d.ts +183 -0
- package/dist/toast/item/toast-item.js +345 -0
- package/dist/toast/root/toast-root.d.ts +72 -0
- package/dist/toast/root/toast-root.js +87 -0
- package/dist/toggle/group/toggle-group.d.ts +140 -0
- package/dist/toggle/group/toggle-group.js +278 -0
- package/dist/toggle/index.d.ts +2 -0
- package/dist/toggle/index.js +2 -0
- package/dist/toggle/root/toggle-root.d.ts +99 -0
- package/dist/toggle/root/toggle-root.js +146 -0
- package/dist/toolbar/index.d.ts +1 -0
- package/dist/toolbar/index.js +1 -0
- package/dist/toolbar/root/toolbar-root.d.ts +105 -0
- package/dist/toolbar/root/toolbar-root.js +260 -0
- package/dist/tooltip/index.d.ts +1 -0
- package/dist/tooltip/index.js +1 -0
- package/dist/tooltip/root/tooltip-root.d.ts +388 -0
- package/dist/tooltip/root/tooltip-root.js +707 -0
- package/dist/tour/index.d.ts +2 -0
- package/dist/tour/index.js +2 -0
- package/dist/tour/root/tour-root.d.ts +161 -0
- package/dist/tour/root/tour-root.js +351 -0
- package/dist/tour/stop/tour-stop.d.ts +131 -0
- package/dist/tour/stop/tour-stop.js +249 -0
- package/dist/tree/index.d.ts +2 -0
- package/dist/tree/index.js +2 -0
- package/dist/tree/item/tree-item.d.ts +208 -0
- package/dist/tree/item/tree-item.js +381 -0
- package/dist/tree/root/tree-root.d.ts +88 -0
- package/dist/tree/root/tree-root.js +287 -0
- package/dist/trend/index.d.ts +1 -0
- package/dist/trend/index.js +1 -0
- package/dist/trend/root/trend-root.d.ts +67 -0
- package/dist/trend/root/trend-root.js +106 -0
- package/dist/video/index.d.ts +1 -0
- package/dist/video/index.js +1 -0
- package/dist/video/root/video-root.d.ts +711 -0
- package/dist/video/root/video-root.js +1821 -0
- package/dist/video-playlist/index.d.ts +3 -0
- package/dist/video-playlist/index.js +3 -0
- package/dist/video-playlist/item/video-playlist-item.d.ts +101 -0
- package/dist/video-playlist/item/video-playlist-item.js +162 -0
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +121 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +237 -0
- package/dist/video-playlist/root/video-playlist-root.d.ts +108 -0
- package/dist/video-playlist/root/video-playlist-root.js +218 -0
- package/dist/virtual-list/index.d.ts +1 -0
- package/dist/virtual-list/index.js +1 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +121 -0
- package/dist/virtual-list/root/virtual-list-root.js +221 -0
- package/jsx.d.ts +49767 -0
- package/package.json +77 -0
- package/svelte.d.ts +129 -0
- package/vue.d.ts +9242 -0
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { AriaForwardController, customElement, HelixFormElement, MixinControllerValue, MixinField, restoreValue, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html, nothing } from 'lit';
|
|
9
|
+
import { property } from 'lit/decorators.js';
|
|
10
|
+
/**
|
|
11
|
+
* @summary A value chosen from a range by dragging.
|
|
12
|
+
*
|
|
13
|
+
* @description
|
|
14
|
+
* A real `<input type="range">`, so the drag, the arrow keys, Home and End, the
|
|
15
|
+
* page keys and the touch target are all the platform's. Every one of those is
|
|
16
|
+
* a thing a hand-built slider gets wrong, and the last is the one nobody
|
|
17
|
+
* notices: a native range has a hit area larger than its thumb, sized by the
|
|
18
|
+
* platform for a finger.
|
|
19
|
+
*
|
|
20
|
+
* **The value is a string, like every other form control's.** A range submits
|
|
21
|
+
* text and `MixinControllerValue` holds text, so the number is a reading of the
|
|
22
|
+
* value rather than the value itself. `valueAsNumber` is there for anything
|
|
23
|
+
* doing arithmetic on it.
|
|
24
|
+
*
|
|
25
|
+
* **Marks are drawn rather than left to `<datalist>`**, which was the first
|
|
26
|
+
* answer and is the wrong one. A datalist's ticks cannot be styled at all, and
|
|
27
|
+
* Firefox does not render them for a range at all, so the platform's version is
|
|
28
|
+
* a mark that looks like someone else's design where it appears and no mark
|
|
29
|
+
* where it does not. Drawing them costs the semantics nothing, because a mark
|
|
30
|
+
* is decoration: what a reader can actually land on is `step`, which the input
|
|
31
|
+
* enforces whether or not anything is drawn.
|
|
32
|
+
*
|
|
33
|
+
* `markers` is a count rather than a flag tied to `step`. A flag reads well
|
|
34
|
+
* until a slider from zero to a hundred stepping by one asks for a hundred and
|
|
35
|
+
* one ticks, and then it is either noise or a silent refusal to draw. A number
|
|
36
|
+
* is what the reader sees, so it cannot surprise anyone.
|
|
37
|
+
*
|
|
38
|
+
* **A range is two of them, not a hand-built one.** There is no native
|
|
39
|
+
* two-thumb range, and the answer is not to stop using the platform's: it is to
|
|
40
|
+
* stack two of them on one track, so each thumb keeps its own drag, its own
|
|
41
|
+
* arrow keys, its own Home and End and its own finger-sized hit area. Rebuilding
|
|
42
|
+
* would throw away every argument this component is made of, to gain a second
|
|
43
|
+
* handle.
|
|
44
|
+
*
|
|
45
|
+
* Crossing is stopped in the handler rather than by the bounds, and that is not
|
|
46
|
+
* the obvious way round. Giving the lower input `max` of the upper reads well
|
|
47
|
+
* and breaks the drawing: an input's thumb sits at a fraction of *its own*
|
|
48
|
+
* range, so a lower thumb bounded at the upper one paints against a shorter
|
|
49
|
+
* track and the two stop lining up. Both inputs span the whole range and the
|
|
50
|
+
* values are clamped against each other on the way in.
|
|
51
|
+
*
|
|
52
|
+
* The properties below are written by this component and read by whoever draws
|
|
53
|
+
* it. A consumer sets none of them: they carry a number this element computed
|
|
54
|
+
* and CSS cannot, which is what lets a stylesheet on this tier draw the thing
|
|
55
|
+
* without measuring anything itself.
|
|
56
|
+
*
|
|
57
|
+
* @since 0.1.0
|
|
58
|
+
* @status experimental
|
|
59
|
+
* @category forms
|
|
60
|
+
* @aliases Range, Range input
|
|
61
|
+
* @documentation https://helix.fusion.dev/components/slider
|
|
62
|
+
*
|
|
63
|
+
* @event {Event} change - Relayed once the reader has let go.
|
|
64
|
+
* @event {HelixBeforeChangeEvent} helix-before-change - Fired as the value changes, and cancelable.
|
|
65
|
+
* @event {Event} input - Announced once the value has moved.
|
|
66
|
+
*
|
|
67
|
+
* @csspart control - The range input.
|
|
68
|
+
* @csspart feedback - What is wrong with it.
|
|
69
|
+
* @csspart field - The row: the control and its readout.
|
|
70
|
+
* @csspart hint - Help under the track, while nothing is wrong.
|
|
71
|
+
* @csspart label - The question, over the track.
|
|
72
|
+
* @csspart marker - One mark.
|
|
73
|
+
* @csspart marker-label - The value a mark stands at, when `marker-labels` is set.
|
|
74
|
+
* @csspart markers - The row of marks along the track.
|
|
75
|
+
* @csspart output - The current value, shown beside it.
|
|
76
|
+
*
|
|
77
|
+
* @cssproperty --slider-fraction - The value as a fraction of the range, 0 to 1.
|
|
78
|
+
* @cssproperty --slider-from - Where the filled span starts, as a percentage of the track.
|
|
79
|
+
* @cssproperty --slider-marker-at - Where one marker sits, as a percentage of the track.
|
|
80
|
+
* @cssproperty --slider-to - Where the filled span ends, as a percentage of the track.
|
|
81
|
+
*/
|
|
82
|
+
let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue(MixinField(HelixFormElement)) {
|
|
83
|
+
constructor() {
|
|
84
|
+
super(...arguments);
|
|
85
|
+
/* A consumer's `aria-describedby` names ids in their own tree and the control
|
|
86
|
+
is in this shadow root, so the reference has to be carried down as an
|
|
87
|
+
element rather than copied as an id. See `AriaForwardController`: measured
|
|
88
|
+
in Chrome's own tree, the host held the description and the control the
|
|
89
|
+
reader is actually on was exposed without it. */
|
|
90
|
+
this.aria = new AriaForwardController(this, {
|
|
91
|
+
target: () => this.renderRoot?.querySelector('[part="control"]') ?? null,
|
|
92
|
+
});
|
|
93
|
+
/** Typed or dragged, so every edit is announced. See `announcesInput`. */
|
|
94
|
+
this.announcesInput = true;
|
|
95
|
+
/**
|
|
96
|
+
* Whether there are two thumbs and the value is a pair.
|
|
97
|
+
*
|
|
98
|
+
* The pair is one string, `"10,50"`, which is what a form submits and what
|
|
99
|
+
* `MixinControllerValue` already holds. `valueAsNumber` reads the lower of
|
|
100
|
+
* the two, since a range has no single number.
|
|
101
|
+
*/
|
|
102
|
+
this.range = false;
|
|
103
|
+
/**
|
|
104
|
+
* The largest value the reader can choose.
|
|
105
|
+
*/
|
|
106
|
+
this.max = 100;
|
|
107
|
+
/**
|
|
108
|
+
* The smallest value the reader can choose.
|
|
109
|
+
*/
|
|
110
|
+
this.min = 0;
|
|
111
|
+
/**
|
|
112
|
+
* Whether the chosen value is shown beside the track.
|
|
113
|
+
*/
|
|
114
|
+
this.showValue = false;
|
|
115
|
+
/**
|
|
116
|
+
* How many marks to draw along the track, evenly spaced, ends included.
|
|
117
|
+
*
|
|
118
|
+
* `0` or `1` draws none: one mark on a track says nothing about a range.
|
|
119
|
+
* They are decoration, so they are `aria-hidden`; what a reader can land on
|
|
120
|
+
* is `step`, which the input enforces regardless.
|
|
121
|
+
*
|
|
122
|
+
* **Each one is snapped to a step before it is placed.** Evenly spaced and
|
|
123
|
+
* on a step are two different things, and asking for four marks across a
|
|
124
|
+
* hundred in twenty-fives wants them at 0, 33.3, 66.7 and 100: two of those
|
|
125
|
+
* are places the thumb cannot go. A mark the thumb can never sit on is the
|
|
126
|
+
* one thing a mark must not be, so the spacing gives way rather than the
|
|
127
|
+
* step, and marks may come out unevenly spaced when the two disagree. That
|
|
128
|
+
* is the honest picture of the range being offered.
|
|
129
|
+
*/
|
|
130
|
+
this.markers = 0;
|
|
131
|
+
/**
|
|
132
|
+
* Whether each mark says which value it stands at.
|
|
133
|
+
*/
|
|
134
|
+
this.markerLabels = false;
|
|
135
|
+
/** How far one press of an arrow key moves it. */
|
|
136
|
+
this.step = 1;
|
|
137
|
+
this.handleInput = (event) => {
|
|
138
|
+
// Stopped for the reason `Input.handleInput` gives: the inner control's own
|
|
139
|
+
// `input` is composed and would reach a consumer beside this element's.
|
|
140
|
+
event.stopPropagation();
|
|
141
|
+
const control = event.target;
|
|
142
|
+
if (this.range) {
|
|
143
|
+
const [start, end] = this.bounds;
|
|
144
|
+
const moved = Number(control.value);
|
|
145
|
+
/* Clamped against the other thumb rather than bounded by it, for the
|
|
146
|
+
reason the class says: bounding shortens the input's own range and the
|
|
147
|
+
two thumbs stop sharing a track. */
|
|
148
|
+
const pair = control.dataset.thumb === 'start'
|
|
149
|
+
? [Math.min(moved, end), end]
|
|
150
|
+
: [start, Math.max(moved, start)];
|
|
151
|
+
this.requestValue(pair.join(','));
|
|
152
|
+
restoreValue(control, String(control.dataset.thumb === 'start' ? this.bounds[0] : this.bounds[1]));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const next = control.value;
|
|
156
|
+
/* Through the mixin, like the other native-backed controls. The thumb has
|
|
157
|
+
already moved either way, so wherever the answer does not follow it has
|
|
158
|
+
to be put back: a refusal and a consumer who owns the value are the same
|
|
159
|
+
situation seen from here. */
|
|
160
|
+
this.requestValue(next);
|
|
161
|
+
restoreValue(control, this.value);
|
|
162
|
+
};
|
|
163
|
+
/** Relayed, because `change` does not cross a shadow boundary on its own. */
|
|
164
|
+
this.handleChange = (event) => {
|
|
165
|
+
event.stopPropagation();
|
|
166
|
+
this.dispatchEvent(new Event('change', { bubbles: true, composed: false }));
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* How many characters the readout has to be able to hold, widest case.
|
|
171
|
+
*
|
|
172
|
+
* **A number that grows a digit makes the track jump.** The output sizes to
|
|
173
|
+
* its text, so a range crossing 99 to 100 widens by a character and the row
|
|
174
|
+
* gives that width back out of the track: the handle moves while the value
|
|
175
|
+
* has not, which reads as the control drifting under the pointer. `3ch` was
|
|
176
|
+
* the floor and covers a plain value up to three digits, and a range says
|
|
177
|
+
* "35 to 100", which is ten.
|
|
178
|
+
*
|
|
179
|
+
* Widest rather than current, so the box never changes size at all. Measured
|
|
180
|
+
* off the bounds because that is what the readout can ever say: the longer of
|
|
181
|
+
* the two ends, twice, plus the four of " to " when both are shown. Negative
|
|
182
|
+
* bounds are covered by measuring the rendered string rather than the digits,
|
|
183
|
+
* since the sign is a character like any other.
|
|
184
|
+
*
|
|
185
|
+
* `tabular-nums` is on the part already and is the other half of this: equal
|
|
186
|
+
* digit widths keep a same-length number from shifting inside the box the
|
|
187
|
+
* same way a different-length one shifted the box.
|
|
188
|
+
*/
|
|
189
|
+
get reserve() {
|
|
190
|
+
const widest = Math.max(String(this.min).length, String(this.max).length);
|
|
191
|
+
return this.range ? widest * 2 + ' to '.length : widest;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* How many decimals the step is written to, so a label is not float noise.
|
|
195
|
+
*
|
|
196
|
+
* `min + index * step` on a fractional step prints `0.30000000000000004`,
|
|
197
|
+
* which is arithmetic being honest and a label being wrong. Rounding back to
|
|
198
|
+
* the step's own precision is what the reader asked for when they wrote it.
|
|
199
|
+
*/
|
|
200
|
+
get precision() {
|
|
201
|
+
return String(this.step).split('.')[1]?.length ?? 0;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* How far one press of an arrow key moves it.
|
|
205
|
+
*/
|
|
206
|
+
get markerValues() {
|
|
207
|
+
const span = this.max - this.min;
|
|
208
|
+
if (this.markers < 2 || span <= 0) {
|
|
209
|
+
return [];
|
|
210
|
+
}
|
|
211
|
+
const step = this.step > 0 ? this.step : 1;
|
|
212
|
+
const snapped = Array.from({ length: this.markers }, (_, at) => {
|
|
213
|
+
const raw = this.min + (at / (this.markers - 1)) * span;
|
|
214
|
+
const snappedAt = Math.min(this.max, Math.max(this.min, this.min + Math.round((raw - this.min) / step) * step));
|
|
215
|
+
// Back to the step's own precision, or a fractional step prints
|
|
216
|
+
// `0.30000000000000004` on a marker label.
|
|
217
|
+
return Number(snappedAt.toFixed(this.precision));
|
|
218
|
+
});
|
|
219
|
+
return [...new Set(snapped)];
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* The chosen value as a number, for anything doing arithmetic on it.
|
|
223
|
+
*
|
|
224
|
+
* @reference https://html.spec.whatwg.org/multipage/input.html#dom-input-valueasnumber HTMLInputElement.valueAsNumber
|
|
225
|
+
*/
|
|
226
|
+
get valueAsNumber() {
|
|
227
|
+
const parsed = Number.parseFloat(this.value);
|
|
228
|
+
return Number.isNaN(parsed) ? this.min : parsed;
|
|
229
|
+
}
|
|
230
|
+
/** Focus is delegated to the control, so the host is never the target. */
|
|
231
|
+
static { this.shadowRootOptions = {
|
|
232
|
+
...HelixFormElement.shadowRootOptions,
|
|
233
|
+
delegatesFocus: true,
|
|
234
|
+
}; }
|
|
235
|
+
/**
|
|
236
|
+
* The pair, as numbers, in order.
|
|
237
|
+
*
|
|
238
|
+
* Falls back to the whole range rather than to zero, so a range slider given
|
|
239
|
+
* no value opens fully wide instead of pinned shut at its own minimum, which
|
|
240
|
+
* is what a filter with nothing filtered out looks like.
|
|
241
|
+
*/
|
|
242
|
+
get bounds() {
|
|
243
|
+
/* A lone number is not a range, so it is not read as one.
|
|
244
|
+
*
|
|
245
|
+
* An untouched range slider does not hold an empty string: the native input
|
|
246
|
+
* reports its own midpoint and the mixin takes it, so `value` came back as
|
|
247
|
+
* "50" on a slider from 10 to 90 and reading that as the lower thumb put a
|
|
248
|
+
* filter half shut before anyone touched it. Only a pair is a pair, and
|
|
249
|
+
* anything else opens fully wide, which is what "nothing filtered out"
|
|
250
|
+
* looks like. */
|
|
251
|
+
const parts = this.value.split(',');
|
|
252
|
+
const from = Number.parseFloat(parts[0] ?? '');
|
|
253
|
+
const to = Number.parseFloat(parts[1] ?? '');
|
|
254
|
+
if (!Number.isFinite(from) || !Number.isFinite(to)) {
|
|
255
|
+
return [this.min, this.max];
|
|
256
|
+
}
|
|
257
|
+
return [Math.min(from, to), Math.max(from, to)];
|
|
258
|
+
}
|
|
259
|
+
/** Where one value sits along the track, as a fraction of it. */
|
|
260
|
+
along(at) {
|
|
261
|
+
const span = this.max - this.min;
|
|
262
|
+
if (span === 0) {
|
|
263
|
+
return 0;
|
|
264
|
+
}
|
|
265
|
+
return Math.min(1, Math.max(0, (at - this.min) / span));
|
|
266
|
+
}
|
|
267
|
+
/** Reports the value. */
|
|
268
|
+
sync() {
|
|
269
|
+
this.internals.setFormValue(this.value);
|
|
270
|
+
this.refreshFeedback();
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* How far along the track the thumb sits, as a fraction.
|
|
274
|
+
*
|
|
275
|
+
* Arithmetic rather than a measurement, because the browser already knows
|
|
276
|
+
* where it drew the handle and measuring it would be a guess at that.
|
|
277
|
+
*
|
|
278
|
+
* **Sanitized here, not read back off the control.** This asked the input for
|
|
279
|
+
* its value, on the reasoning that a range clamps and snaps whatever it is
|
|
280
|
+
* given, so the control is the truth about where the thumb is. The reasoning
|
|
281
|
+
* is right and the timing is not: `fraction` is evaluated inside `render()`,
|
|
282
|
+
* and the `style` binding carrying it is committed *before* the `.value`
|
|
283
|
+
* binding below it, so it read the value this very render was about to
|
|
284
|
+
* replace. The fill was a render behind the thumb, and on the first pass it
|
|
285
|
+
* read the seeded midpoint and stayed there.
|
|
286
|
+
*
|
|
287
|
+
* Measured on a slider from 0 to 1: after dragging to either end, the host's
|
|
288
|
+
* `value` was `1`, the control's was `1`, and `--slider-fraction` was still
|
|
289
|
+
* `0.5`. Off by half a track, and stable, which is what made it look like a
|
|
290
|
+
* drawing bug rather than a timing one.
|
|
291
|
+
*
|
|
292
|
+
* So the same two operations a range performs are done here: snap to the step
|
|
293
|
+
* from `min`, then clamp to the bounds. Nothing is read from the tree, so
|
|
294
|
+
* there is no order for this to be on the wrong side of.
|
|
295
|
+
*/
|
|
296
|
+
get fraction() {
|
|
297
|
+
const span = this.max - this.min;
|
|
298
|
+
if (span === 0) {
|
|
299
|
+
return 0;
|
|
300
|
+
}
|
|
301
|
+
return this.along(this.snapped(this.valueAsNumber));
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* A value snapped to the step, counted from `min` the way a range counts it.
|
|
305
|
+
*
|
|
306
|
+
* `min` rather than zero is the whole of it: a slider from `0.2` with a step
|
|
307
|
+
* of `0.05` can land on `0.2`, `0.25` and so on, and snapping against zero
|
|
308
|
+
* would offer `0.2` and `0.25` too but round the ones between to the wrong
|
|
309
|
+
* side. `precision` is what keeps `0.30000000000000004` off the track, the
|
|
310
|
+
* same guard the marker labels already use.
|
|
311
|
+
*/
|
|
312
|
+
snapped(at) {
|
|
313
|
+
if (!(this.step > 0)) {
|
|
314
|
+
return at;
|
|
315
|
+
}
|
|
316
|
+
const steps = Math.round((at - this.min) / this.step);
|
|
317
|
+
return Number((this.min + steps * this.step).toFixed(this.precision));
|
|
318
|
+
}
|
|
319
|
+
willUpdate(changed) {
|
|
320
|
+
super.willUpdate(changed);
|
|
321
|
+
/* A range with no value starts in the middle, which is the platform's own
|
|
322
|
+
rule and is what the control will show whether or not this agrees. Seeded
|
|
323
|
+
here so the value the form would submit matches the thumb from the first
|
|
324
|
+
render rather than from the first drag. */
|
|
325
|
+
if (!this.hasUpdated && this.value === '') {
|
|
326
|
+
/* Onto `defaultValue`, never onto `value`. Writing `value` is how a
|
|
327
|
+
consumer says they own it, so seeding through it would have made every
|
|
328
|
+
range with no value controlled on its first render and frozen the thumb
|
|
329
|
+
where it started. `defaultValue` is where the markup's intent lives,
|
|
330
|
+
and "no value given" is exactly a fact about the markup. */
|
|
331
|
+
this.defaultValue = String(this.min + (this.max - this.min) / 2);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
updated(changed) {
|
|
335
|
+
super.updated(changed);
|
|
336
|
+
this.sync();
|
|
337
|
+
}
|
|
338
|
+
render() {
|
|
339
|
+
/* The range's bounds are written before its value below, and that order is
|
|
340
|
+
the whole of this element's correctness on a wide scale. Lit commits
|
|
341
|
+
bindings in template order, and a range clamps whatever is assigned to the
|
|
342
|
+
bounds it holds at that moment: with the value first, a slider from 0 to
|
|
343
|
+
360 given 225 took the default max of 100, clamped to 100, and drew its
|
|
344
|
+
handle at 100/360.
|
|
345
|
+
*
|
|
346
|
+
* Found on Color Input's hue channel, where the handle sat at 28 per cent of a
|
|
347
|
+
* track whose fill said 62.5. The two disagreed because they are computed from
|
|
348
|
+
* different things: the fill is arithmetic on this element's property, and the
|
|
349
|
+
* handle is the platform's reading of the input's own clamped value. Every
|
|
350
|
+
* slider with a max above 100 had it, and the fill being right is what made it
|
|
351
|
+
* read as a drawing bug rather than a value one. */
|
|
352
|
+
const [start, end] = this.bounds;
|
|
353
|
+
/* One input per thumb, each spanning the whole range so both read against
|
|
354
|
+
the same track. The lower one paints the fill and the upper one's track
|
|
355
|
+
is transparent, because two stacked tracks would paint the ramp twice. */
|
|
356
|
+
/* **The lower thumb answers to `control`, and it has to answer to
|
|
357
|
+
something.** `MixinField.renderLabel` writes `<label for="control">` for
|
|
358
|
+
every field in the library, and only the single-thumb branch below ever
|
|
359
|
+
rendered that id: a range slider therefore shipped a label pointing at
|
|
360
|
+
nothing, so pressing the words focused no thumb and the `<output for>`
|
|
361
|
+
beside it named a missing element too. It was the only unresolved IDREF
|
|
362
|
+
in the whole corpus, which is the shape this class of fault takes, valid
|
|
363
|
+
markup that reaches nothing and says nothing.
|
|
364
|
+
|
|
365
|
+
The lower one, because a label forwards a press to the first control it
|
|
366
|
+
names and the reader expects the start of the range. The upper takes
|
|
367
|
+
`control-end`, which is what the readout lists alongside it. */
|
|
368
|
+
const thumb = (which, at) => html `<input
|
|
369
|
+
part="control"
|
|
370
|
+
id=${which === 'start' ? 'control' : 'control-end'}
|
|
371
|
+
data-thumb=${which}
|
|
372
|
+
type="range"
|
|
373
|
+
style="--slider-from: ${this.along(start)}; --slider-to: ${this.along(end)}"
|
|
374
|
+
min=${this.min}
|
|
375
|
+
max=${this.max}
|
|
376
|
+
step=${this.step}
|
|
377
|
+
.value=${String(at)}
|
|
378
|
+
aria-label=${`${this.label} ${which === 'start' ? 'minimum' : 'maximum'}`}
|
|
379
|
+
aria-describedby=${this.describedBy ?? nothing}
|
|
380
|
+
?disabled=${this.isDisabled}
|
|
381
|
+
@input=${this.handleInput}
|
|
382
|
+
@change=${this.handleChange}
|
|
383
|
+
/>`;
|
|
384
|
+
/* `data-markers` mirrors "there are marks" for the stylesheet.
|
|
385
|
+
*
|
|
386
|
+
* The whole marker layout hung off `:host([markers])` and `markers` does
|
|
387
|
+
* not reflect, so `slider.markers = 5` drew nothing at all: only the
|
|
388
|
+
* attribute written in the markup ever worked, and the property that is the
|
|
389
|
+
* documented API silently did not.
|
|
390
|
+
*
|
|
391
|
+
* Reflecting the count instead would put `markers="0"` on every slider, an
|
|
392
|
+
* attribute the server's markup does not have and one that selector would
|
|
393
|
+
* match, drawing the layout for no marks. So the boolean fact is mirrored
|
|
394
|
+
* to a `data-` name, which is the rule this library already follows for
|
|
395
|
+
* state: the stylesheet wants to know whether there are marks, not how
|
|
396
|
+
* many. How many is what `markerValues` answers, and `< 2` is where it
|
|
397
|
+
* already draws the line.
|
|
398
|
+
*
|
|
399
|
+
* A `/*` and written here, because it describes this binding and not a
|
|
400
|
+
* member. As a `/**` above `markerLabels` it never closed, so it swallowed
|
|
401
|
+
* that property's one-line description and the manifest shipped this whole
|
|
402
|
+
* argument as the text for "whether each mark says which value it stands
|
|
403
|
+
* at". `check:orphans` cannot see an unclosed block, only one sitting on
|
|
404
|
+
* another. */
|
|
405
|
+
return html `${this.renderLabel()}
|
|
406
|
+
<div
|
|
407
|
+
part="field"
|
|
408
|
+
data-markers=${this.markerValues.length > 0 ? '' : nothing}
|
|
409
|
+
data-range=${this.range ? '' : nothing}
|
|
410
|
+
style="--slider-fraction: ${this.fraction}; --slider-from: ${this.along(start)}; --slider-to: ${this.along(end)}"
|
|
411
|
+
>
|
|
412
|
+
${this.range ? thumb('start', start) : nothing}
|
|
413
|
+
${this.range ? thumb('end', end) : nothing}
|
|
414
|
+
${this.range
|
|
415
|
+
? nothing
|
|
416
|
+
: html `<input
|
|
417
|
+
part="control"
|
|
418
|
+
id="control"
|
|
419
|
+
type="range"
|
|
420
|
+
style="--slider-fraction: ${this.fraction}"
|
|
421
|
+
min=${this.min}
|
|
422
|
+
max=${this.max}
|
|
423
|
+
step=${this.step}
|
|
424
|
+
.value=${this.value}
|
|
425
|
+
name=${this.name || nothing}
|
|
426
|
+
aria-describedby=${this.describedBy ?? nothing}
|
|
427
|
+
?disabled=${this.isDisabled}
|
|
428
|
+
@input=${this.handleInput}
|
|
429
|
+
@change=${this.handleChange}
|
|
430
|
+
/>`}
|
|
431
|
+
${this.markers > 1
|
|
432
|
+
? html `<div part="markers" aria-hidden="true">
|
|
433
|
+
${this.markerValues.map((at) => html `<span
|
|
434
|
+
part="marker"
|
|
435
|
+
style="--slider-marker-at: ${((at - this.min) / (this.max - this.min)) * 100}%"
|
|
436
|
+
>${this.markerLabels ? html `<span part="marker-label">${at}</span>` : nothing}</span
|
|
437
|
+
>`)}
|
|
438
|
+
</div>`
|
|
439
|
+
: nothing}
|
|
440
|
+
${
|
|
441
|
+
/* Hidden from the accessibility tree, like the markers above it.
|
|
442
|
+
*
|
|
443
|
+
* A bare `<output>` maps to `role="status"` with an implicit polite
|
|
444
|
+
* live region, so every intermediate value during a drag was announced
|
|
445
|
+
* on top of the range's own value announcement: a reader dragging from
|
|
446
|
+
* 10 to 60 heard both twice, fifty times. It repeats what the control
|
|
447
|
+
* already reports, which is the definition of decoration. */
|
|
448
|
+
this.showValue
|
|
449
|
+
? html `<output
|
|
450
|
+
part="output"
|
|
451
|
+
for=${this.range ? 'control control-end' : 'control'}
|
|
452
|
+
aria-hidden="true"
|
|
453
|
+
style=${`--_slider-output-reserve: ${this.reserve}ch`}
|
|
454
|
+
>${this.range ? `${start} to ${end}` : this.value}</output
|
|
455
|
+
>`
|
|
456
|
+
: nothing}
|
|
457
|
+
</div>
|
|
458
|
+
${this.renderHint()}${this.renderFeedback()}`;
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
__decorate([
|
|
462
|
+
property({ reflect: true, type: Boolean })
|
|
463
|
+
], HelixHeadlessSlider.prototype, "range", void 0);
|
|
464
|
+
__decorate([
|
|
465
|
+
property({ type: Number })
|
|
466
|
+
], HelixHeadlessSlider.prototype, "max", void 0);
|
|
467
|
+
__decorate([
|
|
468
|
+
property({ type: Number })
|
|
469
|
+
], HelixHeadlessSlider.prototype, "min", void 0);
|
|
470
|
+
__decorate([
|
|
471
|
+
property({ attribute: 'show-value', reflect: true, type: Boolean })
|
|
472
|
+
], HelixHeadlessSlider.prototype, "showValue", void 0);
|
|
473
|
+
__decorate([
|
|
474
|
+
property({ type: Number })
|
|
475
|
+
], HelixHeadlessSlider.prototype, "markers", void 0);
|
|
476
|
+
__decorate([
|
|
477
|
+
property({ attribute: 'marker-labels', reflect: true, type: Boolean })
|
|
478
|
+
], HelixHeadlessSlider.prototype, "markerLabels", void 0);
|
|
479
|
+
__decorate([
|
|
480
|
+
property({ type: Number })
|
|
481
|
+
], HelixHeadlessSlider.prototype, "step", void 0);
|
|
482
|
+
__decorate([
|
|
483
|
+
property({ reflect: true })
|
|
484
|
+
], HelixHeadlessSlider.prototype, "orientation", void 0);
|
|
485
|
+
HelixHeadlessSlider = __decorate([
|
|
486
|
+
customElement('helix-headless-slider')
|
|
487
|
+
], HelixHeadlessSlider);
|
|
488
|
+
export { HelixHeadlessSlider };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './root/sparkline-root.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './root/sparkline-root.js';
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { type Curve, HelixElement, SourceController } from '@fusion.dev/helix-core';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
/**
|
|
4
|
+
* @summary A line with no axes, for the shape of a series beside the number it belongs to.
|
|
5
|
+
*
|
|
6
|
+
* @description
|
|
7
|
+
* The one chart here that takes its numbers from an attribute, and the reversal
|
|
8
|
+
* is deliberate. Every other chart reads a table because a reader might want to
|
|
9
|
+
* interrogate it; nobody interrogates the squiggle next to a figure. A
|
|
10
|
+
* fourteen-row table behind a bare trend line is fourteen dates read aloud in
|
|
11
|
+
* place of the one sentence that carries the meaning, so `values` is the list
|
|
12
|
+
* and `label` is the sentence.
|
|
13
|
+
*
|
|
14
|
+
* That is the library's own rule rather than a second data channel: a content
|
|
15
|
+
* property is its slot's fallback, which is why `Tooltip` takes `content` and
|
|
16
|
+
* `Avatar` takes `name`. `for` stays for the sparkline that genuinely has a
|
|
17
|
+
* table behind it, and it wins where both are given.
|
|
18
|
+
*
|
|
19
|
+
* **No label means decorative, and that is a choice rather than an oversight.**
|
|
20
|
+
* A sparkline beside a stat that already says "Sessions, 1,102" has nothing of
|
|
21
|
+
* its own to announce, and an unnamed `role="img"` announces "graphic" and
|
|
22
|
+
* stops. So an unlabelled sparkline is `aria-hidden`, and a labeled one is an
|
|
23
|
+
* image named by its sentence.
|
|
24
|
+
*
|
|
25
|
+
* It goes *beside* a `Stat` rather than inside one. The plan this was built
|
|
26
|
+
* from called for a `trend` slot on `Stat`; the spec already on `Stat` says the
|
|
27
|
+
* opposite, that a change beside a figure is a second fact, and the spec is
|
|
28
|
+
* right. `Trend` composes the same way.
|
|
29
|
+
*
|
|
30
|
+
* The properties below are written by this component and read by whoever draws
|
|
31
|
+
* it. A consumer sets none of them: they carry a number this element computed
|
|
32
|
+
* and CSS cannot, which is what lets a stylesheet on this tier draw the thing
|
|
33
|
+
* without measuring anything itself.
|
|
34
|
+
*
|
|
35
|
+
* @since 0.1.0
|
|
36
|
+
* @status experimental
|
|
37
|
+
* @category charts
|
|
38
|
+
* @aliases Micro Chart, Trend Line, Inline Chart
|
|
39
|
+
* @documentation https://helix.fusion.dev/components/sparkline
|
|
40
|
+
*
|
|
41
|
+
* @csspart area - The region between the line and the bottom of its range.
|
|
42
|
+
* @csspart bar - One column, under `plot="bar"`.
|
|
43
|
+
* @csspart line - The path itself.
|
|
44
|
+
* @csspart svg - The drawing.
|
|
45
|
+
* @csspart terminus - The mark on the last value.
|
|
46
|
+
* @csspart wash-end - The far stop of the area's gradient.
|
|
47
|
+
* @csspart wash-start - The stop of the area's gradient that meets the line.
|
|
48
|
+
*
|
|
49
|
+
* @cssproperty --chart-terminus-x - Where the last point sits horizontally, as a percentage.
|
|
50
|
+
* @cssproperty --chart-terminus-y - Where the last point sits vertically, as a percentage.
|
|
51
|
+
*/
|
|
52
|
+
export declare class HelixHeadlessSparkline extends HelixElement {
|
|
53
|
+
#private;
|
|
54
|
+
/**
|
|
55
|
+
* What the readings are drawn as.
|
|
56
|
+
*
|
|
57
|
+
* Absent is a line, `area` is a line with the region beneath it washed, and
|
|
58
|
+
* `bar` is a column per reading.
|
|
59
|
+
*
|
|
60
|
+
* **A bar plot measures from zero and the other two measure from the data's
|
|
61
|
+
* own range**, which is the one way the plots are not interchangeable. A line
|
|
62
|
+
* says where the readings sit relative to each other, so a scale over their
|
|
63
|
+
* extent uses the whole box and claims nothing about absolute size. A bar's
|
|
64
|
+
* length *is* the value, so any baseline but zero makes the lengths
|
|
65
|
+
* proportional to nothing.
|
|
66
|
+
*
|
|
67
|
+
* **Which is a reason to prefer a line for readings in a narrow band far from
|
|
68
|
+
* zero.** Seven values between 1,102 and 1,408 drawn as columns from zero are
|
|
69
|
+
* seven columns of nearly the same height, and that is the true picture: they
|
|
70
|
+
* *are* nearly the same. The same readings as a line fill the box and show
|
|
71
|
+
* the movement, because a line is only ever claiming a shape.
|
|
72
|
+
*
|
|
73
|
+
* **Absent is `area`**, which is the departure from the rule that a resting
|
|
74
|
+
* arrangement is the plainest thing. At the size a sparkline is actually
|
|
75
|
+
* drawn, a hairline in a wide box is mostly box: the wash under it is what
|
|
76
|
+
* gives the shape a body and lets a reader see it at a glance rather than
|
|
77
|
+
* hunting for it, which is the entire job. `line` is the bare stroke for
|
|
78
|
+
* anywhere the fill would be noise, several of them in one box for instance.
|
|
79
|
+
*
|
|
80
|
+
* This tier rather than the one above: a plot type is geometry and geometry
|
|
81
|
+
* is markup, the same reason `curve` lives here.
|
|
82
|
+
*/
|
|
83
|
+
plot?: 'area' | 'bar' | 'line';
|
|
84
|
+
/**
|
|
85
|
+
* How the line gets from one reading to the next.
|
|
86
|
+
*
|
|
87
|
+
* **`smooth` is the resting curve.** *Changed 21 Aug 2026, reversing the
|
|
88
|
+
* argument this comment used to make.* It read that joining the readings
|
|
89
|
+
* claims nothing in between and is the default for that reason, which is true
|
|
90
|
+
* and is why `straight` still exists: a straight segment asserts nothing about
|
|
91
|
+
* the values between two readings, and a curve invents them.
|
|
92
|
+
*
|
|
93
|
+
* What settles it the other way is that the invention is bounded. The
|
|
94
|
+
* interpolation is monotone cubic, so it never leaves the band the data sets
|
|
95
|
+
* and never introduces a peak or a trough the series does not have. Within
|
|
96
|
+
* that bound the smoothed line is the easier one to follow across a long
|
|
97
|
+
* series, which is what the drawing is for. `straight` becomes the claim a
|
|
98
|
+
* consumer makes deliberately rather than the one they get by saying nothing.
|
|
99
|
+
*
|
|
100
|
+
* **The property stays optional and the default lives in the render.** A
|
|
101
|
+
* reflecting property with a default writes its attribute onto every host
|
|
102
|
+
* anybody renders, including the ones nobody configured, which the SSR specs
|
|
103
|
+
* assert against. So the resting state is still the attribute's absence, and
|
|
104
|
+
* `curve ?? 'smooth'` is what reads it.
|
|
105
|
+
*
|
|
106
|
+
* `step` claims the opposite of both, that a reading holds until the next.
|
|
107
|
+
* Bars ignore it, having no between to interpolate.
|
|
108
|
+
*/
|
|
109
|
+
curve?: Curve;
|
|
110
|
+
/**
|
|
111
|
+
* The id of a table to read instead, when there is one behind the line.
|
|
112
|
+
*
|
|
113
|
+
* The first column of numbers is the series drawn. This wins over `values`,
|
|
114
|
+
* because a table is the readable representation and a list of numbers in an
|
|
115
|
+
* attribute is not.
|
|
116
|
+
*
|
|
117
|
+
* **In React this arrives as a property and not as an attribute**, the way
|
|
118
|
+
* `Tooltip.for` does, so it does not reflect and nothing styles on it.
|
|
119
|
+
*/
|
|
120
|
+
for: string;
|
|
121
|
+
/**
|
|
122
|
+
* What the line says, in a sentence.
|
|
123
|
+
*
|
|
124
|
+
* "Sessions rose from 1,240 to 1,318 and fell to 1,102 over fourteen days" is
|
|
125
|
+
* the accessible representation of a sparkline, and a list of the fourteen
|
|
126
|
+
* numbers is not. Absent, the drawing is hidden from a screen reader rather
|
|
127
|
+
* than announced without a name.
|
|
128
|
+
*/
|
|
129
|
+
label: string;
|
|
130
|
+
/**
|
|
131
|
+
* The numbers, separated by whitespace or by commas.
|
|
132
|
+
*
|
|
133
|
+
* Both separators, so `values="1240 1318"` and an array assigned to the
|
|
134
|
+
* property both work: assigning `[1240, 1318]` stringifies to `1240,1318`,
|
|
135
|
+
* and a string is what survives React's hydration where an array property
|
|
136
|
+
* does not.
|
|
137
|
+
*/
|
|
138
|
+
values: string;
|
|
139
|
+
protected readonly source: SourceController;
|
|
140
|
+
protected willUpdate(changed: PropertyValues<this>): void;
|
|
141
|
+
protected render(): TemplateResult;
|
|
142
|
+
}
|
|
143
|
+
declare global {
|
|
144
|
+
interface HTMLElementTagNameMap {
|
|
145
|
+
'helix-headless-sparkline': HelixHeadlessSparkline;
|
|
146
|
+
}
|
|
147
|
+
}
|