@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,695 @@
|
|
|
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, formatNumbers, HelixElement, HelixNavigateEvent, hostAria, requestChange, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { caretDoubleLeft, caretDoubleRight, caretLeft, caretRight, } from '@fusion.dev/helix-icons';
|
|
9
|
+
import { html, nothing } from 'lit';
|
|
10
|
+
import { property, state } from 'lit/decorators.js';
|
|
11
|
+
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
12
|
+
/**
|
|
13
|
+
* Fills `{page}` and `{pages}` in a template a consumer wrote.
|
|
14
|
+
*
|
|
15
|
+
* A template rather than a prefix, because word order is not universal and a
|
|
16
|
+
* `page-label="Page"` that this glued a number onto would produce the English
|
|
17
|
+
* order in every language. `href="/products?page={page}"` is the same mechanism
|
|
18
|
+
* doing a second job, which is why there is one placeholder syntax and not two.
|
|
19
|
+
*
|
|
20
|
+
* `format` is what makes the numbers local as well as the words. It is the
|
|
21
|
+
* identity for an address and an `Intl.NumberFormat` for anything a person
|
|
22
|
+
* reads: a URL is machine-facing and `?page=1,234` is a different page from
|
|
23
|
+
* `?page=1234`, where a label read aloud should say the number the way the
|
|
24
|
+
* reader's locale says it.
|
|
25
|
+
*/
|
|
26
|
+
const fill = (template, page, pages, format = String) => template.replaceAll('{page}', format(page)).replaceAll('{pages}', format(pages));
|
|
27
|
+
/**
|
|
28
|
+
* @summary Moves between pages of a longer result.
|
|
29
|
+
*
|
|
30
|
+
* @description
|
|
31
|
+
* The component is the truncation. Given a page and a total it works out which
|
|
32
|
+
* numbers to show and where the runs break, which is the whole of what a
|
|
33
|
+
* consumer would otherwise write by hand and get subtly wrong; everything else
|
|
34
|
+
* here is markup around that. So this is data-driven rather than composed:
|
|
35
|
+
* `<helix-pagination page="4" pages="12">` rather than twelve slotted children
|
|
36
|
+
* a consumer has to keep in step with their own query.
|
|
37
|
+
*
|
|
38
|
+
* **The width does not change as you page.** The run around the current page is
|
|
39
|
+
* `siblings` either side normally, and grows to absorb a gap slot when it meets
|
|
40
|
+
* a boundary, so the control holds the same number of slots from the first page
|
|
41
|
+
* to the last. Every arrangement that lets the count vary makes the buttons move
|
|
42
|
+
* under the pointer between one click and the next.
|
|
43
|
+
*
|
|
44
|
+
* **A gap is only drawn where it hides more than one page.** An ellipsis
|
|
45
|
+
* standing in for a single number costs the same space as the number and tells
|
|
46
|
+
* the reader less.
|
|
47
|
+
*
|
|
48
|
+
* **And a gap is a control.** It goes to the middle of the run it stands over,
|
|
49
|
+
* which is the binary-search step: any page in a set of any size is a handful of
|
|
50
|
+
* presses, where a jump of a fixed size would need forty of them on a set of a
|
|
51
|
+
* hundred and twenty-eight. A menu listing the hidden pages was the other idea
|
|
52
|
+
* and the arithmetic refuses it, for the reasons on `renderGap`.
|
|
53
|
+
*
|
|
54
|
+
* **`href` is what makes these links.** Set it and every page renders an `<a>`
|
|
55
|
+
* with `{page}` filled in, so the server's output is crawlable, a middle click
|
|
56
|
+
* opens a tab, and the address bar is the state. Left unset they are buttons,
|
|
57
|
+
* which is right for a table paging in place. Either way the click announces
|
|
58
|
+
* `helix-navigate` first, and `preventDefault()` on it stops the navigation as
|
|
59
|
+
* well as the change: that is how a router takes over without the page reloading
|
|
60
|
+
* underneath it.
|
|
61
|
+
*
|
|
62
|
+
* **`helix-navigate` and not `helix-change`**, for the reason the calendar pages
|
|
63
|
+
* with it too. Moving to page four chooses nothing; it moves the view over a
|
|
64
|
+
* result that has not changed. A consumer driving the view has to be able to
|
|
65
|
+
* hear that without being told an answer changed.
|
|
66
|
+
*
|
|
67
|
+
* **The count and the page-size control are their own elements.** They were
|
|
68
|
+
* briefly a part and a pair of slots in here, and a slot can only offer one
|
|
69
|
+
* place: at one end of one row, in one order, on one axis. `Pagination.Summary`
|
|
70
|
+
* and `Pagination.Size` sit beside this one instead, so the direction and the
|
|
71
|
+
* order of a footer are the consumer's, which is what they were always going to
|
|
72
|
+
* want. `total` and `page-size` stay here for the arithmetic below and nothing
|
|
73
|
+
* else.
|
|
74
|
+
*
|
|
75
|
+
* **A single page renders nothing.** A control offering one page offers no
|
|
76
|
+
* navigation, and the row it sits in should close over it rather than hold a
|
|
77
|
+
* space for a thing that cannot be used. Reported through
|
|
78
|
+
* `ElementInternals.states` rather than an attribute on the host, because an
|
|
79
|
+
* attribute written at upgrade is markup a server's output never had and a
|
|
80
|
+
* framework reports the difference; a custom state carries the same fact to a
|
|
81
|
+
* stylesheet and none of that to the DOM.
|
|
82
|
+
*
|
|
83
|
+
* **And a page change is announced.** Nothing did: moving the page moves
|
|
84
|
+
* `aria-current` onto a different element, and a screen reader does not announce
|
|
85
|
+
* that, so a reader who pressed 5 heard the word "5" from the button they were
|
|
86
|
+
* on and nothing at all about having arrived. A polite live region says where
|
|
87
|
+
* they now are. It ships empty and is filled only on a change, because a region
|
|
88
|
+
* populated as it enters the document announces itself on arrival.
|
|
89
|
+
*
|
|
90
|
+
* `page` is the controlled property and `default-page` seeds one the element
|
|
91
|
+
* owns. Naming `page` is a claim of ownership: the element announces and waits
|
|
92
|
+
* to be told, which is what a consumer paging through a router already wants.
|
|
93
|
+
*
|
|
94
|
+
* @since 0.1.0
|
|
95
|
+
* @status experimental
|
|
96
|
+
* @category navigation
|
|
97
|
+
* @aliases Pager, Page nav
|
|
98
|
+
* @documentation https://helix.fusion.dev/components/pagination
|
|
99
|
+
*
|
|
100
|
+
* @slot first-icon - The glyph on the jump-to-first control, usually a double caret.
|
|
101
|
+
* @slot last-icon - The glyph on the jump-to-last control, usually a double caret.
|
|
102
|
+
* @slot next-icon - The glyph on the forward-one-page control, usually a caret.
|
|
103
|
+
* @slot previous-icon - The glyph on the back-one-page control, usually a caret.
|
|
104
|
+
*
|
|
105
|
+
* @event {HelixNavigateEvent} helix-navigate - Fired before the page changes, and cancelable. The only way to refuse one.
|
|
106
|
+
*
|
|
107
|
+
* @csspart first - The control that jumps to the first page, under `ends`.
|
|
108
|
+
* @csspart gap - The control standing over pages not shown, which jumps into them.
|
|
109
|
+
* @csspart item - One slot in the run, holding a page or a gap.
|
|
110
|
+
* @csspart last - The control that jumps to the last page, under `ends`.
|
|
111
|
+
* @csspart list - The run of pages.
|
|
112
|
+
* @csspart live - The region that says the page changed. Clipped, not hidden.
|
|
113
|
+
* @csspart mark - The glyph on a first, previous, next or last control, where none is slotted.
|
|
114
|
+
* @csspart next - The control that moves forward one page.
|
|
115
|
+
* @csspart page - The control for one page.
|
|
116
|
+
* @csspart previous - The control that moves back one page.
|
|
117
|
+
* @csspart status - The reading of where you are, in `compact`.
|
|
118
|
+
*/
|
|
119
|
+
let HelixHeadlessPagination = class HelixHeadlessPagination extends HelixElement {
|
|
120
|
+
constructor() {
|
|
121
|
+
super(...arguments);
|
|
122
|
+
/**
|
|
123
|
+
* How many pages there are in total.
|
|
124
|
+
*
|
|
125
|
+
* Clamped to at least one wherever it is read, so a result that has not
|
|
126
|
+
* loaded yet renders a single page rather than an empty control that then
|
|
127
|
+
* appears and pushes the layout down.
|
|
128
|
+
*
|
|
129
|
+
* Left unset where `total` and `page-size` are both given, since the two of
|
|
130
|
+
* them already say it. A fallback rather than an override: writing this wins,
|
|
131
|
+
* so there is never a question of which of two sources is current.
|
|
132
|
+
*/
|
|
133
|
+
this.pages = 0;
|
|
134
|
+
/**
|
|
135
|
+
* How many items there are across every page.
|
|
136
|
+
*
|
|
137
|
+
* What `pages` falls back to together with `page-size`. Unset is the common
|
|
138
|
+
* case, where a consumer knows the page total and not the item total.
|
|
139
|
+
*
|
|
140
|
+
* Nothing is rendered from it. `Pagination.Summary` is what reads a total out
|
|
141
|
+
* to a reader, and takes its own.
|
|
142
|
+
*/
|
|
143
|
+
this.total = 0;
|
|
144
|
+
/**
|
|
145
|
+
* How many items are on a page.
|
|
146
|
+
*
|
|
147
|
+
* Only arithmetic: this does not slice anything, because the component never
|
|
148
|
+
* sees the items. It is what turns `total` into a page count, and nothing
|
|
149
|
+
* else.
|
|
150
|
+
*/
|
|
151
|
+
this.pageSize = 0;
|
|
152
|
+
/**
|
|
153
|
+
* Whether to offer a jump to the first and last pages.
|
|
154
|
+
*
|
|
155
|
+
* Off by default. The gaps already reach any page in a few presses and the
|
|
156
|
+
* last page is one of the two the run always shows, so on a short set these
|
|
157
|
+
* are two more controls for a move already on screen. They earn their place
|
|
158
|
+
* where the reader is deep in a long result and "back to the start" is the
|
|
159
|
+
* move they actually want.
|
|
160
|
+
*
|
|
161
|
+
* Not reflected. It adds two elements rather than changing how any of them
|
|
162
|
+
* look, so no rule selects on it, and the house rule is that reflection
|
|
163
|
+
* exists for selectors: an unread reflected attribute is one more thing
|
|
164
|
+
* written onto a host at upgrade that a server's output never had.
|
|
165
|
+
*/
|
|
166
|
+
this.ends = false;
|
|
167
|
+
/**
|
|
168
|
+
* Page to open on, where nothing declared one.
|
|
169
|
+
*/
|
|
170
|
+
this.defaultPage = 1;
|
|
171
|
+
/**
|
|
172
|
+
* How many pages to show either side of the current one.
|
|
173
|
+
*/
|
|
174
|
+
this.siblings = 1;
|
|
175
|
+
/**
|
|
176
|
+
* How many pages to show at each end, whatever the current one is.
|
|
177
|
+
*/
|
|
178
|
+
this.boundaries = 1;
|
|
179
|
+
/**
|
|
180
|
+
* Address for a page, with `{page}` standing in for its number.
|
|
181
|
+
*
|
|
182
|
+
* Absent renders buttons. Present renders links, which is what a paged result
|
|
183
|
+
* with its own URL should be: a crawler follows them, a middle click opens
|
|
184
|
+
* one, and the back button works without the consumer wiring anything.
|
|
185
|
+
*/
|
|
186
|
+
this.href = '';
|
|
187
|
+
/**
|
|
188
|
+
* Where the numbers are replaced by a reading of the two.
|
|
189
|
+
*
|
|
190
|
+
* A different structure rather than a different look, which is why it is
|
|
191
|
+
* here: the run of pages is gone and a single status line stands in its
|
|
192
|
+
* place. This is the shape a narrow screen wants, and the only shape possible
|
|
193
|
+
* where the total is large enough that no window over it is useful.
|
|
194
|
+
*
|
|
195
|
+
* Not reflected, for the reason `ends` is not: it decides what renders, so
|
|
196
|
+
* nothing has to select on it.
|
|
197
|
+
*/
|
|
198
|
+
this.compact = false;
|
|
199
|
+
/**
|
|
200
|
+
* Accessible name for the navigation landmark.
|
|
201
|
+
*/
|
|
202
|
+
this.label = 'Pagination';
|
|
203
|
+
/**
|
|
204
|
+
* Locale for the page numbers. Absent uses the runtime's own.
|
|
205
|
+
*
|
|
206
|
+
* The same property the calendar takes, doing the same job one layer down:
|
|
207
|
+
* the templates make the *words* the consumer's, and this makes the *numbers*
|
|
208
|
+
* theirs. A page number is a number like any other, so `1234` is `1,234` in
|
|
209
|
+
* `en-US`, `1.234` in `de-DE` and `١٢٣٤` in `ar-EG`, and a component that
|
|
210
|
+
* lets a consumer translate "Page {page} of {pages}" and then prints Latin
|
|
211
|
+
* digits into it has done half the job.
|
|
212
|
+
*
|
|
213
|
+
* Not applied to `href`. That one is machine-facing, and `?page=1,234` is a
|
|
214
|
+
* different address from `?page=1234`.
|
|
215
|
+
*/
|
|
216
|
+
this.locale = '';
|
|
217
|
+
/**
|
|
218
|
+
* Accessible name for one page, with `{page}` and `{pages}` filled in.
|
|
219
|
+
*/
|
|
220
|
+
this.pageLabel = 'Page {page}';
|
|
221
|
+
/**
|
|
222
|
+
* The reading shown in `compact`, with `{page}` and `{pages}` filled in.
|
|
223
|
+
*
|
|
224
|
+
* The word went: it read "Page 7 of 24" and the landmark it sits in is
|
|
225
|
+
* already named "Pagination", so the noun was said twice to a screen reader
|
|
226
|
+
* and took a third of the width from a control whose whole reason for
|
|
227
|
+
* existing is that the row is narrow. The numbers are the reading.
|
|
228
|
+
*/
|
|
229
|
+
this.statusLabel = '{page} of {pages}';
|
|
230
|
+
/**
|
|
231
|
+
* Accessible name for the control that moves back.
|
|
232
|
+
*/
|
|
233
|
+
this.previousLabel = 'Previous page';
|
|
234
|
+
/**
|
|
235
|
+
* Accessible name for the control that moves forward.
|
|
236
|
+
*/
|
|
237
|
+
this.nextLabel = 'Next page';
|
|
238
|
+
/**
|
|
239
|
+
* Accessible name for the control that jumps to the first page.
|
|
240
|
+
*/
|
|
241
|
+
this.firstLabel = 'First page';
|
|
242
|
+
/**
|
|
243
|
+
* Accessible name for the control that jumps to the last page.
|
|
244
|
+
*/
|
|
245
|
+
this.lastLabel = 'Last page';
|
|
246
|
+
/**
|
|
247
|
+
* Accessible name for a gap, with `{page}` filled in as where it goes.
|
|
248
|
+
*/
|
|
249
|
+
this.gapLabel = 'Skip to page {page}';
|
|
250
|
+
/**
|
|
251
|
+
* What the live region says, and nothing until the page has moved once.
|
|
252
|
+
*
|
|
253
|
+
* `pageLabel` rather than a template of its own, so the announcement is the
|
|
254
|
+
* same sentence the control the reader just pressed already carried, and
|
|
255
|
+
* there is not a ninth string to translate for the sake of one of them.
|
|
256
|
+
*/
|
|
257
|
+
this.announcement = '';
|
|
258
|
+
/** The page last announced, so the first render announces nothing. */
|
|
259
|
+
this.announced = undefined;
|
|
260
|
+
/** The page on show, whoever set it, and `undefined` until somebody has. */
|
|
261
|
+
this.pageState = undefined;
|
|
262
|
+
/**
|
|
263
|
+
* The click handler, which is also what stops a link from following itself.
|
|
264
|
+
*
|
|
265
|
+
* A refused change has to refuse the navigation with it, or a router that
|
|
266
|
+
* cancels the event still loses the document underneath it. `preventDefault`
|
|
267
|
+
* on a button's click does nothing and costs nothing, so this is one handler
|
|
268
|
+
* for both shapes rather than two that have to stay in step.
|
|
269
|
+
*/
|
|
270
|
+
this.go = (next, event) => {
|
|
271
|
+
if (!this.request(next)) {
|
|
272
|
+
event.preventDefault();
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* The page on show, one-based.
|
|
278
|
+
*
|
|
279
|
+
* An accessor pair, the same shape as the calendar's `month`. Reading gives
|
|
280
|
+
* the page on show; writing declares it the consumer's, and `default-page`
|
|
281
|
+
* seeds one the element owns.
|
|
282
|
+
*
|
|
283
|
+
* **Clamped on the way out, because "the page on show" is what it says it
|
|
284
|
+
* gives.** It returned whatever had been written, so `default-page="99"` on a
|
|
285
|
+
* ten-page result rendered page 10, marked page 10 with `aria-current`, and
|
|
286
|
+
* reported 99. A consumer syncing their query from this read a page that does
|
|
287
|
+
* not exist while the control in front of them said otherwise. Not a
|
|
288
|
+
* far-fetched value: it is a bookmarked link after the result shrank.
|
|
289
|
+
*
|
|
290
|
+
* Rounded here too, so `2.7` reads as the 2 it renders.
|
|
291
|
+
*
|
|
292
|
+
*
|
|
293
|
+
*/
|
|
294
|
+
get page() {
|
|
295
|
+
const asked = this.pageState ?? this.defaultPage;
|
|
296
|
+
return Math.min(this.count, Math.max(1, Math.floor(asked) || 1));
|
|
297
|
+
}
|
|
298
|
+
set page(next) {
|
|
299
|
+
const previous = this.page;
|
|
300
|
+
this.pageState = next;
|
|
301
|
+
this.requestUpdate('page', previous);
|
|
302
|
+
}
|
|
303
|
+
/** Held across every component asking for the same locale. */
|
|
304
|
+
get numbers() {
|
|
305
|
+
return formatNumbers(this.locale);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* How many pages, clamped once, so every reader agrees on it.
|
|
309
|
+
*
|
|
310
|
+
* `pages` first, because writing it is the explicit answer. Then `total` over
|
|
311
|
+
* `pageSize`, which is the same fact stated the other way round and is what a
|
|
312
|
+
* consumer holding a result set already has. Then one, so a result that has
|
|
313
|
+
* not loaded renders a single page rather than an empty control that appears
|
|
314
|
+
* later and pushes the layout down.
|
|
315
|
+
*/
|
|
316
|
+
get count() {
|
|
317
|
+
if (this.pages > 0) {
|
|
318
|
+
return Math.max(1, Math.floor(this.pages));
|
|
319
|
+
}
|
|
320
|
+
if (this.total > 0 && this.pageSize > 0) {
|
|
321
|
+
return Math.max(1, Math.ceil(this.total / this.pageSize));
|
|
322
|
+
}
|
|
323
|
+
return 1;
|
|
324
|
+
}
|
|
325
|
+
/** The page on show. `page` does the clamping now; this is the older name. */
|
|
326
|
+
get current() {
|
|
327
|
+
return this.page;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Which pages to show, and where the runs break.
|
|
331
|
+
*
|
|
332
|
+
* `most` is the number of slots the control holds at its widest: both
|
|
333
|
+
* boundaries, the run around the current page, and a gap on each side. Below
|
|
334
|
+
* that there is nothing to hide, and the whole range is shown.
|
|
335
|
+
*
|
|
336
|
+
* Above it, the two gaps are decided independently, and a gap standing over
|
|
337
|
+
* exactly one page is not drawn: `boundaries + 2` is the first page whose
|
|
338
|
+
* predecessor is not a boundary, so a run starting there is contiguous with
|
|
339
|
+
* what precedes it. Where one side has no gap the run on that side extends to
|
|
340
|
+
* `most` slots, which is what holds the width still.
|
|
341
|
+
*/
|
|
342
|
+
get slots() {
|
|
343
|
+
const total = this.count;
|
|
344
|
+
const current = this.current;
|
|
345
|
+
const boundaries = Math.max(0, Math.floor(this.boundaries) || 0);
|
|
346
|
+
const siblings = Math.max(0, Math.floor(this.siblings) || 0);
|
|
347
|
+
const run = 2 * siblings + 1;
|
|
348
|
+
const most = 2 * boundaries + run + 2;
|
|
349
|
+
const range = (from, to) => Array.from({ length: Math.max(0, to - from + 1) }, (_, index) => from + index);
|
|
350
|
+
if (total <= most) {
|
|
351
|
+
return range(1, total);
|
|
352
|
+
}
|
|
353
|
+
const before = current - siblings > boundaries + 2;
|
|
354
|
+
const after = current + siblings < total - boundaries - 1;
|
|
355
|
+
/* A gap carries the run it stands over rather than being a bare marker,
|
|
356
|
+
because it is a control now and a control has to say where it goes. */
|
|
357
|
+
const gap = (from, to) => ({ from, to });
|
|
358
|
+
if (!before) {
|
|
359
|
+
const head = most - boundaries - 1;
|
|
360
|
+
return [
|
|
361
|
+
...range(1, head),
|
|
362
|
+
gap(head + 1, total - boundaries),
|
|
363
|
+
...range(total - boundaries + 1, total),
|
|
364
|
+
];
|
|
365
|
+
}
|
|
366
|
+
if (!after) {
|
|
367
|
+
const tail = total - (most - boundaries - 2);
|
|
368
|
+
return [...range(1, boundaries), gap(boundaries + 1, tail - 1), ...range(tail, total)];
|
|
369
|
+
}
|
|
370
|
+
return [
|
|
371
|
+
...range(1, boundaries),
|
|
372
|
+
gap(boundaries + 1, current - siblings - 1),
|
|
373
|
+
...range(current - siblings, current + siblings),
|
|
374
|
+
gap(current + siblings + 1, total - boundaries),
|
|
375
|
+
...range(total - boundaries + 1, total),
|
|
376
|
+
];
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Asks to move, and reports whether the request stood.
|
|
380
|
+
*
|
|
381
|
+
* Announced before it is applied, so `preventDefault()` is a refusal and
|
|
382
|
+
* nothing moves. In controlled mode nothing is written whatever the answer:
|
|
383
|
+
* the consumer holds the page and this is the element telling them a reader
|
|
384
|
+
* asked for another one.
|
|
385
|
+
*/
|
|
386
|
+
request(next) {
|
|
387
|
+
if (next === this.current || next < 1 || next > this.count) {
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
return requestChange({
|
|
391
|
+
apply: (page) => {
|
|
392
|
+
const previous = this.page;
|
|
393
|
+
this.pageState = page;
|
|
394
|
+
this.requestUpdate('page', previous);
|
|
395
|
+
},
|
|
396
|
+
event: (page) => new HelixNavigateEvent({ value: String(page) }),
|
|
397
|
+
host: this,
|
|
398
|
+
next,
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
willUpdate(changed) {
|
|
402
|
+
super.willUpdate(changed);
|
|
403
|
+
/* On the host through internals, so the landmark is the element itself. A
|
|
404
|
+
page may hold more than one navigation and landmarks are how a
|
|
405
|
+
screen-reader user chooses between them, which is why this carries a
|
|
406
|
+
default name at all: an author's own `aria-label` is an attribute and
|
|
407
|
+
beats internals, so naming it here costs them nothing. */
|
|
408
|
+
hostAria(this.internals, { label: this.label, role: 'navigation' });
|
|
409
|
+
/* Through `toggleState`, which carries the feature test this wrote out
|
|
410
|
+
itself until every state in the library came through one door. An engine
|
|
411
|
+
without `CustomStateSet` gets a control that renders its one page instead
|
|
412
|
+
of disappearing, which is the behavior this had before and is not
|
|
413
|
+
broken. */
|
|
414
|
+
this.toggleState('empty', this.count <= 1);
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Says where the reader now is, once they have moved.
|
|
418
|
+
*
|
|
419
|
+
* In `updated` rather than in `request`, so it covers both modes: a controlled
|
|
420
|
+
* consumer assigns `page` and never goes through the request path at all, and
|
|
421
|
+
* a reader who got there that way deserves the same sentence.
|
|
422
|
+
*/
|
|
423
|
+
updated(changed) {
|
|
424
|
+
super.updated(changed);
|
|
425
|
+
if (this.announced === undefined) {
|
|
426
|
+
// The first render establishes where we started. Arriving is not moving.
|
|
427
|
+
this.announced = this.page;
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
if (this.announced !== this.page) {
|
|
431
|
+
this.announced = this.page;
|
|
432
|
+
this.announcement = fill(this.pageLabel, this.page, this.count, this.numbers);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* One page, as a link or a button.
|
|
437
|
+
*
|
|
438
|
+
* `aria-current="page"` is what says which one you are on, and it stays a
|
|
439
|
+
* control rather than becoming text: a reader who tabs into the run and finds
|
|
440
|
+
* the current page missing from it has lost the only landmark in the row.
|
|
441
|
+
*/
|
|
442
|
+
renderPage(page) {
|
|
443
|
+
const current = page === this.current;
|
|
444
|
+
const shown = this.numbers(page);
|
|
445
|
+
const name = fill(this.pageLabel, page, this.count, this.numbers);
|
|
446
|
+
return html `<li part="item">
|
|
447
|
+
${this.href
|
|
448
|
+
? html `<a
|
|
449
|
+
part="page"
|
|
450
|
+
href=${fill(this.href, page, this.count)}
|
|
451
|
+
aria-current=${current ? 'page' : nothing}
|
|
452
|
+
aria-label=${name}
|
|
453
|
+
@click=${(event) => this.go(page, event)}
|
|
454
|
+
>${shown}</a
|
|
455
|
+
>`
|
|
456
|
+
: html `<button
|
|
457
|
+
part="page"
|
|
458
|
+
type="button"
|
|
459
|
+
aria-current=${current ? 'page' : nothing}
|
|
460
|
+
aria-label=${name}
|
|
461
|
+
@click=${(event) => this.go(page, event)}
|
|
462
|
+
>
|
|
463
|
+
${shown}
|
|
464
|
+
</button>`}
|
|
465
|
+
</li>`;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* A gap, which is a control and not a mark.
|
|
469
|
+
*
|
|
470
|
+
* **It goes to the middle of what it hides**, and the label says so. That is
|
|
471
|
+
* the binary-search step, so an arbitrary page in a set of any size is a
|
|
472
|
+
* handful of presses: 128 pages is `1 … 96 97 98 … 128`, and the leading gap
|
|
473
|
+
* lands on 48, whose gaps land on 24 and 88, and so on. A jump of a fixed size
|
|
474
|
+
* would need forty presses on that set.
|
|
475
|
+
*
|
|
476
|
+
* **A menu over these pages was the other idea and it does not survive the
|
|
477
|
+
* arithmetic.** The run a gap covers is unbounded by construction: two pages
|
|
478
|
+
* on a twelve-page set, ninety-four on a hundred-and-twenty-eight-page one. A
|
|
479
|
+
* menu is pleasant at the first and is a scroll of ninety-four items at the
|
|
480
|
+
* second, which is worse than the ellipsis it replaced, and there is no total
|
|
481
|
+
* at which it stops being possible. It would also make `Pagination` depend on
|
|
482
|
+
* `Menu` and `Popover` for a case a button already covers.
|
|
483
|
+
*
|
|
484
|
+
* So it is announced rather than hidden, which is the change from when it was
|
|
485
|
+
* a decoration: a control a reader can reach has to be in the tree, and the
|
|
486
|
+
* label naming its destination is the whole affordance.
|
|
487
|
+
*/
|
|
488
|
+
renderGap(hidden) {
|
|
489
|
+
const to = Math.round((hidden.from + hidden.to) / 2);
|
|
490
|
+
const name = fill(this.gapLabel, to, this.count, this.numbers);
|
|
491
|
+
return html `<li part="item">
|
|
492
|
+
${this.href
|
|
493
|
+
? html `<a
|
|
494
|
+
part="gap"
|
|
495
|
+
href=${fill(this.href, to, this.count)}
|
|
496
|
+
aria-label=${name}
|
|
497
|
+
@click=${(event) => this.go(to, event)}
|
|
498
|
+
>…</a
|
|
499
|
+
>`
|
|
500
|
+
: html `<button
|
|
501
|
+
part="gap"
|
|
502
|
+
type="button"
|
|
503
|
+
aria-label=${name}
|
|
504
|
+
@click=${(event) => this.go(to, event)}
|
|
505
|
+
>
|
|
506
|
+
…
|
|
507
|
+
</button>`}
|
|
508
|
+
</li>`;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Everything a step needs, computed once, so the markup below is only markup.
|
|
512
|
+
*
|
|
513
|
+
* Split out because the part name has to be a literal. `check:parts` reads
|
|
514
|
+
* `part="name"` out of the source, so a computed one is a part the tooling
|
|
515
|
+
* cannot see: nothing pairs it with its `@csspart` and a later rename takes
|
|
516
|
+
* the promise silently. With four controls and two shapes each that is eight
|
|
517
|
+
* literals, and eight copies of the arithmetic behind them would be the
|
|
518
|
+
* actual duplication. This is the arithmetic, written once.
|
|
519
|
+
*/
|
|
520
|
+
step(to, spent, icon, name) {
|
|
521
|
+
return {
|
|
522
|
+
address: spent ? nothing : fill(this.href, to, this.count),
|
|
523
|
+
click: (event) => this.go(to, event),
|
|
524
|
+
glyph: html `<svg part="mark" fill="currentColor" viewBox=${icon.viewBox} aria-hidden="true">
|
|
525
|
+
${unsafeSVG(icon.content)}
|
|
526
|
+
</svg>`,
|
|
527
|
+
name,
|
|
528
|
+
off: spent ? 'true' : nothing,
|
|
529
|
+
spent,
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* The four controls, inert at the end each points at.
|
|
534
|
+
*
|
|
535
|
+
* Inert rather than absent: a control that disappears at the first page takes
|
|
536
|
+
* the row's width with it and moves everything else under the pointer. In
|
|
537
|
+
* link mode the inert one is an `<a>` with no `href`, which is not a link and
|
|
538
|
+
* is not focusable, and is the platform's own way of saying there is nowhere
|
|
539
|
+
* to go.
|
|
540
|
+
*
|
|
541
|
+
* **Each glyph is a slot fallback, and each method is a seam**, which answer
|
|
542
|
+
* two different people: the slot is how a page swaps a caret for its own icon
|
|
543
|
+
* set, and `protected` is how the tier above swaps all four without
|
|
544
|
+
* reimplementing a template that renders eight controls across two shapes.
|
|
545
|
+
* `Select` and `Listbox` carry the same pairing on one mark each.
|
|
546
|
+
*
|
|
547
|
+
* **Four slot names rather than one**, even though the four controls draw
|
|
548
|
+
* from the same shared `mark` part. A single `<slot name="icon">` is assigned
|
|
549
|
+
* once and the other three occurrences of it get nothing, so a consumer
|
|
550
|
+
* replacing the caret would silently lose three of their four marks.
|
|
551
|
+
*/
|
|
552
|
+
renderFirst() {
|
|
553
|
+
const { address, click, glyph, name, off, spent } = this.step(1, this.current <= 1, caretDoubleLeft, this.firstLabel);
|
|
554
|
+
const mark = html `<slot name="first-icon">${glyph}</slot>`;
|
|
555
|
+
return this.href
|
|
556
|
+
? html `<a part="first" href=${address} aria-disabled=${off} aria-label=${name} @click=${click}
|
|
557
|
+
>${mark}</a
|
|
558
|
+
>`
|
|
559
|
+
: html `<button part="first" type="button" ?disabled=${spent} aria-label=${name} @click=${click}>
|
|
560
|
+
${mark}
|
|
561
|
+
</button>`;
|
|
562
|
+
}
|
|
563
|
+
renderPrevious() {
|
|
564
|
+
const { address, click, glyph, name, off, spent } = this.step(this.current - 1, this.current <= 1, caretLeft, this.previousLabel);
|
|
565
|
+
const mark = html `<slot name="previous-icon">${glyph}</slot>`;
|
|
566
|
+
return this.href
|
|
567
|
+
? html `<a
|
|
568
|
+
part="previous"
|
|
569
|
+
href=${address}
|
|
570
|
+
aria-disabled=${off}
|
|
571
|
+
aria-label=${name}
|
|
572
|
+
@click=${click}
|
|
573
|
+
>${mark}</a
|
|
574
|
+
>`
|
|
575
|
+
: html `<button
|
|
576
|
+
part="previous"
|
|
577
|
+
type="button"
|
|
578
|
+
?disabled=${spent}
|
|
579
|
+
aria-label=${name}
|
|
580
|
+
@click=${click}
|
|
581
|
+
>
|
|
582
|
+
${mark}
|
|
583
|
+
</button>`;
|
|
584
|
+
}
|
|
585
|
+
renderNext() {
|
|
586
|
+
const { address, click, glyph, name, off, spent } = this.step(this.current + 1, this.current >= this.count, caretRight, this.nextLabel);
|
|
587
|
+
const mark = html `<slot name="next-icon">${glyph}</slot>`;
|
|
588
|
+
return this.href
|
|
589
|
+
? html `<a part="next" href=${address} aria-disabled=${off} aria-label=${name} @click=${click}
|
|
590
|
+
>${mark}</a
|
|
591
|
+
>`
|
|
592
|
+
: html `<button part="next" type="button" ?disabled=${spent} aria-label=${name} @click=${click}>
|
|
593
|
+
${mark}
|
|
594
|
+
</button>`;
|
|
595
|
+
}
|
|
596
|
+
renderLast() {
|
|
597
|
+
const { address, click, glyph, name, off, spent } = this.step(this.count, this.current >= this.count, caretDoubleRight, this.lastLabel);
|
|
598
|
+
const mark = html `<slot name="last-icon">${glyph}</slot>`;
|
|
599
|
+
return this.href
|
|
600
|
+
? html `<a part="last" href=${address} aria-disabled=${off} aria-label=${name} @click=${click}
|
|
601
|
+
>${mark}</a
|
|
602
|
+
>`
|
|
603
|
+
: html `<button part="last" type="button" ?disabled=${spent} aria-label=${name} @click=${click}>
|
|
604
|
+
${mark}
|
|
605
|
+
</button>`;
|
|
606
|
+
}
|
|
607
|
+
render() {
|
|
608
|
+
if (this.compact) {
|
|
609
|
+
return html `${this.ends ? this.renderFirst() : nothing}${this.renderPrevious()}
|
|
610
|
+
<span part="status"
|
|
611
|
+
>${fill(this.statusLabel, this.current, this.count, this.numbers)}</span
|
|
612
|
+
>
|
|
613
|
+
${this.renderNext()}${this.ends ? this.renderLast() : nothing}${this.renderLive()}`;
|
|
614
|
+
}
|
|
615
|
+
return html `${this.ends ? this.renderFirst() : nothing}${this.renderPrevious()}
|
|
616
|
+
<ol part="list" role="list">
|
|
617
|
+
${this.slots.map((slot) => typeof slot === 'number' ? this.renderPage(slot) : this.renderGap(slot))}
|
|
618
|
+
</ol>
|
|
619
|
+
${this.renderNext()}${this.ends ? this.renderLast() : nothing}${this.renderLive()}`;
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* The region that says the page moved.
|
|
623
|
+
*
|
|
624
|
+
* Always rendered and empty until it has something to say. A live region
|
|
625
|
+
* populated at the moment it enters the document announces itself on arrival,
|
|
626
|
+
* which for a component that upgrades on load is every page load.
|
|
627
|
+
*/
|
|
628
|
+
renderLive() {
|
|
629
|
+
return html `<span part="live" role="status" aria-live="polite">${this.announcement}</span>`;
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
__decorate([
|
|
633
|
+
property({ type: Number })
|
|
634
|
+
], HelixHeadlessPagination.prototype, "pages", void 0);
|
|
635
|
+
__decorate([
|
|
636
|
+
property({ type: Number })
|
|
637
|
+
], HelixHeadlessPagination.prototype, "total", void 0);
|
|
638
|
+
__decorate([
|
|
639
|
+
property({ attribute: 'page-size', type: Number })
|
|
640
|
+
], HelixHeadlessPagination.prototype, "pageSize", void 0);
|
|
641
|
+
__decorate([
|
|
642
|
+
property({ type: Boolean })
|
|
643
|
+
], HelixHeadlessPagination.prototype, "ends", void 0);
|
|
644
|
+
__decorate([
|
|
645
|
+
property({ type: Number })
|
|
646
|
+
], HelixHeadlessPagination.prototype, "page", null);
|
|
647
|
+
__decorate([
|
|
648
|
+
property({ attribute: 'default-page', type: Number })
|
|
649
|
+
], HelixHeadlessPagination.prototype, "defaultPage", void 0);
|
|
650
|
+
__decorate([
|
|
651
|
+
property({ type: Number })
|
|
652
|
+
], HelixHeadlessPagination.prototype, "siblings", void 0);
|
|
653
|
+
__decorate([
|
|
654
|
+
property({ type: Number })
|
|
655
|
+
], HelixHeadlessPagination.prototype, "boundaries", void 0);
|
|
656
|
+
__decorate([
|
|
657
|
+
property()
|
|
658
|
+
], HelixHeadlessPagination.prototype, "href", void 0);
|
|
659
|
+
__decorate([
|
|
660
|
+
property({ type: Boolean })
|
|
661
|
+
], HelixHeadlessPagination.prototype, "compact", void 0);
|
|
662
|
+
__decorate([
|
|
663
|
+
property()
|
|
664
|
+
], HelixHeadlessPagination.prototype, "label", void 0);
|
|
665
|
+
__decorate([
|
|
666
|
+
property()
|
|
667
|
+
], HelixHeadlessPagination.prototype, "locale", void 0);
|
|
668
|
+
__decorate([
|
|
669
|
+
property({ attribute: 'page-label' })
|
|
670
|
+
], HelixHeadlessPagination.prototype, "pageLabel", void 0);
|
|
671
|
+
__decorate([
|
|
672
|
+
property({ attribute: 'status-label' })
|
|
673
|
+
], HelixHeadlessPagination.prototype, "statusLabel", void 0);
|
|
674
|
+
__decorate([
|
|
675
|
+
property({ attribute: 'previous-label' })
|
|
676
|
+
], HelixHeadlessPagination.prototype, "previousLabel", void 0);
|
|
677
|
+
__decorate([
|
|
678
|
+
property({ attribute: 'next-label' })
|
|
679
|
+
], HelixHeadlessPagination.prototype, "nextLabel", void 0);
|
|
680
|
+
__decorate([
|
|
681
|
+
property({ attribute: 'first-label' })
|
|
682
|
+
], HelixHeadlessPagination.prototype, "firstLabel", void 0);
|
|
683
|
+
__decorate([
|
|
684
|
+
property({ attribute: 'last-label' })
|
|
685
|
+
], HelixHeadlessPagination.prototype, "lastLabel", void 0);
|
|
686
|
+
__decorate([
|
|
687
|
+
property({ attribute: 'gap-label' })
|
|
688
|
+
], HelixHeadlessPagination.prototype, "gapLabel", void 0);
|
|
689
|
+
__decorate([
|
|
690
|
+
state()
|
|
691
|
+
], HelixHeadlessPagination.prototype, "announcement", void 0);
|
|
692
|
+
HelixHeadlessPagination = __decorate([
|
|
693
|
+
customElement('helix-headless-pagination')
|
|
694
|
+
], HelixHeadlessPagination);
|
|
695
|
+
export { HelixHeadlessPagination };
|