@adia-ai/web-components 0.6.33 → 0.6.35
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/CHANGELOG.md +64 -0
- package/color/index.js +1 -1
- package/components/accordion/accordion-item.yaml +2 -2
- package/components/accordion/accordion.css +2 -2
- package/components/accordion/accordion.js +1 -1
- package/components/action-list/action-item.yaml +2 -2
- package/components/action-list/action-list.css +2 -2
- package/components/action-list/action-list.js +1 -1
- package/components/agent-artifact/{class.js → agent-artifact.class.js} +1 -1
- package/components/agent-artifact/agent-artifact.css +31 -31
- package/components/agent-artifact/agent-artifact.js +1 -1
- package/components/agent-feedback-bar/agent-feedback-bar.css +10 -10
- package/components/agent-feedback-bar/agent-feedback-bar.js +1 -1
- package/components/agent-questions/agent-questions.css +57 -57
- package/components/agent-questions/agent-questions.js +1 -1
- package/components/agent-reasoning/agent-reasoning.css +62 -62
- package/components/agent-reasoning/agent-reasoning.js +1 -1
- package/components/agent-suggestions/agent-suggestions.css +4 -4
- package/components/agent-suggestions/agent-suggestions.js +1 -1
- package/components/agent-trace/agent-trace.css +53 -53
- package/components/alert/alert.a2ui.json +64 -1
- package/components/alert/{class.js → alert.class.js} +189 -2
- package/components/alert/alert.css +119 -41
- package/components/alert/alert.d.ts +14 -0
- package/components/alert/alert.js +1 -1
- package/components/alert/alert.test.js +184 -0
- package/components/alert/alert.yaml +114 -1
- package/components/avatar/avatar-group.yaml +2 -2
- package/components/avatar/avatar.css +27 -27
- package/components/avatar/avatar.js +1 -1
- package/components/badge/badge.css +27 -27
- package/components/badge/badge.js +1 -1
- package/components/block/block.css +16 -16
- package/components/block/block.js +1 -1
- package/components/breadcrumb/breadcrumb.css +23 -23
- package/components/breadcrumb/breadcrumb.js +1 -1
- package/components/button/button.css +101 -91
- package/components/button/button.js +1 -1
- package/components/calendar-grid/calendar-grid.a2ui.json +146 -0
- package/components/calendar-grid/calendar-grid.class.js +326 -0
- package/components/calendar-grid/calendar-grid.css +246 -0
- package/components/calendar-grid/calendar-grid.d.ts +41 -0
- package/components/calendar-grid/calendar-grid.js +17 -0
- package/components/calendar-grid/calendar-grid.yaml +136 -0
- package/components/calendar-picker/calendar-picker.css +139 -139
- package/components/calendar-picker/calendar-picker.js +1 -1
- package/components/canvas/canvas.css +12 -12
- package/components/card/card.css +83 -83
- package/components/card/card.js +1 -1
- package/components/chart/chart.css +224 -224
- package/components/chart/chart.js +1 -1
- package/components/chart-legend/chart-legend.css +26 -26
- package/components/chart-legend/chart-legend.js +1 -1
- package/components/chat-thread/chat-input.a2ui.json +1 -1
- package/components/chat-thread/chat-input.js +6 -1
- package/components/chat-thread/chat-input.yaml +4 -1
- package/components/chat-thread/chat-thread.js +1 -1
- package/components/check/check.css +40 -40
- package/components/check/check.js +1 -1
- package/components/code/code.css +125 -125
- package/components/code/code.js +1 -1
- package/components/col/col.css +15 -15
- package/components/col/col.js +1 -1
- package/components/color-input/color-input.js +1 -1
- package/components/color-picker/color-picker.css +55 -55
- package/components/color-picker/color-picker.js +1 -1
- package/components/combobox/combobox.a2ui.json +363 -0
- package/components/combobox/combobox.class.js +861 -0
- package/components/combobox/combobox.css +244 -0
- package/components/combobox/combobox.d.ts +113 -0
- package/components/combobox/combobox.examples.md +59 -0
- package/components/combobox/combobox.js +17 -0
- package/components/combobox/combobox.test.js +181 -0
- package/components/combobox/combobox.yaml +369 -0
- package/components/command/command.css +90 -90
- package/components/command/command.js +1 -1
- package/components/date-range-picker/date-range-picker.a2ui.json +300 -0
- package/components/date-range-picker/date-range-picker.class.js +791 -0
- package/components/date-range-picker/date-range-picker.css +224 -0
- package/components/date-range-picker/date-range-picker.d.ts +82 -0
- package/components/date-range-picker/date-range-picker.examples.md +37 -0
- package/components/date-range-picker/date-range-picker.js +17 -0
- package/components/date-range-picker/date-range-picker.test.js +387 -0
- package/components/date-range-picker/date-range-picker.yaml +285 -0
- package/components/datetime-picker/datetime-picker.a2ui.json +334 -0
- package/components/datetime-picker/datetime-picker.class.js +706 -0
- package/components/datetime-picker/datetime-picker.css +150 -0
- package/components/datetime-picker/datetime-picker.d.ts +86 -0
- package/components/datetime-picker/datetime-picker.examples.md +46 -0
- package/components/datetime-picker/datetime-picker.js +17 -0
- package/components/datetime-picker/datetime-picker.test.js +454 -0
- package/components/datetime-picker/datetime-picker.yaml +332 -0
- package/components/demo-toggle/demo-toggle.css +27 -27
- package/components/demo-toggle/demo-toggle.js +1 -1
- package/components/description-list/description-list.css +18 -18
- package/components/description-list/description-list.js +1 -1
- package/components/divider/divider.css +24 -24
- package/components/divider/divider.js +1 -1
- package/components/drawer/drawer.js +1 -1
- package/components/embed/embed.css +6 -6
- package/components/embed/embed.js +1 -1
- package/components/empty-state/empty-state.css +27 -27
- package/components/empty-state/empty-state.js +1 -1
- package/components/feed/feed.css +12 -12
- package/components/feed/feed.js +1 -1
- package/components/field/field.css +28 -28
- package/components/field/field.js +1 -1
- package/components/field/field.test.js +1 -1
- package/components/fields/fields.css +5 -5
- package/components/fields/fields.js +1 -1
- package/components/grid/grid.css +5 -5
- package/components/grid/grid.js +1 -1
- package/components/heatmap/heatmap.css +63 -63
- package/components/heatmap/heatmap.js +1 -1
- package/components/icon/icon.css +12 -12
- package/components/icon/icon.js +1 -1
- package/components/image/image.css +14 -14
- package/components/image/image.js +1 -1
- package/components/index.js +11 -0
- package/components/inline-message/inline-message.a2ui.json +143 -0
- package/components/inline-message/inline-message.class.js +169 -0
- package/components/inline-message/inline-message.css +75 -0
- package/components/inline-message/inline-message.d.ts +31 -0
- package/components/inline-message/inline-message.examples.md +19 -0
- package/components/inline-message/inline-message.js +17 -0
- package/components/inline-message/inline-message.test.js +203 -0
- package/components/inline-message/inline-message.yaml +205 -0
- package/components/input/input.css +67 -67
- package/components/input/input.js +1 -1
- package/components/input/input.yaml +5 -4
- package/components/inspector/inspector.css +6 -6
- package/components/inspector/inspector.js +1 -1
- package/components/integration-card/integration-card.a2ui.json +268 -0
- package/components/integration-card/integration-card.class.js +410 -0
- package/components/integration-card/integration-card.css +169 -0
- package/components/integration-card/integration-card.d.ts +63 -0
- package/components/integration-card/integration-card.examples.md +41 -0
- package/components/integration-card/integration-card.js +17 -0
- package/components/integration-card/integration-card.test.js +306 -0
- package/components/integration-card/integration-card.yaml +280 -0
- package/components/kbd/kbd.css +32 -32
- package/components/kbd/kbd.js +1 -1
- package/components/link/link.css +12 -12
- package/components/link/link.js +1 -1
- package/components/list/list-item.yaml +2 -2
- package/components/list/list.css +8 -8
- package/components/list/list.js +1 -1
- package/components/list-window/list-window.a2ui.json +277 -0
- package/components/list-window/list-window.class.js +688 -0
- package/components/list-window/list-window.css +124 -0
- package/components/list-window/list-window.d.ts +84 -0
- package/components/list-window/list-window.examples.md +73 -0
- package/components/list-window/list-window.js +17 -0
- package/components/list-window/list-window.test.js +303 -0
- package/components/list-window/list-window.yaml +270 -0
- package/components/loading-overlay/loading-overlay.a2ui.json +176 -0
- package/components/loading-overlay/loading-overlay.class.js +203 -0
- package/components/loading-overlay/loading-overlay.css +81 -0
- package/components/loading-overlay/loading-overlay.d.ts +24 -0
- package/components/loading-overlay/loading-overlay.examples.md +50 -0
- package/components/loading-overlay/loading-overlay.js +17 -0
- package/components/loading-overlay/loading-overlay.test.js +257 -0
- package/components/loading-overlay/loading-overlay.yaml +260 -0
- package/components/menu/menu-divider.yaml +1 -1
- package/components/menu/menu-item.yaml +1 -1
- package/components/menu/menu.a2ui.json +3 -0
- package/components/menu/menu.css +8 -8
- package/components/menu/menu.js +1 -1
- package/components/menu/menu.yaml +7 -0
- package/components/modal/{class.js → modal.class.js} +12 -1
- package/components/modal/modal.css +54 -44
- package/components/modal/modal.js +1 -1
- package/components/nav/nav.css +40 -40
- package/components/nav/nav.js +1 -1
- package/components/nav-group/nav-group.css +52 -52
- package/components/nav-group/nav-group.js +1 -1
- package/components/nav-item/nav-item.css +44 -44
- package/components/nav-item/nav-item.js +1 -1
- package/components/noodles/noodles.css +31 -31
- package/components/noodles/noodles.js +1 -1
- package/components/option-card/option-card.css +69 -69
- package/components/option-card/option-card.js +1 -1
- package/components/otp-input/otp-input.css +30 -30
- package/components/otp-input/otp-input.js +1 -1
- package/components/page/page.css +18 -18
- package/components/page/page.js +1 -1
- package/components/pagination/pagination.css +61 -61
- package/components/pagination/pagination.js +1 -1
- package/components/pane/pane.css +57 -57
- package/components/pane/pane.js +1 -1
- package/components/pipeline-status/pipeline-status.css +65 -65
- package/components/pipeline-status/pipeline-status.js +1 -1
- package/components/popover/popover.a2ui.json +8 -1
- package/components/popover/popover.css +17 -17
- package/components/popover/popover.js +1 -1
- package/components/popover/popover.yaml +14 -1
- package/components/progress/progress.css +23 -23
- package/components/progress/progress.js +1 -1
- package/components/progress-row/progress-row.css +17 -17
- package/components/progress-row/progress-row.js +1 -1
- package/components/radio/radio.css +39 -39
- package/components/radio/radio.js +1 -1
- package/components/range/range.css +55 -55
- package/components/range/range.js +1 -1
- package/components/rating/rating.css +28 -28
- package/components/rating/rating.js +1 -1
- package/components/richtext/richtext.css +133 -133
- package/components/richtext/richtext.js +1 -1
- package/components/row/row.css +19 -19
- package/components/row/row.js +1 -1
- package/components/search/search.css +5 -5
- package/components/search/search.js +1 -1
- package/components/segment/segment.css +24 -24
- package/components/segment/segment.js +1 -1
- package/components/segmented/segmented.css +25 -25
- package/components/segmented/segmented.js +1 -1
- package/components/select/select.a2ui.json +58 -4
- package/components/select/{class.js → select.class.js} +415 -6
- package/components/select/select.css +242 -84
- package/components/select/select.d.ts +31 -1
- package/components/select/select.js +1 -1
- package/components/select/select.test.js +202 -0
- package/components/select/select.yaml +126 -5
- package/components/skeleton/skeleton.css +14 -14
- package/components/skeleton/skeleton.js +1 -1
- package/components/slider/slider.css +46 -46
- package/components/slider/slider.js +1 -1
- package/components/spinner/spinner.a2ui.json +198 -0
- package/components/spinner/spinner.class.js +99 -0
- package/components/spinner/spinner.css +221 -0
- package/components/spinner/spinner.d.ts +26 -0
- package/components/spinner/spinner.examples.md +26 -0
- package/components/spinner/spinner.js +17 -0
- package/components/spinner/spinner.test.js +272 -0
- package/components/spinner/spinner.yaml +238 -0
- package/components/stack/stack.css +11 -11
- package/components/stack/stack.js +1 -1
- package/components/stat/stat.css +25 -25
- package/components/step-progress/step-progress.css +20 -20
- package/components/step-progress/step-progress.js +1 -1
- package/components/stepper/stepper-item.yaml +1 -1
- package/components/stepper/stepper.css +29 -29
- package/components/stepper/stepper.js +1 -1
- package/components/stream/stream.css +12 -12
- package/components/stream/stream.js +1 -1
- package/components/swatch/swatch.css +68 -68
- package/components/swatch/swatch.js +1 -1
- package/components/swiper/swiper.css +57 -57
- package/components/swiper/swiper.js +1 -1
- package/components/switch/switch.css +52 -52
- package/components/switch/switch.js +1 -1
- package/components/table/table.css +163 -163
- package/components/table/table.js +1 -1
- package/components/table-toolbar/{class.js → table-toolbar.class.js} +1 -1
- package/components/table-toolbar/table-toolbar.css +32 -32
- package/components/table-toolbar/table-toolbar.js +1 -1
- package/components/tabs/tab.yaml +2 -2
- package/components/tabs/tabs.css +51 -51
- package/components/tabs/tabs.js +1 -1
- package/components/tag/tag.css +48 -48
- package/components/tag/tag.js +1 -1
- package/components/tags-input/tags-input.a2ui.json +337 -0
- package/components/tags-input/tags-input.class.js +776 -0
- package/components/tags-input/tags-input.css +201 -0
- package/components/tags-input/tags-input.d.ts +120 -0
- package/components/tags-input/tags-input.examples.md +92 -0
- package/components/tags-input/tags-input.js +17 -0
- package/components/tags-input/tags-input.test.js +368 -0
- package/components/tags-input/tags-input.yaml +367 -0
- package/components/text/text.css +44 -44
- package/components/text/text.js +1 -1
- package/components/textarea/textarea.a2ui.json +1 -1
- package/components/textarea/textarea.css +46 -46
- package/components/textarea/textarea.js +1 -1
- package/components/textarea/textarea.yaml +11 -8
- package/components/time-picker/time-picker.a2ui.json +267 -0
- package/components/time-picker/time-picker.class.js +693 -0
- package/components/time-picker/time-picker.css +122 -0
- package/components/time-picker/time-picker.d.ts +75 -0
- package/components/time-picker/time-picker.examples.md +35 -0
- package/components/time-picker/time-picker.js +17 -0
- package/components/time-picker/time-picker.test.js +287 -0
- package/components/time-picker/time-picker.yaml +256 -0
- package/components/timeline/timeline-item.yaml +2 -2
- package/components/timeline/{class.js → timeline.class.js} +1 -1
- package/components/timeline/timeline.css +50 -50
- package/components/timeline/timeline.js +1 -1
- package/components/toast/toast.css +58 -58
- package/components/toast/toast.js +1 -1
- package/components/toggle-group/toggle-group.css +6 -6
- package/components/toggle-group/toggle-group.js +1 -1
- package/components/toggle-group/toggle-option.yaml +1 -1
- package/components/toggle-scheme/toggle-scheme.css +2 -2
- package/components/toggle-scheme/toggle-scheme.js +1 -1
- package/components/toolbar/toolbar-group.yaml +1 -1
- package/components/toolbar/toolbar.css +17 -17
- package/components/toolbar/toolbar.js +1 -1
- package/components/tooltip/tooltip.css +2 -2
- package/components/tooltip/tooltip.js +1 -1
- package/components/tree/tree-item.yaml +1 -1
- package/components/tree/tree.css +37 -37
- package/components/tree/tree.js +1 -1
- package/components/upload/upload.css +49 -49
- package/components/upload/upload.js +1 -1
- package/dist/web-components.min.css +1 -1
- package/dist/web-components.min.js +146 -87
- package/package.json +3 -3
- package/styles/components.css +11 -0
- /package/components/accordion/{class.js → accordion.class.js} +0 -0
- /package/components/action-list/{class.js → action-list.class.js} +0 -0
- /package/components/agent-feedback-bar/{class.js → agent-feedback-bar.class.js} +0 -0
- /package/components/agent-questions/{class.js → agent-questions.class.js} +0 -0
- /package/components/agent-reasoning/{class.js → agent-reasoning.class.js} +0 -0
- /package/components/agent-suggestions/{class.js → agent-suggestions.class.js} +0 -0
- /package/components/avatar/{class.js → avatar.class.js} +0 -0
- /package/components/badge/{class.js → badge.class.js} +0 -0
- /package/components/block/{class.js → block.class.js} +0 -0
- /package/components/breadcrumb/{class.js → breadcrumb.class.js} +0 -0
- /package/components/button/{class.js → button.class.js} +0 -0
- /package/components/calendar-picker/{class.js → calendar-picker.class.js} +0 -0
- /package/components/card/{class.js → card.class.js} +0 -0
- /package/components/chart/{class.js → chart.class.js} +0 -0
- /package/components/chart-legend/{class.js → chart-legend.class.js} +0 -0
- /package/components/chat-thread/{class.js → chat-thread.class.js} +0 -0
- /package/components/check/{class.js → check.class.js} +0 -0
- /package/components/code/{class.js → code.class.js} +0 -0
- /package/components/col/{class.js → col.class.js} +0 -0
- /package/components/color-input/{class.js → color-input.class.js} +0 -0
- /package/components/color-picker/{class.js → color-picker.class.js} +0 -0
- /package/components/command/{class.js → command.class.js} +0 -0
- /package/components/demo-toggle/{class.js → demo-toggle.class.js} +0 -0
- /package/components/description-list/{class.js → description-list.class.js} +0 -0
- /package/components/divider/{class.js → divider.class.js} +0 -0
- /package/components/drawer/{class.js → drawer.class.js} +0 -0
- /package/components/embed/{class.js → embed.class.js} +0 -0
- /package/components/empty-state/{class.js → empty-state.class.js} +0 -0
- /package/components/feed/{class.js → feed.class.js} +0 -0
- /package/components/field/{class.js → field.class.js} +0 -0
- /package/components/fields/{class.js → fields.class.js} +0 -0
- /package/components/grid/{class.js → grid.class.js} +0 -0
- /package/components/heatmap/{class.js → heatmap.class.js} +0 -0
- /package/components/icon/{class.js → icon.class.js} +0 -0
- /package/components/image/{class.js → image.class.js} +0 -0
- /package/components/input/{class.js → input.class.js} +0 -0
- /package/components/inspector/{class.js → inspector.class.js} +0 -0
- /package/components/kbd/{class.js → kbd.class.js} +0 -0
- /package/components/link/{class.js → link.class.js} +0 -0
- /package/components/list/{class.js → list.class.js} +0 -0
- /package/components/menu/{class.js → menu.class.js} +0 -0
- /package/components/nav/{class.js → nav.class.js} +0 -0
- /package/components/nav-group/{class.js → nav-group.class.js} +0 -0
- /package/components/nav-item/{class.js → nav-item.class.js} +0 -0
- /package/components/noodles/{class.js → noodles.class.js} +0 -0
- /package/components/option-card/{class.js → option-card.class.js} +0 -0
- /package/components/otp-input/{class.js → otp-input.class.js} +0 -0
- /package/components/page/{class.js → page.class.js} +0 -0
- /package/components/pagination/{class.js → pagination.class.js} +0 -0
- /package/components/pane/{class.js → pane.class.js} +0 -0
- /package/components/pipeline-status/{class.js → pipeline-status.class.js} +0 -0
- /package/components/popover/{class.js → popover.class.js} +0 -0
- /package/components/progress/{class.js → progress.class.js} +0 -0
- /package/components/progress-row/{class.js → progress-row.class.js} +0 -0
- /package/components/radio/{class.js → radio.class.js} +0 -0
- /package/components/range/{class.js → range.class.js} +0 -0
- /package/components/rating/{class.js → rating.class.js} +0 -0
- /package/components/richtext/{class.js → richtext.class.js} +0 -0
- /package/components/row/{class.js → row.class.js} +0 -0
- /package/components/search/{class.js → search.class.js} +0 -0
- /package/components/segment/{class.js → segment.class.js} +0 -0
- /package/components/segmented/{class.js → segmented.class.js} +0 -0
- /package/components/skeleton/{class.js → skeleton.class.js} +0 -0
- /package/components/slider/{class.js → slider.class.js} +0 -0
- /package/components/stack/{class.js → stack.class.js} +0 -0
- /package/components/step-progress/{class.js → step-progress.class.js} +0 -0
- /package/components/stepper/{class.js → stepper.class.js} +0 -0
- /package/components/stream/{class.js → stream.class.js} +0 -0
- /package/components/swatch/{class.js → swatch.class.js} +0 -0
- /package/components/swiper/{class.js → swiper.class.js} +0 -0
- /package/components/switch/{class.js → switch.class.js} +0 -0
- /package/components/table/{class.js → table.class.js} +0 -0
- /package/components/tabs/{class.js → tabs.class.js} +0 -0
- /package/components/tag/{class.js → tag.class.js} +0 -0
- /package/components/text/{class.js → text.class.js} +0 -0
- /package/components/textarea/{class.js → textarea.class.js} +0 -0
- /package/components/toast/{class.js → toast.class.js} +0 -0
- /package/components/toggle-group/{class.js → toggle-group.class.js} +0 -0
- /package/components/toggle-scheme/{class.js → toggle-scheme.class.js} +0 -0
- /package/components/toolbar/{class.js → toolbar.class.js} +0 -0
- /package/components/tooltip/{class.js → tooltip.class.js} +0 -0
- /package/components/tree/{class.js → tree.class.js} +0 -0
- /package/components/upload/{class.js → upload.class.js} +0 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
@scope (time-picker-ui) {
|
|
2
|
+
:where(:scope) {
|
|
3
|
+
/* ── Tokens ── */
|
|
4
|
+
--time-picker-bg-default: var(--a-ui-bg);
|
|
5
|
+
--time-picker-fg-default: var(--a-ui-text);
|
|
6
|
+
--time-picker-fg-muted-default: var(--a-ui-text-placeholder);
|
|
7
|
+
--time-picker-border-default: var(--a-ui-border);
|
|
8
|
+
--time-picker-border-hover-default: var(--a-ui-border-hover);
|
|
9
|
+
--time-picker-radius-default: var(--a-radius);
|
|
10
|
+
--time-picker-height-default: var(--a-size);
|
|
11
|
+
--time-picker-px-default: var(--a-ui-px);
|
|
12
|
+
--time-picker-py-default: 0;
|
|
13
|
+
--time-picker-gap-default: var(--a-space-1);
|
|
14
|
+
--time-picker-font-size-default: var(--a-ui-size);
|
|
15
|
+
|
|
16
|
+
--time-picker-segment-radius-default: var(--a-radius-sm);
|
|
17
|
+
--time-picker-segment-px-default: var(--a-space-1);
|
|
18
|
+
--time-picker-segment-bg-focus-default: var(--a-accent);
|
|
19
|
+
--time-picker-segment-fg-focus-default: var(--a-accent-fg);
|
|
20
|
+
|
|
21
|
+
--time-picker-separator-fg-default: var(--a-fg-muted);
|
|
22
|
+
|
|
23
|
+
--time-picker-focus-ring-default: var(--a-focus-ring);
|
|
24
|
+
--time-picker-focus-ring-invalid-default: var(--a-focus-ring-invalid);
|
|
25
|
+
|
|
26
|
+
--time-picker-duration-default: var(--a-duration-fast);
|
|
27
|
+
--time-picker-easing-default: var(--a-easing);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
:scope {
|
|
31
|
+
/* ── Base ── */
|
|
32
|
+
box-sizing: border-box;
|
|
33
|
+
display: inline-flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
gap: var(--time-picker-gap, var(--time-picker-gap-default));
|
|
36
|
+
min-height: var(--time-picker-height, var(--time-picker-height-default));
|
|
37
|
+
padding: var(--time-picker-py, var(--time-picker-py-default)) var(--time-picker-px, var(--time-picker-px-default));
|
|
38
|
+
background: var(--time-picker-bg, var(--time-picker-bg-default));
|
|
39
|
+
color: var(--time-picker-fg, var(--time-picker-fg-default));
|
|
40
|
+
border: 1px solid var(--time-picker-border, var(--time-picker-border-default));
|
|
41
|
+
border-radius: var(--time-picker-radius, var(--time-picker-radius-default));
|
|
42
|
+
font-family: inherit;
|
|
43
|
+
font-size: var(--time-picker-font-size, var(--time-picker-font-size-default));
|
|
44
|
+
font-variant-numeric: tabular-nums;
|
|
45
|
+
line-height: 1.4;
|
|
46
|
+
cursor: text;
|
|
47
|
+
transition:
|
|
48
|
+
border-color var(--time-picker-duration, var(--time-picker-duration-default)) var(--time-picker-easing, var(--time-picker-easing-default)),
|
|
49
|
+
background var(--time-picker-duration, var(--time-picker-duration-default)) var(--time-picker-easing, var(--time-picker-easing-default)),
|
|
50
|
+
box-shadow var(--time-picker-duration, var(--time-picker-duration-default)) var(--time-picker-easing, var(--time-picker-easing-default));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* ── Segments ── */
|
|
54
|
+
:scope [data-segment] {
|
|
55
|
+
display: inline-block;
|
|
56
|
+
min-width: 2ch;
|
|
57
|
+
padding: 0 var(--time-picker-segment-px, var(--time-picker-segment-px-default));
|
|
58
|
+
text-align: center;
|
|
59
|
+
border-radius: var(--time-picker-segment-radius, var(--time-picker-segment-radius-default));
|
|
60
|
+
color: inherit;
|
|
61
|
+
background: transparent;
|
|
62
|
+
outline: none;
|
|
63
|
+
caret-color: transparent;
|
|
64
|
+
cursor: text;
|
|
65
|
+
transition:
|
|
66
|
+
background var(--time-picker-duration, var(--time-picker-duration-default)) var(--time-picker-easing, var(--time-picker-easing-default)),
|
|
67
|
+
color var(--time-picker-duration, var(--time-picker-duration-default)) var(--time-picker-easing, var(--time-picker-easing-default));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* Meridiem is a touch wider since it carries two letters (AM/PM). */
|
|
71
|
+
:scope [data-segment="meridiem"] {
|
|
72
|
+
min-width: 2.5ch;
|
|
73
|
+
text-transform: uppercase;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* ── State: empty (placeholder via :empty) ── */
|
|
77
|
+
:scope [data-segment]:empty::before {
|
|
78
|
+
content: '--';
|
|
79
|
+
color: var(--time-picker-fg-muted, var(--time-picker-fg-muted-default));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* ── State: focused segment ── */
|
|
83
|
+
:scope [data-segment]:focus,
|
|
84
|
+
:scope [data-segment]:focus-visible {
|
|
85
|
+
background: var(--time-picker-segment-bg-focus, var(--time-picker-segment-bg-focus-default));
|
|
86
|
+
color: var(--time-picker-segment-fg-focus, var(--time-picker-segment-fg-focus-default));
|
|
87
|
+
outline: none;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* ── Separator ── */
|
|
91
|
+
:scope [data-separator] {
|
|
92
|
+
color: var(--time-picker-separator-fg, var(--time-picker-separator-fg-default));
|
|
93
|
+
pointer-events: none;
|
|
94
|
+
user-select: none;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* hover rules — outside @scope (matches input-ui's Safari 17.x workaround). */
|
|
99
|
+
time-picker-ui:not([disabled]):hover {
|
|
100
|
+
border-color: var(--time-picker-border-hover, var(--time-picker-border-hover-default));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Focus ring on the host when any segment is focused.
|
|
104
|
+
Canonical L3 ring; consumed via --time-picker-focus-ring (aliases --a-focus-ring). */
|
|
105
|
+
time-picker-ui:not([disabled]):focus-within {
|
|
106
|
+
box-shadow: var(--time-picker-focus-ring, var(--time-picker-focus-ring-default));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
time-picker-ui[aria-invalid="true"]:not([disabled]):focus-within,
|
|
110
|
+
time-picker-ui[error]:not([disabled]):focus-within {
|
|
111
|
+
box-shadow: var(--time-picker-focus-ring-invalid, var(--time-picker-focus-ring-invalid-default));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* Disabled / readonly affordance */
|
|
115
|
+
time-picker-ui[disabled] {
|
|
116
|
+
opacity: var(--a-opacity-disabled, 0.5);
|
|
117
|
+
pointer-events: none;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
time-picker-ui[readonly] [data-segment] {
|
|
121
|
+
cursor: default;
|
|
122
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<time-picker-ui>` — Time-of-day picker with discrete segments (hour, minute, optional second, optional AM/PM). Each segment follows the WAI-ARIA Spinbutton pattern with Arrow-key increment/decrement, Page Up/Down for larger jumps, Home/End for segment min/max, and Tab to move between segments. Form-associated input emitting ISO 8601 time string ("HH:mm" or "HH:mm:ss") via change events. Per ADR-0025 no native form controls — segments are contenteditable spans inside a custom host. SPEC-043.
|
|
3
|
+
*
|
|
4
|
+
* @see https://ui-kit.exe.xyz/site/components/time-picker
|
|
5
|
+
*
|
|
6
|
+
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
|
+
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
|
+
* regenerate; or hand-author this file fully if rich event types are
|
|
10
|
+
* needed beyond what the yaml `events:` block can express.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { UIElement } from '../../core/element.js';
|
|
14
|
+
|
|
15
|
+
export interface TimePickerChangeEventDetail {
|
|
16
|
+
/** Which segment commit fired the event (`hour` | `minute` | `second` | `meridiem`). */
|
|
17
|
+
segment: string;
|
|
18
|
+
/** Current value as ISO 8601 ("HH:mm" or "HH:mm:ss"). */
|
|
19
|
+
value: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type TimePickerChangeEvent = CustomEvent<TimePickerChangeEventDetail>;
|
|
23
|
+
export interface TimePickerInputEventDetail {
|
|
24
|
+
/** In-flight value as ISO 8601. */
|
|
25
|
+
value: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type TimePickerInputEvent = CustomEvent<TimePickerInputEventDetail>;
|
|
29
|
+
export interface TimePickerInvalidEventDetail {
|
|
30
|
+
/** Why it failed (`min` | `max` | `parse`). */
|
|
31
|
+
reason: 'min' | 'max' | 'parse';
|
|
32
|
+
/** Value that failed validation. */
|
|
33
|
+
value: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type TimePickerInvalidEvent = CustomEvent<TimePickerInvalidEventDetail>;
|
|
37
|
+
|
|
38
|
+
export class UITimePicker extends UIElement {
|
|
39
|
+
/** Marks the field as required for form validation. Sets aria-required. */
|
|
40
|
+
required: boolean;
|
|
41
|
+
/** Disables interaction; dims the control */
|
|
42
|
+
disabled: boolean;
|
|
43
|
+
/** Hour cycle. Empty (default) derives from the document locale — most
|
|
44
|
+
en-* locales resolve to `h23`. `h12` forces a 12-hour cycle with an
|
|
45
|
+
AM/PM (meridiem) segment; `h23` forces 24-hour cycle.
|
|
46
|
+
*/
|
|
47
|
+
hourcycle: '' | 'h12' | 'h23';
|
|
48
|
+
/** BCP-47 locale tag used to derive hour-cycle when `hour-cycle` is empty. Falls back to `<html lang>` then to browser default. */
|
|
49
|
+
locale: string;
|
|
50
|
+
/** Latest selectable time as ISO 8601. Empty disables the constraint. */
|
|
51
|
+
max: string;
|
|
52
|
+
/** Earliest selectable time as ISO 8601. Empty disables the constraint. */
|
|
53
|
+
min: string;
|
|
54
|
+
/** Form field name for FormData submission */
|
|
55
|
+
name: string;
|
|
56
|
+
/** Per-segment placeholder text shown when a segment is empty. Defaults to "--". */
|
|
57
|
+
placeholder: string;
|
|
58
|
+
/** Whether the seconds segment is exposed. `minute` (default) hides seconds; `second` adds the seconds segment + separator. */
|
|
59
|
+
precision: 'minute' | 'second';
|
|
60
|
+
/** Prevents editing while keeping the field focusable. Segments stay focusable for inspection. */
|
|
61
|
+
readonly: boolean;
|
|
62
|
+
/** Per-Arrow-keypress increment in seconds. 60 = minute precision (default), 900 = 15-minute, 1 = second precision. */
|
|
63
|
+
step: number;
|
|
64
|
+
/** Current time value as ISO 8601 ("HH:mm" or "HH:mm:ss"). Empty when no value selected. */
|
|
65
|
+
value: string;
|
|
66
|
+
|
|
67
|
+
addEventListener<K extends keyof HTMLElementEventMap>(
|
|
68
|
+
type: K,
|
|
69
|
+
listener: (this: UITimePicker, ev: HTMLElementEventMap[K]) => unknown,
|
|
70
|
+
options?: boolean | AddEventListenerOptions,
|
|
71
|
+
): void;
|
|
72
|
+
addEventListener(type: 'change', listener: (ev: TimePickerChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
73
|
+
addEventListener(type: 'input', listener: (ev: TimePickerInputEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
74
|
+
addEventListener(type: 'invalid', listener: (ev: TimePickerInvalidEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
75
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# time-picker — Examples
|
|
2
|
+
|
|
3
|
+
## Default
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<time-picker-ui></time-picker-ui>
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## value
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<field-ui label="Start time">
|
|
13
|
+
<time-picker-ui value="09:30"></time-picker-ui>
|
|
14
|
+
</field-ui>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 15-minute step
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<field-ui label="Meeting">
|
|
21
|
+
<time-picker-ui value="09:30" step="900"></time-picker-ui>
|
|
22
|
+
</field-ui>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Second precision
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<time-picker-ui precision="second" step="1" value="14:30:45"></time-picker-ui>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 12-hour cycle
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<time-picker-ui hour-cycle="h12" value="07:00"></time-picker-ui>
|
|
35
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<time-picker-ui>` — auto-registers the tag on import.
|
|
3
|
+
*
|
|
4
|
+
* For non-side-effect class import (test isolation, tag override), use
|
|
5
|
+
* the `class` subpath:
|
|
6
|
+
*
|
|
7
|
+
* import { UITimePicker } from '@adia-ai/web-components/components/time-picker/class';
|
|
8
|
+
*
|
|
9
|
+
* @see ../../USAGE.md#registration--auto-vs-explicit
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { defineIfFree } from '../../core/register.js';
|
|
13
|
+
import { UITimePicker } from './time-picker.class.js';
|
|
14
|
+
|
|
15
|
+
defineIfFree('time-picker-ui', UITimePicker);
|
|
16
|
+
|
|
17
|
+
export { UITimePicker };
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* time-picker-ui — SPEC-043
|
|
3
|
+
*
|
|
4
|
+
* Coverage:
|
|
5
|
+
* - Stamp shape (precision × hour-cycle)
|
|
6
|
+
* - Segment text sync from value
|
|
7
|
+
* - Arrow Up / Down increments
|
|
8
|
+
* - Page Up / Down + Home / End
|
|
9
|
+
* - Tab equivalents (ArrowLeft / ArrowRight)
|
|
10
|
+
* - Digit typing + auto-advance
|
|
11
|
+
* - Form participation (name + ISO value)
|
|
12
|
+
* - min / max → invalid event
|
|
13
|
+
* - disabled / readonly behavior
|
|
14
|
+
* - precision toggle re-stamps without losing hh/mm
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
18
|
+
import '../../core/element.js';
|
|
19
|
+
import './time-picker.js';
|
|
20
|
+
|
|
21
|
+
const tick = () => new Promise((r) => queueMicrotask(r));
|
|
22
|
+
|
|
23
|
+
function mount(html) {
|
|
24
|
+
const wrap = document.createElement('div');
|
|
25
|
+
wrap.innerHTML = html;
|
|
26
|
+
document.body.appendChild(wrap);
|
|
27
|
+
return wrap.firstElementChild;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function segText(el, key) {
|
|
31
|
+
return el.querySelector(`[data-segment="${key}"]`)?.textContent || '';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function fireKey(el, key) {
|
|
35
|
+
el.dispatchEvent(new KeyboardEvent('keydown', { key, bubbles: true }));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
describe('time-picker-ui', () => {
|
|
39
|
+
beforeEach(() => { document.body.innerHTML = ''; });
|
|
40
|
+
|
|
41
|
+
it('renders with empty segments when no value is set', async () => {
|
|
42
|
+
const el = mount('<time-picker-ui></time-picker-ui>');
|
|
43
|
+
await tick();
|
|
44
|
+
expect(el.querySelector('[data-segment="hour"]')).not.toBeNull();
|
|
45
|
+
expect(el.querySelector('[data-segment="minute"]')).not.toBeNull();
|
|
46
|
+
expect(segText(el, 'hour')).toBe('');
|
|
47
|
+
expect(segText(el, 'minute')).toBe('');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('populates hour/minute segments from value="09:30"', async () => {
|
|
51
|
+
const el = mount('<time-picker-ui value="09:30"></time-picker-ui>');
|
|
52
|
+
await tick();
|
|
53
|
+
expect(segText(el, 'hour')).toBe('09');
|
|
54
|
+
expect(segText(el, 'minute')).toBe('30');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('precision="second" stamps a seconds segment + separator', async () => {
|
|
58
|
+
const el = mount('<time-picker-ui precision="second" value="14:30:45"></time-picker-ui>');
|
|
59
|
+
await tick();
|
|
60
|
+
expect(el.querySelector('[data-segment="second"]')).not.toBeNull();
|
|
61
|
+
expect(segText(el, 'second')).toBe('45');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('hour-cycle="h12" stamps a meridiem segment + 12h display', async () => {
|
|
65
|
+
const el = mount('<time-picker-ui hour-cycle="h12" value="14:30"></time-picker-ui>');
|
|
66
|
+
await tick();
|
|
67
|
+
const meridiem = el.querySelector('[data-segment="meridiem"]');
|
|
68
|
+
expect(meridiem).not.toBeNull();
|
|
69
|
+
expect(segText(el, 'hour')).toBe('02');
|
|
70
|
+
expect(segText(el, 'meridiem')).toBe('PM');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('hour-cycle="h12" displays midnight as 12 AM', async () => {
|
|
74
|
+
const el = mount('<time-picker-ui hour-cycle="h12" value="00:15"></time-picker-ui>');
|
|
75
|
+
await tick();
|
|
76
|
+
expect(segText(el, 'hour')).toBe('12');
|
|
77
|
+
expect(segText(el, 'meridiem')).toBe('AM');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('Arrow Up on hour segment increments by 1', async () => {
|
|
81
|
+
const el = mount('<time-picker-ui value="09:30"></time-picker-ui>');
|
|
82
|
+
await tick();
|
|
83
|
+
const hour = el.querySelector('[data-segment="hour"]');
|
|
84
|
+
hour.focus();
|
|
85
|
+
fireKey(hour, 'ArrowUp');
|
|
86
|
+
await tick();
|
|
87
|
+
expect(el.value).toBe('10:30');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('Arrow Down on minute segment decrements by step/60 minutes', async () => {
|
|
91
|
+
const el = mount('<time-picker-ui value="09:30" step="60"></time-picker-ui>');
|
|
92
|
+
await tick();
|
|
93
|
+
const min = el.querySelector('[data-segment="minute"]');
|
|
94
|
+
min.focus();
|
|
95
|
+
fireKey(min, 'ArrowDown');
|
|
96
|
+
await tick();
|
|
97
|
+
expect(el.value).toBe('09:29');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('step="900" increments minute by 15 on Arrow Up', async () => {
|
|
101
|
+
const el = mount('<time-picker-ui value="09:30" step="900"></time-picker-ui>');
|
|
102
|
+
await tick();
|
|
103
|
+
const min = el.querySelector('[data-segment="minute"]');
|
|
104
|
+
min.focus();
|
|
105
|
+
fireKey(min, 'ArrowUp');
|
|
106
|
+
await tick();
|
|
107
|
+
expect(el.value).toBe('09:45');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('Page Up increments by 10× the small step', async () => {
|
|
111
|
+
const el = mount('<time-picker-ui value="09:00"></time-picker-ui>');
|
|
112
|
+
await tick();
|
|
113
|
+
const min = el.querySelector('[data-segment="minute"]');
|
|
114
|
+
min.focus();
|
|
115
|
+
fireKey(min, 'PageUp');
|
|
116
|
+
await tick();
|
|
117
|
+
expect(el.value).toBe('09:10');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('Home jumps to segment min; End jumps to segment max', async () => {
|
|
121
|
+
const el = mount('<time-picker-ui value="09:30"></time-picker-ui>');
|
|
122
|
+
await tick();
|
|
123
|
+
const hour = el.querySelector('[data-segment="hour"]');
|
|
124
|
+
hour.focus();
|
|
125
|
+
fireKey(hour, 'Home');
|
|
126
|
+
await tick();
|
|
127
|
+
expect(el.value).toBe('00:30');
|
|
128
|
+
fireKey(hour, 'End');
|
|
129
|
+
await tick();
|
|
130
|
+
expect(el.value).toBe('23:30');
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('ArrowRight moves focus to next segment; ArrowLeft to previous', async () => {
|
|
134
|
+
const el = mount('<time-picker-ui value="09:30"></time-picker-ui>');
|
|
135
|
+
await tick();
|
|
136
|
+
const hour = el.querySelector('[data-segment="hour"]');
|
|
137
|
+
const minute = el.querySelector('[data-segment="minute"]');
|
|
138
|
+
hour.focus();
|
|
139
|
+
fireKey(hour, 'ArrowRight');
|
|
140
|
+
await tick();
|
|
141
|
+
expect(document.activeElement).toBe(minute);
|
|
142
|
+
fireKey(minute, 'ArrowLeft');
|
|
143
|
+
await tick();
|
|
144
|
+
expect(document.activeElement).toBe(hour);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('disabled prop blocks Arrow-key step', async () => {
|
|
148
|
+
const el = mount('<time-picker-ui value="09:30" disabled></time-picker-ui>');
|
|
149
|
+
await tick();
|
|
150
|
+
const hour = el.querySelector('[data-segment="hour"]');
|
|
151
|
+
fireKey(hour, 'ArrowUp');
|
|
152
|
+
await tick();
|
|
153
|
+
expect(el.value).toBe('09:30');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('readonly prop blocks edits but keeps segments focusable', async () => {
|
|
157
|
+
const el = mount('<time-picker-ui value="09:30" readonly></time-picker-ui>');
|
|
158
|
+
await tick();
|
|
159
|
+
const hour = el.querySelector('[data-segment="hour"]');
|
|
160
|
+
expect(hour.getAttribute('tabindex')).toBe('0');
|
|
161
|
+
expect(hour.contentEditable).toBe('false');
|
|
162
|
+
hour.focus();
|
|
163
|
+
fireKey(hour, 'ArrowUp');
|
|
164
|
+
await tick();
|
|
165
|
+
expect(el.value).toBe('09:30');
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('min violation fires invalid + does not mutate value', async () => {
|
|
169
|
+
const el = mount('<time-picker-ui value="08:00" min="08:00" max="18:00"></time-picker-ui>');
|
|
170
|
+
await tick();
|
|
171
|
+
let captured = null;
|
|
172
|
+
el.addEventListener('invalid', (e) => { captured = e; });
|
|
173
|
+
const hour = el.querySelector('[data-segment="hour"]');
|
|
174
|
+
hour.focus();
|
|
175
|
+
fireKey(hour, 'ArrowDown');
|
|
176
|
+
await tick();
|
|
177
|
+
expect(captured).not.toBeNull();
|
|
178
|
+
expect(captured.detail.reason).toBe('min');
|
|
179
|
+
expect(el.value).toBe('08:00');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('max violation fires invalid', async () => {
|
|
183
|
+
const el = mount('<time-picker-ui value="18:00" min="08:00" max="18:00"></time-picker-ui>');
|
|
184
|
+
await tick();
|
|
185
|
+
let captured = null;
|
|
186
|
+
el.addEventListener('invalid', (e) => { captured = e; });
|
|
187
|
+
const hour = el.querySelector('[data-segment="hour"]');
|
|
188
|
+
hour.focus();
|
|
189
|
+
fireKey(hour, 'ArrowUp');
|
|
190
|
+
await tick();
|
|
191
|
+
expect(captured).not.toBeNull();
|
|
192
|
+
expect(captured.detail.reason).toBe('max');
|
|
193
|
+
expect(el.value).toBe('18:00');
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('emits change with detail.segment on Arrow step', async () => {
|
|
197
|
+
const el = mount('<time-picker-ui value="09:30"></time-picker-ui>');
|
|
198
|
+
await tick();
|
|
199
|
+
let captured = null;
|
|
200
|
+
el.addEventListener('change', (e) => { captured = e; });
|
|
201
|
+
const hour = el.querySelector('[data-segment="hour"]');
|
|
202
|
+
hour.focus();
|
|
203
|
+
fireKey(hour, 'ArrowUp');
|
|
204
|
+
await tick();
|
|
205
|
+
expect(captured).not.toBeNull();
|
|
206
|
+
expect(captured.detail).toEqual({ value: '10:30', segment: 'hour' });
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('precision="minute" → "second" re-stamps without losing hh/mm', async () => {
|
|
210
|
+
const el = mount('<time-picker-ui value="09:30"></time-picker-ui>');
|
|
211
|
+
await tick();
|
|
212
|
+
expect(el.querySelector('[data-segment="second"]')).toBeNull();
|
|
213
|
+
el.precision = 'second';
|
|
214
|
+
await tick();
|
|
215
|
+
expect(el.querySelector('[data-segment="second"]')).not.toBeNull();
|
|
216
|
+
expect(segText(el, 'hour')).toBe('09');
|
|
217
|
+
expect(segText(el, 'minute')).toBe('30');
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('aria-valuemax matches segment max (h23 → 23 for hour)', async () => {
|
|
221
|
+
const el = mount('<time-picker-ui hour-cycle="h23"></time-picker-ui>');
|
|
222
|
+
await tick();
|
|
223
|
+
const hour = el.querySelector('[data-segment="hour"]');
|
|
224
|
+
expect(hour.getAttribute('aria-valuemax')).toBe('23');
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('aria-valuemax for hour is 12 in h12 cycle', async () => {
|
|
228
|
+
const el = mount('<time-picker-ui hour-cycle="h12"></time-picker-ui>');
|
|
229
|
+
await tick();
|
|
230
|
+
const hour = el.querySelector('[data-segment="hour"]');
|
|
231
|
+
expect(hour.getAttribute('aria-valuemax')).toBe('12');
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('aria-valuenow + aria-valuetext are populated from value', async () => {
|
|
235
|
+
const el = mount('<time-picker-ui value="09:30"></time-picker-ui>');
|
|
236
|
+
await tick();
|
|
237
|
+
const hour = el.querySelector('[data-segment="hour"]');
|
|
238
|
+
const minute = el.querySelector('[data-segment="minute"]');
|
|
239
|
+
expect(hour.getAttribute('aria-valuenow')).toBe('9');
|
|
240
|
+
expect(minute.getAttribute('aria-valuenow')).toBe('30');
|
|
241
|
+
expect(hour.getAttribute('aria-valuetext')).toContain('hour');
|
|
242
|
+
expect(minute.getAttribute('aria-valuetext')).toContain('minute');
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('host role="group" + aria-label default', async () => {
|
|
246
|
+
const el = mount('<time-picker-ui></time-picker-ui>');
|
|
247
|
+
await tick();
|
|
248
|
+
expect(el.getAttribute('role')).toBe('group');
|
|
249
|
+
expect(el.hasAttribute('aria-label')).toBe(true);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it('clear() resets value to empty', async () => {
|
|
253
|
+
const el = mount('<time-picker-ui value="09:30"></time-picker-ui>');
|
|
254
|
+
await tick();
|
|
255
|
+
el.clear();
|
|
256
|
+
await tick();
|
|
257
|
+
expect(el.value).toBe('');
|
|
258
|
+
expect(segText(el, 'hour')).toBe('');
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it('stepUp() increments programmatically', async () => {
|
|
262
|
+
const el = mount('<time-picker-ui value="09:30"></time-picker-ui>');
|
|
263
|
+
await tick();
|
|
264
|
+
el.stepUp('hour');
|
|
265
|
+
await tick();
|
|
266
|
+
expect(el.value).toBe('10:30');
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('value setter syncs segments', async () => {
|
|
270
|
+
const el = mount('<time-picker-ui value="09:30"></time-picker-ui>');
|
|
271
|
+
await tick();
|
|
272
|
+
el.value = '11:45';
|
|
273
|
+
await tick();
|
|
274
|
+
expect(segText(el, 'hour')).toBe('11');
|
|
275
|
+
expect(segText(el, 'minute')).toBe('45');
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it('focusing a segment sets [editing] + [segment="…"] on host', async () => {
|
|
279
|
+
const el = mount('<time-picker-ui value="09:30"></time-picker-ui>');
|
|
280
|
+
await tick();
|
|
281
|
+
const minute = el.querySelector('[data-segment="minute"]');
|
|
282
|
+
minute.focus();
|
|
283
|
+
await tick();
|
|
284
|
+
expect(el.hasAttribute('editing')).toBe(true);
|
|
285
|
+
expect(el.getAttribute('segment')).toBe('minute');
|
|
286
|
+
});
|
|
287
|
+
});
|