@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,526 @@
|
|
|
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
|
+
var HelixHeadlessMegamenu_1;
|
|
8
|
+
import { anchorElement, customElement, HelixElement, MixinControllerOpen, PopoverController, tellDisclosure, } from '@fusion.dev/helix-core';
|
|
9
|
+
import { html, nothing } from 'lit';
|
|
10
|
+
import { property, state } from 'lit/decorators.js';
|
|
11
|
+
/**
|
|
12
|
+
* The panel showing now, so opening one closes the last.
|
|
13
|
+
*
|
|
14
|
+
* A page has one of these open at a time: a nav bar whose Products panel is
|
|
15
|
+
* still down while Solutions opens is a nav bar with two panels over the page.
|
|
16
|
+
* Module scope rather than a coordinating parent, because there is nothing to
|
|
17
|
+
* coordinate through: these sit in whatever container the consumer used, which
|
|
18
|
+
* is usually `helix-navigation` and is not required to be. `Video` holds the
|
|
19
|
+
* media session the same way and for the same reason.
|
|
20
|
+
*/
|
|
21
|
+
let showing;
|
|
22
|
+
/**
|
|
23
|
+
* @summary A section of a navigation that opens a panel of destinations.
|
|
24
|
+
*
|
|
25
|
+
* @description
|
|
26
|
+
* **A disclosure, not a menu, and that is the whole design.** `role="menu"` and
|
|
27
|
+
* `menuitem` are for an application's commands: they take over the arrow keys,
|
|
28
|
+
* announce "menu" to a reader who asked for navigation, and put every link
|
|
29
|
+
* inside a role that is not a link. What this is, is a button that shows and
|
|
30
|
+
* hides a region of the consumer's own anchors, which is the pattern the APG
|
|
31
|
+
* gives for site navigation and the one that leaves a middle click, a modified
|
|
32
|
+
* click and the status bar working. `Menu` remains right for a row of commands.
|
|
33
|
+
*
|
|
34
|
+
* **It renders no links**, for the reason `Navigation` gives: a router renders
|
|
35
|
+
* its own anchor and cannot render one inside this shadow root. The panel is a
|
|
36
|
+
* slot, and what goes in it is lists and headings the consumer wrote.
|
|
37
|
+
*
|
|
38
|
+
* **It opens on hover, and a press is always the fallback.** `open-on` says
|
|
39
|
+
* which, and hover is the resting value because a nav bar is the one place a
|
|
40
|
+
* reader expects to sweep along a row and see each section: making them click,
|
|
41
|
+
* read, click again to compare two is the interaction hover exists to save.
|
|
42
|
+
*
|
|
43
|
+
* Hover is not the only way in, and the code is mostly about that. There is no
|
|
44
|
+
* hover on a touch screen, so a tap opens the panel there whatever `open-on`
|
|
45
|
+
* says, which is why the pointer type is checked rather than assumed. Focus
|
|
46
|
+
* still opens nothing, for the same reason a tab through a nav bar should not
|
|
47
|
+
* unfold it, but Enter on the trigger does, and a keyboard press arrives as a
|
|
48
|
+
* click with no pointer behind it.
|
|
49
|
+
*
|
|
50
|
+
* A mouse click on a trigger the pointer is already sitting on is the case
|
|
51
|
+
* worth naming: toggling there would close the panel and the pointer, still on
|
|
52
|
+
* the trigger, would open it again, so the trigger would flicker and never
|
|
53
|
+
* close. In hover mode the mouse's own clicks are left alone and hover governs
|
|
54
|
+
* on its own. Escape and a click away still close it.
|
|
55
|
+
*
|
|
56
|
+
* The delays are intent, not decoration. Opening waits, so a pointer crossing
|
|
57
|
+
* the bar on its way somewhere else opens nothing; closing waits longer, so the
|
|
58
|
+
* diagonal from the trigger down into the panel does not pass through a gap and
|
|
59
|
+
* shut it. Moving along a bar where a panel is already down opens the next one
|
|
60
|
+
* at once, because at that point the reader is reading the bar, not crossing it.
|
|
61
|
+
*
|
|
62
|
+
* **Focus is not trapped and not moved.** A disclosure leaves the reader on the
|
|
63
|
+
* trigger and the panel follows in the tab order, which is what the markup
|
|
64
|
+
* already says, so Tab walks into the links and out the far side without
|
|
65
|
+
* anything managing it. Escape closes and puts focus back, because Escape is
|
|
66
|
+
* the one key that has to return the reader to where they were.
|
|
67
|
+
*
|
|
68
|
+
* The properties below are written by this component and read by whoever draws
|
|
69
|
+
* it. A consumer sets none of them: they carry a number this element computed
|
|
70
|
+
* and CSS cannot, which is what lets a stylesheet on this tier draw the thing
|
|
71
|
+
* without measuring anything itself.
|
|
72
|
+
*
|
|
73
|
+
* @since 0.1.0
|
|
74
|
+
* @status experimental
|
|
75
|
+
* @category navigation
|
|
76
|
+
* @aliases Mega menu, Flyout, Nav panel
|
|
77
|
+
* @documentation https://helix.fusion.dev/components/megamenu
|
|
78
|
+
*
|
|
79
|
+
* @slot - The panel's contents: the consumer's own lists and headings.
|
|
80
|
+
* @slot trigger - The control that opens it. Falls back to a button named by `label`.
|
|
81
|
+
*
|
|
82
|
+
* @event {HelixBeforeCloseEvent} helix-before-close - Fired before it closes, and cancelable.
|
|
83
|
+
* @event {HelixBeforeOpenEvent} helix-before-open - Fired before it opens, and cancelable.
|
|
84
|
+
* @event {Event} toggle - Says the state moved, carrying `newState` and `oldState`.
|
|
85
|
+
*
|
|
86
|
+
* @csspart surface - The floating panel, which is what opens.
|
|
87
|
+
* @csspart trigger - The default trigger, where none was slotted.
|
|
88
|
+
*
|
|
89
|
+
* @cssproperty --megamenu-top - Where the panel starts, measured from the bar above it.
|
|
90
|
+
*/
|
|
91
|
+
let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerOpen(HelixElement) {
|
|
92
|
+
constructor() {
|
|
93
|
+
super(...arguments);
|
|
94
|
+
/**
|
|
95
|
+
* The section's name, which names the default trigger and the panel.
|
|
96
|
+
*/
|
|
97
|
+
this.label = '';
|
|
98
|
+
/**
|
|
99
|
+
* Whether hovering the trigger opens the panel, or only a press does.
|
|
100
|
+
*
|
|
101
|
+
* A press always works. This says whether a mouse also opens it by resting on
|
|
102
|
+
* the trigger, and it is the default because that is what a navigation bar
|
|
103
|
+
* does. `click` is for a trigger that does something else as well, or a panel
|
|
104
|
+
* heavy enough that opening it on the way past is rude.
|
|
105
|
+
*/
|
|
106
|
+
/* Read, never written back. It has a default, and a reflected default puts an
|
|
107
|
+
attribute on the host that the consumer did not write, which the server
|
|
108
|
+
then ships: the SSR spec for this element checks exactly that and caught
|
|
109
|
+
it. Nothing selects on it, so there is nothing to reflect for. */
|
|
110
|
+
this.openOn = 'hover';
|
|
111
|
+
/**
|
|
112
|
+
* The width, in pixels, under which a card becomes a band. Zero never does.
|
|
113
|
+
*
|
|
114
|
+
* A card is a panel hung off one word, and there is no room to hang anything
|
|
115
|
+
* off a word on a phone: the columns do not shrink past
|
|
116
|
+
* `--megamenu-column-size`, so four of them stay four of them and the panel
|
|
117
|
+
* runs off the side of the screen rather than reflowing. Below this it takes
|
|
118
|
+
* the whole width and its columns stack, which is the only arrangement that
|
|
119
|
+
* fits.
|
|
120
|
+
*
|
|
121
|
+
* **In script rather than a media query, and only once.** Whether the panel is
|
|
122
|
+
* a band is not a question of paint: a band is not placed against the trigger,
|
|
123
|
+
* so the controller has to be told not to measure, and that decision is here
|
|
124
|
+
* whatever the stylesheet says. Writing the width in both places would be one
|
|
125
|
+
* number in two languages, drifting the first time either moved. This sets
|
|
126
|
+
* `data-narrow` on the host and the stylesheet arranges itself off that.
|
|
127
|
+
*/
|
|
128
|
+
this.fullBelow = 640;
|
|
129
|
+
this.narrow = false;
|
|
130
|
+
this.handleWidth = (event) => {
|
|
131
|
+
this.narrow = event.matches;
|
|
132
|
+
};
|
|
133
|
+
this.panel = new PopoverController(this, {
|
|
134
|
+
anchor: () => this.trigger,
|
|
135
|
+
/* The host, not the panel. A press on the trigger is a press on this
|
|
136
|
+
element, and counting it as outside would close the panel on the way to
|
|
137
|
+
the click that toggles it. `Menu` says the same about its own. */
|
|
138
|
+
boundary: () => this,
|
|
139
|
+
onDismiss: () => this.close(),
|
|
140
|
+
place: () => !this.banded,
|
|
141
|
+
placement: () => 'bottom-start',
|
|
142
|
+
surface: () => this.renderRoot?.querySelector('[part="surface"]'),
|
|
143
|
+
});
|
|
144
|
+
/**
|
|
145
|
+
* Keeps a band under its bar while the page moves, and closes it when the bar
|
|
146
|
+
* goes.
|
|
147
|
+
*
|
|
148
|
+
* The band is fixed and its offset is measured once, when it opens. That is
|
|
149
|
+
* fine until the page scrolls: a header that scrolls away leaves the band
|
|
150
|
+
* pinned where the header used to be, open, in the middle of the page with
|
|
151
|
+
* nothing above it. Measured at a scroll of 300: header bottom at -243 and the
|
|
152
|
+
* band still sitting at 57.
|
|
153
|
+
*
|
|
154
|
+
* The card has none of this, because the floating controller follows its
|
|
155
|
+
* anchor. Turning that off for the band, which has nothing to be placed
|
|
156
|
+
* against, took the scroll handling with it, and this is the half that was
|
|
157
|
+
* still wanted.
|
|
158
|
+
*
|
|
159
|
+
* A sticky bar does not move, so re-measuring returns the same number and the
|
|
160
|
+
* band stays where it is. `requestOpen` rather than `close`, because closing
|
|
161
|
+
* puts focus back on the trigger and a reader who has scrolled away should not
|
|
162
|
+
* be dragged back up to it.
|
|
163
|
+
*/
|
|
164
|
+
this.handleScroll = () => {
|
|
165
|
+
if (!this.open || !this.banded) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (this.bar() <= 0) {
|
|
169
|
+
this.requestOpen(false);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
this.band();
|
|
173
|
+
};
|
|
174
|
+
this.handlePointerDown = (event) => {
|
|
175
|
+
this.pointer = event.pointerType;
|
|
176
|
+
};
|
|
177
|
+
this.handlePointerEnter = (event) => {
|
|
178
|
+
/* Mouse only. A touch screen synthesises an enter on tap, and acting on it
|
|
179
|
+
would open the panel and then let the click that follows close it again,
|
|
180
|
+
so a tap would do nothing at all. */
|
|
181
|
+
if (this.openOn !== 'hover' || event.pointerType !== 'mouse') {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
/* No wait when a panel is already down: the bar is open, and the reader
|
|
185
|
+
moving along it is choosing, not passing through. */
|
|
186
|
+
this.schedule(showing && showing !== this ? 0 : HelixHeadlessMegamenu_1.OPEN_DELAY, () => {
|
|
187
|
+
this.requestOpen(true);
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
this.handlePointerLeave = (event) => {
|
|
191
|
+
if (this.openOn !== 'hover' || event.pointerType !== 'mouse') {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
this.schedule(HelixHeadlessMegamenu_1.CLOSE_DELAY, () => {
|
|
195
|
+
/* Not `close()`: leaving with the pointer should not pull focus back to
|
|
196
|
+
the trigger, which would scroll the page to a nav bar the reader has
|
|
197
|
+
moved on from. Escape is the one that returns them. */
|
|
198
|
+
this.requestOpen(false);
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
this.handleTriggerClick = (event) => {
|
|
202
|
+
this.stop();
|
|
203
|
+
if (this.openOn !== 'hover') {
|
|
204
|
+
this.requestOpen(!this.open);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
/* In hover mode the mouse's own clicks are hover's business. Toggling here
|
|
208
|
+
would close a panel the pointer is still standing on, and the pointer
|
|
209
|
+
would reopen it. A keyboard press arrives with no clicks behind it, and a
|
|
210
|
+
tap arrives with a pointer that is not a mouse: both are the only way in
|
|
211
|
+
for the people making them, so both toggle. */
|
|
212
|
+
if (event.detail === 0 || (this.pointer !== undefined && this.pointer !== 'mouse')) {
|
|
213
|
+
this.requestOpen(!this.open);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* Shuts the panel when a reader takes one of the destinations in it.
|
|
218
|
+
*
|
|
219
|
+
* Nothing closed it before, so a click navigated and left the panel hanging
|
|
220
|
+
* over wherever the reader landed. With a router that navigates in place, and
|
|
221
|
+
* this is one, that is a panel covering the page it was asked to go to.
|
|
222
|
+
*
|
|
223
|
+
* **A modified click leaves it open**, which is the same position this
|
|
224
|
+
* element already takes on middle clicks and the status bar: `cmd` on a link
|
|
225
|
+
* opens a tab behind this page rather than navigating it, so the reader is
|
|
226
|
+
* still standing in the menu and collecting, and shutting it under them would
|
|
227
|
+
* make the second choice cost a second open.
|
|
228
|
+
*
|
|
229
|
+
* `requestOpen(false)` rather than `close()`, for the reason `pointerleave`
|
|
230
|
+
* gives: the trigger is not where the reader is going, and pulling focus back
|
|
231
|
+
* to a nav bar they have just left is a scroll they did not ask for.
|
|
232
|
+
*
|
|
233
|
+
* **On the host rather than on the panel**, which is the same reason the
|
|
234
|
+
* pointer handlers give and one more. A row is slotted light DOM and the
|
|
235
|
+
* panel is in the shadow root, so a click only reaches the panel through the
|
|
236
|
+
* flattened tree: real ones do, and a DOM that does not implement slot
|
|
237
|
+
* propagation never delivers it, which makes every case here pass by never
|
|
238
|
+
* running this at all. The host is the row's own ancestor in both.
|
|
239
|
+
*/
|
|
240
|
+
this.handleContentClick = (event) => {
|
|
241
|
+
if (!this.open || event.defaultPrevented || event.button !== 0) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
/* Asking for the destination rather than for any click, so the headings,
|
|
248
|
+
the gaps between rows and a reader's stray click on the panel's own
|
|
249
|
+
padding leave it where it is. */
|
|
250
|
+
const target = event.target;
|
|
251
|
+
const chosen = target?.closest?.('a[href], button:not([disabled]), [role="menuitem"]');
|
|
252
|
+
/* Inside this element and not the trigger. A press on the trigger is the
|
|
253
|
+
trigger's to answer, and a shadow-rendered one retargets to the host, so
|
|
254
|
+
`closest` there climbs past this element entirely. */
|
|
255
|
+
if (!chosen || !this.contains(chosen) || chosen.closest('[slot="trigger"]')) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
this.requestOpen(false);
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
static { HelixHeadlessMegamenu_1 = this; }
|
|
262
|
+
/** A band, whether because it was asked for or because there is no room. */
|
|
263
|
+
get banded() {
|
|
264
|
+
return this.variant === 'full' || this.narrow;
|
|
265
|
+
}
|
|
266
|
+
/* Rebuilt rather than kept, because the width is a property and a query
|
|
267
|
+
cannot be edited once it is made. */
|
|
268
|
+
watchWidth() {
|
|
269
|
+
this.query?.removeEventListener('change', this.handleWidth);
|
|
270
|
+
this.query = undefined;
|
|
271
|
+
if (!(this.fullBelow > 0) || typeof matchMedia !== 'function') {
|
|
272
|
+
this.narrow = false;
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
this.query = matchMedia(`(max-width: ${this.fullBelow - 0.02}px)`);
|
|
276
|
+
this.query.addEventListener('change', this.handleWidth);
|
|
277
|
+
this.handleWidth(this.query);
|
|
278
|
+
}
|
|
279
|
+
/** Tells a slotted trigger the disclosure state, by property. See `tellDisclosure`. */
|
|
280
|
+
tellTrigger() {
|
|
281
|
+
const slotted = this.slotted;
|
|
282
|
+
if (slotted) {
|
|
283
|
+
tellDisclosure(slotted, this.open);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/** What the consumer slotted, if they slotted anything. */
|
|
287
|
+
get slotted() {
|
|
288
|
+
const slot = this.renderRoot?.querySelector('slot[name="trigger"]');
|
|
289
|
+
return slot?.assignedElements({ flatten: false })[0];
|
|
290
|
+
}
|
|
291
|
+
/** Whatever the consumer slotted, or the button rendered in its place. */
|
|
292
|
+
get trigger() {
|
|
293
|
+
return anchorElement(this.renderRoot?.querySelector('slot[name="trigger"]'), this.renderRoot?.querySelector('[part="trigger"]') ?? this);
|
|
294
|
+
}
|
|
295
|
+
/** Shuts it and puts the reader back where they were. */
|
|
296
|
+
close() {
|
|
297
|
+
if (!this.requestOpen(false)) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
this.trigger.focus();
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Where a full-bleed band starts, which is the only number it needs.
|
|
304
|
+
*
|
|
305
|
+
* The placing pass is off for that appearance, so nothing else is measuring:
|
|
306
|
+
* a band spans the viewport and has only one degree of freedom, how far down
|
|
307
|
+
* it sits, and that is the bottom of the trigger in viewport coordinates
|
|
308
|
+
* because the panel is fixed. A header that scrolls takes the band with it,
|
|
309
|
+
* which is what a panel hanging off a header should do.
|
|
310
|
+
*
|
|
311
|
+
* Written as a custom property rather than an inline `top`, so the stylesheet
|
|
312
|
+
* keeps the arrangement and this contributes the one measurement it cannot
|
|
313
|
+
* make. Nothing to do for the card, which the controller places.
|
|
314
|
+
*/
|
|
315
|
+
band() {
|
|
316
|
+
if (!this.banded) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
this.style.setProperty('--megamenu-top', `${Math.round(this.bar())}px`);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* The bottom edge of the bar this hangs from.
|
|
323
|
+
*
|
|
324
|
+
* The trigger's own bottom is the obvious answer and is the wrong one: a
|
|
325
|
+
* header is taller than the word inside it, so a band starting at the word
|
|
326
|
+
* starts partway up the header, over its lower padding and its border.
|
|
327
|
+
* Measured: trigger bottom 44, header bottom 57, thirteen pixels of header
|
|
328
|
+
* with a band drawn across it.
|
|
329
|
+
*
|
|
330
|
+
* **The first ancestor as wide as the window, which is a fact and not a tag
|
|
331
|
+
* name.** A band spans the viewport, so what it should hang from is whatever
|
|
332
|
+
* else does: that is what makes something a bar. Asking for `helix-app-header`
|
|
333
|
+
* by name would make this element know about that one, which is the coupling
|
|
334
|
+
* `Menu` is careful not to have with `Drilldown`, and would leave a consumer
|
|
335
|
+
* who wrote their own header with a band across it.
|
|
336
|
+
*
|
|
337
|
+
* `body` ends the walk. It is as wide as the window and is not a bar, and its
|
|
338
|
+
* bottom is the foot of the page: without the guard a megamenu on a plain page
|
|
339
|
+
* would put its band down there. Nothing found means nothing to hang from, and
|
|
340
|
+
* the trigger is the honest answer again.
|
|
341
|
+
*/
|
|
342
|
+
bar() {
|
|
343
|
+
const wide = document.documentElement.clientWidth;
|
|
344
|
+
let node = this.parentElement;
|
|
345
|
+
while (node && node !== document.body) {
|
|
346
|
+
const box = node.getBoundingClientRect();
|
|
347
|
+
if (Math.round(box.width) >= wide) {
|
|
348
|
+
return box.bottom;
|
|
349
|
+
}
|
|
350
|
+
node = node.parentElement;
|
|
351
|
+
}
|
|
352
|
+
return this.trigger.getBoundingClientRect().bottom;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* How long a pointer has to mean it, in milliseconds.
|
|
356
|
+
*
|
|
357
|
+
* Opening is the shorter wait: too long and the panel feels stuck, too short
|
|
358
|
+
* and crossing the bar opens things. Closing is longer because the pointer
|
|
359
|
+
* has to get from the trigger to the panel, and the straight line between
|
|
360
|
+
* them is not the line anybody moves along.
|
|
361
|
+
*/
|
|
362
|
+
static { this.OPEN_DELAY = 120; }
|
|
363
|
+
static { this.CLOSE_DELAY = 220; }
|
|
364
|
+
schedule(delay, then) {
|
|
365
|
+
this.stop();
|
|
366
|
+
this.timer = setTimeout(then, delay);
|
|
367
|
+
}
|
|
368
|
+
stop() {
|
|
369
|
+
if (this.timer !== undefined) {
|
|
370
|
+
clearTimeout(this.timer);
|
|
371
|
+
this.timer = undefined;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/* On the host, and here rather than in the template, because Lit templates
|
|
375
|
+
bind inside a shadow root and these have to hear the panel too. Not the
|
|
376
|
+
constructor: the server runs that and has no events. */
|
|
377
|
+
connectedCallback() {
|
|
378
|
+
super.connectedCallback();
|
|
379
|
+
this.watchWidth();
|
|
380
|
+
/* On the window and capturing, so a band over a scrolling panel hears that
|
|
381
|
+
too rather than only the page's own scrolling. Passive: this measures and
|
|
382
|
+
never prevents. */
|
|
383
|
+
addEventListener('scroll', this.handleScroll, { capture: true, passive: true });
|
|
384
|
+
this.addEventListener('pointerdown', this.handlePointerDown);
|
|
385
|
+
this.addEventListener('click', this.handleContentClick);
|
|
386
|
+
this.addEventListener('pointerenter', this.handlePointerEnter);
|
|
387
|
+
this.addEventListener('pointerleave', this.handlePointerLeave);
|
|
388
|
+
}
|
|
389
|
+
disconnectedCallback() {
|
|
390
|
+
super.disconnectedCallback();
|
|
391
|
+
removeEventListener('scroll', this.handleScroll, { capture: true });
|
|
392
|
+
this.query?.removeEventListener('change', this.handleWidth);
|
|
393
|
+
this.query = undefined;
|
|
394
|
+
this.removeEventListener('pointerdown', this.handlePointerDown);
|
|
395
|
+
this.removeEventListener('click', this.handleContentClick);
|
|
396
|
+
this.removeEventListener('pointerenter', this.handlePointerEnter);
|
|
397
|
+
this.removeEventListener('pointerleave', this.handlePointerLeave);
|
|
398
|
+
this.stop();
|
|
399
|
+
if (showing === this) {
|
|
400
|
+
showing = undefined;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
updated(changed) {
|
|
404
|
+
super.updated?.(changed);
|
|
405
|
+
if (changed.has('fullBelow')) {
|
|
406
|
+
this.watchWidth();
|
|
407
|
+
}
|
|
408
|
+
/* The one thing the stylesheet cannot work out for itself, since the
|
|
409
|
+
breakpoint is declared up here. */
|
|
410
|
+
this.toggleAttribute('data-narrow', this.narrow);
|
|
411
|
+
/* A slotted trigger is told the disclosure state, by property.
|
|
412
|
+
|
|
413
|
+
`render` writes `aria-expanded` onto the button it renders itself, and a
|
|
414
|
+
consumer who takes the documented `trigger` slot replaces that button: the
|
|
415
|
+
panel opened and closed and nothing announced it, so a reader was told the
|
|
416
|
+
control was a plain button forever. Silent, because the slot works in
|
|
417
|
+
every other respect and the failure is only audible.
|
|
418
|
+
|
|
419
|
+
**It was `setAttribute` and that really was a hydration mismatch**, which
|
|
420
|
+
is what `Popover`'s class note has said since the day it was written.
|
|
421
|
+
*Measured 28 Aug 2026 against React 19.2.8*, four families server-rendered
|
|
422
|
+
and hydrated with the definitions loaded either side of `hydrateRoot`:
|
|
423
|
+
this one and `SpeedDial` produced "some attributes of the server rendered
|
|
424
|
+
HTML didn't match the client properties. This won't be patched up" in both
|
|
425
|
+
orders, and `Popover` and `Menu`, which write nothing, were clean in both.
|
|
426
|
+
React answers a mismatch by discarding the server's HTML for that subtree
|
|
427
|
+
and rebuilding it, which is the expensive half rather than the console
|
|
428
|
+
line.
|
|
429
|
+
|
|
430
|
+
**The property is the way through, and it is this library's own answer
|
|
431
|
+
already.** `Menu` tells its items by property for exactly this reason and
|
|
432
|
+
says so. React diffs the attributes it rendered and never looks at a
|
|
433
|
+
property, so `expanded` travels to the trigger, lands as `aria-expanded`
|
|
434
|
+
inside that element's shadow root, and the consumer's markup is left as
|
|
435
|
+
they served it. Both notes get what they were protecting: nothing is
|
|
436
|
+
written onto their element, and the reader is still told.
|
|
437
|
+
|
|
438
|
+
**What it cannot reach is a trigger that is not a Helix element.** A plain
|
|
439
|
+
`<button slot="trigger">` has no shadow root to hide the state in and no
|
|
440
|
+
property to take it, and a React consumer cannot mirror it themselves
|
|
441
|
+
because the open state is this element's. That case is warned about rather
|
|
442
|
+
than written to, on the same argument `Tooltip` makes about a link it
|
|
443
|
+
will not write for the consumer.
|
|
444
|
+
|
|
445
|
+
**`aria-controls` is not written here and cannot be.** It named `panel`,
|
|
446
|
+
an id inside this shadow root, and an IDREF resolves only within the tree
|
|
447
|
+
that holds it: from a light-DOM trigger looking in, the reference was to
|
|
448
|
+
nothing. Measured, `document.querySelector('#panel')` came back `null`
|
|
449
|
+
while the same id resolved inside `megamenu.shadowRoot`. An inert
|
|
450
|
+
`aria-controls` is worse than none, an audit tool reporting it satisfied
|
|
451
|
+
and a screen reader following it nowhere. See #322. */
|
|
452
|
+
this.tellTrigger();
|
|
453
|
+
if (this.open) {
|
|
454
|
+
/* Before showing this one, so the two are never both up for a frame. The
|
|
455
|
+
other closes through `requestOpen`, so a consumer holding it open is
|
|
456
|
+
asked rather than overruled. */
|
|
457
|
+
if (showing && showing !== this) {
|
|
458
|
+
showing.requestOpen(false);
|
|
459
|
+
}
|
|
460
|
+
showing = this;
|
|
461
|
+
this.panel.show();
|
|
462
|
+
this.band();
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
if (showing === this) {
|
|
466
|
+
showing = undefined;
|
|
467
|
+
}
|
|
468
|
+
this.panel.hide();
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* The control that opens it, behind a seam the styled tier can move.
|
|
473
|
+
*
|
|
474
|
+
* The same case `SpeedDial` records: a bare `<button>` is what this tier can
|
|
475
|
+
* write, `helix-button` lives a tier above, and a render method is how a tier
|
|
476
|
+
* that has one reaches this without reimplementing the panel below it.
|
|
477
|
+
*/
|
|
478
|
+
renderTrigger() {
|
|
479
|
+
return html `<slot name="trigger" @click=${this.handleTriggerClick}>
|
|
480
|
+
<button
|
|
481
|
+
part="trigger"
|
|
482
|
+
type="button"
|
|
483
|
+
aria-controls="panel"
|
|
484
|
+
aria-expanded=${this.open ? 'true' : 'false'}
|
|
485
|
+
>
|
|
486
|
+
${this.label}
|
|
487
|
+
</button>
|
|
488
|
+
</slot>`;
|
|
489
|
+
}
|
|
490
|
+
render() {
|
|
491
|
+
/* The listeners sit on the host rather than the trigger, so the panel counts
|
|
492
|
+
as inside it: the top layer changes where the panel is painted and not
|
|
493
|
+
where it is in the tree, so a pointer moving off the trigger and onto the
|
|
494
|
+
panel has not left this element and fires no leave. */
|
|
495
|
+
return html `${this.renderTrigger()}
|
|
496
|
+
<div
|
|
497
|
+
part="surface"
|
|
498
|
+
id="panel"
|
|
499
|
+
popover="manual"
|
|
500
|
+
aria-label=${this.label || nothing}
|
|
501
|
+
role="group"
|
|
502
|
+
?hidden=${!this.open}
|
|
503
|
+
>
|
|
504
|
+
<slot></slot>
|
|
505
|
+
</div>`;
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
__decorate([
|
|
509
|
+
property()
|
|
510
|
+
], HelixHeadlessMegamenu.prototype, "label", void 0);
|
|
511
|
+
__decorate([
|
|
512
|
+
property({ reflect: true })
|
|
513
|
+
], HelixHeadlessMegamenu.prototype, "variant", void 0);
|
|
514
|
+
__decorate([
|
|
515
|
+
property({ attribute: 'open-on' })
|
|
516
|
+
], HelixHeadlessMegamenu.prototype, "openOn", void 0);
|
|
517
|
+
__decorate([
|
|
518
|
+
property({ attribute: 'full-below', type: Number })
|
|
519
|
+
], HelixHeadlessMegamenu.prototype, "fullBelow", void 0);
|
|
520
|
+
__decorate([
|
|
521
|
+
state()
|
|
522
|
+
], HelixHeadlessMegamenu.prototype, "narrow", void 0);
|
|
523
|
+
HelixHeadlessMegamenu = HelixHeadlessMegamenu_1 = __decorate([
|
|
524
|
+
customElement('helix-headless-megamenu')
|
|
525
|
+
], HelixHeadlessMegamenu);
|
|
526
|
+
export { HelixHeadlessMegamenu };
|