@human-kit/svelte-components 1.0.0-alpha.1 → 1.0.0-alpha.11
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/dist/FOCUS_STATE_CONTRACT.md +63 -0
- package/dist/FOCUS_STATE_REVIEW_TEMPLATE.md +70 -0
- package/dist/button/README.md +48 -0
- package/dist/button/TODO.md +13 -0
- package/dist/button/index.d.ts +5 -0
- package/dist/button/index.js +4 -0
- package/dist/button/index.parts.d.ts +1 -0
- package/dist/button/index.parts.js +1 -0
- package/dist/button/root/README.md +43 -0
- package/dist/button/root/button-root.svelte +362 -0
- package/dist/button/root/button-root.svelte.d.ts +21 -0
- package/dist/button/root/button-test.svelte +76 -0
- package/dist/button/root/button-test.svelte.d.ts +11 -0
- package/dist/calendar/README.md +66 -0
- package/dist/calendar/TODO.md +23 -0
- package/dist/calendar/body-cell/README.md +15 -0
- package/dist/calendar/body-cell/calendar-body-cell.svelte +230 -0
- package/dist/calendar/body-cell/calendar-body-cell.svelte.d.ts +9 -0
- package/dist/calendar/grid/README.md +13 -0
- package/dist/calendar/grid/calendar-grid-month-scope.svelte +16 -0
- package/dist/calendar/grid/calendar-grid-month-scope.svelte.d.ts +8 -0
- package/dist/calendar/grid/calendar-grid.svelte +45 -0
- package/dist/calendar/grid/calendar-grid.svelte.d.ts +8 -0
- package/dist/calendar/grid/month-scope.d.ts +2 -0
- package/dist/calendar/grid/month-scope.js +8 -0
- package/dist/calendar/grid-body/README.md +13 -0
- package/dist/calendar/grid-body/calendar-grid-body-custom-test.svelte +13 -0
- package/dist/calendar/grid-body/calendar-grid-body-custom-test.svelte.d.ts +18 -0
- package/dist/calendar/grid-body/calendar-grid-body.svelte +36 -0
- package/dist/calendar/grid-body/calendar-grid-body.svelte.d.ts +8 -0
- package/dist/calendar/grid-header/README.md +13 -0
- package/dist/calendar/grid-header/calendar-grid-header-custom-test.svelte +13 -0
- package/dist/calendar/grid-header/calendar-grid-header-custom-test.svelte.d.ts +18 -0
- package/dist/calendar/grid-header/calendar-grid-header.svelte +31 -0
- package/dist/calendar/grid-header/calendar-grid-header.svelte.d.ts +8 -0
- package/dist/calendar/header-cell/README.md +14 -0
- package/dist/calendar/header-cell/calendar-header-cell-test.svelte +11 -0
- package/dist/calendar/header-cell/calendar-header-cell-test.svelte.d.ts +18 -0
- package/dist/calendar/header-cell/calendar-header-cell.svelte +16 -0
- package/dist/calendar/header-cell/calendar-header-cell.svelte.d.ts +8 -0
- package/dist/calendar/heading/README.md +13 -0
- package/dist/calendar/heading/calendar-heading.svelte +17 -0
- package/dist/calendar/heading/calendar-heading.svelte.d.ts +5 -0
- package/dist/calendar/index.d.ts +13 -0
- package/dist/calendar/index.js +13 -0
- package/dist/calendar/index.parts.d.ts +9 -0
- package/dist/calendar/index.parts.js +9 -0
- package/dist/calendar/root/README.md +24 -0
- package/dist/calendar/root/calendar-root-bind-value-test.svelte +14 -0
- package/dist/calendar/root/calendar-root-bind-value-test.svelte.d.ts +3 -0
- package/dist/calendar/root/calendar-root-controlled-clear-test.svelte +20 -0
- package/dist/calendar/root/calendar-root-controlled-clear-test.svelte.d.ts +3 -0
- package/dist/calendar/root/calendar-root-test.svelte +71 -0
- package/dist/calendar/root/calendar-root-test.svelte.d.ts +13 -0
- package/dist/calendar/root/calendar-root.svelte +143 -0
- package/dist/calendar/root/calendar-root.svelte.d.ts +31 -0
- package/dist/calendar/root/context.d.ts +66 -0
- package/dist/calendar/root/context.js +727 -0
- package/dist/calendar/root/date-utils.d.ts +17 -0
- package/dist/calendar/root/date-utils.js +94 -0
- package/dist/calendar/trigger-next/README.md +14 -0
- package/dist/calendar/trigger-next/calendar-trigger-next.svelte +43 -0
- package/dist/calendar/trigger-next/calendar-trigger-next.svelte.d.ts +9 -0
- package/dist/calendar/trigger-previous/README.md +14 -0
- package/dist/calendar/trigger-previous/calendar-trigger-previous.svelte +43 -0
- package/dist/calendar/trigger-previous/calendar-trigger-previous.svelte.d.ts +9 -0
- package/dist/checkbox/README.md +53 -0
- package/dist/checkbox/TODO.md +16 -0
- package/dist/checkbox/index.d.ts +6 -0
- package/dist/checkbox/index.js +6 -0
- package/dist/checkbox/index.parts.d.ts +2 -0
- package/dist/checkbox/index.parts.js +2 -0
- package/dist/checkbox/indicator/README.md +23 -0
- package/dist/checkbox/indicator/checkbox-indicator.svelte +43 -0
- package/dist/checkbox/indicator/checkbox-indicator.svelte.d.ts +10 -0
- package/dist/checkbox/root/README.md +47 -0
- package/dist/checkbox/root/checkbox-label-test.svelte +10 -0
- package/dist/checkbox/root/checkbox-label-test.svelte.d.ts +18 -0
- package/dist/checkbox/root/checkbox-root.svelte +361 -0
- package/dist/checkbox/root/checkbox-root.svelte.d.ts +23 -0
- package/dist/checkbox/root/checkbox-test.svelte +59 -0
- package/dist/checkbox/root/checkbox-test.svelte.d.ts +18 -0
- package/dist/checkbox/root/context.d.ts +21 -0
- package/dist/checkbox/root/context.js +15 -0
- package/dist/clock/README.md +75 -0
- package/dist/clock/axis/README.md +24 -0
- package/dist/clock/axis/clock-axis.svelte +37 -0
- package/dist/clock/axis/clock-axis.svelte.d.ts +8 -0
- package/dist/clock/hooks/use-wheel-scroll.svelte.d.ts +16 -0
- package/dist/clock/hooks/use-wheel-scroll.svelte.js +336 -0
- package/dist/clock/index.d.ts +10 -0
- package/dist/clock/index.js +10 -0
- package/dist/clock/index.parts.d.ts +4 -0
- package/dist/clock/index.parts.js +4 -0
- package/dist/clock/root/README.md +38 -0
- package/dist/clock/root/clock-root-test.svelte +62 -0
- package/dist/clock/root/clock-root-test.svelte.d.ts +14 -0
- package/dist/clock/root/clock-root.svelte +329 -0
- package/dist/clock/root/clock-root.svelte.d.ts +25 -0
- package/dist/clock/root/context.d.ts +22 -0
- package/dist/clock/root/context.js +15 -0
- package/dist/clock/root/resolve-visible-columns.d.ts +7 -0
- package/dist/clock/root/resolve-visible-columns.js +16 -0
- package/dist/clock/root/time-utils.d.ts +48 -0
- package/dist/clock/root/time-utils.js +314 -0
- package/dist/clock/root/wheel-options.d.ts +17 -0
- package/dist/clock/root/wheel-options.js +63 -0
- package/dist/clock/wheel-column/README.md +25 -0
- package/dist/clock/wheel-column/clock-wheel-column-bindable-test.svelte +16 -0
- package/dist/clock/wheel-column/clock-wheel-column-bindable-test.svelte.d.ts +3 -0
- package/dist/clock/wheel-column/clock-wheel-column-custom-snippet-test.svelte +29 -0
- package/dist/clock/wheel-column/clock-wheel-column-custom-snippet-test.svelte.d.ts +6 -0
- package/dist/clock/wheel-column/clock-wheel-column-default-height-test.svelte +11 -0
- package/dist/clock/wheel-column/clock-wheel-column-default-height-test.svelte.d.ts +3 -0
- package/dist/clock/wheel-column/clock-wheel-column-test.svelte +38 -0
- package/dist/clock/wheel-column/clock-wheel-column-test.svelte.d.ts +12 -0
- package/dist/clock/wheel-column/clock-wheel-column-tp-test.svelte +38 -0
- package/dist/clock/wheel-column/clock-wheel-column-tp-test.svelte.d.ts +12 -0
- package/dist/clock/wheel-column/clock-wheel-column-untagged-snippet-test.svelte +29 -0
- package/dist/clock/wheel-column/clock-wheel-column-untagged-snippet-test.svelte.d.ts +6 -0
- package/dist/clock/wheel-column/clock-wheel-column.svelte +499 -0
- package/dist/clock/wheel-column/clock-wheel-column.svelte.d.ts +17 -0
- package/dist/clock/wheel-item/README.md +17 -0
- package/dist/clock/wheel-item/clock-wheel-item.svelte +49 -0
- package/dist/clock/wheel-item/clock-wheel-item.svelte.d.ts +17 -0
- package/dist/combobox/README.md +46 -0
- package/dist/combobox/TODO.md +28 -175
- package/dist/combobox/button/README.md +20 -0
- package/dist/combobox/button/combobox-button-test.svelte +27 -0
- package/dist/combobox/button/combobox-button-test.svelte.d.ts +6 -0
- package/dist/combobox/button/combobox-button.svelte +10 -11
- package/dist/combobox/clear/README.md +21 -0
- package/dist/combobox/clear/combobox-clear-test.svelte +34 -0
- package/dist/combobox/clear/combobox-clear-test.svelte.d.ts +3 -0
- package/dist/combobox/clear/combobox-clear.svelte +61 -0
- package/dist/combobox/clear/combobox-clear.svelte.d.ts +9 -0
- package/dist/combobox/index.d.ts +5 -3
- package/dist/combobox/index.js +5 -3
- package/dist/combobox/index.parts.d.ts +2 -0
- package/dist/combobox/index.parts.js +2 -0
- package/dist/combobox/input/README.md +16 -0
- package/dist/combobox/input/combobox-input.svelte +43 -12
- package/dist/combobox/item/README.md +27 -0
- package/dist/combobox/item/combobox-item-implicit-text-test.svelte +1 -1
- package/dist/combobox/item/combobox-listboxitem.svelte +3 -9
- package/dist/combobox/item-indicator/README.md +15 -0
- package/dist/combobox/item-indicator/combobox-item-indicator.svelte +4 -15
- package/dist/combobox/list/README.md +27 -0
- package/dist/combobox/list/combobox-listbox.svelte.d.ts +1 -1
- package/dist/combobox/popover/README.md +27 -0
- package/dist/combobox/popover/combobox-popover-props-test.svelte +38 -0
- package/dist/combobox/popover/combobox-popover-props-test.svelte.d.ts +11 -0
- package/dist/combobox/popover/combobox-popover.svelte +166 -23
- package/dist/combobox/popover/combobox-popover.svelte.d.ts +3 -3
- package/dist/combobox/popover/combobox-scrollable-list-test.svelte +23 -0
- package/dist/combobox/popover/combobox-scrollable-list-test.svelte.d.ts +18 -0
- package/dist/combobox/root/README.md +45 -0
- package/dist/combobox/root/combobox-multiselect-test.svelte +1 -1
- package/dist/combobox/root/combobox-numeric-string-id-test.svelte +1 -1
- package/dist/combobox/root/combobox-test.svelte +16 -3
- package/dist/combobox/root/combobox-test.svelte.d.ts +1 -0
- package/dist/combobox/root/combobox.svelte +100 -4
- package/dist/combobox/root/combobox.svelte.d.ts +1 -0
- package/dist/combobox/root/context.d.ts +19 -1
- package/dist/combobox/tag/README.md +37 -0
- package/dist/combobox/tag-remove/README.md +14 -0
- package/dist/combobox/tag-remove/combobox-tag-remove.svelte +3 -2
- package/dist/combobox/tags/README.md +23 -0
- package/dist/combobox/trigger/README.md +21 -0
- package/dist/combobox/trigger/combobox-trigger.svelte +56 -0
- package/dist/combobox/trigger/combobox-trigger.svelte.d.ts +9 -0
- package/dist/datepicker/README.md +100 -0
- package/dist/datepicker/TODO.md +28 -0
- package/dist/datepicker/calendar/README.md +19 -0
- package/dist/datepicker/calendar/date-picker-calendar-unsafe-props-test.svelte +60 -0
- package/dist/datepicker/calendar/date-picker-calendar-unsafe-props-test.svelte.d.ts +3 -0
- package/dist/datepicker/calendar/date-picker-calendar.svelte +65 -0
- package/dist/datepicker/calendar/date-picker-calendar.svelte.d.ts +10 -0
- package/dist/datepicker/index.d.ts +18 -0
- package/dist/datepicker/index.js +18 -0
- package/dist/datepicker/index.parts.d.ts +14 -0
- package/dist/datepicker/index.parts.js +14 -0
- package/dist/datepicker/input/README.md +15 -0
- package/dist/datepicker/input/date-picker-input.svelte +108 -0
- package/dist/datepicker/input/date-picker-input.svelte.d.ts +11 -0
- package/dist/datepicker/internal/strict-props.d.ts +2 -0
- package/dist/datepicker/internal/strict-props.js +28 -0
- package/dist/datepicker/popover/README.md +20 -0
- package/dist/datepicker/popover/date-picker-popover-handler-test.svelte +57 -0
- package/dist/datepicker/popover/date-picker-popover-handler-test.svelte.d.ts +3 -0
- package/dist/datepicker/popover/date-picker-popover-unsafe-props-test.svelte +45 -0
- package/dist/datepicker/popover/date-picker-popover-unsafe-props-test.svelte.d.ts +18 -0
- package/dist/datepicker/popover/date-picker-popover.svelte +87 -0
- package/dist/datepicker/popover/date-picker-popover.svelte.d.ts +7 -0
- package/dist/datepicker/root/README.md +38 -0
- package/dist/datepicker/root/context.d.ts +43 -0
- package/dist/datepicker/root/context.js +15 -0
- package/dist/datepicker/root/date-picker-bindable-empty-test.svelte +24 -0
- package/dist/datepicker/root/date-picker-bindable-empty-test.svelte.d.ts +3 -0
- package/dist/datepicker/root/date-picker-bindable-test.svelte +41 -0
- package/dist/datepicker/root/date-picker-bindable-test.svelte.d.ts +3 -0
- package/dist/datepicker/root/date-picker-empty-test.svelte +47 -0
- package/dist/datepicker/root/date-picker-empty-test.svelte.d.ts +3 -0
- package/dist/datepicker/root/date-picker-locale-typing-test.svelte +47 -0
- package/dist/datepicker/root/date-picker-locale-typing-test.svelte.d.ts +3 -0
- package/dist/datepicker/root/date-picker-open-cancel-test.svelte +54 -0
- package/dist/datepicker/root/date-picker-open-cancel-test.svelte.d.ts +8 -0
- package/dist/datepicker/root/date-picker-root.svelte +495 -0
- package/dist/datepicker/root/date-picker-root.svelte.d.ts +24 -0
- package/dist/datepicker/root/date-picker-test.svelte +86 -0
- package/dist/datepicker/root/date-picker-test.svelte.d.ts +13 -0
- package/dist/datepicker/root/date-utils.d.ts +17 -0
- package/dist/datepicker/root/date-utils.js +138 -0
- package/dist/datepicker/root/draft-evaluation.d.ts +13 -0
- package/dist/datepicker/root/draft-evaluation.js +56 -0
- package/dist/datepicker/root/focus-controller.d.ts +3 -0
- package/dist/datepicker/root/focus-controller.js +15 -0
- package/dist/datepicker/root/open-change.d.ts +5 -0
- package/dist/datepicker/root/open-change.js +13 -0
- package/dist/datepicker/root/open-controller.d.ts +7 -0
- package/dist/datepicker/root/open-controller.js +15 -0
- package/dist/datepicker/root/segment-controller.d.ts +8 -0
- package/dist/datepicker/root/segment-controller.js +53 -0
- package/dist/datepicker/root/segment-state.d.ts +18 -0
- package/dist/datepicker/root/segment-state.js +134 -0
- package/dist/datepicker/root/value-commit.d.ts +4 -0
- package/dist/datepicker/root/value-commit.js +8 -0
- package/dist/datepicker/segment/README.md +14 -0
- package/dist/datepicker/segment/date-picker-segment.svelte +319 -0
- package/dist/datepicker/segment/date-picker-segment.svelte.d.ts +9 -0
- package/dist/datepicker/trigger/README.md +14 -0
- package/dist/datepicker/trigger/date-picker-trigger.svelte +110 -0
- package/dist/datepicker/trigger/date-picker-trigger.svelte.d.ts +9 -0
- package/dist/dialog/README.md +35 -0
- package/dist/dialog/content/README.md +16 -0
- package/dist/dialog/content/dialog-content.svelte +6 -6
- package/dist/dialog/index.d.ts +3 -3
- package/dist/dialog/index.js +2 -2
- package/dist/dialog/overlay/README.md +13 -0
- package/dist/dialog/portal/README.md +12 -0
- package/dist/dialog/root/README.md +53 -0
- package/dist/dialog/root/context.d.ts +2 -1
- package/dist/dialog/root/dialog-root.svelte +9 -2
- package/dist/dialog/trigger/README.md +12 -0
- package/dist/dialog/trigger/dialog-trigger-multi-button-test.svelte +19 -0
- package/dist/dialog/trigger/dialog-trigger-multi-button-test.svelte.d.ts +18 -0
- package/dist/dialog/trigger/dialog-trigger.svelte +18 -6
- package/dist/index.d.ts +31 -13
- package/dist/index.js +31 -13
- package/dist/input/README.md +38 -0
- package/dist/input/TODO.md +12 -0
- package/dist/input/input-test.svelte +43 -0
- package/dist/input/input-test.svelte.d.ts +12 -0
- package/dist/input/input.svelte +151 -7
- package/dist/input/input.svelte.d.ts +8 -2
- package/dist/listbox/README.md +26 -0
- package/dist/listbox/index.d.ts +3 -3
- package/dist/listbox/index.js +3 -3
- package/dist/listbox/item/README.md +25 -0
- package/dist/listbox/item/listbox-item.svelte +158 -2
- package/dist/listbox/item/listbox-item.svelte.d.ts +4 -0
- package/dist/listbox/root/README.md +40 -0
- package/dist/listbox/root/listbox-test.svelte +14 -2
- package/dist/listbox/root/listbox-test.svelte.d.ts +1 -0
- package/dist/listbox/root/listbox.svelte +44 -0
- package/dist/listbox/root/listbox.svelte.d.ts +2 -2
- package/dist/locale-provider/context.d.ts +8 -0
- package/dist/locale-provider/context.js +18 -0
- package/dist/locale-provider/index.d.ts +4 -0
- package/dist/locale-provider/index.js +4 -0
- package/dist/locale-provider/locale-provider-initial-value-test.svelte +15 -0
- package/dist/locale-provider/locale-provider-initial-value-test.svelte.d.ts +7 -0
- package/dist/locale-provider/locale-provider-test.svelte +20 -0
- package/dist/locale-provider/locale-provider-test.svelte.d.ts +6 -0
- package/dist/locale-provider/locale-provider-value-probe.svelte +22 -0
- package/dist/locale-provider/locale-provider-value-probe.svelte.d.ts +6 -0
- package/dist/locale-provider/locale-provider.svelte +23 -0
- package/dist/locale-provider/locale-provider.svelte.d.ts +8 -0
- package/dist/popover/README.md +42 -0
- package/dist/popover/content/README.md +36 -0
- package/dist/popover/content/popover-content-standalone-test.svelte +28 -0
- package/dist/popover/content/popover-content-standalone-test.svelte.d.ts +6 -0
- package/dist/popover/content/popover-content-test.svelte +32 -2
- package/dist/popover/content/popover-content-test.svelte.d.ts +3 -1
- package/dist/popover/content/popover-content.svelte +277 -24
- package/dist/popover/content/popover-content.svelte.d.ts +5 -1
- package/dist/popover/index.d.ts +3 -3
- package/dist/popover/index.js +3 -5
- package/dist/popover/root/README.md +25 -0
- package/dist/popover/root/context.d.ts +16 -7
- package/dist/popover/root/context.js +0 -2
- package/dist/popover/root/focus-state.d.ts +4 -0
- package/dist/popover/root/focus-state.js +33 -0
- package/dist/popover/root/popover-root.svelte +90 -17
- package/dist/popover/root/popover-root.svelte.d.ts +2 -1
- package/dist/popover/root/popover-test.svelte +2 -1
- package/dist/popover/root/popover-test.svelte.d.ts +2 -1
- package/dist/popover/trigger/README.md +23 -0
- package/dist/popover/trigger/popover-trigger-button.svelte +14 -10
- package/dist/popover/trigger/popover-trigger-button.svelte.d.ts +2 -3
- package/dist/popover/trigger/popover-trigger-multi-button-test.svelte +16 -0
- package/dist/popover/trigger/popover-trigger-multi-button-test.svelte.d.ts +18 -0
- package/dist/popover/trigger/popover-trigger.svelte +19 -7
- package/dist/portal/portal.svelte +3 -1
- package/dist/primitives/click-outside.d.ts +1 -1
- package/dist/primitives/click-outside.js +1 -1
- package/dist/primitives/floating.js +12 -4
- package/dist/primitives/focus-trap.d.ts +7 -2
- package/dist/primitives/focus-trap.js +50 -17
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.js +1 -0
- package/dist/primitives/input-modality.d.ts +7 -0
- package/dist/primitives/input-modality.js +125 -0
- package/dist/table/IMPLEMENTATION_NOTES.md +8 -0
- package/dist/table/PLAN-HIDDEN-COLUMNS.md +152 -0
- package/dist/table/PLAN.md +924 -0
- package/dist/table/README.md +116 -0
- package/dist/table/SELECTION_CHECKBOX_PLAN.md +234 -0
- package/dist/table/TODO.md +100 -0
- package/dist/table/body/README.md +24 -0
- package/dist/table/body/table-body.svelte +25 -0
- package/dist/table/body/table-body.svelte.d.ts +9 -0
- package/dist/table/cell/README.md +25 -0
- package/dist/table/cell/table-cell.svelte +247 -0
- package/dist/table/cell/table-cell.svelte.d.ts +9 -0
- package/dist/table/checkbox/README.md +38 -0
- package/dist/table/checkbox/table-checkbox-test.svelte +121 -0
- package/dist/table/checkbox/table-checkbox-test.svelte.d.ts +16 -0
- package/dist/table/checkbox/table-checkbox.svelte +274 -0
- package/dist/table/checkbox/table-checkbox.svelte.d.ts +13 -0
- package/dist/table/checkbox-indicator/README.md +29 -0
- package/dist/table/checkbox-indicator/table-checkbox-indicator.svelte +22 -0
- package/dist/table/checkbox-indicator/table-checkbox-indicator.svelte.d.ts +10 -0
- package/dist/table/column/README.md +32 -0
- package/dist/table/column/table-column.svelte +108 -0
- package/dist/table/column/table-column.svelte.d.ts +18 -0
- package/dist/table/column-header-cell/README.md +28 -0
- package/dist/table/column-header-cell/table-column-header-cell.svelte +281 -0
- package/dist/table/column-header-cell/table-column-header-cell.svelte.d.ts +9 -0
- package/dist/table/column-resizer/README.md +32 -0
- package/dist/table/column-resizer/table-column-resizer-freeze-layout-test.svelte +51 -0
- package/dist/table/column-resizer/table-column-resizer-freeze-layout-test.svelte.d.ts +3 -0
- package/dist/table/column-resizer/table-column-resizer-selection-column-test.svelte +83 -0
- package/dist/table/column-resizer/table-column-resizer-selection-column-test.svelte.d.ts +3 -0
- package/dist/table/column-resizer/table-column-resizer-test.svelte +75 -0
- package/dist/table/column-resizer/table-column-resizer-test.svelte.d.ts +3 -0
- package/dist/table/column-resizer/table-column-resizer.svelte +616 -0
- package/dist/table/column-resizer/table-column-resizer.svelte.d.ts +11 -0
- package/dist/table/empty-state/README.md +25 -0
- package/dist/table/empty-state/table-empty-state.svelte +38 -0
- package/dist/table/empty-state/table-empty-state.svelte.d.ts +8 -0
- package/dist/table/footer/README.md +24 -0
- package/dist/table/footer/table-footer.svelte +19 -0
- package/dist/table/footer/table-footer.svelte.d.ts +9 -0
- package/dist/table/header/README.md +24 -0
- package/dist/table/header/table-header.svelte +19 -0
- package/dist/table/header/table-header.svelte.d.ts +9 -0
- package/dist/table/index.d.ts +16 -0
- package/dist/table/index.js +16 -0
- package/dist/table/index.parts.d.ts +12 -0
- package/dist/table/index.parts.js +12 -0
- package/dist/table/root/README.md +56 -0
- package/dist/table/root/context.d.ts +198 -0
- package/dist/table/root/context.js +1426 -0
- package/dist/table/root/table-reorder-test.svelte +64 -0
- package/dist/table/root/table-reorder-test.svelte.d.ts +3 -0
- package/dist/table/root/table-root.svelte +410 -0
- package/dist/table/root/table-root.svelte.d.ts +29 -0
- package/dist/table/root/table-test.svelte +165 -0
- package/dist/table/root/table-test.svelte.d.ts +25 -0
- package/dist/table/row/README.md +27 -0
- package/dist/table/row/table-row.svelte +321 -0
- package/dist/table/row/table-row.svelte.d.ts +13 -0
- package/dist/test-utils/focus-contract.d.ts +3 -0
- package/dist/test-utils/focus-contract.js +26 -0
- package/dist/timepicker/IMPLEMENTATION_PLAN.md +254 -0
- package/dist/timepicker/README.md +97 -0
- package/dist/timepicker/TODO.md +86 -0
- package/dist/timepicker/clock/README.md +14 -0
- package/dist/timepicker/clock/time-picker-clock-test.svelte +45 -0
- package/dist/timepicker/clock/time-picker-clock-test.svelte.d.ts +11 -0
- package/dist/timepicker/clock/time-picker-clock.svelte +65 -0
- package/dist/timepicker/clock/time-picker-clock.svelte.d.ts +10 -0
- package/dist/timepicker/index.d.ts +14 -0
- package/dist/timepicker/index.js +14 -0
- package/dist/timepicker/index.parts.d.ts +8 -0
- package/dist/timepicker/index.parts.js +8 -0
- package/dist/timepicker/input/README.md +15 -0
- package/dist/timepicker/input/time-picker-input-forwarding-test.svelte +40 -0
- package/dist/timepicker/input/time-picker-input-forwarding-test.svelte.d.ts +3 -0
- package/dist/timepicker/input/time-picker-input.svelte +109 -0
- package/dist/timepicker/input/time-picker-input.svelte.d.ts +11 -0
- package/dist/timepicker/internal/strict-props.d.ts +4 -0
- package/dist/timepicker/internal/strict-props.js +51 -0
- package/dist/timepicker/popover/README.md +20 -0
- package/dist/timepicker/popover/time-picker-popover-unsafe-props-test.svelte +22 -0
- package/dist/timepicker/popover/time-picker-popover-unsafe-props-test.svelte.d.ts +3 -0
- package/dist/timepicker/popover/time-picker-popover.svelte +89 -0
- package/dist/timepicker/popover/time-picker-popover.svelte.d.ts +7 -0
- package/dist/timepicker/root/README.md +42 -0
- package/dist/timepicker/root/context.d.ts +51 -0
- package/dist/timepicker/root/context.js +15 -0
- package/dist/timepicker/root/time-picker-12h-test.svelte +22 -0
- package/dist/timepicker/root/time-picker-12h-test.svelte.d.ts +3 -0
- package/dist/timepicker/root/time-picker-bindable-test.svelte +25 -0
- package/dist/timepicker/root/time-picker-bindable-test.svelte.d.ts +3 -0
- package/dist/timepicker/root/time-picker-empty-test.svelte +20 -0
- package/dist/timepicker/root/time-picker-empty-test.svelte.d.ts +3 -0
- package/dist/timepicker/root/time-picker-root.svelte +625 -0
- package/dist/timepicker/root/time-picker-root.svelte.d.ts +28 -0
- package/dist/timepicker/root/time-picker-test.svelte +72 -0
- package/dist/timepicker/root/time-picker-test.svelte.d.ts +15 -0
- package/dist/timepicker/root/time-utils.d.ts +1 -0
- package/dist/timepicker/root/time-utils.js +3 -0
- package/dist/timepicker/segment/README.md +14 -0
- package/dist/timepicker/segment/time-picker-segment.svelte +365 -0
- package/dist/timepicker/segment/time-picker-segment.svelte.d.ts +9 -0
- package/dist/timepicker/trigger/README.md +14 -0
- package/dist/timepicker/trigger/time-picker-trigger-forwarding-test.svelte +35 -0
- package/dist/timepicker/trigger/time-picker-trigger-forwarding-test.svelte.d.ts +3 -0
- package/dist/timepicker/trigger/time-picker-trigger.svelte +122 -0
- package/dist/timepicker/trigger/time-picker-trigger.svelte.d.ts +9 -0
- package/dist/utils/date-only.d.ts +11 -0
- package/dist/utils/date-only.js +53 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/package.json +41 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!-- markdownlint-disable MD024 -->
|
|
2
|
+
|
|
3
|
+
# Table.Row
|
|
4
|
+
|
|
5
|
+
## API reference
|
|
6
|
+
|
|
7
|
+
### Table.Row
|
|
8
|
+
|
|
9
|
+
Name: `Table.Row`
|
|
10
|
+
Description: Semantic table row part used in the header, body, or footer. In body scope it reflects row focus, selection, and disabled state.
|
|
11
|
+
|
|
12
|
+
| Prop | Type | Default | Description |
|
|
13
|
+
| ------------ | ------------------ | ----------- | --------------------------------------------------------------- |
|
|
14
|
+
| `id` | `string \| number` | `undefined` | Stable row identifier used for selection state in `Table.Body`. |
|
|
15
|
+
| `isDisabled` | `boolean` | `false` | Marks a body row as non-selectable. |
|
|
16
|
+
| `textValue` | `string` | `undefined` | Reserved for future text-based navigation features. |
|
|
17
|
+
| `class` | `string` | `''` | Class names for the `tr` element. |
|
|
18
|
+
| `children` | `Snippet` | `undefined` | Row cells. |
|
|
19
|
+
|
|
20
|
+
### Context utilities
|
|
21
|
+
|
|
22
|
+
Name: `Table.Row` row context
|
|
23
|
+
Description: Publishes row registration and cell-order helpers to descendant cells.
|
|
24
|
+
|
|
25
|
+
| Prop | Type | Default | Description |
|
|
26
|
+
| -------------------- | ----------------------- | ------- | ---------------------------------------------------- |
|
|
27
|
+
| `useTableRowContext` | `() => TableRowContext` | `-` | Reads the current row token and cell-order contract. |
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onDestroy } from 'svelte';
|
|
3
|
+
import { SvelteMap } from 'svelte/reactivity';
|
|
4
|
+
import { writable } from 'svelte/store';
|
|
5
|
+
import type { Snippet } from 'svelte';
|
|
6
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
7
|
+
import {
|
|
8
|
+
setTableRowContext,
|
|
9
|
+
useTableContext,
|
|
10
|
+
useTableSectionContext,
|
|
11
|
+
type TableSelectionKey
|
|
12
|
+
} from '../root/context';
|
|
13
|
+
import {
|
|
14
|
+
shouldShowFocusVisible,
|
|
15
|
+
trackInteractionModality
|
|
16
|
+
} from '../../primitives/input-modality';
|
|
17
|
+
|
|
18
|
+
type TableRowProps = Omit<HTMLAttributes<HTMLTableRowElement>, 'children' | 'id'> & {
|
|
19
|
+
id?: TableSelectionKey;
|
|
20
|
+
isDisabled?: boolean;
|
|
21
|
+
textValue?: string;
|
|
22
|
+
children?: Snippet;
|
|
23
|
+
class?: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
let {
|
|
27
|
+
id,
|
|
28
|
+
isDisabled = false,
|
|
29
|
+
children,
|
|
30
|
+
class: className = '',
|
|
31
|
+
...restProps
|
|
32
|
+
}: TableRowProps = $props();
|
|
33
|
+
|
|
34
|
+
const table = useTableContext();
|
|
35
|
+
const section = useTableSectionContext();
|
|
36
|
+
const rowToken = table.createInstanceToken('row');
|
|
37
|
+
const cellOrder: string[] = [];
|
|
38
|
+
const cellElements = new SvelteMap<string, () => HTMLElement | undefined>();
|
|
39
|
+
const cellOrderVersion = writable(0);
|
|
40
|
+
|
|
41
|
+
let rowElement = $state<HTMLTableRowElement | undefined>(undefined);
|
|
42
|
+
let childListObserver: MutationObserver | null = null;
|
|
43
|
+
|
|
44
|
+
function notifyCellOrderChange() {
|
|
45
|
+
cellIndexCache = null;
|
|
46
|
+
cellOrderVersion.update((value) => value + 1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function registerCellToken(token: string, getElement?: () => HTMLElement | undefined) {
|
|
50
|
+
if (!cellOrder.includes(token)) {
|
|
51
|
+
cellOrder.push(token);
|
|
52
|
+
notifyCellOrderChange();
|
|
53
|
+
}
|
|
54
|
+
if (getElement) {
|
|
55
|
+
cellElements.set(token, getElement);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function unregisterCellToken(token: string) {
|
|
60
|
+
cellElements.delete(token);
|
|
61
|
+
const index = cellOrder.indexOf(token);
|
|
62
|
+
if (index >= 0) {
|
|
63
|
+
cellOrder.splice(index, 1);
|
|
64
|
+
notifyCellOrderChange();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let cellIndexCache: Map<string, number> | null = null;
|
|
69
|
+
|
|
70
|
+
function buildCellIndexCache(): Map<string, number> {
|
|
71
|
+
if (cellIndexCache) return cellIndexCache;
|
|
72
|
+
// eslint-disable-next-line svelte/prefer-svelte-reactivity -- plain cache, not reactive state
|
|
73
|
+
const cache = new Map<string, number>();
|
|
74
|
+
if (rowElement) {
|
|
75
|
+
const directCells = rowElement.children;
|
|
76
|
+
// eslint-disable-next-line svelte/prefer-svelte-reactivity -- plain cache, not reactive state
|
|
77
|
+
const elementToIndex = new Map<HTMLElement, number>();
|
|
78
|
+
for (let i = 0; i < directCells.length; i += 1) {
|
|
79
|
+
const child = directCells[i];
|
|
80
|
+
if (child instanceof HTMLElement) {
|
|
81
|
+
elementToIndex.set(child, i);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
for (const registeredToken of cellOrder) {
|
|
85
|
+
const element = cellElements.get(registeredToken)?.();
|
|
86
|
+
if (element) {
|
|
87
|
+
const idx = elementToIndex.get(element);
|
|
88
|
+
if (idx !== undefined) {
|
|
89
|
+
cache.set(registeredToken, idx);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
cellIndexCache = cache;
|
|
95
|
+
return cache;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function getCellIndex(token: string) {
|
|
99
|
+
const cache = buildCellIndexCache();
|
|
100
|
+
const cached = cache.get(token);
|
|
101
|
+
if (cached !== undefined) return cached;
|
|
102
|
+
return cellOrder.indexOf(token);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
setTableRowContext({
|
|
106
|
+
rowToken,
|
|
107
|
+
section: section.section,
|
|
108
|
+
get rowId() {
|
|
109
|
+
return id;
|
|
110
|
+
},
|
|
111
|
+
get isDisabled() {
|
|
112
|
+
return isDisabled;
|
|
113
|
+
},
|
|
114
|
+
cellOrderVersion,
|
|
115
|
+
registerCellToken,
|
|
116
|
+
unregisterCellToken,
|
|
117
|
+
getCellIndex
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
function syncRowRegistration() {
|
|
121
|
+
table.registerRow({
|
|
122
|
+
token: rowToken,
|
|
123
|
+
section: section.section,
|
|
124
|
+
id,
|
|
125
|
+
disabled: isDisabled,
|
|
126
|
+
element: rowElement
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
syncRowRegistration();
|
|
131
|
+
|
|
132
|
+
$effect(() => {
|
|
133
|
+
syncRowRegistration();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
let pendingCellOrderNotify = false;
|
|
137
|
+
|
|
138
|
+
function scheduleCellOrderNotify() {
|
|
139
|
+
if (!pendingCellOrderNotify) {
|
|
140
|
+
pendingCellOrderNotify = true;
|
|
141
|
+
queueMicrotask(() => {
|
|
142
|
+
pendingCellOrderNotify = false;
|
|
143
|
+
cellIndexCache = null;
|
|
144
|
+
notifyCellOrderChange();
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
$effect(() => {
|
|
150
|
+
childListObserver?.disconnect();
|
|
151
|
+
childListObserver = null;
|
|
152
|
+
|
|
153
|
+
if (!rowElement) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const observer = new MutationObserver(() => {
|
|
158
|
+
scheduleCellOrderNotify();
|
|
159
|
+
});
|
|
160
|
+
observer.observe(rowElement, { childList: true });
|
|
161
|
+
childListObserver = observer;
|
|
162
|
+
|
|
163
|
+
return () => {
|
|
164
|
+
observer.disconnect();
|
|
165
|
+
if (childListObserver === observer) {
|
|
166
|
+
childListObserver = null;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
onDestroy(() => {
|
|
172
|
+
childListObserver?.disconnect();
|
|
173
|
+
table.unregisterRow(rowToken);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const selectionVersion = table.selectionVersion;
|
|
177
|
+
const focusVersion = table.focusVersion;
|
|
178
|
+
const isSelected = $derived.by(() => {
|
|
179
|
+
void $selectionVersion;
|
|
180
|
+
return section.section === 'body' ? table.isRowSelected(id) : false;
|
|
181
|
+
});
|
|
182
|
+
const isFocusWithin = $derived.by(() => {
|
|
183
|
+
void $focusVersion;
|
|
184
|
+
return section.section === 'body' ? table.isRowFocused(rowToken) : false;
|
|
185
|
+
});
|
|
186
|
+
const isFocused = $derived.by(() => {
|
|
187
|
+
void $focusVersion;
|
|
188
|
+
return section.section === 'body' ? table.isRowFocusTarget(rowToken) : false;
|
|
189
|
+
});
|
|
190
|
+
const isFocusVisible = $derived.by(() => {
|
|
191
|
+
void $focusVersion;
|
|
192
|
+
return section.section === 'body' ? isFocused && table.focusVisible : false;
|
|
193
|
+
});
|
|
194
|
+
const isFocusVisibleWithin = $derived.by(() => {
|
|
195
|
+
void $focusVersion;
|
|
196
|
+
return section.section === 'body' ? isFocusWithin && table.focusVisible : false;
|
|
197
|
+
});
|
|
198
|
+
const isAriaDisabled = $derived.by(() => {
|
|
199
|
+
void $selectionVersion;
|
|
200
|
+
return section.section === 'body' ? table.isRowDisabled(id, isDisabled) : isDisabled;
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
function handleFocus() {
|
|
204
|
+
if (section.section !== 'body') return;
|
|
205
|
+
if (isAriaDisabled) return;
|
|
206
|
+
if (!table.isRowTabStop(rowToken)) return;
|
|
207
|
+
table.setFocusedRow(rowToken, table.getRowFocusEdge(rowToken) ?? 'start');
|
|
208
|
+
table.setFocusVisible(shouldShowFocusVisible(rowElement ?? null));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function handleMouseDown(event: MouseEvent) {
|
|
212
|
+
trackInteractionModality(event, rowElement ?? null);
|
|
213
|
+
table.setFocusVisible(false);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function handleKeyDown(event: KeyboardEvent) {
|
|
217
|
+
if (section.section !== 'body') return;
|
|
218
|
+
if (event.target !== rowElement) return;
|
|
219
|
+
trackInteractionModality(event, rowElement ?? null);
|
|
220
|
+
|
|
221
|
+
if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'a') {
|
|
222
|
+
if (table.selectionMode === 'multiple') {
|
|
223
|
+
event.preventDefault();
|
|
224
|
+
table.selectAllRows();
|
|
225
|
+
}
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if ((event.ctrlKey || event.metaKey) && event.key === 'Home') {
|
|
230
|
+
event.preventDefault();
|
|
231
|
+
table.moveToGridStart();
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if ((event.ctrlKey || event.metaKey) && event.key === 'End') {
|
|
236
|
+
event.preventDefault();
|
|
237
|
+
table.moveToGridEnd();
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
switch (event.key) {
|
|
242
|
+
case 'ArrowUp':
|
|
243
|
+
event.preventDefault();
|
|
244
|
+
table.moveFocus('up', {
|
|
245
|
+
shiftKey: event.shiftKey,
|
|
246
|
+
ctrlKey: event.ctrlKey,
|
|
247
|
+
metaKey: event.metaKey,
|
|
248
|
+
altKey: event.altKey
|
|
249
|
+
});
|
|
250
|
+
return;
|
|
251
|
+
case 'ArrowDown':
|
|
252
|
+
event.preventDefault();
|
|
253
|
+
table.moveFocus('down', {
|
|
254
|
+
shiftKey: event.shiftKey,
|
|
255
|
+
ctrlKey: event.ctrlKey,
|
|
256
|
+
metaKey: event.metaKey,
|
|
257
|
+
altKey: event.altKey
|
|
258
|
+
});
|
|
259
|
+
return;
|
|
260
|
+
case 'ArrowLeft':
|
|
261
|
+
event.preventDefault();
|
|
262
|
+
table.moveFocus('left');
|
|
263
|
+
return;
|
|
264
|
+
case 'ArrowRight':
|
|
265
|
+
event.preventDefault();
|
|
266
|
+
table.moveFocus('right');
|
|
267
|
+
return;
|
|
268
|
+
case 'Home':
|
|
269
|
+
event.preventDefault();
|
|
270
|
+
table.moveToBodyRowStart();
|
|
271
|
+
return;
|
|
272
|
+
case 'End':
|
|
273
|
+
event.preventDefault();
|
|
274
|
+
table.moveToBodyRowEnd();
|
|
275
|
+
return;
|
|
276
|
+
case 'Enter':
|
|
277
|
+
case ' ':
|
|
278
|
+
event.preventDefault();
|
|
279
|
+
if (event.repeat) return;
|
|
280
|
+
if (!isAriaDisabled) {
|
|
281
|
+
table.pressRow(id, {
|
|
282
|
+
shiftKey: event.shiftKey,
|
|
283
|
+
ctrlKey: event.ctrlKey,
|
|
284
|
+
metaKey: event.metaKey,
|
|
285
|
+
altKey: event.altKey
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
</script>
|
|
292
|
+
|
|
293
|
+
<tr
|
|
294
|
+
bind:this={rowElement}
|
|
295
|
+
class={className}
|
|
296
|
+
tabindex={section.section === 'body'
|
|
297
|
+
? !isAriaDisabled
|
|
298
|
+
? table.isRowTabStop(rowToken)
|
|
299
|
+
? 0
|
|
300
|
+
: -1
|
|
301
|
+
: undefined
|
|
302
|
+
: undefined}
|
|
303
|
+
data-focused={isFocused ? 'true' : undefined}
|
|
304
|
+
data-focus-visible={isFocusVisible ? 'true' : undefined}
|
|
305
|
+
data-focus-within={isFocusWithin ? 'true' : undefined}
|
|
306
|
+
data-focus-visible-within={isFocusVisibleWithin ? 'true' : undefined}
|
|
307
|
+
data-selected={isSelected ? 'true' : undefined}
|
|
308
|
+
data-disabled={isAriaDisabled || undefined}
|
|
309
|
+
aria-selected={section.section === 'body' && table.selectionMode !== 'none'
|
|
310
|
+
? isSelected
|
|
311
|
+
: undefined}
|
|
312
|
+
aria-disabled={section.section === 'body' && isAriaDisabled ? true : undefined}
|
|
313
|
+
onfocus={handleFocus}
|
|
314
|
+
onmousedown={handleMouseDown}
|
|
315
|
+
onkeydown={handleKeyDown}
|
|
316
|
+
{...restProps}
|
|
317
|
+
>
|
|
318
|
+
{#if children}
|
|
319
|
+
{@render children()}
|
|
320
|
+
{/if}
|
|
321
|
+
</tr>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { type TableSelectionKey } from '../root/context';
|
|
4
|
+
type TableRowProps = Omit<HTMLAttributes<HTMLTableRowElement>, 'children' | 'id'> & {
|
|
5
|
+
id?: TableSelectionKey;
|
|
6
|
+
isDisabled?: boolean;
|
|
7
|
+
textValue?: string;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
class?: string;
|
|
10
|
+
};
|
|
11
|
+
declare const TableRow: import("svelte").Component<TableRowProps, {}, "">;
|
|
12
|
+
type TableRow = ReturnType<typeof TableRow>;
|
|
13
|
+
export default TableRow;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { expect } from 'vitest';
|
|
2
|
+
export function expectFocusVisibleImpliesFocusWithin(root) {
|
|
3
|
+
expect(root).toBeTruthy();
|
|
4
|
+
const focusVisible = root?.getAttribute('data-focus-visible');
|
|
5
|
+
const focusWithin = root?.getAttribute('data-focus-within');
|
|
6
|
+
if (focusVisible === 'true') {
|
|
7
|
+
expect(focusWithin).toBe('true');
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export function expectFocusVisibleImpliesFocused(node) {
|
|
11
|
+
expect(node).toBeTruthy();
|
|
12
|
+
const focusVisible = node?.getAttribute('data-focus-visible');
|
|
13
|
+
const focused = node?.getAttribute('data-focused');
|
|
14
|
+
if (focusVisible === 'true') {
|
|
15
|
+
expect(focused).toBe('true');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function expectNoFalseFocusAttributes(scope = document) {
|
|
19
|
+
const focusAttrs = ['data-focused', 'data-focus-visible', 'data-focus-within'];
|
|
20
|
+
for (const attr of focusAttrs) {
|
|
21
|
+
const nodes = Array.from(scope.querySelectorAll(`[${attr}]`));
|
|
22
|
+
for (const node of nodes) {
|
|
23
|
+
expect(node.getAttribute(attr)).not.toBe('false');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# TimePicker Implementation Plan
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
Implement all open items from `TODO.md` in one delivery, prioritizing correctness and stability first, then accessibility/performance, and finally coverage hardening.
|
|
6
|
+
|
|
7
|
+
## Goals
|
|
8
|
+
|
|
9
|
+
- Fix state/event correctness regressions first.
|
|
10
|
+
- Keep wheel interaction fluid while improving robustness.
|
|
11
|
+
- Add missing accessibility semantics without introducing noisy behavior.
|
|
12
|
+
- Apply low-risk performance improvements.
|
|
13
|
+
- Expand tests to protect the full wheel pipeline.
|
|
14
|
+
|
|
15
|
+
## Phase 1 — Correctness (P0/P1 behavior)
|
|
16
|
+
|
|
17
|
+
### 1a) Allow external clearing via `value = undefined`
|
|
18
|
+
|
|
19
|
+
**Files**
|
|
20
|
+
|
|
21
|
+
- `root/time-picker-root.svelte`
|
|
22
|
+
|
|
23
|
+
**Changes**
|
|
24
|
+
|
|
25
|
+
- Remove the `if (value === undefined) return;` early-return in the `$effect` that observes `value`.
|
|
26
|
+
- When `value` becomes `undefined`, treat it as an explicit clear: reset `segmentDraft` to empty, set `valueInternal = null`, and publish `null` via `publishCommittedValue`.
|
|
27
|
+
|
|
28
|
+
**Risk**
|
|
29
|
+
|
|
30
|
+
- Controlled/uncontrolled sync regressions — initial mount with `value={undefined}` must not trigger a spurious publish.
|
|
31
|
+
|
|
32
|
+
**Validation**
|
|
33
|
+
|
|
34
|
+
- `bun run test -- --run src/lib/timepicker/root/time-picker-root.test.ts`
|
|
35
|
+
|
|
36
|
+
### 1b) Publish `null` when all segments are cleared
|
|
37
|
+
|
|
38
|
+
**Files**
|
|
39
|
+
|
|
40
|
+
- `root/time-picker-root.svelte`
|
|
41
|
+
|
|
42
|
+
**Changes**
|
|
43
|
+
|
|
44
|
+
- In `commitFromDraft`, when `buildTimePartsFromDraft` returns `null` **and** `hasAnyRequiredValue` is `false` (every segment is empty), call `publishCommittedValue(null)` instead of doing a silent return.
|
|
45
|
+
- This ensures `bind:value` transitions from a valid time to `null` when the user backspaces every segment.
|
|
46
|
+
|
|
47
|
+
**Risk**
|
|
48
|
+
|
|
49
|
+
- Must avoid re-publishing `null` on every keystroke while segments are partially filled — the `hasAnyRequiredValue === true` path already handles that correctly.
|
|
50
|
+
|
|
51
|
+
**Validation**
|
|
52
|
+
|
|
53
|
+
- `bun run test -- --run src/lib/timepicker/root/time-picker-root.test.ts`
|
|
54
|
+
|
|
55
|
+
### 2) Event forwarding consistency
|
|
56
|
+
|
|
57
|
+
**Files**
|
|
58
|
+
|
|
59
|
+
- `input/time-picker-input.svelte`
|
|
60
|
+
- `trigger/time-picker-trigger.svelte`
|
|
61
|
+
**Changes**
|
|
62
|
+
|
|
63
|
+
- Compose external/internal handlers consistently.
|
|
64
|
+
|
|
65
|
+
- User handlers accidentally suppress internal logic.
|
|
66
|
+
|
|
67
|
+
- `bun run test -- --run src/lib/timepicker/input/time-picker-input.test.ts src/lib/timepicker/trigger/time-picker-trigger.test.ts`
|
|
68
|
+
|
|
69
|
+
- Add safety restoration to current draft value when drift is detected.
|
|
70
|
+
|
|
71
|
+
**Policy**
|
|
72
|
+
|
|
73
|
+
- Implement guard + restore strategy aligned with TODO note.
|
|
74
|
+
**Risk**
|
|
75
|
+
|
|
76
|
+
- IME/paste edge cases and cross-browser input events.
|
|
77
|
+
**Validation**
|
|
78
|
+
|
|
79
|
+
- `bun run test -- --run src/lib/timepicker/segment/time-picker-segment.test.ts`
|
|
80
|
+
|
|
81
|
+
**Files**
|
|
82
|
+
|
|
83
|
+
- `segment/time-picker-segment.svelte`
|
|
84
|
+
|
|
85
|
+
- Use explicit 12h boundaries (`1`/`12`) instead of relying on clamping side effects.
|
|
86
|
+
|
|
87
|
+
- Segment keyboard tests in same run as above.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Phase 2 — Wheel stability and interaction quality
|
|
92
|
+
|
|
93
|
+
### 5) Wheel settle behavior and anchor sync
|
|
94
|
+
|
|
95
|
+
**Files**
|
|
96
|
+
**Changes**
|
|
97
|
+
|
|
98
|
+
- Increase scroll debounce fallback from 64ms to 120ms. The debounce only fires in browsers without native `scrollend` support, so higher values do not affect perceived latency. 120ms is conservative enough to avoid interrupting touch momentum on iOS Safari.
|
|
99
|
+
**Risk**
|
|
100
|
+
|
|
101
|
+
- Async timing loops (`scroll`, `scrollend`, debounce). The silent flag must be cleared reliably (on `scrollend` or animation completion).
|
|
102
|
+
**Validation**
|
|
103
|
+
|
|
104
|
+
- `bun run test -- --run src/lib/clock/wheel-column/clock-wheel-column.test.ts src/lib/clock/panel/clock-panel.test.ts`
|
|
105
|
+
|
|
106
|
+
### 6) ResizeObserver loop mitigation
|
|
107
|
+
|
|
108
|
+
**Files**
|
|
109
|
+
|
|
110
|
+
- `../clock/wheel-column/clock-wheel-column.svelte`
|
|
111
|
+
- Batch measurement updates through `requestAnimationFrame` to reduce observer-loop warnings.
|
|
112
|
+
|
|
113
|
+
**Validation**
|
|
114
|
+
|
|
115
|
+
- Re-run wheel and root tests:
|
|
116
|
+
- `bun run test -- --run src/lib/clock/wheel-column/clock-wheel-column.test.ts src/lib/timepicker/root/time-picker-root.test.ts`
|
|
117
|
+
|
|
118
|
+
## Phase 3 — Accessibility and API surface
|
|
119
|
+
|
|
120
|
+
### 7) Wheel announcements and semantics
|
|
121
|
+
|
|
122
|
+
- `../clock/wheel-column/clock-wheel-column.svelte`
|
|
123
|
+
|
|
124
|
+
**Changes**
|
|
125
|
+
|
|
126
|
+
- Add `aria-roledescription` on wheel spinbutton.
|
|
127
|
+
|
|
128
|
+
**Risk**
|
|
129
|
+
|
|
130
|
+
- Over-announcement/noise for SR users.
|
|
131
|
+
|
|
132
|
+
### 8) `isRequired` propagation
|
|
133
|
+
|
|
134
|
+
**Files**
|
|
135
|
+
|
|
136
|
+
- `root/time-picker-root.svelte`
|
|
137
|
+
- `root/context.ts`
|
|
138
|
+
- `input/time-picker-input.svelte`
|
|
139
|
+
- `README.md`
|
|
140
|
+
|
|
141
|
+
- Add `isRequired` to root API and context.
|
|
142
|
+
- Expose `aria-required` on input group.
|
|
143
|
+
- Document API addition.
|
|
144
|
+
|
|
145
|
+
- Input/root tests + typecheck.
|
|
146
|
+
|
|
147
|
+
- `../clock/wheel-item/clock-wheel-item.svelte`
|
|
148
|
+
|
|
149
|
+
**Changes**
|
|
150
|
+
|
|
151
|
+
- Remove default visual inline styles (opacity, cursor, font-weight, etc.) entirely. The component becomes fully headless — consumers style via `data-selected`, `data-disabled`, `data-centered` attributes.
|
|
152
|
+
- This aligns WheelItem with the rest of the library where components ship zero visual opinions.
|
|
153
|
+
**Risk**
|
|
154
|
+
|
|
155
|
+
- Technically breaking for anyone relying on the default inline styles. Acceptable at current maturity — the component is new and the old styles were inconsistent (all dropped when `class` was passed).
|
|
156
|
+
|
|
157
|
+
## Phase 4 — Performance and code cleanup
|
|
158
|
+
|
|
159
|
+
### 10) Formatter and locale caching
|
|
160
|
+
|
|
161
|
+
- `root/time-picker-root.svelte`
|
|
162
|
+
- `root/time-utils.ts`
|
|
163
|
+
**Changes**
|
|
164
|
+
|
|
165
|
+
- Cache `Intl.DateTimeFormat` by `locale` + `hourCycle` + `granularity`.
|
|
166
|
+
- Cache system-locale fallback once per component lifetime.
|
|
167
|
+
|
|
168
|
+
**Files**
|
|
169
|
+
|
|
170
|
+
**Changes**
|
|
171
|
+
|
|
172
|
+
- Skip disabled candidate computation when no min/max is set.
|
|
173
|
+
|
|
174
|
+
### 12) Low-risk code quality cleanups
|
|
175
|
+
|
|
176
|
+
**Files**
|
|
177
|
+
|
|
178
|
+
- `root/time-utils.ts`
|
|
179
|
+
- `root/time-picker-root.svelte`
|
|
180
|
+
|
|
181
|
+
**Changes**
|
|
182
|
+
|
|
183
|
+
- Remove unreachable min>max branch in `isTimeOutOfRange`.
|
|
184
|
+
- Replace meaningless ternary `type === 'hour' ? 2 : 2` with constant.
|
|
185
|
+
|
|
186
|
+
**Validation**
|
|
187
|
+
|
|
188
|
+
## Phase 5 — Test hardening
|
|
189
|
+
|
|
190
|
+
### 13) Wheel test matrix expansion
|
|
191
|
+
|
|
192
|
+
**Add coverage for**
|
|
193
|
+
|
|
194
|
+
- Open alignment and external value sync.
|
|
195
|
+
- Focus contract (`data-focus-within`, `data-focus-visible`).
|
|
196
|
+
- Min/max disabled behavior.
|
|
197
|
+
|
|
198
|
+
### 14) End-to-end wheel integration test
|
|
199
|
+
|
|
200
|
+
**Files**
|
|
201
|
+
|
|
202
|
+
- `root/time-picker-root.test.ts` and/or `wheel-column/time-picker-wheel-column.test.ts`
|
|
203
|
+
|
|
204
|
+
**Flow to cover**
|
|
205
|
+
|
|
206
|
+
- Wheel interaction → snap → `selectWheelValue` → root commit → segment UI + bound value sync.
|
|
207
|
+
|
|
208
|
+
### 15) Segment paste/IME resilience tests
|
|
209
|
+
|
|
210
|
+
**Files**
|
|
211
|
+
|
|
212
|
+
- `segment/time-picker-segment.test.ts`
|
|
213
|
+
|
|
214
|
+
**Cases**
|
|
215
|
+
|
|
216
|
+
- Paste attempts do not corrupt draft.
|
|
217
|
+
- Input DOM restores to draft when mutation bypass happens.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Execution Order (Single PR)
|
|
222
|
+
|
|
223
|
+
1. Phase 1
|
|
224
|
+
2. Phase 2
|
|
225
|
+
3. Phase 3
|
|
226
|
+
4. Phase 4
|
|
227
|
+
5. Phase 5
|
|
228
|
+
|
|
229
|
+
This order minimizes risk: behavior correctness first, wheel timing second, API/accessibility third, refactors fourth, broad tests last.
|
|
230
|
+
|
|
231
|
+
## Verification Checklist
|
|
232
|
+
|
|
233
|
+
### Targeted runs after each phase
|
|
234
|
+
|
|
235
|
+
- `bun run test -- --run src/lib/timepicker/root/time-picker-root.test.ts`
|
|
236
|
+
- `bun run test -- --run src/lib/timepicker/input/time-picker-input.test.ts src/lib/timepicker/trigger/time-picker-trigger.test.ts`
|
|
237
|
+
- `bun run test -- --run src/lib/timepicker/segment/time-picker-segment.test.ts`
|
|
238
|
+
- `bun run test -- --run src/lib/clock/wheel-column/clock-wheel-column.test.ts src/lib/clock/panel/clock-panel.test.ts`
|
|
239
|
+
- `bun run test -- --run src/lib/timepicker/root/time-utils.test.ts`
|
|
240
|
+
|
|
241
|
+
### Final gate
|
|
242
|
+
|
|
243
|
+
- `bun run typecheck`
|
|
244
|
+
- `bun run test -- --run`
|
|
245
|
+
- `bun run lint`
|
|
246
|
+
- `bun run build`
|
|
247
|
+
- `bunx changeset` — generate changeset file (CI requires it for `packages/svelte/src/**` changes)
|
|
248
|
+
|
|
249
|
+
## Notes
|
|
250
|
+
|
|
251
|
+
- Debounce increase (64→120ms) is safe because it only acts as a fallback for browsers without `scrollend`. Modern browsers use `scrollend` as the primary settle signal.
|
|
252
|
+
- Preserve existing public APIs except where TODO explicitly requests additions (`isRequired`) or removals (WheelItem default styles).
|
|
253
|
+
- Phase 5 tests must be written against the corrected behavior from Phases 1-4, not against the current (buggy) behavior.
|
|
254
|
+
- Update docs/tests together with behavior changes to keep CI stable.
|