@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,144 @@
|
|
|
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, hostAria, MixinDismissible, slotFilled, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { x } from '@fusion.dev/helix-icons';
|
|
9
|
+
import { html, nothing } from 'lit';
|
|
10
|
+
import { property } from 'lit/decorators.js';
|
|
11
|
+
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
12
|
+
/**
|
|
13
|
+
* @summary A page-level message above the masthead, which can be dismissed.
|
|
14
|
+
*
|
|
15
|
+
* @description
|
|
16
|
+
* Chrome rather than content. An announcement sits above the header and speaks
|
|
17
|
+
* for the whole page: a trial ending, a service degraded, a change of terms. A
|
|
18
|
+
* passage that interrupts a document to set itself apart is a `Callout`, which
|
|
19
|
+
* is read where it sits and cannot be dismissed. Neither is a variant of the
|
|
20
|
+
* other.
|
|
21
|
+
*
|
|
22
|
+
* **Always a polite live region.** `role="alert"` is assertive and interrupts
|
|
23
|
+
* whatever is being read, which is right for something that appears mid-session
|
|
24
|
+
* and wrong for something that was in the served HTML: an assertive
|
|
25
|
+
* announcement would cut across a screen-reader user on every page load, before
|
|
26
|
+
* they had read anything. Politeness costs a moment and is never wrong; the tone
|
|
27
|
+
* does not change that, because an error that was always there is still not an
|
|
28
|
+
* interruption.
|
|
29
|
+
*
|
|
30
|
+
* Dismissing is a request. The announcement does not remove itself, because the
|
|
31
|
+
* consumer owns the markup and taking the node out from under them would put
|
|
32
|
+
* their state and the document out of step. `preventDefault()` on the
|
|
33
|
+
* `helix-dismiss` is a refusal.
|
|
34
|
+
*
|
|
35
|
+
* @since 0.1.0
|
|
36
|
+
* @status stable
|
|
37
|
+
* @category feedback
|
|
38
|
+
* @aliases Banner, Notification bar, Alert bar
|
|
39
|
+
* @documentation https://helix.fusion.dev/components/announcement
|
|
40
|
+
*
|
|
41
|
+
* @slot - The message.
|
|
42
|
+
* @slot actions - What to do about it, usually a link or a button.
|
|
43
|
+
* @slot icon - Replaces the glyph inside the dismiss control.
|
|
44
|
+
*
|
|
45
|
+
* @event {HelixDismissEvent} helix-dismiss - Fired when the reader asks to close it. Cancelable: refusing it takes the decision and nothing moves.
|
|
46
|
+
*
|
|
47
|
+
* @csspart actions - The trailing action region.
|
|
48
|
+
* @csspart content - The message region.
|
|
49
|
+
* @csspart dismiss - The control that asks to close.
|
|
50
|
+
* @csspart dismiss-mark - The glyph on the dismiss control, where none is slotted.
|
|
51
|
+
*/
|
|
52
|
+
let HelixHeadlessAnnouncement = class HelixHeadlessAnnouncement extends MixinDismissible(HelixElement) {
|
|
53
|
+
willUpdate(changed) {
|
|
54
|
+
super.willUpdate(changed);
|
|
55
|
+
// On the host, and always polite. See the note above on `role="alert"`.
|
|
56
|
+
hostAria(this.internals, { role: 'status' });
|
|
57
|
+
this.internals.ariaLive = 'polite';
|
|
58
|
+
}
|
|
59
|
+
updated(changed) {
|
|
60
|
+
super.updated(changed);
|
|
61
|
+
this.markEmpty();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Says on the `actions` region whether anything is in it.
|
|
65
|
+
*
|
|
66
|
+
* An empty region is not free: it is still a flex item, so it still takes the
|
|
67
|
+
* container's gap. There is no selector that can ask, `slot:empty` being
|
|
68
|
+
* about a slot's fallback rather than its assigned nodes, so the component
|
|
69
|
+
* asks and says so, on the region inside this shadow root rather than on the
|
|
70
|
+
* host: an attribute written onto the host is a change to markup the consumer
|
|
71
|
+
* rendered, which React reports on hydration and does not patch up.
|
|
72
|
+
*/
|
|
73
|
+
markEmpty() {
|
|
74
|
+
const region = this.renderRoot?.querySelector('[part="actions"]');
|
|
75
|
+
const empty = !slotFilled(this.renderRoot?.querySelector('slot[name="actions"]'));
|
|
76
|
+
region?.toggleAttribute('data-empty', empty);
|
|
77
|
+
/* `hidden` beside the mirror, because `data-empty` is a hook the styled
|
|
78
|
+
sheet reads and this tier has no sheet: an empty region left in the box
|
|
79
|
+
tree is a gap a consumer cannot close without knowing to look for it. The
|
|
80
|
+
styled rule stays, because that sheet sets `display` on this part and
|
|
81
|
+
therefore outranks the UA one. */
|
|
82
|
+
region?.toggleAttribute('hidden', empty);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The cross inside the dismiss button, behind a seam.
|
|
86
|
+
*
|
|
87
|
+
* Slot fallback, so a consumer replaces it by slotting; and a method, so the
|
|
88
|
+
* tier above replaces it by overriding. Those answer different people: the
|
|
89
|
+
* slot is for the page and the method is for whoever is building the styled
|
|
90
|
+
* layer, and a fallback with only the first is one a tier can restyle and
|
|
91
|
+
* cannot change.
|
|
92
|
+
*
|
|
93
|
+
* **Named for what it draws, which it was not.** It was `renderIcon`, with a
|
|
94
|
+
* description of "the mark for the announcement's tone", and it draws the `x`
|
|
95
|
+
* glyph inside the dismiss button and has never drawn a tone. The name is
|
|
96
|
+
* `renderIcon` on `Toast` and `Callout` too, and on both of those it takes a
|
|
97
|
+
* severity and draws exactly the tone mark this claimed to: the prose came
|
|
98
|
+
* from a sibling that meant it. An announcement has no tone mark at all.
|
|
99
|
+
*/
|
|
100
|
+
renderDismissIcon() {
|
|
101
|
+
return html `<slot name="icon">
|
|
102
|
+
<svg part="dismiss-mark" viewBox=${x.viewBox} fill="currentColor" aria-hidden="true">
|
|
103
|
+
${unsafeSVG(x.content)}
|
|
104
|
+
</svg>
|
|
105
|
+
</slot>`;
|
|
106
|
+
}
|
|
107
|
+
render() {
|
|
108
|
+
return html `<div part="content"><slot></slot></div>
|
|
109
|
+
<div part="actions"><slot name="actions"></slot></div>
|
|
110
|
+
${
|
|
111
|
+
/* A plain `<button>`, the way `Menu` renders its way back and every
|
|
112
|
+
other in-shadow control in the library.
|
|
113
|
+
|
|
114
|
+
It was `helix-headless-icon-button`, which is the headless tier and
|
|
115
|
+
therefore ships no CSS at all, so the `<button>` inside it kept the
|
|
116
|
+
browser's own border and gray fill and the dismiss control read as a
|
|
117
|
+
form button dropped into a message bar. The styled tier could not
|
|
118
|
+
reach it: `[part="dismiss"]` selects the host and stops at its shadow
|
|
119
|
+
boundary, and its rules were already written for a plain button,
|
|
120
|
+
`all: unset` and all, which is the clue that this element was never
|
|
121
|
+
meant to be here.
|
|
122
|
+
|
|
123
|
+
Nesting a component inside a component's shadow root also makes the
|
|
124
|
+
parent depend on the child being registered, invisibly, and this was
|
|
125
|
+
the only place in the library doing it. */
|
|
126
|
+
this.dismissible
|
|
127
|
+
? html `<button
|
|
128
|
+
part="dismiss"
|
|
129
|
+
type="button"
|
|
130
|
+
aria-label=${this.dismissLabel}
|
|
131
|
+
@click=${() => this.dismiss()}
|
|
132
|
+
>
|
|
133
|
+
${this.renderDismissIcon()}
|
|
134
|
+
</button>`
|
|
135
|
+
: nothing}`;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
__decorate([
|
|
139
|
+
property({ reflect: true })
|
|
140
|
+
], HelixHeadlessAnnouncement.prototype, "tone", void 0);
|
|
141
|
+
HelixHeadlessAnnouncement = __decorate([
|
|
142
|
+
customElement('helix-headless-announcement')
|
|
143
|
+
], HelixHeadlessAnnouncement);
|
|
144
|
+
export { HelixHeadlessAnnouncement };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './root/app-header-root.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './root/app-header-root.js';
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
/**
|
|
4
|
+
* @summary Page-level banner holding brand, navigation, and actions.
|
|
5
|
+
*
|
|
6
|
+
* @description
|
|
7
|
+
* Tracks whether the page has scrolled and carries it as the custom state
|
|
8
|
+
* `scrolled`, so the styled tier can lift the bar off the page without a scroll
|
|
9
|
+
* handler of its own. Scroll position is the one piece of state the server
|
|
10
|
+
* genuinely cannot know, so it is read on connect rather than derived: a fresh
|
|
11
|
+
* load starts at the top, which is what the server rendered, and a reload
|
|
12
|
+
* part-way down corrects on hydration.
|
|
13
|
+
*
|
|
14
|
+
* **A custom state and not `data-scrolled`, which is what this used to be.**
|
|
15
|
+
* The attribute was written onto the host by the element itself, so a server
|
|
16
|
+
* sent the header without it and the element added it on upgrade. A framework
|
|
17
|
+
* hydrating the page then found an attribute it had not rendered and reported
|
|
18
|
+
* the tree as mismatched: intermittently, because it only happens when the
|
|
19
|
+
* reader reloads far enough down the page to pass the threshold. Every
|
|
20
|
+
* server-rendered consumer paid for that, and could only answer it by
|
|
21
|
+
* suppressing hydration warnings on an element they did not write.
|
|
22
|
+
*
|
|
23
|
+
* `ElementInternals.states` is deliberately not in the DOM, so there is nothing
|
|
24
|
+
* for a hydration pass to disagree with, and `:state(scrolled)` selects it. The
|
|
25
|
+
* base class made the same move for `data-settled` and its note explains the
|
|
26
|
+
* rest.
|
|
27
|
+
*
|
|
28
|
+
* The listener is passive and reads `scrollY` only, so it never blocks
|
|
29
|
+
* scrolling.
|
|
30
|
+
*
|
|
31
|
+
* Three regions, each in its own wrapper, because the row is a grid and a grid
|
|
32
|
+
* needs three items to put the middle one in the middle. A bare slot is
|
|
33
|
+
* `display: contents`, so its assigned elements become grid items themselves:
|
|
34
|
+
* two actions would take two tracks and push the navigation off center. These
|
|
35
|
+
* wrappers earn their boxes, which is the test; they carry no inset or fill of
|
|
36
|
+
* their own, so an empty one still paints nothing.
|
|
37
|
+
*
|
|
38
|
+
* The host is the banner and spans the viewport; the row inside it is what gets
|
|
39
|
+
* centered. A banner that is itself narrowed leaves its background stopping
|
|
40
|
+
* short of the window edges, which reads as a floating bar rather than as the
|
|
41
|
+
* top of the page. That needs one element and one row, not a wrapper as well:
|
|
42
|
+
* the host carries the material and `content` carries the measure.
|
|
43
|
+
*
|
|
44
|
+
* @since 0.1.0
|
|
45
|
+
* @status stable
|
|
46
|
+
* @category navigation
|
|
47
|
+
* @aliases Masthead, Navbar, TopBar
|
|
48
|
+
* @documentation https://helix.fusion.dev/components/app-header
|
|
49
|
+
*
|
|
50
|
+
* @slot - The middle region, usually a `Navigation`.
|
|
51
|
+
* @slot end - Trailing content.
|
|
52
|
+
* @slot start - Leading content, usually a wordmark.
|
|
53
|
+
*
|
|
54
|
+
* @event {HelixScrolledEvent} helix-scrolled - Fired when the page crosses the
|
|
55
|
+
* threshold, with the new state. A custom state cannot be observed the way an
|
|
56
|
+
* attribute could, so the header says when it changes rather than leaving
|
|
57
|
+
* consumers to run a second scroll listener and disagree about the hysteresis.
|
|
58
|
+
*
|
|
59
|
+
* @csspart content - The middle region.
|
|
60
|
+
* @csspart end - The trailing region.
|
|
61
|
+
* @csspart row - The centered row inside the banner.
|
|
62
|
+
* @csspart start - The leading region.
|
|
63
|
+
*/
|
|
64
|
+
export declare class HelixHeadlessAppHeader extends HelixElement {
|
|
65
|
+
/**
|
|
66
|
+
* Where the middle region sits in the bar.
|
|
67
|
+
*
|
|
68
|
+
* Centered by default, which reads as the site's spine when the navigation is
|
|
69
|
+
* the primary thing in the header rather than an afterthought beside a logo.
|
|
70
|
+
* Centered against the banner rather than against whatever space the brand
|
|
71
|
+
* left over, so the middle of the nav is the middle of the window whatever
|
|
72
|
+
* the wordmark and the actions happen to measure.
|
|
73
|
+
*
|
|
74
|
+
* `start` is the opt-out, for a header whose middle region trails the brand.
|
|
75
|
+
*
|
|
76
|
+
* **Named for the region and not for what is usually in it.** It was
|
|
77
|
+
* `nav-align`, which reads as a property about `Navigation` and is not: the
|
|
78
|
+
* middle slot takes whatever a consumer puts there, a search field or a
|
|
79
|
+
* breadcrumb trail as readily as a nav, and a header that centered its search
|
|
80
|
+
* box would have been setting `nav-align` to do it. The part is called
|
|
81
|
+
* `content`, so the property is too.
|
|
82
|
+
*/
|
|
83
|
+
contentAlign?: 'start';
|
|
84
|
+
private scrolled;
|
|
85
|
+
/**
|
|
86
|
+
* A band rather than a line, so the fill cannot flicker at the boundary.
|
|
87
|
+
*
|
|
88
|
+
* **`scrollY > 0` is a threshold with no width, and a threshold with no width
|
|
89
|
+
* is a switch sitting exactly where scroll positions cluster.** Zero is not a
|
|
90
|
+
* quiet place: rubber-banding overshoots past it and comes back, scroll
|
|
91
|
+
* anchoring nudges by a pixel when an image or a font lands, and a
|
|
92
|
+
* `scroll-behavior: smooth` jump settles by oscillating around its target.
|
|
93
|
+
* Every one of those crossings toggled the attribute, and the fill and the
|
|
94
|
+
* blur are both transitioned, so each toggle started a fresh animation in the
|
|
95
|
+
* opposite direction. What a reader sees is a bar that shimmers, and text
|
|
96
|
+
* legible through it for as long as the fill is part way in.
|
|
97
|
+
*
|
|
98
|
+
* Eight pixels to take the fill, two to give it back. Asymmetric on purpose:
|
|
99
|
+
* the bar should look attached to the top of the page for as long as it
|
|
100
|
+
* honestly is, so leaving is nearly the whole way back, and arriving needs
|
|
101
|
+
* enough travel to mean the reader moved rather than the layout did.
|
|
102
|
+
*/
|
|
103
|
+
private readonly handleScroll;
|
|
104
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
105
|
+
connectedCallback(): void;
|
|
106
|
+
disconnectedCallback(): void;
|
|
107
|
+
protected render(): TemplateResult;
|
|
108
|
+
}
|
|
109
|
+
declare global {
|
|
110
|
+
interface HTMLElementTagNameMap {
|
|
111
|
+
'helix-headless-app-header': HelixHeadlessAppHeader;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
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, HelixScrolledEvent, hostAria } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html } from 'lit';
|
|
9
|
+
import { property } from 'lit/decorators.js';
|
|
10
|
+
/**
|
|
11
|
+
* @summary Page-level banner holding brand, navigation, and actions.
|
|
12
|
+
*
|
|
13
|
+
* @description
|
|
14
|
+
* Tracks whether the page has scrolled and carries it as the custom state
|
|
15
|
+
* `scrolled`, so the styled tier can lift the bar off the page without a scroll
|
|
16
|
+
* handler of its own. Scroll position is the one piece of state the server
|
|
17
|
+
* genuinely cannot know, so it is read on connect rather than derived: a fresh
|
|
18
|
+
* load starts at the top, which is what the server rendered, and a reload
|
|
19
|
+
* part-way down corrects on hydration.
|
|
20
|
+
*
|
|
21
|
+
* **A custom state and not `data-scrolled`, which is what this used to be.**
|
|
22
|
+
* The attribute was written onto the host by the element itself, so a server
|
|
23
|
+
* sent the header without it and the element added it on upgrade. A framework
|
|
24
|
+
* hydrating the page then found an attribute it had not rendered and reported
|
|
25
|
+
* the tree as mismatched: intermittently, because it only happens when the
|
|
26
|
+
* reader reloads far enough down the page to pass the threshold. Every
|
|
27
|
+
* server-rendered consumer paid for that, and could only answer it by
|
|
28
|
+
* suppressing hydration warnings on an element they did not write.
|
|
29
|
+
*
|
|
30
|
+
* `ElementInternals.states` is deliberately not in the DOM, so there is nothing
|
|
31
|
+
* for a hydration pass to disagree with, and `:state(scrolled)` selects it. The
|
|
32
|
+
* base class made the same move for `data-settled` and its note explains the
|
|
33
|
+
* rest.
|
|
34
|
+
*
|
|
35
|
+
* The listener is passive and reads `scrollY` only, so it never blocks
|
|
36
|
+
* scrolling.
|
|
37
|
+
*
|
|
38
|
+
* Three regions, each in its own wrapper, because the row is a grid and a grid
|
|
39
|
+
* needs three items to put the middle one in the middle. A bare slot is
|
|
40
|
+
* `display: contents`, so its assigned elements become grid items themselves:
|
|
41
|
+
* two actions would take two tracks and push the navigation off center. These
|
|
42
|
+
* wrappers earn their boxes, which is the test; they carry no inset or fill of
|
|
43
|
+
* their own, so an empty one still paints nothing.
|
|
44
|
+
*
|
|
45
|
+
* The host is the banner and spans the viewport; the row inside it is what gets
|
|
46
|
+
* centered. A banner that is itself narrowed leaves its background stopping
|
|
47
|
+
* short of the window edges, which reads as a floating bar rather than as the
|
|
48
|
+
* top of the page. That needs one element and one row, not a wrapper as well:
|
|
49
|
+
* the host carries the material and `content` carries the measure.
|
|
50
|
+
*
|
|
51
|
+
* @since 0.1.0
|
|
52
|
+
* @status stable
|
|
53
|
+
* @category navigation
|
|
54
|
+
* @aliases Masthead, Navbar, TopBar
|
|
55
|
+
* @documentation https://helix.fusion.dev/components/app-header
|
|
56
|
+
*
|
|
57
|
+
* @slot - The middle region, usually a `Navigation`.
|
|
58
|
+
* @slot end - Trailing content.
|
|
59
|
+
* @slot start - Leading content, usually a wordmark.
|
|
60
|
+
*
|
|
61
|
+
* @event {HelixScrolledEvent} helix-scrolled - Fired when the page crosses the
|
|
62
|
+
* threshold, with the new state. A custom state cannot be observed the way an
|
|
63
|
+
* attribute could, so the header says when it changes rather than leaving
|
|
64
|
+
* consumers to run a second scroll listener and disagree about the hysteresis.
|
|
65
|
+
*
|
|
66
|
+
* @csspart content - The middle region.
|
|
67
|
+
* @csspart end - The trailing region.
|
|
68
|
+
* @csspart row - The centered row inside the banner.
|
|
69
|
+
* @csspart start - The leading region.
|
|
70
|
+
*/
|
|
71
|
+
let HelixHeadlessAppHeader = class HelixHeadlessAppHeader extends HelixElement {
|
|
72
|
+
constructor() {
|
|
73
|
+
super(...arguments);
|
|
74
|
+
/* Whether the bar currently believes the page has moved, kept alongside the
|
|
75
|
+
attribute so a scroll that changes nothing writes nothing. */
|
|
76
|
+
this.scrolled = false;
|
|
77
|
+
/**
|
|
78
|
+
* A band rather than a line, so the fill cannot flicker at the boundary.
|
|
79
|
+
*
|
|
80
|
+
* **`scrollY > 0` is a threshold with no width, and a threshold with no width
|
|
81
|
+
* is a switch sitting exactly where scroll positions cluster.** Zero is not a
|
|
82
|
+
* quiet place: rubber-banding overshoots past it and comes back, scroll
|
|
83
|
+
* anchoring nudges by a pixel when an image or a font lands, and a
|
|
84
|
+
* `scroll-behavior: smooth` jump settles by oscillating around its target.
|
|
85
|
+
* Every one of those crossings toggled the attribute, and the fill and the
|
|
86
|
+
* blur are both transitioned, so each toggle started a fresh animation in the
|
|
87
|
+
* opposite direction. What a reader sees is a bar that shimmers, and text
|
|
88
|
+
* legible through it for as long as the fill is part way in.
|
|
89
|
+
*
|
|
90
|
+
* Eight pixels to take the fill, two to give it back. Asymmetric on purpose:
|
|
91
|
+
* the bar should look attached to the top of the page for as long as it
|
|
92
|
+
* honestly is, so leaving is nearly the whole way back, and arriving needs
|
|
93
|
+
* enough travel to mean the reader moved rather than the layout did.
|
|
94
|
+
*/
|
|
95
|
+
this.handleScroll = () => {
|
|
96
|
+
const y = window.scrollY;
|
|
97
|
+
const next = this.scrolled ? y > 2 : y > 8;
|
|
98
|
+
if (next === this.scrolled) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
this.scrolled = next;
|
|
102
|
+
/* The state is what CSS selects; the event is what anything outside this
|
|
103
|
+
element can hear. Both, because neither covers the other: a state cannot
|
|
104
|
+
be observed and an event cannot be styled. */
|
|
105
|
+
if (next) {
|
|
106
|
+
this.internals.states.add('scrolled');
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
this.internals.states.delete('scrolled');
|
|
110
|
+
}
|
|
111
|
+
this.dispatchEvent(new HelixScrolledEvent({ scrolled: next }));
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
willUpdate(changed) {
|
|
115
|
+
super.willUpdate(changed);
|
|
116
|
+
// On the host, since the host is the banner.
|
|
117
|
+
hostAria(this.internals, { role: 'banner' });
|
|
118
|
+
}
|
|
119
|
+
connectedCallback() {
|
|
120
|
+
super.connectedCallback();
|
|
121
|
+
// Never reached on the server, which is correct: there is no scroll
|
|
122
|
+
// position to read there, and the un-scrolled markup it emits is what a
|
|
123
|
+
// fresh load actually shows.
|
|
124
|
+
window.addEventListener('scroll', this.handleScroll, { passive: true });
|
|
125
|
+
this.handleScroll();
|
|
126
|
+
}
|
|
127
|
+
disconnectedCallback() {
|
|
128
|
+
super.disconnectedCallback();
|
|
129
|
+
window.removeEventListener('scroll', this.handleScroll);
|
|
130
|
+
}
|
|
131
|
+
render() {
|
|
132
|
+
return html `
|
|
133
|
+
<div part="row">
|
|
134
|
+
<div part="start"><slot name="start"></slot></div>
|
|
135
|
+
<div part="content"><slot></slot></div>
|
|
136
|
+
<div part="end"><slot name="end"></slot></div>
|
|
137
|
+
</div>
|
|
138
|
+
`;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
__decorate([
|
|
142
|
+
property({ attribute: 'content-align', reflect: true })
|
|
143
|
+
], HelixHeadlessAppHeader.prototype, "contentAlign", void 0);
|
|
144
|
+
HelixHeadlessAppHeader = __decorate([
|
|
145
|
+
customElement('helix-headless-app-header')
|
|
146
|
+
], HelixHeadlessAppHeader);
|
|
147
|
+
export { HelixHeadlessAppHeader };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
/**
|
|
4
|
+
* The largest `max` the styled tier can hide past.
|
|
5
|
+
*
|
|
6
|
+
* The fold is `:host([max="N"]) ::slotted(:nth-child(n + N+1))`, one selector
|
|
7
|
+
* per value, because `An+B` takes a literal and no custom property can be read
|
|
8
|
+
* into it. So the range is finite and this is where it is written down, in the
|
|
9
|
+
* tier that has to agree with it: a count that folds and a stylesheet that does
|
|
10
|
+
* not would put a "+5" beside five avatars that are still on screen.
|
|
11
|
+
*/
|
|
12
|
+
export declare const FOLDS_UP_TO = 12;
|
|
13
|
+
/**
|
|
14
|
+
* @summary Overlapping avatars, with a count for the ones not shown.
|
|
15
|
+
*
|
|
16
|
+
* @description
|
|
17
|
+
* A part of `Avatar` rather than a family of its own: it arranges avatars and
|
|
18
|
+
* is about nothing else, and its member is a complete `Avatar` the group did
|
|
19
|
+
* not have to explain.
|
|
20
|
+
*
|
|
21
|
+
* **The overflow count is the group's, not a slot.** Which avatars are hidden
|
|
22
|
+
* is a fact the group works out from `max` and how many it was given, so a
|
|
23
|
+
* consumer writing the "+3" themselves would be writing a number that has to
|
|
24
|
+
* agree with a list they do not control.
|
|
25
|
+
*
|
|
26
|
+
* **Hidden, not removed.** Past `max`, the extra avatars stay in the DOM and
|
|
27
|
+
* stop being shown, so nothing re-renders when `max` changes and the accessible
|
|
28
|
+
* name can still be built from all of them. The count is what a sighted reader
|
|
29
|
+
* gets; the group's own name is what everyone else gets, and "Seven people" is
|
|
30
|
+
* more useful than seven names read in a row.
|
|
31
|
+
*
|
|
32
|
+
* **And hidden by the stylesheet, not by this class.** It wrote `data-overflow`
|
|
33
|
+
* onto each avatar from `updated`, which is one update too late and one element
|
|
34
|
+
* too far out: Lit renders on a microtask, so an avatar appended past the limit
|
|
35
|
+
* was laid out and painted before anything ran to hide it, and the group was
|
|
36
|
+
* writing attributes onto markup a consumer owns to do it. Measured in Chrome
|
|
37
|
+
* 148, appending two past `max="3"` and reading before yielding: five `flex`,
|
|
38
|
+
* folding to three on the next update. The styled tier now does it with
|
|
39
|
+
* `:host([max="N"]) ::slotted(:nth-child(n + N+1))`, which is right at the
|
|
40
|
+
* first style resolution and writes nothing.
|
|
41
|
+
*
|
|
42
|
+
* **The fold is finite, and the count agrees with it.** `An+B` takes a literal,
|
|
43
|
+
* so there is one selector per value of `max` and the range stops at twelve.
|
|
44
|
+
* Past that the group shows everyone, counts nothing and says so, because
|
|
45
|
+
* showing everyone is a defensible answer and showing everyone beside a "+5" is
|
|
46
|
+
* not. `max` above twelve is a list the consumer should be slicing themselves.
|
|
47
|
+
*
|
|
48
|
+
* **It is a list.** A row of faces is a set of separate people, and a group
|
|
49
|
+
* with no role announces as one run of text. `role="list"` needs its children
|
|
50
|
+
* to be `listitem`, which they cannot be told to become without writing an
|
|
51
|
+
* attribute onto a consumer's element, so the group carries `role="group"` and
|
|
52
|
+
* its name instead: one announcement, correct, and nothing written to anyone
|
|
53
|
+
* else's markup.
|
|
54
|
+
*
|
|
55
|
+
* @since 0.1.0
|
|
56
|
+
* @status stable
|
|
57
|
+
* @aliases Avatar stack, Facepile
|
|
58
|
+
* @documentation https://helix.fusion.dev/components/avatar
|
|
59
|
+
*
|
|
60
|
+
* @slot - The avatars, in the order they should be read.
|
|
61
|
+
*
|
|
62
|
+
* @csspart overflow - The count of avatars past `max`.
|
|
63
|
+
*/
|
|
64
|
+
export declare class HelixHeadlessAvatarGroup extends HelixElement {
|
|
65
|
+
/**
|
|
66
|
+
* Accessible name for the set, such as "Reviewers".
|
|
67
|
+
*/
|
|
68
|
+
label: string;
|
|
69
|
+
/**
|
|
70
|
+
* How many avatars are shown before the rest become a count.
|
|
71
|
+
*
|
|
72
|
+
* Unset shows all of them, which is what no limit means and is more useful
|
|
73
|
+
* than refusing to render.
|
|
74
|
+
*
|
|
75
|
+
* **Reflected, because the fold is a stylesheet rule and nothing else.** The
|
|
76
|
+
* styled tier hides past the limit with `:host([max="N"]) ::slotted(:nth-child(n + N+1))`,
|
|
77
|
+
* so the attribute *is* the mechanism: a `max` that reaches this property and
|
|
78
|
+
* never reaches the host matches no rule, and every avatar is drawn beside a
|
|
79
|
+
* count that says two of them are hidden. That is the failure this repository
|
|
80
|
+
* already writes down as "reflect only what CSS selects on", and it went
|
|
81
|
+
* unnoticed because the examples set `max` in markup, where the author had
|
|
82
|
+
* written the attribute themselves.
|
|
83
|
+
*
|
|
84
|
+
* It is the path a script takes that was broken, and React takes it for
|
|
85
|
+
* everyone: React assigns a matching property rather than an attribute, so
|
|
86
|
+
* `<helix-avatar-group max={4}>` folded nothing at all. Measured against the
|
|
87
|
+
* markup twin, the fifth and sixth avatars rendered at full size where the
|
|
88
|
+
* markup version had them at 0x0.
|
|
89
|
+
*
|
|
90
|
+
* **Optional rather than defaulted, per the rule that a reflected property
|
|
91
|
+
* takes no default**: `max = 0` would stamp `max="0"` onto every host that
|
|
92
|
+
* never asked for a limit, including on the server.
|
|
93
|
+
*/
|
|
94
|
+
max?: number;
|
|
95
|
+
/** The avatars, in light-DOM order. Empty on the server, which has no tree. */
|
|
96
|
+
get avatars(): HTMLElement[];
|
|
97
|
+
/**
|
|
98
|
+
* How many avatars are past the limit, and so not shown.
|
|
99
|
+
*
|
|
100
|
+
* Not `hidden`, which is `HTMLElement`'s own boolean: a getter of that name
|
|
101
|
+
* returning a number is a type error, and had it been assignable it would
|
|
102
|
+
* have been worse, because a group with three extra members would have set
|
|
103
|
+
* the attribute that hides the whole group.
|
|
104
|
+
*/
|
|
105
|
+
get overflow(): number;
|
|
106
|
+
/** Said once per element, because a re-render is not a second mistake. */
|
|
107
|
+
private warned;
|
|
108
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
109
|
+
protected updated(changed: PropertyValues): void;
|
|
110
|
+
protected render(): TemplateResult;
|
|
111
|
+
}
|
|
112
|
+
declare global {
|
|
113
|
+
interface HTMLElementTagNameMap {
|
|
114
|
+
'helix-headless-avatar-group': HelixHeadlessAvatarGroup;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
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, hostAria } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html } from 'lit';
|
|
9
|
+
import { property } from 'lit/decorators.js';
|
|
10
|
+
/**
|
|
11
|
+
* The largest `max` the styled tier can hide past.
|
|
12
|
+
*
|
|
13
|
+
* The fold is `:host([max="N"]) ::slotted(:nth-child(n + N+1))`, one selector
|
|
14
|
+
* per value, because `An+B` takes a literal and no custom property can be read
|
|
15
|
+
* into it. So the range is finite and this is where it is written down, in the
|
|
16
|
+
* tier that has to agree with it: a count that folds and a stylesheet that does
|
|
17
|
+
* not would put a "+5" beside five avatars that are still on screen.
|
|
18
|
+
*/
|
|
19
|
+
export const FOLDS_UP_TO = 12;
|
|
20
|
+
/**
|
|
21
|
+
* @summary Overlapping avatars, with a count for the ones not shown.
|
|
22
|
+
*
|
|
23
|
+
* @description
|
|
24
|
+
* A part of `Avatar` rather than a family of its own: it arranges avatars and
|
|
25
|
+
* is about nothing else, and its member is a complete `Avatar` the group did
|
|
26
|
+
* not have to explain.
|
|
27
|
+
*
|
|
28
|
+
* **The overflow count is the group's, not a slot.** Which avatars are hidden
|
|
29
|
+
* is a fact the group works out from `max` and how many it was given, so a
|
|
30
|
+
* consumer writing the "+3" themselves would be writing a number that has to
|
|
31
|
+
* agree with a list they do not control.
|
|
32
|
+
*
|
|
33
|
+
* **Hidden, not removed.** Past `max`, the extra avatars stay in the DOM and
|
|
34
|
+
* stop being shown, so nothing re-renders when `max` changes and the accessible
|
|
35
|
+
* name can still be built from all of them. The count is what a sighted reader
|
|
36
|
+
* gets; the group's own name is what everyone else gets, and "Seven people" is
|
|
37
|
+
* more useful than seven names read in a row.
|
|
38
|
+
*
|
|
39
|
+
* **And hidden by the stylesheet, not by this class.** It wrote `data-overflow`
|
|
40
|
+
* onto each avatar from `updated`, which is one update too late and one element
|
|
41
|
+
* too far out: Lit renders on a microtask, so an avatar appended past the limit
|
|
42
|
+
* was laid out and painted before anything ran to hide it, and the group was
|
|
43
|
+
* writing attributes onto markup a consumer owns to do it. Measured in Chrome
|
|
44
|
+
* 148, appending two past `max="3"` and reading before yielding: five `flex`,
|
|
45
|
+
* folding to three on the next update. The styled tier now does it with
|
|
46
|
+
* `:host([max="N"]) ::slotted(:nth-child(n + N+1))`, which is right at the
|
|
47
|
+
* first style resolution and writes nothing.
|
|
48
|
+
*
|
|
49
|
+
* **The fold is finite, and the count agrees with it.** `An+B` takes a literal,
|
|
50
|
+
* so there is one selector per value of `max` and the range stops at twelve.
|
|
51
|
+
* Past that the group shows everyone, counts nothing and says so, because
|
|
52
|
+
* showing everyone is a defensible answer and showing everyone beside a "+5" is
|
|
53
|
+
* not. `max` above twelve is a list the consumer should be slicing themselves.
|
|
54
|
+
*
|
|
55
|
+
* **It is a list.** A row of faces is a set of separate people, and a group
|
|
56
|
+
* with no role announces as one run of text. `role="list"` needs its children
|
|
57
|
+
* to be `listitem`, which they cannot be told to become without writing an
|
|
58
|
+
* attribute onto a consumer's element, so the group carries `role="group"` and
|
|
59
|
+
* its name instead: one announcement, correct, and nothing written to anyone
|
|
60
|
+
* else's markup.
|
|
61
|
+
*
|
|
62
|
+
* @since 0.1.0
|
|
63
|
+
* @status stable
|
|
64
|
+
* @aliases Avatar stack, Facepile
|
|
65
|
+
* @documentation https://helix.fusion.dev/components/avatar
|
|
66
|
+
*
|
|
67
|
+
* @slot - The avatars, in the order they should be read.
|
|
68
|
+
*
|
|
69
|
+
* @csspart overflow - The count of avatars past `max`.
|
|
70
|
+
*/
|
|
71
|
+
let HelixHeadlessAvatarGroup = class HelixHeadlessAvatarGroup extends HelixElement {
|
|
72
|
+
constructor() {
|
|
73
|
+
super(...arguments);
|
|
74
|
+
/**
|
|
75
|
+
* Accessible name for the set, such as "Reviewers".
|
|
76
|
+
*/
|
|
77
|
+
this.label = '';
|
|
78
|
+
/** Said once per element, because a re-render is not a second mistake. */
|
|
79
|
+
this.warned = false;
|
|
80
|
+
}
|
|
81
|
+
/** The avatars, in light-DOM order. Empty on the server, which has no tree. */
|
|
82
|
+
get avatars() {
|
|
83
|
+
/* `?? []` is the server: Lit's element shim carries attributes and not a
|
|
84
|
+
tree, so `children` is undefined there and spreading it throws. The same
|
|
85
|
+
fault the menu item, the table and the carousel each had in turn, which
|
|
86
|
+
is why it is written before it can happen again. */
|
|
87
|
+
return [...(this.children ?? [])].filter((child) => child instanceof HTMLElement);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* How many avatars are past the limit, and so not shown.
|
|
91
|
+
*
|
|
92
|
+
* Not `hidden`, which is `HTMLElement`'s own boolean: a getter of that name
|
|
93
|
+
* returning a number is a type error, and had it been assignable it would
|
|
94
|
+
* have been worse, because a group with three extra members would have set
|
|
95
|
+
* the attribute that hides the whole group.
|
|
96
|
+
*/
|
|
97
|
+
get overflow() {
|
|
98
|
+
const limit = this.max ?? 0;
|
|
99
|
+
const limited = limit > 0 && limit <= FOLDS_UP_TO;
|
|
100
|
+
return limited ? Math.max(this.avatars.length - limit, 0) : 0;
|
|
101
|
+
}
|
|
102
|
+
willUpdate(changed) {
|
|
103
|
+
super.willUpdate(changed);
|
|
104
|
+
hostAria(this.internals, { label: this.label, role: 'group' });
|
|
105
|
+
}
|
|
106
|
+
updated(changed) {
|
|
107
|
+
super.updated(changed);
|
|
108
|
+
/* Nothing hides anything here any more: the stylesheet does it, from `max`
|
|
109
|
+
on the host, so the arrangement is right at the first style resolution
|
|
110
|
+
rather than one update later. What is left is saying so when a `max` is
|
|
111
|
+
set that no rule can match, because showing everyone is a defensible
|
|
112
|
+
answer and showing everyone beside a "+5" is not. */
|
|
113
|
+
const limit = this.max ?? 0;
|
|
114
|
+
if (limit > FOLDS_UP_TO && this.avatars.length > limit && !this.warned) {
|
|
115
|
+
this.warned = true;
|
|
116
|
+
console.warn(`<${this.localName}> has max="${this.max}", past the ${FOLDS_UP_TO} the fold is written for, ` +
|
|
117
|
+
'so every avatar is shown and none are counted. Lower `max`, or hand the group the ' +
|
|
118
|
+
'avatars you want shown.');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
render() {
|
|
122
|
+
const past = this.overflow;
|
|
123
|
+
return html `<slot @slotchange=${() => this.requestUpdate()}></slot>
|
|
124
|
+
${past > 0 ? html `<span part="overflow" aria-hidden="true">+${past}</span>` : ''}`;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
__decorate([
|
|
128
|
+
property()
|
|
129
|
+
], HelixHeadlessAvatarGroup.prototype, "label", void 0);
|
|
130
|
+
__decorate([
|
|
131
|
+
property({ reflect: true, type: Number })
|
|
132
|
+
], HelixHeadlessAvatarGroup.prototype, "max", void 0);
|
|
133
|
+
HelixHeadlessAvatarGroup = __decorate([
|
|
134
|
+
customElement('helix-headless-avatar-group')
|
|
135
|
+
], HelixHeadlessAvatarGroup);
|
|
136
|
+
export { HelixHeadlessAvatarGroup };
|