@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,515 @@
|
|
|
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 { customElement, drawTooltip, extent, HelixElement, linear, linePath, MixinChartSource, seriesIndex, ticks, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html, nothing, svg } from 'lit';
|
|
9
|
+
import { property } from 'lit/decorators.js';
|
|
10
|
+
import '../../tooltip/index.js';
|
|
11
|
+
/** The drawing's own coordinates. Height only: the width is the element's. */
|
|
12
|
+
const HEIGHT = 100;
|
|
13
|
+
/**
|
|
14
|
+
* @summary Categories as columns, read from a table.
|
|
15
|
+
*
|
|
16
|
+
* @description
|
|
17
|
+
* The chart most often asked for and the one most often drawn wrongly, so two
|
|
18
|
+
* decisions are made here rather than left to a consumer.
|
|
19
|
+
*
|
|
20
|
+
* **It measures from zero and there is no property to change that.** A bar's
|
|
21
|
+
* length *is* its value, so a baseline anywhere else makes the lengths
|
|
22
|
+
* proportional to nothing. That is the oldest misleading chart there is, and a
|
|
23
|
+
* design system that ships the switch has shipped the mistake. A reader who
|
|
24
|
+
* wants the differences between values rather than the values should be drawing
|
|
25
|
+
* a line, which claims only a shape.
|
|
26
|
+
*
|
|
27
|
+
* **The labels are HTML beside the drawing rather than `<text>` inside it.** An
|
|
28
|
+
* `<svg>` that fills its box scales everything in it, including type: the same
|
|
29
|
+
* `font-size` comes out at 10px in a narrow chart and 43px in a wide one, and
|
|
30
|
+
* there is no non-scaling-font to answer it the way `vector-effect` answers
|
|
31
|
+
* strokes. So the columns are drawn and the words are written around them.
|
|
32
|
+
*
|
|
33
|
+
* The table is the accessible representation and this drawing is `aria-hidden`.
|
|
34
|
+
* A reader who wants the numbers gets the numbers, not a described picture of
|
|
35
|
+
* them.
|
|
36
|
+
*
|
|
37
|
+
* The properties below are written by this component and read by whoever draws
|
|
38
|
+
* it. A consumer sets none of them: they carry a number this element computed
|
|
39
|
+
* and CSS cannot, which is what lets a stylesheet on this tier draw the thing
|
|
40
|
+
* without measuring anything itself.
|
|
41
|
+
*
|
|
42
|
+
* @since 0.1.0
|
|
43
|
+
* @status experimental
|
|
44
|
+
* @category charts
|
|
45
|
+
* @aliases Column Chart, Categorical Chart
|
|
46
|
+
* @documentation https://helix.fusion.dev/components/bar-chart
|
|
47
|
+
*
|
|
48
|
+
* @csspart axis - One scale's numbers, drawn only when `secondary` splits them.
|
|
49
|
+
* @csspart band - The slot the pointer is resting in.
|
|
50
|
+
* @csspart bar - One column.
|
|
51
|
+
* @csspart bar-wash-end - The far stop of a bar's gradient, where one is used.
|
|
52
|
+
* @csspart bar-wash-start - The stop of a bar's gradient at its base.
|
|
53
|
+
* @csspart baseline - The rule the columns stand on.
|
|
54
|
+
* @csspart gridline - One rule across the plot, under `gridlines`.
|
|
55
|
+
* @csspart group - One category's columns, together.
|
|
56
|
+
* @csspart label - One category's name.
|
|
57
|
+
* @csspart labels - The row of category names.
|
|
58
|
+
* @csspart line - A series drawn as a line rather than as columns, under `lines`.
|
|
59
|
+
* @csspart mark - The invisible point the tooltip is anchored to.
|
|
60
|
+
* @csspart plot - The drawing.
|
|
61
|
+
* @csspart svg - The drawing surface the bars and lines sit on.
|
|
62
|
+
* @csspart tick - One number on an axis.
|
|
63
|
+
* @csspart tooltip - The bubble, forwarded from `Tooltip`.
|
|
64
|
+
* @csspart tooltip-anchor - The `Tooltip` element itself.
|
|
65
|
+
* @csspart tooltip-cell - One column's name and value inside the tooltip.
|
|
66
|
+
* @csspart tooltip-label - The reading's own name inside the tooltip.
|
|
67
|
+
* @csspart tooltip-name - A column's name inside the tooltip.
|
|
68
|
+
* @csspart tooltip-value - A column's value inside the tooltip.
|
|
69
|
+
*
|
|
70
|
+
* @cssproperty --bar-chart-axis - The color of a single-series axis, taken from that series.
|
|
71
|
+
* @cssproperty --bar-chart-secondary - The color of the secondary axis when one series owns it. It resolves a `--helix-color-series-*` token, so on the headless tier alone it names something that is not there. #138.
|
|
72
|
+
* @cssproperty --chart-bar-wash - The gradient a bar would take, named per bar so the
|
|
73
|
+
* styled tier can point `fill` at it. Drawn whatever the treatment and used only where
|
|
74
|
+
* `wash="gradient"` asks for it.
|
|
75
|
+
*/
|
|
76
|
+
let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource(HelixElement) {
|
|
77
|
+
/** The series names on the second scale, lowercased and trimmed. */
|
|
78
|
+
get scaled() {
|
|
79
|
+
return new Set((this.secondary ?? '')
|
|
80
|
+
.split(/\s+/)
|
|
81
|
+
.map((name) => name.trim().toLowerCase())
|
|
82
|
+
.filter(Boolean));
|
|
83
|
+
}
|
|
84
|
+
/** The series names drawn as a line, lowercased and trimmed for matching. */
|
|
85
|
+
get lined() {
|
|
86
|
+
return new Set((this.lines ?? '')
|
|
87
|
+
.split(/\s+/)
|
|
88
|
+
.map((name) => name.trim().toLowerCase())
|
|
89
|
+
.filter(Boolean));
|
|
90
|
+
}
|
|
91
|
+
/** Whether the levels are ruled, which is every value but `category`. */
|
|
92
|
+
get rulesValue() {
|
|
93
|
+
return this.gridlines !== undefined && this.gridlines !== 'category';
|
|
94
|
+
}
|
|
95
|
+
/** Whether each category is ruled, which only two values ask for. */
|
|
96
|
+
get rulesCategory() {
|
|
97
|
+
return this.gridlines === 'both' || this.gridlines === 'category';
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Tells the pointer which way the categories run.
|
|
101
|
+
*
|
|
102
|
+
* In `willUpdate` because `direction` is a property a consumer can change at
|
|
103
|
+
* any time, and the controller resolves a reading from whichever axis it was
|
|
104
|
+
* last told about: set once at connect, a chart turned sideways after that
|
|
105
|
+
* would go on reading x and answer with the same row wherever the pointer
|
|
106
|
+
* went. That is the bug this pair was written for, one step later.
|
|
107
|
+
*
|
|
108
|
+
* `willUpdate` and not `updated`, because SSR calls the first and not the
|
|
109
|
+
* second, and a value the server and the client disagree about is worse than
|
|
110
|
+
* one neither has.
|
|
111
|
+
*/
|
|
112
|
+
willUpdate(changed) {
|
|
113
|
+
super.willUpdate(changed);
|
|
114
|
+
this.pointer.axis = this.direction === 'horizontal' ? 'block' : 'inline';
|
|
115
|
+
}
|
|
116
|
+
render() {
|
|
117
|
+
const series = this.series;
|
|
118
|
+
const categories = series[0]?.points.map((point) => point.label) ?? [];
|
|
119
|
+
if (categories.length === 0) {
|
|
120
|
+
return html `<div id="helix-chart-plot" part="plot"></div>`;
|
|
121
|
+
}
|
|
122
|
+
/* Zero at both ends, so a series that goes negative gets a baseline inside
|
|
123
|
+
the box and its columns hang below it. `extent` over every series at once
|
|
124
|
+
rather than per series, because two series drawn to different scales are
|
|
125
|
+
two charts sharing a picture. */
|
|
126
|
+
const scaled = this.scaled;
|
|
127
|
+
const own = (one) => scaled.has(one.name.trim().toLowerCase());
|
|
128
|
+
/* Two extents where a series asked for its own, and the primary is taken
|
|
129
|
+
over the series that did *not*: measuring the primary over everything
|
|
130
|
+
would stretch it to hold numbers no column is drawn against, which is the
|
|
131
|
+
one thing splitting the axes was meant to stop. Empty on either side
|
|
132
|
+
falls back to the whole set, so `secondary` naming a column that is not
|
|
133
|
+
there leaves a chart rather than a blank. */
|
|
134
|
+
const values = series.flatMap((one) => one.points.map((point) => point.value));
|
|
135
|
+
const on = (which) => {
|
|
136
|
+
const found = series.filter(which).flatMap((one) => one.points.map((point) => point.value));
|
|
137
|
+
return found.length > 0 ? found : values.length > 0 ? values : [0];
|
|
138
|
+
};
|
|
139
|
+
const [low, high] = extent(scaled.size === 0 ? on(() => true) : on((one) => !own(one)));
|
|
140
|
+
/* **The range is inverted for columns and not for bars**, which is the
|
|
141
|
+
whole of what makes the two directions different arithmetic rather than
|
|
142
|
+
one drawing turned on its side. SVG counts down from the top, so a column
|
|
143
|
+
growing upward needs `[HEIGHT, 0]`; a bar growing rightward is already
|
|
144
|
+
going the way x counts, so it takes `[0, HEIGHT]`.
|
|
145
|
+
*
|
|
146
|
+
* Reusing the inverted scale for both was the first version. It put the
|
|
147
|
+
longest bar at x=0 and every shorter one hard against the right edge,
|
|
148
|
+
growing away from the baseline instead of out of it. */
|
|
149
|
+
const domain = [Math.min(0, low), Math.max(0, high)];
|
|
150
|
+
const range = this.direction === 'horizontal' ? [0, HEIGHT] : [HEIGHT, 0];
|
|
151
|
+
const y = linear(domain, range);
|
|
152
|
+
const floor = y(0);
|
|
153
|
+
const sideways = this.direction === 'horizontal';
|
|
154
|
+
const [second, top] = extent(scaled.size > 0 ? on(own) : [0]);
|
|
155
|
+
const other = [Math.min(0, second), Math.max(0, top)];
|
|
156
|
+
const z = scaled.size > 0 ? linear(other, range) : undefined;
|
|
157
|
+
/* Widest number on either scale, in characters, so the axis column is the
|
|
158
|
+
size of its own contents.
|
|
159
|
+
*
|
|
160
|
+
* The ticks are absolutely positioned, which is what puts each one on the
|
|
161
|
+
* level it names and also what stops any of them contributing a width: an
|
|
162
|
+
* axis of six numbers laid out that way is an empty box. The count is known
|
|
163
|
+
* here and unknowable to a selector, so it is written as a length and the
|
|
164
|
+
stylesheet reads it. */
|
|
165
|
+
const widest = z === undefined
|
|
166
|
+
? 0
|
|
167
|
+
: Math.max(...[...ticks(domain), ...ticks(other)].map((level) => level.toLocaleString().length));
|
|
168
|
+
/* The second axis wears its series' color when exactly one series is on it,
|
|
169
|
+
which is the case worth helping and the only one a single color can
|
|
170
|
+
describe honestly: with two sharing it, painting the axis either of their
|
|
171
|
+
colours says it belongs to that one.
|
|
172
|
+
*
|
|
173
|
+
**Written onto the axis and not onto the plot**, which is where it went
|
|
174
|
+
first and where it did nothing. The axis is the plot's sibling now that it
|
|
175
|
+
is a column of the host grid, and a custom property inherits down and
|
|
176
|
+
never sideways. Measured: both axes came out the neutral, which is the
|
|
177
|
+
same mistake `--donut-chart-stroke` made one component over. */
|
|
178
|
+
const lone = series.filter(own);
|
|
179
|
+
const tint = lone.length === 1 && lone[0] !== undefined
|
|
180
|
+
? `--bar-chart-secondary: var(--chart-series-${seriesIndex(series.indexOf(lone[0]))})`
|
|
181
|
+
: undefined;
|
|
182
|
+
return html `${z === undefined ? nothing : this.renderAxis(y, domain, 'primary', sideways, widest)}${this.renderPlot(series, categories, y, domain, floor, z)}${z === undefined ? nothing : this.renderAxis(z, other, 'secondary', sideways, widest, tint)}${this.renderLabels(categories)}`;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* The columns themselves, behind a seam the styled tier can move.
|
|
186
|
+
*
|
|
187
|
+
* `aria-hidden`, because the table it was read from is the readable version
|
|
188
|
+
* and a screen reader hearing both hears the same numbers twice.
|
|
189
|
+
*/
|
|
190
|
+
renderPlot(series, categories, y, domain, floor, z) {
|
|
191
|
+
const sideways = this.direction === 'horizontal';
|
|
192
|
+
const slot = 100 / categories.length;
|
|
193
|
+
/* Split first, because the columns share the slot between themselves and a
|
|
194
|
+
line takes none of it. Sized by every series instead, a chart of two
|
|
195
|
+
columns and one line drew both columns two thirds as wide and left a
|
|
196
|
+
third of every slot empty, for a mark that is not in the slot at all. */
|
|
197
|
+
const lined = this.lined;
|
|
198
|
+
/* Kept with the index it has among *all* the series, because a column needs
|
|
199
|
+
two different numbers and they stopped being the same the moment one
|
|
200
|
+
series could be a line. `depth` is its place in the slot, so the columns
|
|
201
|
+
stand shoulder to shoulder with no gap where a line was; `tone` is its
|
|
202
|
+
place in the palette, so it keeps the color the legend gives it.
|
|
203
|
+
*
|
|
204
|
+
Passing the first for both is what the first version did, and it was
|
|
205
|
+
visible: with `Target` drawn as a line, `Forecast` moved up into its slot
|
|
206
|
+
*and* into its color, so a chart of four series painted three columns in
|
|
207
|
+
the first three colours and the line in the third one as well. */
|
|
208
|
+
const scaled = this.scaled;
|
|
209
|
+
const own = (one) => scaled.has(one.name.trim().toLowerCase());
|
|
210
|
+
/* The scale a series is measured against, resolved once per series rather
|
|
211
|
+
than per point. `z` is absent unless `secondary` named something, so the
|
|
212
|
+
ordinary chart takes exactly the path it took before this existed. */
|
|
213
|
+
const against = (one) => z !== undefined && own(one) ? z : y;
|
|
214
|
+
const columns = series
|
|
215
|
+
.map((one, index) => ({ one, tone: index }))
|
|
216
|
+
.filter(({ one }) => !lined.has(one.name.trim().toLowerCase()));
|
|
217
|
+
/* **The stride is what the columns share and the thickness is what they
|
|
218
|
+
draw**, and the difference between them is why they had none. Back to
|
|
219
|
+
back, two columns meet on one coordinate and each one's edge is the
|
|
220
|
+
other's: an outlined chart showed a single line between them rather than
|
|
221
|
+
two, and a bar looked as though it were missing a side. A gap is also just
|
|
222
|
+
the right way to draw a group, which is why the split stays whether
|
|
223
|
+
anything is outlined or not.
|
|
224
|
+
|
|
225
|
+
Centered in the stride rather than flush against it, so the gap between two
|
|
226
|
+
columns is the same size everywhere and the group sits where it did. One
|
|
227
|
+
series has no neighbor to be separated from and keeps the full stride. */
|
|
228
|
+
const stride = (slot * 0.72) / Math.max(columns.length, 1);
|
|
229
|
+
const gap = columns.length > 1 ? stride * 0.08 : 0;
|
|
230
|
+
const thickness = stride - gap;
|
|
231
|
+
/* **The geometry is computed for the axis it is drawn on, not rotated onto
|
|
232
|
+
it.** The first version turned the whole plot with `rotate: 90deg`, which
|
|
233
|
+
is the shorter CSS and does not work: a rotation is about the element's
|
|
234
|
+
own center, so the drawing left its grid cell entirely and the labels,
|
|
235
|
+
which are a separate row, stayed where they were. What it produced was
|
|
236
|
+
one column floating beside a list of names.
|
|
237
|
+
*
|
|
238
|
+
* Swapping the two axes here costs one branch and keeps every other fact
|
|
239
|
+
* about the chart the same. `value` runs along x when the bars are
|
|
240
|
+
* sideways and along y otherwise; `category` takes the other one. */
|
|
241
|
+
const bar = (value, index, depth, tone, scale) => {
|
|
242
|
+
const at = scale(value);
|
|
243
|
+
const along = Math.min(floor, at);
|
|
244
|
+
const size = Math.abs(floor - at);
|
|
245
|
+
const across = index * slot + slot * 0.14 + depth * stride + gap / 2;
|
|
246
|
+
return sideways
|
|
247
|
+
? svg `<rect
|
|
248
|
+
data-series=${seriesIndex(tone)}
|
|
249
|
+
height=${thickness}
|
|
250
|
+
style="--chart-series: var(--chart-series-${seriesIndex(tone)}); --chart-bar-wash: url(#helix-bar-wash-${seriesIndex(tone)})"
|
|
251
|
+
part="bar"
|
|
252
|
+
width=${size}
|
|
253
|
+
x=${along}
|
|
254
|
+
y=${across}
|
|
255
|
+
/>`
|
|
256
|
+
: svg `<rect
|
|
257
|
+
data-series=${seriesIndex(tone)}
|
|
258
|
+
height=${size}
|
|
259
|
+
style="--chart-series: var(--chart-series-${seriesIndex(tone)}); --chart-bar-wash: url(#helix-bar-wash-${seriesIndex(tone)})"
|
|
260
|
+
part="bar"
|
|
261
|
+
width=${thickness}
|
|
262
|
+
x=${across}
|
|
263
|
+
y=${along}
|
|
264
|
+
/>`;
|
|
265
|
+
};
|
|
266
|
+
return html `<div
|
|
267
|
+
aria-hidden="true"
|
|
268
|
+
id="helix-chart-plot"
|
|
269
|
+
part="plot"
|
|
270
|
+
>
|
|
271
|
+
<svg part="svg"
|
|
272
|
+
preserveAspectRatio="none"
|
|
273
|
+
viewBox="0 0 100 ${HEIGHT}"
|
|
274
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
275
|
+
>
|
|
276
|
+
${
|
|
277
|
+
/* **One gradient per series, rendered whether or not anything points
|
|
278
|
+
at it.** A `<defs>` entry draws nothing on its own, and this tier's
|
|
279
|
+
business is elements while which fill a bar takes is the styled
|
|
280
|
+
tier's: `wash="gradient"` there switches `fill` to
|
|
281
|
+
`--chart-bar-wash` and this is what it would find.
|
|
282
|
+
|
|
283
|
+
Coloured through the series property rather than an attribute, so
|
|
284
|
+
the stops read a token this tier never names. The id resolves
|
|
285
|
+
within the shadow root, so two charts on a page carrying the same
|
|
286
|
+
ids stay independent, which the sparkline measured before relying
|
|
287
|
+
on it. */
|
|
288
|
+
svg `<defs>
|
|
289
|
+
${series.map((_, index) => svg `<linearGradient
|
|
290
|
+
id="helix-bar-wash-${seriesIndex(index)}"
|
|
291
|
+
style="--chart-series: var(--chart-series-${seriesIndex(index)})"
|
|
292
|
+
x1="0"
|
|
293
|
+
x2=${sideways ? '1' : '0'}
|
|
294
|
+
y1="0"
|
|
295
|
+
y2=${sideways ? '0' : '1'}
|
|
296
|
+
>
|
|
297
|
+
<stop offset="0" part="bar-wash-start" />
|
|
298
|
+
<stop offset="1" part="bar-wash-end" />
|
|
299
|
+
</linearGradient>`)}
|
|
300
|
+
</defs>`}
|
|
301
|
+
${this.renderGridlines(y, domain, sideways, categories.length)}
|
|
302
|
+
${sideways
|
|
303
|
+
? svg `<line part="baseline" x1=${floor} x2=${floor} y1="0" y2="100" />`
|
|
304
|
+
: svg `<line part="baseline" x1="0" x2="100" y1=${floor} y2=${floor} />`}
|
|
305
|
+
${this.renderBand(categories.length, sideways)}
|
|
306
|
+
${categories.map((_, index) =>
|
|
307
|
+
/* The group the tooltip is about says so, and the stylesheet fades
|
|
308
|
+
the rest. A tooltip over a chart of five categories otherwise
|
|
309
|
+
makes a reader match its heading against the row of names to find
|
|
310
|
+
out which columns it means. */
|
|
311
|
+
svg `<g data-active=${this.pointer.at === index ? '' : nothing} part="group">
|
|
312
|
+
${columns.map(({ one, tone }, depth) => bar(one.points[index]?.value ?? 0, index, depth, tone, against(one)))}
|
|
313
|
+
</g>`)}
|
|
314
|
+
${
|
|
315
|
+
/* After the groups, so a line is never drawn under the columns it is
|
|
316
|
+
meant to be read against. Outside them too: a group is one
|
|
317
|
+
category and a line crosses all of them, so it belongs to the plot
|
|
318
|
+
rather than to any one slot. */
|
|
319
|
+
series.map((one) => lined.has(one.name.trim().toLowerCase())
|
|
320
|
+
? this.renderLine(one, series.indexOf(one), slot, against(one), sideways)
|
|
321
|
+
: nothing)}
|
|
322
|
+
</svg>
|
|
323
|
+
${this.renderTooltip()}
|
|
324
|
+
</div>`;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* The numbers along one scale, drawn only where there are two of them.
|
|
328
|
+
*
|
|
329
|
+
* **A chart with one scale renders no axis, on purpose.** Columns measured
|
|
330
|
+
* against each other need no numbers to be compared, and a row of them beside
|
|
331
|
+
* a small chart is furniture that makes the drawing smaller for no reading a
|
|
332
|
+
* reader was going to do. With two scales that argument inverts: a reader
|
|
333
|
+
* cannot tell there are two, cannot tell which series is on which, and cannot
|
|
334
|
+
* recover either from the picture. So this appears with `secondary` and never
|
|
335
|
+
* without it.
|
|
336
|
+
*
|
|
337
|
+
* **Beside the plot and not inside it**, which is the second thing this got
|
|
338
|
+
* wrong. Inside, the numbers are drawn over the drawing, and a horizontal
|
|
339
|
+
* chart shows it immediately: its value axis runs along the bottom, which is
|
|
340
|
+
* where the last row of bars is. The vertical case has the same fault and
|
|
341
|
+
* enough slack to hide it. The plot is also the pointer's catchment and the
|
|
342
|
+
* tooltip's containing block, both measured from its box, so padding it to
|
|
343
|
+
* make room would move every reading half an axis to the right.
|
|
344
|
+
*
|
|
345
|
+
* A column of the host grid instead, which the stylesheet grows only when
|
|
346
|
+
* `secondary` is set. That is what the property reflects for.
|
|
347
|
+
*
|
|
348
|
+
* The primary hugs the edge the drawing starts at and the secondary the edge
|
|
349
|
+
* it ends at: down the two sides for columns, along the bottom and top for
|
|
350
|
+
* bars, which is where each axis is when the chart is turned.
|
|
351
|
+
*/
|
|
352
|
+
renderAxis(scale, domain, which, sideways, widest, tint) {
|
|
353
|
+
const sizing = sideways ? undefined : `--bar-chart-axis: ${widest}ch`;
|
|
354
|
+
return html `<div
|
|
355
|
+
aria-hidden="true"
|
|
356
|
+
data-axis=${which}
|
|
357
|
+
part="axis"
|
|
358
|
+
style=${[sizing, tint].filter(Boolean).join('; ') || nothing}
|
|
359
|
+
>
|
|
360
|
+
${ticks(domain).map((level) => html `<span
|
|
361
|
+
part="tick"
|
|
362
|
+
style=${sideways ? `inset-inline-start: ${scale(level)}%` : `inset-block-start: ${scale(level)}%`}
|
|
363
|
+
>${level.toLocaleString()}</span
|
|
364
|
+
>`)}
|
|
365
|
+
</div>`;
|
|
366
|
+
}
|
|
367
|
+
/*
|
|
368
|
+
* The category names, as HTML beside the drawing rather than inside it.
|
|
369
|
+
*
|
|
370
|
+
* Inside, they would scale with the box: an `<svg>` that fills its container
|
|
371
|
+
* scales its type along with everything else, and there is no non-scaling
|
|
372
|
+
* equivalent for a font the way `vector-effect` is one for a stroke.
|
|
373
|
+
*/
|
|
374
|
+
/**
|
|
375
|
+
* The grid, behind everything, or nothing at all.
|
|
376
|
+
*
|
|
377
|
+
* Across the measured axis, which turns with `direction`: a rule belongs to
|
|
378
|
+
* the axis the bars are measured on and not the one they are arranged on, so
|
|
379
|
+
* columns get horizontal rules and rows get vertical ones. Getting that
|
|
380
|
+
* backwards draws a grid that divides the categories, which are already
|
|
381
|
+
* divided by being separate bars.
|
|
382
|
+
*
|
|
383
|
+
* Drawn before the baseline, so where a gridline and zero coincide the
|
|
384
|
+
* baseline is what shows: zero is a fact about the data and a gridline is a
|
|
385
|
+
* ruler.
|
|
386
|
+
*/
|
|
387
|
+
renderGridlines(y, domain, sideways, count) {
|
|
388
|
+
if (this.gridlines === undefined) {
|
|
389
|
+
return nothing;
|
|
390
|
+
}
|
|
391
|
+
/* Through the middle of each group, which is where the column stands, and
|
|
392
|
+
not on the boundary between two of them. */
|
|
393
|
+
const slot = 100 / Math.max(count, 1);
|
|
394
|
+
const categories = this.rulesCategory
|
|
395
|
+
? Array.from({ length: count }, (_, index) => (index + 0.5) * slot).map((at) => sideways
|
|
396
|
+
? svg `<line part="gridline" x1="0" x2="100" y1=${at} y2=${at} />`
|
|
397
|
+
: svg `<line part="gridline" x1=${at} x2=${at} y1="0" y2="100" />`)
|
|
398
|
+
: [];
|
|
399
|
+
const levels = this.rulesValue
|
|
400
|
+
? ticks(domain).map((level) => sideways
|
|
401
|
+
? svg `<line part="gridline" x1=${y(level)} x2=${y(level)} y1="0" y2="100" />`
|
|
402
|
+
: svg `<line part="gridline" x1="0" x2="100" y1=${y(level)} y2=${y(level)} />`)
|
|
403
|
+
: [];
|
|
404
|
+
return svg `${categories}${levels}`;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* The slot the pointer is resting in, drawn behind the columns.
|
|
408
|
+
*
|
|
409
|
+
* **The honest version of the fade.** A group under the pointer already sets
|
|
410
|
+
* `data-active` and the stylesheet dims the others, which says which group is
|
|
411
|
+
* meant by making four of five quieter: it reads as the chart losing
|
|
412
|
+
* confidence rather than as one column being pointed at. A band says the same
|
|
413
|
+
* thing by lighting the region the pointer is actually in, and the region is
|
|
414
|
+
* the whole slot, because that is the catchment the pointer resolves against.
|
|
415
|
+
*
|
|
416
|
+
* Both are kept. The fade separates the active group from its neighbours and
|
|
417
|
+
* the band says where the neighbourhood is, and on a chart of two categories
|
|
418
|
+
* the fade alone is ambiguous about which half is lit.
|
|
419
|
+
*/
|
|
420
|
+
renderBand(count, sideways) {
|
|
421
|
+
const at = this.pointer.at;
|
|
422
|
+
if (at < 0 || count === 0) {
|
|
423
|
+
return nothing;
|
|
424
|
+
}
|
|
425
|
+
const slot = 100 / count;
|
|
426
|
+
return sideways
|
|
427
|
+
? svg `<rect height=${slot} part="band" width="100" x="0" y=${at * slot} />`
|
|
428
|
+
: svg `<rect height="100" part="band" width=${slot} x=${at * slot} y="0" />`;
|
|
429
|
+
}
|
|
430
|
+
renderLabels(categories) {
|
|
431
|
+
return html `<div aria-hidden="true" part="labels">
|
|
432
|
+
${categories.map((one) => html `<span part="label">${one}</span>`)}
|
|
433
|
+
</div>`;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* One series drawn as a line across the categories, behind a seam.
|
|
437
|
+
*
|
|
438
|
+
* Through the middle of each slot, which is where the group stands, so a
|
|
439
|
+
* point sits over its own columns rather than over the gap between two of
|
|
440
|
+
* them. The same arithmetic the category gridlines use, and for the same
|
|
441
|
+
* reason: the reading is the thing, the boundary is only where the pointer
|
|
442
|
+
* changes its mind.
|
|
443
|
+
*
|
|
444
|
+
* `data-series` keeps the index the series has among *all* of them, not among
|
|
445
|
+
* the lines, so the color a line takes is the color the legend gives it and
|
|
446
|
+
* moving a column between marks does not repaint the chart.
|
|
447
|
+
*/
|
|
448
|
+
renderLine(one, depth, slot, y, sideways) {
|
|
449
|
+
const points = one.points.map((point, index) => {
|
|
450
|
+
const across = index * slot + slot / 2;
|
|
451
|
+
const along = y(point.value);
|
|
452
|
+
return sideways ? [along, across] : [across, along];
|
|
453
|
+
});
|
|
454
|
+
/* Straight between the category centres, and no `curve` property to change
|
|
455
|
+
it. A bar chart's other axis is categorical: there is nothing between
|
|
456
|
+
Gateway and Billing, so a curve through them draws values at positions
|
|
457
|
+
that do not exist and bulges past the readings on the way. `LineChart`
|
|
458
|
+
offers the choice because its axis is continuous and the shape between
|
|
459
|
+
two readings is a claim somebody may legitimately want to make. */
|
|
460
|
+
return svg `<path
|
|
461
|
+
d=${linePath(points, 'straight')}
|
|
462
|
+
data-series=${seriesIndex(depth)}
|
|
463
|
+
part="line"
|
|
464
|
+
style="--chart-series: var(--chart-series-${seriesIndex(depth)})"
|
|
465
|
+
/>`;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* What a pointer resting on a reading shows.
|
|
469
|
+
*
|
|
470
|
+
* A seam over `drawTooltip`, which holds the markup every chart shares. The
|
|
471
|
+
* usual reason to override is arrangement: every cell of the row is already
|
|
472
|
+
* there, including the columns nothing was plotted from.
|
|
473
|
+
*/
|
|
474
|
+
renderTooltip() {
|
|
475
|
+
const at = this.pointer.at;
|
|
476
|
+
const series = this.series;
|
|
477
|
+
if (at < 0 || series.length === 0) {
|
|
478
|
+
return drawTooltip(this.sourceRows, at, this.tag('tooltip'));
|
|
479
|
+
}
|
|
480
|
+
/* Off the far end of the tallest bar in the group, so the box never covers
|
|
481
|
+
the columns it is describing. Horizontal bars grow rightward, so the far
|
|
482
|
+
end is along x and the arrow hangs off the box's start edge. */
|
|
483
|
+
const values = series.map((one) => one.points[at]?.value ?? 0);
|
|
484
|
+
const all = series.flatMap((one) => one.points.map((point) => point.value));
|
|
485
|
+
const [low, high] = extent(all.length > 0 ? all : [0]);
|
|
486
|
+
const domain = [Math.min(0, low), Math.max(0, high)];
|
|
487
|
+
const sideways = this.direction === 'horizontal';
|
|
488
|
+
const scale = sideways ? linear(domain, [0, HEIGHT]) : linear(domain, [HEIGHT, 0]);
|
|
489
|
+
const ends = values.map((one) => scale(one));
|
|
490
|
+
const far = sideways ? Math.max(...ends) : Math.min(...ends);
|
|
491
|
+
const slot = 100 / this.readings;
|
|
492
|
+
const across = at * slot + slot / 2;
|
|
493
|
+
return drawTooltip(this.sourceRows, at, this.tag('tooltip'), {
|
|
494
|
+
placement: sideways ? 'right' : 'top',
|
|
495
|
+
x: sideways ? `${far}%` : `${across}%`,
|
|
496
|
+
y: sideways ? `${across}%` : `${far}%`,
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
__decorate([
|
|
501
|
+
property({ reflect: true })
|
|
502
|
+
], HelixHeadlessBarChart.prototype, "direction", void 0);
|
|
503
|
+
__decorate([
|
|
504
|
+
property()
|
|
505
|
+
], HelixHeadlessBarChart.prototype, "gridlines", void 0);
|
|
506
|
+
__decorate([
|
|
507
|
+
property()
|
|
508
|
+
], HelixHeadlessBarChart.prototype, "lines", void 0);
|
|
509
|
+
__decorate([
|
|
510
|
+
property({ reflect: true })
|
|
511
|
+
], HelixHeadlessBarChart.prototype, "secondary", void 0);
|
|
512
|
+
HelixHeadlessBarChart = __decorate([
|
|
513
|
+
customElement('helix-headless-bar-chart')
|
|
514
|
+
], HelixHeadlessBarChart);
|
|
515
|
+
export { HelixHeadlessBarChart };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './root/blockquote-root.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './root/blockquote-root.js';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
/**
|
|
4
|
+
* @summary A passage set off from the prose around it.
|
|
5
|
+
*
|
|
6
|
+
* @description
|
|
7
|
+
* Renders a real `<blockquote>` with a `<footer>` for the attribution, which is
|
|
8
|
+
* the structure the HTML spec describes for exactly this: the attribution is
|
|
9
|
+
* about the quotation rather than part of it, and putting it inside the quoted
|
|
10
|
+
* text claims the source said their own name.
|
|
11
|
+
*
|
|
12
|
+
* A quotation run inside a sentence is a `Quote`, which is a different element
|
|
13
|
+
* because it is a different job.
|
|
14
|
+
*
|
|
15
|
+
* @since 0.1.0
|
|
16
|
+
* @status stable
|
|
17
|
+
* @category typography
|
|
18
|
+
* @aliases Pullquote, Citation, Excerpt
|
|
19
|
+
* @documentation https://helix.fusion.dev/components/blockquote
|
|
20
|
+
*
|
|
21
|
+
* @slot - The quoted passage.
|
|
22
|
+
* @slot attribution - Who said it, and where.
|
|
23
|
+
*
|
|
24
|
+
* @csspart attribution - The footer carrying the source.
|
|
25
|
+
* @csspart blockquote - The quotation.
|
|
26
|
+
*/
|
|
27
|
+
export declare class HelixHeadlessBlockquote extends HelixElement {
|
|
28
|
+
/**
|
|
29
|
+
* URL identifying where the passage came from.
|
|
30
|
+
*/
|
|
31
|
+
cite: string;
|
|
32
|
+
/**
|
|
33
|
+
* Says on the footer whether there is an attribution in it.
|
|
34
|
+
*
|
|
35
|
+
* A `<footer>` with nothing in it is still a block in the quote's flow and
|
|
36
|
+
* still takes the container's gap, so every blockquote written without an
|
|
37
|
+
* attribution reserved a full space below itself. There is no selector that
|
|
38
|
+
* can ask, `slot:empty` being about a slot's fallback rather than its
|
|
39
|
+
* assigned nodes, so the component asks and says so on the footer inside this
|
|
40
|
+
* shadow root: an attribute on the host is a change to markup the consumer
|
|
41
|
+
* rendered, which React reports on hydration.
|
|
42
|
+
*/
|
|
43
|
+
private markEmpty;
|
|
44
|
+
protected updated(changed: PropertyValues): void;
|
|
45
|
+
protected render(): TemplateResult;
|
|
46
|
+
}
|
|
47
|
+
declare global {
|
|
48
|
+
interface HTMLElementTagNameMap {
|
|
49
|
+
'helix-headless-blockquote': HelixHeadlessBlockquote;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
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 { customElement, HelixElement, slotFilled } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html, nothing } from 'lit';
|
|
9
|
+
import { property } from 'lit/decorators.js';
|
|
10
|
+
/**
|
|
11
|
+
* @summary A passage set off from the prose around it.
|
|
12
|
+
*
|
|
13
|
+
* @description
|
|
14
|
+
* Renders a real `<blockquote>` with a `<footer>` for the attribution, which is
|
|
15
|
+
* the structure the HTML spec describes for exactly this: the attribution is
|
|
16
|
+
* about the quotation rather than part of it, and putting it inside the quoted
|
|
17
|
+
* text claims the source said their own name.
|
|
18
|
+
*
|
|
19
|
+
* A quotation run inside a sentence is a `Quote`, which is a different element
|
|
20
|
+
* because it is a different job.
|
|
21
|
+
*
|
|
22
|
+
* @since 0.1.0
|
|
23
|
+
* @status stable
|
|
24
|
+
* @category typography
|
|
25
|
+
* @aliases Pullquote, Citation, Excerpt
|
|
26
|
+
* @documentation https://helix.fusion.dev/components/blockquote
|
|
27
|
+
*
|
|
28
|
+
* @slot - The quoted passage.
|
|
29
|
+
* @slot attribution - Who said it, and where.
|
|
30
|
+
*
|
|
31
|
+
* @csspart attribution - The footer carrying the source.
|
|
32
|
+
* @csspart blockquote - The quotation.
|
|
33
|
+
*/
|
|
34
|
+
let HelixHeadlessBlockquote = class HelixHeadlessBlockquote extends HelixElement {
|
|
35
|
+
constructor() {
|
|
36
|
+
super(...arguments);
|
|
37
|
+
/**
|
|
38
|
+
* URL identifying where the passage came from.
|
|
39
|
+
*/
|
|
40
|
+
this.cite = '';
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Says on the footer whether there is an attribution in it.
|
|
44
|
+
*
|
|
45
|
+
* A `<footer>` with nothing in it is still a block in the quote's flow and
|
|
46
|
+
* still takes the container's gap, so every blockquote written without an
|
|
47
|
+
* attribution reserved a full space below itself. There is no selector that
|
|
48
|
+
* can ask, `slot:empty` being about a slot's fallback rather than its
|
|
49
|
+
* assigned nodes, so the component asks and says so on the footer inside this
|
|
50
|
+
* shadow root: an attribute on the host is a change to markup the consumer
|
|
51
|
+
* rendered, which React reports on hydration.
|
|
52
|
+
*/
|
|
53
|
+
markEmpty() {
|
|
54
|
+
const footer = this.renderRoot?.querySelector('[part="attribution"]');
|
|
55
|
+
const empty = !slotFilled(this.renderRoot?.querySelector('slot[name="attribution"]'));
|
|
56
|
+
footer?.toggleAttribute('data-empty', empty);
|
|
57
|
+
/* `hidden` beside the mirror, because `data-empty` is a hook the styled
|
|
58
|
+
sheet reads and this tier has no sheet: an empty region left in the box
|
|
59
|
+
tree is a gap a consumer cannot close without knowing to look for it. The
|
|
60
|
+
styled rule stays, because that sheet sets `display` on this part and so
|
|
61
|
+
outranks the UA one. */
|
|
62
|
+
footer?.toggleAttribute('hidden', empty);
|
|
63
|
+
}
|
|
64
|
+
updated(changed) {
|
|
65
|
+
super.updated(changed);
|
|
66
|
+
this.markEmpty();
|
|
67
|
+
}
|
|
68
|
+
render() {
|
|
69
|
+
// The footer is a bare slot inside a real `<footer>`: the element is the
|
|
70
|
+
// semantics and cannot be omitted, while an unfilled slot inside it is
|
|
71
|
+
// `display: contents` and generates no box.
|
|
72
|
+
return html `<blockquote part="blockquote" cite=${this.cite || nothing}>
|
|
73
|
+
<slot></slot>
|
|
74
|
+
<footer part="attribution"><slot name="attribution"></slot></footer>
|
|
75
|
+
</blockquote>`;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
__decorate([
|
|
79
|
+
property()
|
|
80
|
+
], HelixHeadlessBlockquote.prototype, "cite", void 0);
|
|
81
|
+
HelixHeadlessBlockquote = __decorate([
|
|
82
|
+
customElement('helix-headless-blockquote')
|
|
83
|
+
], HelixHeadlessBlockquote);
|
|
84
|
+
export { HelixHeadlessBlockquote };
|