@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,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter, sort, then window. In that order, over the whole set, every time.
|
|
3
|
+
*
|
|
4
|
+
* **This is the file that stops the classic virtualization bug.** Sorting the
|
|
5
|
+
* rendered window looks completely correct on the first screen and is wrong
|
|
6
|
+
* everywhere else, and it is the natural thing to write once rows are data and
|
|
7
|
+
* only some of them are drawn. Keeping the three operations here, as functions
|
|
8
|
+
* over an array with no knowledge of what is on screen, is what makes that
|
|
9
|
+
* mistake hard to make: nothing in this module can see a window, and `window()`
|
|
10
|
+
* is the last thing applied rather than the first.
|
|
11
|
+
*
|
|
12
|
+
* The order is not a preference. Filtering after sorting sorts rows that are
|
|
13
|
+
* about to be thrown away, which is only slower; paging before either is the bug.
|
|
14
|
+
* Filter narrows, sort arranges what is left, the page is a slice of that, and
|
|
15
|
+
* the count a reader is shown is the length after filtering rather than the
|
|
16
|
+
* length of the data, or the pagination promises pages that are empty.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* A row, which is whatever the consumer's data is.
|
|
20
|
+
*
|
|
21
|
+
* Not `DataRow`: `@fusion.dev/helix-core` already exports one, for a cell read out of a
|
|
22
|
+
* chart series, and the headless barrel re-exports both. Two different `DataRow`s
|
|
23
|
+
* reaching a consumer through one package is the kind of ambiguity TypeScript
|
|
24
|
+
* refuses outright, which is how this was caught.
|
|
25
|
+
*/
|
|
26
|
+
export type DataRow = Readonly<Record<string, unknown>>;
|
|
27
|
+
/** One column's contribution, reduced to the two functions this module needs. */
|
|
28
|
+
export interface Axis {
|
|
29
|
+
/** The field this axis is named by, matched against a sort spec. */
|
|
30
|
+
field: string;
|
|
31
|
+
/** The value to compare and match on, which is not always what the cell shows. */
|
|
32
|
+
order: (row: DataRow) => unknown;
|
|
33
|
+
}
|
|
34
|
+
/** A parsed `field:direction`. */
|
|
35
|
+
export interface Sort {
|
|
36
|
+
direction: 'asc' | 'desc';
|
|
37
|
+
field: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* `field:asc` and `field:desc`, and nothing else.
|
|
41
|
+
*
|
|
42
|
+
* A bare `field` parses as ascending, because that is what a URL query usually
|
|
43
|
+
* carries and refusing it would make the common case the verbose one. Anything
|
|
44
|
+
* unparseable is no sort rather than an error: this value arrives from a query
|
|
45
|
+
* string as often as from code, and a bad one should leave the table in the
|
|
46
|
+
* order the data came in rather than break the page.
|
|
47
|
+
*/
|
|
48
|
+
export declare const parse: (spec: string) => Sort | undefined;
|
|
49
|
+
/** A `Sort` written back out, so the property and the attribute agree. */
|
|
50
|
+
export declare const format: (sort: Sort | undefined) => string;
|
|
51
|
+
/**
|
|
52
|
+
* What a reader gets on the next click of a sortable heading.
|
|
53
|
+
*
|
|
54
|
+
* Ascending, descending, then none. **The third state is not an omission to be
|
|
55
|
+
* tidied away**: the order rows arrived in is information the data came with,
|
|
56
|
+
* often the server's own relevance ranking, and a two-state cycle makes it
|
|
57
|
+
* unreachable once a reader has sorted once.
|
|
58
|
+
*/
|
|
59
|
+
export declare const cycle: (current: Sort | undefined, field: string) => Sort | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Rows matching a query, across every axis.
|
|
62
|
+
*
|
|
63
|
+
* One query over all columns rather than a predicate per column, which is what a
|
|
64
|
+
* reader means by a search box above a table. Per-column predicates are a
|
|
65
|
+
* different feature and compose with this rather than replacing it.
|
|
66
|
+
*
|
|
67
|
+
* Case-insensitive and substring, on the ordering value rather than the rendered
|
|
68
|
+
* one: a cell showing a formatted date should be findable by the text a reader
|
|
69
|
+
* sees, and a cell showing an icon should be findable by the value behind it.
|
|
70
|
+
* Where those differ, `compare` on the column is what decides, which is the same
|
|
71
|
+
* function sorting uses, so search and sort cannot disagree about what a column
|
|
72
|
+
* holds.
|
|
73
|
+
*/
|
|
74
|
+
export declare const filter: (rows: readonly DataRow[], query: string, axes: readonly Axis[]) => DataRow[];
|
|
75
|
+
/**
|
|
76
|
+
* Rows in the asked-for order, stably.
|
|
77
|
+
*
|
|
78
|
+
* **Stable, and that is load-bearing rather than tidy.** `Array.prototype.sort`
|
|
79
|
+
* is required to be stable since ES2019, so equal rows keep the order they
|
|
80
|
+
* arrived in, which means sorting by one column and then another leaves the
|
|
81
|
+
* first as the tiebreak. A reader who sorts by status and then by name expects
|
|
82
|
+
* exactly that, and an unstable sort would shuffle equal rows on every
|
|
83
|
+
* re-render, which reads as the table twitching.
|
|
84
|
+
*/
|
|
85
|
+
export declare const sort: (rows: readonly DataRow[], spec: Sort | undefined, axes: readonly Axis[]) => DataRow[];
|
|
86
|
+
/**
|
|
87
|
+
* One page of rows, clamped.
|
|
88
|
+
*
|
|
89
|
+
* A page past the end returns the last page rather than nothing, because the
|
|
90
|
+
* usual way to be past the end is a bookmarked link after the result shrank, and
|
|
91
|
+
* an empty table is a worse answer than the last page of a smaller one. The
|
|
92
|
+
* same clamp `helix-pagination` already applies to what it reports.
|
|
93
|
+
*/
|
|
94
|
+
export declare const window_: (rows: readonly DataRow[], page: number, size: number) => DataRow[];
|
|
95
|
+
/** What one pass over the data produces: the window, and the counts around it. */
|
|
96
|
+
export interface Ordered {
|
|
97
|
+
/** Rows after filtering, before paging. The number a pagination must page. */
|
|
98
|
+
matched: number;
|
|
99
|
+
/** The rows to draw. */
|
|
100
|
+
rows: DataRow[];
|
|
101
|
+
/** Rows before filtering, which is what tells a reader a filter is on. */
|
|
102
|
+
total: number;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The whole pass, in the one order that is correct.
|
|
106
|
+
*
|
|
107
|
+
* Exported as a single function so a caller cannot get the order wrong by
|
|
108
|
+
* calling the three in the sequence that reads naturally, which is the sequence
|
|
109
|
+
* that pages before it sorts.
|
|
110
|
+
*/
|
|
111
|
+
export declare const ordered: (rows: readonly DataRow[], axes: readonly Axis[], { page, query, size, spec }: {
|
|
112
|
+
page: number;
|
|
113
|
+
query: string;
|
|
114
|
+
size: number;
|
|
115
|
+
spec: string;
|
|
116
|
+
}) => Ordered;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter, sort, then window. In that order, over the whole set, every time.
|
|
3
|
+
*
|
|
4
|
+
* **This is the file that stops the classic virtualization bug.** Sorting the
|
|
5
|
+
* rendered window looks completely correct on the first screen and is wrong
|
|
6
|
+
* everywhere else, and it is the natural thing to write once rows are data and
|
|
7
|
+
* only some of them are drawn. Keeping the three operations here, as functions
|
|
8
|
+
* over an array with no knowledge of what is on screen, is what makes that
|
|
9
|
+
* mistake hard to make: nothing in this module can see a window, and `window()`
|
|
10
|
+
* is the last thing applied rather than the first.
|
|
11
|
+
*
|
|
12
|
+
* The order is not a preference. Filtering after sorting sorts rows that are
|
|
13
|
+
* about to be thrown away, which is only slower; paging before either is the bug.
|
|
14
|
+
* Filter narrows, sort arranges what is left, the page is a slice of that, and
|
|
15
|
+
* the count a reader is shown is the length after filtering rather than the
|
|
16
|
+
* length of the data, or the pagination promises pages that are empty.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* `field:asc` and `field:desc`, and nothing else.
|
|
20
|
+
*
|
|
21
|
+
* A bare `field` parses as ascending, because that is what a URL query usually
|
|
22
|
+
* carries and refusing it would make the common case the verbose one. Anything
|
|
23
|
+
* unparseable is no sort rather than an error: this value arrives from a query
|
|
24
|
+
* string as often as from code, and a bad one should leave the table in the
|
|
25
|
+
* order the data came in rather than break the page.
|
|
26
|
+
*/
|
|
27
|
+
export const parse = (spec) => {
|
|
28
|
+
const trimmed = spec.trim();
|
|
29
|
+
if (trimmed === '') {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const [field = '', direction = 'asc'] = trimmed.split(':');
|
|
33
|
+
if (field === '' || (direction !== 'asc' && direction !== 'desc')) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
return { direction, field };
|
|
37
|
+
};
|
|
38
|
+
/** A `Sort` written back out, so the property and the attribute agree. */
|
|
39
|
+
export const format = (sort) => sort ? `${sort.field}:${sort.direction}` : '';
|
|
40
|
+
/**
|
|
41
|
+
* What a reader gets on the next click of a sortable heading.
|
|
42
|
+
*
|
|
43
|
+
* Ascending, descending, then none. **The third state is not an omission to be
|
|
44
|
+
* tidied away**: the order rows arrived in is information the data came with,
|
|
45
|
+
* often the server's own relevance ranking, and a two-state cycle makes it
|
|
46
|
+
* unreachable once a reader has sorted once.
|
|
47
|
+
*/
|
|
48
|
+
export const cycle = (current, field) => {
|
|
49
|
+
if (current?.field !== field) {
|
|
50
|
+
return { direction: 'asc', field };
|
|
51
|
+
}
|
|
52
|
+
return current.direction === 'asc' ? { direction: 'desc', field } : undefined;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Rows matching a query, across every axis.
|
|
56
|
+
*
|
|
57
|
+
* One query over all columns rather than a predicate per column, which is what a
|
|
58
|
+
* reader means by a search box above a table. Per-column predicates are a
|
|
59
|
+
* different feature and compose with this rather than replacing it.
|
|
60
|
+
*
|
|
61
|
+
* Case-insensitive and substring, on the ordering value rather than the rendered
|
|
62
|
+
* one: a cell showing a formatted date should be findable by the text a reader
|
|
63
|
+
* sees, and a cell showing an icon should be findable by the value behind it.
|
|
64
|
+
* Where those differ, `compare` on the column is what decides, which is the same
|
|
65
|
+
* function sorting uses, so search and sort cannot disagree about what a column
|
|
66
|
+
* holds.
|
|
67
|
+
*/
|
|
68
|
+
export const filter = (rows, query, axes) => {
|
|
69
|
+
const needle = query.trim().toLocaleLowerCase();
|
|
70
|
+
if (needle === '') {
|
|
71
|
+
return [...rows];
|
|
72
|
+
}
|
|
73
|
+
return rows.filter((row) => axes.some((axis) => text(axis.order(row)).toLocaleLowerCase().includes(needle)));
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Rows in the asked-for order, stably.
|
|
77
|
+
*
|
|
78
|
+
* **Stable, and that is load-bearing rather than tidy.** `Array.prototype.sort`
|
|
79
|
+
* is required to be stable since ES2019, so equal rows keep the order they
|
|
80
|
+
* arrived in, which means sorting by one column and then another leaves the
|
|
81
|
+
* first as the tiebreak. A reader who sorts by status and then by name expects
|
|
82
|
+
* exactly that, and an unstable sort would shuffle equal rows on every
|
|
83
|
+
* re-render, which reads as the table twitching.
|
|
84
|
+
*/
|
|
85
|
+
export const sort = (rows, spec, axes) => {
|
|
86
|
+
const axis = spec ? axes.find((one) => one.field === spec.field) : undefined;
|
|
87
|
+
if (!spec || !axis) {
|
|
88
|
+
return [...rows];
|
|
89
|
+
}
|
|
90
|
+
const sign = spec.direction === 'asc' ? 1 : -1;
|
|
91
|
+
return [...rows].sort((left, right) => compare(axis.order(left), axis.order(right), sign));
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* One page of rows, clamped.
|
|
95
|
+
*
|
|
96
|
+
* A page past the end returns the last page rather than nothing, because the
|
|
97
|
+
* usual way to be past the end is a bookmarked link after the result shrank, and
|
|
98
|
+
* an empty table is a worse answer than the last page of a smaller one. The
|
|
99
|
+
* same clamp `helix-pagination` already applies to what it reports.
|
|
100
|
+
*/
|
|
101
|
+
export const window_ = (rows, page, size) => {
|
|
102
|
+
if (size <= 0) {
|
|
103
|
+
return [...rows];
|
|
104
|
+
}
|
|
105
|
+
const pages = Math.max(1, Math.ceil(rows.length / size));
|
|
106
|
+
const wanted = Math.min(pages, Math.max(1, Math.floor(page) || 1));
|
|
107
|
+
const from = (wanted - 1) * size;
|
|
108
|
+
return rows.slice(from, from + size);
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* A value as text, for matching.
|
|
112
|
+
*
|
|
113
|
+
* `null` and `undefined` become empty rather than their own names, so a search
|
|
114
|
+
* for "null" does not match every hole in the data.
|
|
115
|
+
*/
|
|
116
|
+
const text = (value) => {
|
|
117
|
+
if (value === null || value === undefined) {
|
|
118
|
+
return '';
|
|
119
|
+
}
|
|
120
|
+
if (value instanceof Date) {
|
|
121
|
+
return value.toISOString();
|
|
122
|
+
}
|
|
123
|
+
return String(value);
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Two cell values ordered, with the types a table actually holds.
|
|
127
|
+
*
|
|
128
|
+
* **Numbers compare as numbers and strings collate.** `String(a) < String(b)`
|
|
129
|
+
* puts 10 before 9 and puts every accented word after every unaccented one, and
|
|
130
|
+
* both look like the sort is broken while every value in the column is correct.
|
|
131
|
+
* `localeCompare` handles the second, and the numeric branch handles the first.
|
|
132
|
+
*
|
|
133
|
+
* **Holes sort last in both directions**, which is deliberate and is the one
|
|
134
|
+
* choice here a reader could disagree with. A missing value is not smaller than
|
|
135
|
+
* a present one, it is absent, and burying the holes at the end is what a reader
|
|
136
|
+
* scanning for the largest or smallest actual value wants. Reversing them with
|
|
137
|
+
* the direction puts every hole first on a descending sort, which is the least
|
|
138
|
+
* useful screen the data can produce.
|
|
139
|
+
*
|
|
140
|
+
* **`sign` is applied in here rather than to the result**, and that is why it is
|
|
141
|
+
* a parameter rather than the caller's multiplication. Written the obvious way,
|
|
142
|
+
* as `sign * compare(a, b)`, the constant this returns for a hole flips with the
|
|
143
|
+
* direction and the holes lead a descending sort: the comment above it claimed
|
|
144
|
+
* otherwise for as long as it took the spec to be written, which is the argument
|
|
145
|
+
* for writing the spec.
|
|
146
|
+
*/
|
|
147
|
+
const compare = (left, right, sign) => {
|
|
148
|
+
const leftMissing = left === null || left === undefined || left === '';
|
|
149
|
+
const rightMissing = right === null || right === undefined || right === '';
|
|
150
|
+
if (leftMissing || rightMissing) {
|
|
151
|
+
return leftMissing && rightMissing ? 0 : leftMissing ? 1 : -1;
|
|
152
|
+
}
|
|
153
|
+
if (typeof left === 'number' && typeof right === 'number') {
|
|
154
|
+
return sign * (left - right);
|
|
155
|
+
}
|
|
156
|
+
if (typeof left === 'boolean' && typeof right === 'boolean') {
|
|
157
|
+
return sign * (Number(left) - Number(right));
|
|
158
|
+
}
|
|
159
|
+
if (left instanceof Date && right instanceof Date) {
|
|
160
|
+
return sign * (left.getTime() - right.getTime());
|
|
161
|
+
}
|
|
162
|
+
return (sign * text(left).localeCompare(text(right), undefined, { numeric: true, sensitivity: 'base' }));
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* The whole pass, in the one order that is correct.
|
|
166
|
+
*
|
|
167
|
+
* Exported as a single function so a caller cannot get the order wrong by
|
|
168
|
+
* calling the three in the sequence that reads naturally, which is the sequence
|
|
169
|
+
* that pages before it sorts.
|
|
170
|
+
*/
|
|
171
|
+
export const ordered = (rows, axes, { page, query, size, spec }) => {
|
|
172
|
+
const matched = filter(rows, query, axes);
|
|
173
|
+
const arranged = sort(matched, parse(spec), axes);
|
|
174
|
+
return { matched: matched.length, rows: window_(arranged, page, size), total: rows.length };
|
|
175
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './root/date-input-root.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './root/date-input-root.js';
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import { AriaForwardController, HelixFormElement, PopoverController } from '@fusion.dev/helix-core';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
import '../../date-picker/index.js';
|
|
4
|
+
import '../../tag/index.js';
|
|
5
|
+
declare const HelixHeadlessDateInput_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
6
|
+
/**
|
|
7
|
+
* @summary A date, typed or picked from a calendar.
|
|
8
|
+
*
|
|
9
|
+
* @description
|
|
10
|
+
* **The calendar is `helix-date-picker`, not a second one written here.** It
|
|
11
|
+
* already knows about months, ranges, disabled days, the first day of the week
|
|
12
|
+
* and every keyboard rule a grid owes a reader, and a picker that reimplemented
|
|
13
|
+
* a tenth of that would be a worse grid that also had to be maintained. This
|
|
14
|
+
* element is the field, the overlay, and the translation between them.
|
|
15
|
+
*
|
|
16
|
+
* **Typed as well as picked, and the typing is the reason it is not
|
|
17
|
+
* `<input type="date">`.** The native control gives a free picker and a free
|
|
18
|
+
* locale and takes almost all styling with it, which is a fair trade until a
|
|
19
|
+
* product needs the calendar to match everything around it. What is kept from
|
|
20
|
+
* the native one is the part worth keeping: a real text field, so a reader who
|
|
21
|
+
* knows the date types it and never opens anything.
|
|
22
|
+
*
|
|
23
|
+
* **The value is `YYYY-MM-DD`, always.** That is what a form submits, what
|
|
24
|
+
* `min` and `max` compare against, and what the calendar speaks. What the field
|
|
25
|
+
* *shows* is the same string: a locale-formatted display would have to be parsed
|
|
26
|
+
* back on every keystroke, and half-typed input does not survive a round trip
|
|
27
|
+
* through a formatter. The same reasoning the sandbox records for its two
|
|
28
|
+
* syntaxes, which is that a document being edited must not be a rendering of
|
|
29
|
+
* something else.
|
|
30
|
+
*
|
|
31
|
+
* **Opening does not commit.** The calendar announces a date, this element takes
|
|
32
|
+
* it, and the overlay shuts, because a single date has nothing more to say. A
|
|
33
|
+
* consumer who owns `value` answers the announcement the way they answer any
|
|
34
|
+
* other control here.
|
|
35
|
+
*
|
|
36
|
+
* @since 0.1.0
|
|
37
|
+
* @status experimental
|
|
38
|
+
* @category forms
|
|
39
|
+
* @aliases DatePicker, DateField, InputDate
|
|
40
|
+
* @documentation https://helix.fusion.dev/components/date-input
|
|
41
|
+
*
|
|
42
|
+
* @slot feedback - What is wrong with it.
|
|
43
|
+
* @slot hint - Help under the field.
|
|
44
|
+
* @slot trigger - The mark on the field saying a calendar opens.
|
|
45
|
+
*
|
|
46
|
+
* @event {Event} change - Announced once the value has moved.
|
|
47
|
+
* @event {HelixBeforeChangeEvent} helix-before-change - Fired before the date changes. Cancelable: refusing it takes the decision and nothing moves.
|
|
48
|
+
* @event {HelixBeforeCloseEvent} helix-before-close - Fired before it closes. Cancelable: refusing it takes the decision and nothing moves.
|
|
49
|
+
* @event {HelixBeforeOpenEvent} helix-before-open - Fired before the calendar opens. Cancelable: refusing it takes the decision and nothing moves.
|
|
50
|
+
* @event {Event} input - Announced once the value has moved.
|
|
51
|
+
* @event {Event} toggle - Says the state moved, carrying `newState` and `oldState`.
|
|
52
|
+
*
|
|
53
|
+
* @csspart control - The text input.
|
|
54
|
+
* @csspart date - One held date, as a tag, in `multiple`.
|
|
55
|
+
* @csspart date-dismiss - The remove button, when `dismissible`.
|
|
56
|
+
* @csspart date-dismiss-mark - The glyph on the dismiss control, where none is slotted.
|
|
57
|
+
* @csspart date-prefix - The category before the label.
|
|
58
|
+
* @csspart feedback - What is wrong with it.
|
|
59
|
+
* @csspart field - The box holding the text and the trigger.
|
|
60
|
+
* @csspart hint - Help under the field, while nothing is wrong.
|
|
61
|
+
* @csspart label - The question, over the field.
|
|
62
|
+
* @csspart picker - The date picker inside it.
|
|
63
|
+
* @csspart picker-cell - One column of a row, which is what a range paints.
|
|
64
|
+
* @csspart picker-day - The shape inside a cell, which is what a single date paints.
|
|
65
|
+
* @csspart picker-grid - The grid of days.
|
|
66
|
+
* @csspart picker-header - The month name and its controls.
|
|
67
|
+
* @csspart picker-heading - The month and year being shown.
|
|
68
|
+
* @csspart picker-month - One month, its header and its grid.
|
|
69
|
+
* @csspart picker-months - The run of months.
|
|
70
|
+
* @csspart picker-next - The control that moves to the next month.
|
|
71
|
+
* @csspart picker-next-mark - The glyph on the next month control.
|
|
72
|
+
* @csspart picker-previous - The control that moves to the previous month.
|
|
73
|
+
* @csspart picker-previous-mark - The glyph on the previous month control.
|
|
74
|
+
* @csspart picker-week - One row of days.
|
|
75
|
+
* @csspart picker-weekday - A column header naming a day of the week.
|
|
76
|
+
* @csspart rest - How many dates are held beyond the ones shown.
|
|
77
|
+
* @csspart surface - The floating panel.
|
|
78
|
+
* @csspart trigger - The control that opens the calendar.
|
|
79
|
+
* @csspart trigger-icon - The mark on the button that opens the calendar.
|
|
80
|
+
*/
|
|
81
|
+
export declare class HelixHeadlessDateInput extends HelixHeadlessDateInput_base {
|
|
82
|
+
protected readonly aria: AriaForwardController;
|
|
83
|
+
/**
|
|
84
|
+
* What the browser may autofill here, as one of the platform's own tokens.
|
|
85
|
+
*
|
|
86
|
+
* Empty leaves the attribute off, which is the browser's default and is what
|
|
87
|
+
* lets autofill work at all. This used to be hardcoded `off`, so a reader
|
|
88
|
+
* could never have a birthday or a postal code filled in for them and a
|
|
89
|
+
* consumer had no way to ask for it. See 295.
|
|
90
|
+
*/
|
|
91
|
+
autocomplete: string;
|
|
92
|
+
/**
|
|
93
|
+
* How many dates can be held at once.
|
|
94
|
+
*
|
|
95
|
+
* Absent is one. `range` holds a start and an end, `multiple` holds any
|
|
96
|
+
* number, and both are carried as one comma-separated value: a form field
|
|
97
|
+
* submits a string, and two fields for one question is a different control.
|
|
98
|
+
*/
|
|
99
|
+
mode?: 'range' | 'multiple';
|
|
100
|
+
/**
|
|
101
|
+
* How many months the calendar shows, side by side.
|
|
102
|
+
*
|
|
103
|
+
* Worth more than one mainly for a range, where picking a start in March and
|
|
104
|
+
* an end in April otherwise means paging between them and losing sight of the
|
|
105
|
+
* first. The panel is sized by its content, so this widens it.
|
|
106
|
+
*/
|
|
107
|
+
months: number;
|
|
108
|
+
/**
|
|
109
|
+
* How many dates are shown as tags before the rest are counted, in `multiple`.
|
|
110
|
+
*
|
|
111
|
+
* `0` is all of them, and is the default: a cap that guesses is worse than no
|
|
112
|
+
* cap, because the number that fits depends on the width of the field and the
|
|
113
|
+
* length of what is in it, neither of which this element knows. What a cap is
|
|
114
|
+
* genuinely for is a field in a row or a table cell, where a set of twelve
|
|
115
|
+
* dates would push everything below it down a line at a time.
|
|
116
|
+
*
|
|
117
|
+
* The remainder is counted rather than hidden. "3 more" is a fact a reader can
|
|
118
|
+
* act on, where a row that silently stops is a field that appears to have lost
|
|
119
|
+
* what was put in it, and the count is what tells them there is more to see.
|
|
120
|
+
*/
|
|
121
|
+
maxTags: number;
|
|
122
|
+
/**
|
|
123
|
+
* Earliest date that can be chosen, as `YYYY-MM-DD`.
|
|
124
|
+
*/
|
|
125
|
+
min: string;
|
|
126
|
+
/**
|
|
127
|
+
* How far apart the selectable dates are, in days.
|
|
128
|
+
*
|
|
129
|
+
* `<input type="date" step>`'s own unit, handed to the calendar this renders
|
|
130
|
+
* so the field and the grid agree about which dates exist. Counted from `min`
|
|
131
|
+
* where there is one and from 1 January 1970 where there is not, which is the
|
|
132
|
+
* platform's base.
|
|
133
|
+
*/
|
|
134
|
+
step: number;
|
|
135
|
+
/**
|
|
136
|
+
* Latest date that can be chosen, as `YYYY-MM-DD`.
|
|
137
|
+
*/
|
|
138
|
+
max: string;
|
|
139
|
+
/**
|
|
140
|
+
* Dates that cannot be chosen, as a comma-separated `YYYY-MM-DD` list.
|
|
141
|
+
*/
|
|
142
|
+
disableDates: string;
|
|
143
|
+
/**
|
|
144
|
+
* Days of the week that cannot be chosen, `0` for Sunday through `6`.
|
|
145
|
+
*/
|
|
146
|
+
disableDays: string;
|
|
147
|
+
/**
|
|
148
|
+
* First column of the week in the calendar, `0` for Sunday through `6`.
|
|
149
|
+
*/
|
|
150
|
+
firstDayOfWeek: number;
|
|
151
|
+
/**
|
|
152
|
+
* How a date is written in the field: `short` through `full`, or ISO.
|
|
153
|
+
*
|
|
154
|
+
* **The field renders when it is idle and holds the value when it is being
|
|
155
|
+
* edited.** A written date is a rendering, and a document being edited must
|
|
156
|
+
* not be a rendering of something else: `Intl.DateTimeFormat` formats and does
|
|
157
|
+
* not parse, so `4 August 2026` cannot be typed back, and writing a parser per
|
|
158
|
+
* locale is how a field ends up rejecting what it just displayed.
|
|
159
|
+
*
|
|
160
|
+
* The way out is not to choose between the two but to separate them in time.
|
|
161
|
+
* Idle, the field shows `4 August 2026`, which is what a date is for reading.
|
|
162
|
+
* Focused, it shows `2026-08-04`, which is what a date is for typing, and it
|
|
163
|
+
* goes back on the way out. Nothing parses a rendering, and nothing is
|
|
164
|
+
* read-only, which is what an earlier version of this settled for.
|
|
165
|
+
*
|
|
166
|
+
* A range is the exception that needs no swap: the dash between its two dates
|
|
167
|
+
* is a separator this element understands, so that much reads back either way.
|
|
168
|
+
*
|
|
169
|
+
* `iso` turns the rendering off, for a field whose reader is entering data
|
|
170
|
+
* rather than reading it, or where the ISO form is itself the point.
|
|
171
|
+
*
|
|
172
|
+
* The value is always `YYYY-MM-DD` regardless, because that is what a form
|
|
173
|
+
* submits and what `min` and `max` compare against.
|
|
174
|
+
*/
|
|
175
|
+
dateStyle: 'full' | 'iso' | 'long' | 'medium' | 'short';
|
|
176
|
+
/**
|
|
177
|
+
* Language tag the calendar names its months and days in.
|
|
178
|
+
*/
|
|
179
|
+
locale: string;
|
|
180
|
+
/**
|
|
181
|
+
* What the field says before a date is in it.
|
|
182
|
+
*/
|
|
183
|
+
placeholder: string;
|
|
184
|
+
/**
|
|
185
|
+
* Accessible name for the control that opens the calendar.
|
|
186
|
+
*/
|
|
187
|
+
triggerLabel: string;
|
|
188
|
+
/**
|
|
189
|
+
* The overlay, placed against the field rather than the trigger.
|
|
190
|
+
*
|
|
191
|
+
* Against the field because that is the box a reader sees as the control: a
|
|
192
|
+
* calendar hung off a small button at one end of a wide field reads as
|
|
193
|
+
* belonging to the button. `Select` anchors to its trigger for the opposite
|
|
194
|
+
* reason, its trigger being the whole control.
|
|
195
|
+
*/
|
|
196
|
+
protected readonly panel: PopoverController;
|
|
197
|
+
private get control();
|
|
198
|
+
/**
|
|
199
|
+
* What the calendar should show, which is only ever a whole date.
|
|
200
|
+
*
|
|
201
|
+
* Half-typed input reaches here on every keystroke, and `2026-08-1` is not a
|
|
202
|
+
* date: handing it to the calendar would move the month under a reader
|
|
203
|
+
* mid-word. So the grid follows the field only once the field says something
|
|
204
|
+
* complete.
|
|
205
|
+
*/
|
|
206
|
+
private get picked();
|
|
207
|
+
/** One date, written the way `dateStyle` asks for. */
|
|
208
|
+
private written;
|
|
209
|
+
private get display();
|
|
210
|
+
/**
|
|
211
|
+
* Whether the caret is in the field, which is when it holds the value.
|
|
212
|
+
*/
|
|
213
|
+
private editing;
|
|
214
|
+
/**
|
|
215
|
+
* What is being typed but not yet held, for `multiple` only.
|
|
216
|
+
*
|
|
217
|
+
* The other modes type into the value directly, because one date and a range
|
|
218
|
+
* are both a whole answer at the moment they are complete. A multiple is not:
|
|
219
|
+
* it is a set being added to, so the field needs somewhere to hold a date
|
|
220
|
+
* before it joins the set and somewhere to leave a half-typed one that is not
|
|
221
|
+
* a date yet.
|
|
222
|
+
*/
|
|
223
|
+
private draft;
|
|
224
|
+
/** Relayed under this element's name, so a consumer hears one control. */
|
|
225
|
+
private readonly handleInput;
|
|
226
|
+
/** Adds what was typed to the set, or takes the last one back out. */
|
|
227
|
+
private readonly handleDraftKey;
|
|
228
|
+
/** The dates that get a tag, which is all of them until `maxTags` says not. */
|
|
229
|
+
private get shownDates();
|
|
230
|
+
/** How many are held beyond the ones shown. */
|
|
231
|
+
private get restCount();
|
|
232
|
+
/** Takes one date back out of the set. */
|
|
233
|
+
private readonly removeDate;
|
|
234
|
+
private readonly handleCalendarChange;
|
|
235
|
+
/**
|
|
236
|
+
* Puts the field back where the answer differs from what was typed.
|
|
237
|
+
*
|
|
238
|
+
* `requestValue` is the mixin's, and it announces and decides; this is the
|
|
239
|
+
* other half, which `Input` needs for the same reason: the native control has
|
|
240
|
+
* already changed, so wherever the answer does not follow it, it has to be
|
|
241
|
+
* restored. A refusal and a consumer who owns `value` and has not given a new
|
|
242
|
+
* one are the same thing from here.
|
|
243
|
+
*/
|
|
244
|
+
private restore;
|
|
245
|
+
/** Reports the value and the validity the host stands behind. */
|
|
246
|
+
private sync;
|
|
247
|
+
/** Escape shuts the calendar without moving the date. */
|
|
248
|
+
private readonly handleKeydown;
|
|
249
|
+
/**
|
|
250
|
+
* Whether the control refuses changes while still submitting its value.
|
|
251
|
+
*
|
|
252
|
+
* **Enforced by refusing every request in one place**, which is the seam this
|
|
253
|
+
* component already has: `requestValue` is what every path here comes through,
|
|
254
|
+
* and gating it once is what stops the next call site from being written
|
|
255
|
+
* without the check.
|
|
256
|
+
*
|
|
257
|
+
* Not `disabled`, which is the confusion worth naming: a disabled control
|
|
258
|
+
* submits nothing and leaves the tab order, and a read-only one submits its
|
|
259
|
+
* value and stays reachable, which is what a form showing a value somebody
|
|
260
|
+
* else set needs.
|
|
261
|
+
*/
|
|
262
|
+
readOnly: boolean;
|
|
263
|
+
/** Refuses every change while read-only. See `readOnly`. */
|
|
264
|
+
requestValue(next: string): boolean;
|
|
265
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
266
|
+
protected updated(changed: PropertyValues): void;
|
|
267
|
+
/**
|
|
268
|
+
* Puts the caret back in the field without the field reopening the calendar.
|
|
269
|
+
*
|
|
270
|
+
* Focus opens the calendar, so handing focus back after a pick reopens the
|
|
271
|
+
* thing that was just answered. `relatedTarget` was the guard and it is not
|
|
272
|
+
* enough on its own: it catches a hand-off from the trigger, and it does not
|
|
273
|
+
* catch this, because the cell that had focus is gone by the time the caret
|
|
274
|
+
* moves and the document has fallen back to something outside this element.
|
|
275
|
+
*
|
|
276
|
+
* **Reasoned rather than measured, and worth saying which.** In a focused
|
|
277
|
+
* document: the reader presses a day, the cell has focus, the panel is hidden,
|
|
278
|
+
* the browser moves focus off the removed cell to the body, and the caret is
|
|
279
|
+
* then put back here with `relatedTarget` pointing at the body, which is
|
|
280
|
+
* outside this element and reads as an arrival. Every step is ordinary browser
|
|
281
|
+
* behavior and none of it can be exercised here: `focus()` dispatches no
|
|
282
|
+
* event in an unfocused document, which is what both the test runtime and the
|
|
283
|
+
* available browser pane are. A spec was written for it and passed with the
|
|
284
|
+
* guard removed, so it was covering nothing and has been taken out rather than
|
|
285
|
+
* left to look like proof.
|
|
286
|
+
*
|
|
287
|
+
* A flag rather than a better guess, because this element is the one moving
|
|
288
|
+
* the focus and is the only thing that can know so. Cleared synchronously,
|
|
289
|
+
* since `focus()` dispatches before it returns.
|
|
290
|
+
*/
|
|
291
|
+
private returning;
|
|
292
|
+
private returnFocus;
|
|
293
|
+
private readonly handleBlur;
|
|
294
|
+
private readonly handleFocus;
|
|
295
|
+
/** Puts the caret in the field, the way a label pointing at one would. */
|
|
296
|
+
focus(options?: FocusOptions): void;
|
|
297
|
+
/**
|
|
298
|
+
* The calendar the field opens, behind a seam the styled tier can move.
|
|
299
|
+
*
|
|
300
|
+
* A method rather than a fragment inline, so a tier above can render its own,
|
|
301
|
+
* wrap this one, pass it a property the base does not know about, or leave it
|
|
302
|
+
* out, without reimplementing the whole template to do any of them. The tag is
|
|
303
|
+
* interpolated rather than written, so `tier` resolves it: this renders the
|
|
304
|
+
* headless element, and a styled subclass that sets `tier` renders the styled one
|
|
305
|
+
* from the same template.
|
|
306
|
+
*/
|
|
307
|
+
protected renderPicker(): TemplateResult;
|
|
308
|
+
/**
|
|
309
|
+
* One chosen date, as a tag, behind a seam the styled tier can move.
|
|
310
|
+
*
|
|
311
|
+
* A method rather than a fragment inline, so a tier above can render its own,
|
|
312
|
+
* wrap this one, pass it a property the base does not know about, or leave it
|
|
313
|
+
* out, without reimplementing the whole template to do any of them. The tag is
|
|
314
|
+
* interpolated rather than written, so `tier` resolves it: this renders the
|
|
315
|
+
* headless element, and a styled subclass that sets `tier` renders the styled one
|
|
316
|
+
* from the same template.
|
|
317
|
+
*/
|
|
318
|
+
protected renderTag(date: string): TemplateResult;
|
|
319
|
+
/**
|
|
320
|
+
* The mark on the button that opens the calendar, behind a seam.
|
|
321
|
+
*
|
|
322
|
+
* Slot fallback, so a consumer replaces it by slotting; and a method, so the
|
|
323
|
+
* tier above replaces it by overriding.
|
|
324
|
+
*
|
|
325
|
+
* **A named import rather than `<helix-icon>`, and that is a reversal.** The
|
|
326
|
+
* element looked like the tidier of the two and loses on three counts.
|
|
327
|
+
* `helix-icon` indexes the whole icon map at runtime, `icons[this.name]`, and
|
|
328
|
+
* no bundler can shake a runtime lookup, so every consumer of any component
|
|
329
|
+
* that renders one ships all 50kB of path data; a named import ships one
|
|
330
|
+
* path. The import is checked when the package compiles, where a `name`
|
|
331
|
+
* string is checked only when `check:icons` runs. And `helix-icon` is not
|
|
332
|
+
* registered on the headless tier at all, which registers `helix-headless-icon`,
|
|
333
|
+
* so a headless consumer got an inert unknown element and no mark whatsoever.
|
|
334
|
+
*/
|
|
335
|
+
protected renderTrigger(): TemplateResult;
|
|
336
|
+
protected render(): TemplateResult;
|
|
337
|
+
/**
|
|
338
|
+
* The value as a `Date`, at midnight UTC, or `null` while there is no date.
|
|
339
|
+
*
|
|
340
|
+
* The platform's own pair on `<input type="date">`, and this control holds the
|
|
341
|
+
* same `YYYY-MM-DD` string, so a consumer moving from one to the other reads
|
|
342
|
+
* the same two properties. UTC because the platform chose UTC: a date that is
|
|
343
|
+
* the same date everywhere must not become a different one by crossing a
|
|
344
|
+
* timezone, and midnight local would do exactly that for anybody west of
|
|
345
|
+
* Greenwich.
|
|
346
|
+
*
|
|
347
|
+
* `null` while the value is half typed, which is most of the keystrokes a
|
|
348
|
+
* reader makes in one of these.
|
|
349
|
+
*/
|
|
350
|
+
get valueAsDate(): Date | null;
|
|
351
|
+
set valueAsDate(date: Date | null);
|
|
352
|
+
/** The value as milliseconds since the epoch, or `NaN` while there is no date. */
|
|
353
|
+
get valueAsNumber(): number;
|
|
354
|
+
set valueAsNumber(ms: number);
|
|
355
|
+
}
|
|
356
|
+
declare global {
|
|
357
|
+
interface HTMLElementTagNameMap {
|
|
358
|
+
'helix-headless-date-input': HelixHeadlessDateInput;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
export {};
|