@adia-ai/web-components 0.8.40 → 0.8.42
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 +71 -3
- package/MIGRATION.md +1229 -16
- package/README.md +25 -30
- package/USAGE.md +30 -4
- package/bin/audit-template-children.mjs +556 -0
- package/components/accordion/accordion-item.a2ui.json +4 -0
- package/components/accordion/accordion-item.yaml +2 -0
- package/components/accordion/accordion.a2ui.json +4 -0
- package/components/accordion/accordion.yaml +2 -0
- package/components/action-list/action-item.a2ui.json +29 -2
- package/components/action-list/action-item.yaml +46 -3
- package/components/action-list/action-list.a2ui.json +6 -1
- package/components/action-list/action-list.class.js +114 -11
- package/components/action-list/action-list.css +43 -3
- package/components/action-list/action-list.d.ts +6 -2
- package/components/action-list/action-list.yaml +5 -0
- package/components/adia-mark/adia-mark.a2ui.json +1 -0
- package/components/adia-wordmark/adia-wordmark.a2ui.json +1 -0
- package/components/agent-artifact/agent-artifact.a2ui.json +1 -0
- package/components/agent-feedback-bar/agent-feedback-bar.a2ui.json +6 -5
- package/components/agent-feedback-bar/agent-feedback-bar.yaml +6 -2
- package/components/agent-questions/agent-questions.a2ui.json +1 -0
- package/components/agent-reasoning/agent-reasoning.a2ui.json +6 -5
- package/components/agent-reasoning/agent-reasoning.yaml +6 -2
- package/components/agent-suggestions/agent-suggestions.a2ui.json +11 -2
- package/components/agent-suggestions/agent-suggestions.class.js +2 -1
- package/components/agent-suggestions/agent-suggestions.d.ts +4 -4
- package/components/agent-suggestions/agent-suggestions.yaml +4 -2
- package/components/agent-trace/agent-trace.a2ui.json +6 -5
- package/components/agent-trace/agent-trace.yaml +6 -2
- package/components/alert/alert.a2ui.json +1 -0
- package/components/alert/alert.css +1 -1
- package/components/anchor-bar/anchor-bar.a2ui.json +1 -0
- package/components/aside/aside.a2ui.json +1 -0
- package/components/avatar/avatar-group.a2ui.json +7 -1
- package/components/avatar/avatar-group.yaml +1 -0
- package/components/avatar/avatar.a2ui.json +12 -11
- package/components/avatar/avatar.d.ts +1 -1
- package/components/avatar/avatar.yaml +4 -4
- package/components/badge/badge.a2ui.json +1 -0
- package/components/block/block.a2ui.json +1 -0
- package/components/blockquote/blockquote.a2ui.json +1 -0
- package/components/breadcrumb/breadcrumb.a2ui.json +1 -0
- package/components/button/button.a2ui.json +1 -3
- package/components/button/button.yaml +1 -3
- package/components/calendar-grid/calendar-grid.a2ui.json +1 -0
- package/components/calendar-grid/calendar-grid.class.js +2 -1
- package/components/calendar-picker/calendar-picker.a2ui.json +143 -24
- package/components/calendar-picker/calendar-picker.class.js +490 -197
- package/components/calendar-picker/calendar-picker.css +120 -171
- package/components/calendar-picker/calendar-picker.yaml +225 -47
- package/components/canvas/canvas.a2ui.json +6 -5
- package/components/canvas/canvas.d.ts +37 -0
- package/components/canvas/canvas.js +72 -3
- package/components/canvas/canvas.yaml +6 -2
- package/components/card/card.a2ui.json +25 -2
- package/components/card/card.class.js +3 -0
- package/components/card/card.css +31 -1
- package/components/card/card.d.ts +2 -2
- package/components/card/card.examples.md +3 -3
- package/components/card/card.yaml +28 -4
- package/components/chart/chart.a2ui.json +27 -7
- package/components/chart/chart.class.js +64 -22
- package/components/chart/chart.css +6 -4
- package/components/chart/chart.d.ts +10 -4
- package/components/chart/chart.yaml +40 -6
- package/components/chart-legend/chart-legend.a2ui.json +7 -1
- package/components/chart-legend/chart-legend.class.js +59 -6
- package/components/chart-legend/chart-legend.css +5 -2
- package/components/chart-legend/chart-legend.d.ts +3 -1
- package/components/chart-legend/chart-legend.yaml +15 -1
- package/components/chat-thread/chat-input.a2ui.json +1 -0
- package/components/chat-thread/chat-thread.a2ui.json +10 -9
- package/components/chat-thread/chat-thread.yaml +13 -20
- package/components/check/check.a2ui.json +10 -9
- package/components/check/check.yaml +4 -4
- package/components/code/code.a2ui.json +1 -0
- package/components/col/col.a2ui.json +1 -0
- package/components/color-area/color-area.a2ui.json +148 -0
- package/components/color-area/color-area.class.js +657 -0
- package/components/color-area/color-area.css +188 -0
- package/components/color-area/color-area.d.ts +66 -0
- package/components/color-area/color-area.examples.md +19 -0
- package/components/color-area/color-area.js +17 -0
- package/components/color-area/color-area.yaml +183 -0
- package/components/color-input/color-input.a2ui.json +6 -5
- package/components/color-input/color-input.class.js +9 -6
- package/components/color-input/color-input.css +1 -1
- package/components/color-input/color-input.js +2 -2
- package/components/color-input/color-input.yaml +14 -12
- package/components/color-picker/color-picker.a2ui.json +16 -12
- package/components/color-picker/color-picker.class.js +24 -633
- package/components/color-picker/color-picker.css +14 -182
- package/components/color-picker/color-picker.yaml +41 -41
- package/components/combobox/combobox.a2ui.json +3 -2
- package/components/combobox/combobox.yaml +2 -2
- package/components/command/command.a2ui.json +12 -10
- package/components/command/command.class.js +3 -2
- package/components/command/command.yaml +17 -4
- package/components/context-menu/context-menu.a2ui.json +1 -0
- package/components/date-range-picker/date-range-picker.a2ui.json +2 -1
- package/components/date-range-picker/date-range-picker.yaml +1 -1
- package/components/datetime-picker/datetime-picker.a2ui.json +15 -108
- package/components/datetime-picker/datetime-picker.class.js +37 -690
- package/components/datetime-picker/datetime-picker.css +11 -183
- package/components/datetime-picker/datetime-picker.d.ts +4 -5
- package/components/datetime-picker/datetime-picker.yaml +44 -135
- package/components/demo-toggle/demo-toggle.a2ui.json +1 -0
- package/components/demo-toggle/demo-toggle.css +1 -1
- package/components/description-list/description-list.a2ui.json +2 -1
- package/components/description-list/description-list.css +1 -1
- package/components/description-list/description-list.d.ts +1 -1
- package/components/description-list/description-list.yaml +1 -1
- package/components/display-field/display-field.a2ui.json +1 -0
- package/components/divider/divider.a2ui.json +1 -0
- package/components/drawer/drawer.a2ui.json +1 -3
- package/components/drawer/drawer.css +1 -1
- package/components/drawer/drawer.yaml +0 -2
- package/components/drilldown/drilldown.a2ui.json +22 -20
- package/components/drilldown/drilldown.class.js +4 -3
- package/components/drilldown/drilldown.css +6 -6
- package/components/drilldown/drilldown.yaml +40 -9
- package/components/embed/embed.a2ui.json +6 -5
- package/components/embed/embed.yaml +2 -2
- package/components/empty-state/empty-state.a2ui.json +1 -0
- package/components/feed/feed-item.a2ui.json +25 -5
- package/components/feed/feed-item.yaml +28 -7
- package/components/feed/feed.a2ui.json +9 -2
- package/components/feed/feed.class.js +19 -12
- package/components/feed/feed.css +8 -8
- package/components/feed/feed.yaml +14 -1
- package/components/field/field.a2ui.json +2 -1
- package/components/field/field.class.js +4 -1
- package/components/field/field.examples.md +1 -1
- package/components/field/field.yaml +1 -1
- package/components/fields/fields.a2ui.json +1 -0
- package/components/fields/fields.examples.md +1 -1
- package/components/footer/footer.a2ui.json +1 -0
- package/components/frame/frame.a2ui.json +1 -0
- package/components/grid/grid.a2ui.json +1 -0
- package/components/header/header.a2ui.json +3 -2
- package/components/header/header.yaml +3 -3
- package/components/heatmap/heatmap.a2ui.json +2 -1
- package/components/heatmap/heatmap.class.js +1 -1
- package/components/heatmap/heatmap.css +4 -4
- package/components/heatmap/heatmap.yaml +1 -1
- package/components/icon/icon.a2ui.json +1 -0
- package/components/image/image.a2ui.json +28 -14
- package/components/image/image.class.js +38 -23
- package/components/image/image.css +18 -8
- package/components/image/image.d.ts +2 -2
- package/components/image/image.examples.md +3 -3
- package/components/image/image.yaml +23 -7
- package/components/index.js +1 -0
- package/components/inline-edit/inline-edit.a2ui.json +1 -0
- package/components/inline-message/inline-message.a2ui.json +3 -1
- package/components/inline-message/inline-message.class.js +3 -1
- package/components/inline-message/inline-message.d.ts +2 -2
- package/components/inline-message/inline-message.yaml +2 -1
- package/components/input/input.a2ui.json +66 -16
- package/components/input/input.class.js +64 -7
- package/components/input/input.css +14 -14
- package/components/input/input.d.ts +9 -4
- package/components/input/input.yaml +83 -10
- package/components/inspector/inspector.a2ui.json +1 -0
- package/components/integration-card/integration-card.a2ui.json +1 -0
- package/components/integration-card/integration-card.examples.md +2 -1
- package/components/kbd/kbd.a2ui.json +1 -0
- package/components/link/link.a2ui.json +2 -1
- package/components/link/link.yaml +1 -1
- package/components/list/list-item.a2ui.json +9 -0
- package/components/list/list-item.yaml +12 -0
- package/components/list/list.a2ui.json +9 -3
- package/components/list/list.class.js +14 -1
- package/components/list/list.css +12 -1
- package/components/list/list.d.ts +7 -5
- package/components/list/list.yaml +16 -6
- package/components/list-window/list-window.a2ui.json +1 -0
- package/components/list-window/list-window.class.js +2 -1
- package/components/loading-overlay/loading-overlay.a2ui.json +1 -0
- package/components/mark/mark.a2ui.json +2 -1
- package/components/mark/mark.yaml +1 -1
- package/components/menu/menu-divider.a2ui.json +1 -0
- package/components/menu/menu-item.a2ui.json +11 -4
- package/components/menu/menu-item.yaml +30 -3
- package/components/menu/menu-label.a2ui.json +1 -0
- package/components/menu/menu.a2ui.json +3 -2
- package/components/menu/menu.class.js +36 -8
- package/components/menu/menu.d.ts +5 -3
- package/components/menu/menu.yaml +3 -3
- package/components/modal/modal.a2ui.json +1 -0
- package/components/nav/nav.a2ui.json +1 -0
- package/components/nav/nav.class.js +14 -3
- package/components/nav-group/nav-group.a2ui.json +1 -0
- package/components/nav-group/nav-group.class.js +3 -1
- package/components/nav-item/nav-item.a2ui.json +1 -0
- package/components/noodles/noodles.a2ui.json +1 -0
- package/components/noodles/noodles.class.js +5 -1
- package/components/number-format/number-format.a2ui.json +1 -0
- package/components/option-card/option-card.a2ui.json +1 -0
- package/components/otp-input/otp-input.a2ui.json +3 -2
- package/components/otp-input/otp-input.yaml +9 -2
- package/components/page/page.a2ui.json +13 -0
- package/components/page/page.d.ts +1 -1
- package/components/page/page.yaml +1 -0
- package/components/pagination/pagination.a2ui.json +1 -0
- package/components/pagination/pagination.class.js +3 -2
- package/components/pane/pane.a2ui.json +17 -1
- package/components/pane/pane.class.js +35 -6
- package/components/pane/pane.css +17 -12
- package/components/pane/pane.d.ts +10 -7
- package/components/pane/pane.yaml +18 -1
- package/components/password-strength/password-strength.a2ui.json +1 -0
- package/components/pipeline-status/pipeline-status.a2ui.json +1 -0
- package/components/popover/popover.a2ui.json +7 -6
- package/components/popover/popover.class.js +2 -2
- package/components/popover/popover.d.ts +2 -2
- package/components/popover/popover.yaml +4 -4
- package/components/preview/preview.a2ui.json +1 -0
- package/components/preview/preview.class.js +5 -1
- package/components/progress/progress.a2ui.json +47 -24
- package/components/progress/progress.class.js +66 -11
- package/components/progress/progress.css +44 -26
- package/components/progress/progress.d.ts +7 -5
- package/components/progress/progress.examples.md +2 -2
- package/components/progress/progress.yaml +235 -53
- package/components/progress-row/progress-row.a2ui.json +16 -12
- package/components/progress-row/progress-row.d.ts +2 -2
- package/components/progress-row/progress-row.examples.md +2 -14
- package/components/progress-row/progress-row.yaml +28 -36
- package/components/qr-code/qr-code.a2ui.json +3 -2
- package/components/qr-code/qr-code.class.js +4 -4
- package/components/qr-code/qr-code.css +1 -1
- package/components/qr-code/qr-code.yaml +5 -3
- package/components/radio/radio.a2ui.json +8 -7
- package/components/radio/radio.class.js +8 -0
- package/components/radio/radio.yaml +3 -3
- package/components/radio-group/radio-group.a2ui.json +5 -3
- package/components/radio-group/radio-group.class.js +11 -0
- package/components/radio-group/radio-group.yaml +7 -1
- package/components/range/range.a2ui.json +6 -0
- package/components/range/range.class.js +2 -2
- package/components/range/range.css +2 -2
- package/components/range/range.yaml +3 -0
- package/components/rating/rating.a2ui.json +1 -0
- package/components/relative-time/relative-time.a2ui.json +1 -0
- package/components/richtext/richtext.a2ui.json +2 -1
- package/components/richtext/richtext.yaml +1 -1
- package/components/row/row.a2ui.json +1 -0
- package/components/search/search.a2ui.json +1 -0
- package/components/search/search.class.js +4 -1
- package/components/section/section.a2ui.json +1 -0
- package/components/segment/segment.a2ui.json +21 -10
- package/components/segment/segment.css +15 -0
- package/components/segment/segment.d.ts +2 -1
- package/components/segment/segment.yaml +20 -13
- package/components/segmented/segmented.a2ui.json +36 -7
- package/components/segmented/segmented.class.js +113 -22
- package/components/segmented/segmented.css +3 -0
- package/components/segmented/segmented.d.ts +3 -1
- package/components/segmented/segmented.yaml +80 -8
- package/components/select/select.a2ui.json +18 -13
- package/components/select/select.class.js +61 -37
- package/components/select/select.css +15 -13
- package/components/select/select.yaml +18 -7
- package/components/skeleton/skeleton.a2ui.json +8 -7
- package/components/skeleton/skeleton.class.js +8 -7
- package/components/skeleton/skeleton.css +21 -6
- package/components/skeleton/skeleton.d.ts +2 -2
- package/components/skeleton/skeleton.examples.md +2 -2
- package/components/skeleton/skeleton.yaml +3 -2
- package/components/skip-nav/skip-nav.a2ui.json +1 -0
- package/components/slider/slider.a2ui.json +6 -0
- package/components/slider/slider.class.js +20 -3
- package/components/slider/slider.css +2 -2
- package/components/slider/slider.yaml +3 -0
- package/components/spinner/spinner.a2ui.json +1 -0
- package/components/stack/stack.a2ui.json +1 -0
- package/components/stat/stat.a2ui.json +1 -0
- package/components/stat/stat.js +2 -2
- package/components/step-progress/step-progress.a2ui.json +1 -0
- package/components/step-progress/step-progress.yaml +1 -1
- package/components/stepper/stepper-item.a2ui.json +7 -3
- package/components/stepper/stepper-item.yaml +15 -5
- package/components/stepper/stepper.a2ui.json +5 -1
- package/components/stepper/stepper.class.js +31 -16
- package/components/stepper/stepper.d.ts +1 -1
- package/components/stepper/stepper.yaml +4 -2
- package/components/stream/stream.a2ui.json +1 -0
- package/components/swatch/swatch.a2ui.json +1 -0
- package/components/swatch/swatch.yaml +1 -1
- package/components/swiper/swiper.a2ui.json +1 -0
- package/components/swiper/swiper.class.js +5 -1
- package/components/switch/switch.a2ui.json +12 -11
- package/components/switch/switch.css +1 -1
- package/components/switch/switch.yaml +6 -6
- package/components/table/table.a2ui.json +1 -0
- package/components/table/table.class.js +14 -12
- package/components/table/table.css +11 -9
- package/components/table-toolbar/table-toolbar.a2ui.json +1 -0
- package/components/table-toolbar/table-toolbar.class.js +53 -22
- package/components/table-toolbar/table-toolbar.css +1 -1
- package/components/tabs/tab.a2ui.json +9 -0
- package/components/tabs/tab.js +4 -0
- package/components/tabs/tab.yaml +15 -0
- package/components/tabs/tabs.a2ui.json +9 -4
- package/components/tabs/tabs.class.js +13 -1
- package/components/tabs/tabs.css +8 -0
- package/components/tabs/tabs.d.ts +2 -0
- package/components/tabs/tabs.yaml +9 -2
- package/components/tag/tag.a2ui.json +1 -0
- package/components/tags-input/tags-input.a2ui.json +22 -17
- package/components/tags-input/tags-input.class.js +13 -11
- package/components/tags-input/tags-input.css +10 -6
- package/components/tags-input/tags-input.d.ts +16 -7
- package/components/tags-input/tags-input.examples.md +2 -2
- package/components/tags-input/tags-input.yaml +25 -8
- package/components/text/text.a2ui.json +6 -5
- package/components/text/text.css +10 -5
- package/components/text/text.d.ts +2 -2
- package/components/text/text.yaml +9 -4
- package/components/textarea/textarea.a2ui.json +2 -1
- package/components/textarea/textarea.yaml +1 -1
- package/components/theme-provider/theme-provider.a2ui.json +2 -1
- package/components/theme-provider/theme-provider.d.ts +5 -3
- package/components/theme-provider/theme-provider.yaml +5 -3
- package/components/time-picker/time-picker.a2ui.json +1 -0
- package/components/time-picker/time-picker.class.js +4 -2
- package/components/timeline/timeline-item.a2ui.json +26 -3
- package/components/timeline/timeline-item.yaml +22 -7
- package/components/timeline/timeline.a2ui.json +4 -0
- package/components/timeline/timeline.class.js +29 -18
- package/components/timeline/timeline.d.ts +3 -3
- package/components/timeline/timeline.yaml +2 -0
- package/components/toast/toast.a2ui.json +10 -3
- package/components/toast/toast.yaml +20 -13
- package/components/toc/toc.a2ui.json +1 -0
- package/components/toggle-group/toggle-group.a2ui.json +7 -3
- package/components/toggle-group/toggle-group.class.js +40 -1
- package/components/toggle-group/toggle-group.css +6 -1
- package/components/toggle-group/toggle-group.d.ts +2 -2
- package/components/toggle-group/toggle-group.yaml +21 -12
- package/components/toggle-group/toggle-option.a2ui.json +7 -3
- package/components/toggle-group/toggle-option.yaml +13 -7
- package/components/toggle-scheme/toggle-scheme.a2ui.json +2 -1
- package/components/toggle-scheme/toggle-scheme.yaml +1 -1
- package/components/toolbar/toolbar-group.a2ui.json +1 -0
- package/components/toolbar/toolbar.a2ui.json +1 -0
- package/components/toolbar/toolbar.class.js +3 -0
- package/components/tooltip/tooltip.a2ui.json +1 -0
- package/components/tour/tour-step.a2ui.json +4 -0
- package/components/tour/tour-step.yaml +2 -0
- package/components/tour/tour.a2ui.json +4 -0
- package/components/tour/tour.yaml +2 -0
- package/components/tree/tree-item.a2ui.json +5 -0
- package/components/tree/tree-item.yaml +3 -0
- package/components/tree/tree.a2ui.json +4 -0
- package/components/tree/tree.class.js +2 -1
- package/components/tree/tree.yaml +2 -0
- package/components/upload/upload.a2ui.json +8 -1
- package/components/upload/upload.class.js +35 -5
- package/components/upload/upload.css +28 -0
- package/components/upload/upload.d.ts +16 -0
- package/components/upload/upload.yaml +27 -7
- package/components/visually-hidden/visually-hidden.a2ui.json +1 -0
- package/core/dom.d.ts +11 -0
- package/core/dom.js +34 -0
- package/core/form.js +7 -0
- package/core/icons.js +5 -0
- package/core/index.d.ts +1 -0
- package/core/index.js +1 -0
- package/core/responsive.js +16 -4
- package/core/template.js +2 -1
- package/custom-elements.json +710 -587
- package/dist/host.min.css +1 -1
- package/dist/host.sheet.js +1 -1
- package/dist/theme-provider.min.js +5 -5
- package/dist/web-components.min.css +1 -1
- package/dist/web-components.min.js +92 -105
- package/dist/web-components.sheet.js +1 -1
- package/index.d.ts +12 -1
- package/package.json +4 -2
- package/patterns/admin-shell/admin-shell.examples.html +2 -2
- package/patterns/conversion-funnel/conversion-funnel.examples.html +15 -15
- package/patterns/form-system/form-system.examples.html +1 -1
- package/patterns/inline-dialog/inline-dialog.examples.html +2 -2
- package/patterns/inline-dialog/inline-dialog.html +4 -0
- package/patterns/timezone-selector/timezone-selector.examples.html +1 -1
- package/patterns/timezone-selector/timezone-selector.html +2 -2
- package/styles/api/text.css +7 -0
- package/styles/components.css +1 -0
- package/traits/_catalog.json +129 -41
- package/traits/anchor-positioning/anchor-positioning.js +1 -0
- package/traits/announcer/announcer.js +1 -0
- package/traits/arrow-grid-nav/arrow-grid-nav.js +1 -0
- package/traits/attention-pulse/attention-pulse.js +1 -0
- package/traits/count-up/count-up.js +1 -0
- package/traits/define.js +78 -0
- package/traits/focus-restore/focus-restore.js +2 -1
- package/traits/haptic-feedback/haptic-feedback.js +1 -0
- package/traits/input-mask/input-mask.js +1 -0
- package/traits/intersection-observer/intersection-observer.js +1 -0
- package/traits/layout-animation/layout-animation.js +1 -0
- package/traits/noise-texture/noise-texture.js +1 -0
- package/traits/resize-observer/resize-observer.js +1 -0
- package/traits/scroll-progress/scroll-progress.js +1 -0
- package/traits/snap-to-grid/snap-to-grid.js +1 -0
- package/traits/sound-feedback/sound-feedback.js +1 -0
- package/traits/spring-animate/spring-animate.js +1 -0
- package/traits/validation/validation.js +1 -0
|
@@ -28,7 +28,9 @@
|
|
|
28
28
|
* When `selectable`:
|
|
29
29
|
* - Children (role="listitem") become keyboard-focusable via roving tabindex.
|
|
30
30
|
* - Click selects the child; key is its id or data-key.
|
|
31
|
-
* - aria-selected
|
|
31
|
+
* - [selected] (ADR-0056, #1363 B7) and aria-selected are both set on
|
|
32
|
+
* all children — [selected] is the declared API state, aria-selected
|
|
33
|
+
* is wiring.
|
|
32
34
|
* - Fires `selection-change` with { key, previousKey }.
|
|
33
35
|
*/
|
|
34
36
|
|
|
@@ -73,6 +75,7 @@ export class UIList extends UIElement {
|
|
|
73
75
|
// (patient-visit rail's roving tabindex, gh#746).
|
|
74
76
|
if (this.#stampedSelection) {
|
|
75
77
|
for (const ch of this.#items()) {
|
|
78
|
+
ch.removeAttribute('selected');
|
|
76
79
|
ch.removeAttribute('aria-selected');
|
|
77
80
|
ch.removeAttribute('tabindex');
|
|
78
81
|
}
|
|
@@ -87,6 +90,11 @@ export class UIList extends UIElement {
|
|
|
87
90
|
for (const ch of items) {
|
|
88
91
|
const k = this.#keyOf(ch);
|
|
89
92
|
const selected = k && k === key;
|
|
93
|
+
// [selected] (ADR-0056, #1363 B7) is the declared, reflected API
|
|
94
|
+
// surface — parent-managed, mirrors <segment-ui>. aria-selected
|
|
95
|
+
// stays as-is: ARIA is wiring, not API.
|
|
96
|
+
if (selected) ch.setAttribute('selected', '');
|
|
97
|
+
else ch.removeAttribute('selected');
|
|
90
98
|
ch.setAttribute('aria-selected', selected ? 'true' : 'false');
|
|
91
99
|
ch.setAttribute('tabindex', selected ? '0' : '-1');
|
|
92
100
|
if (selected) focusTarget = ch;
|
|
@@ -173,6 +181,11 @@ export class UIListItem extends UIElement {
|
|
|
173
181
|
icon: { type: String, default: '', reflect: true },
|
|
174
182
|
text: { type: String, default: '', reflect: true },
|
|
175
183
|
description: { type: String, default: '', reflect: true },
|
|
184
|
+
// ADR-0056 (gh#1303, #1363 B7): declared reflected selection-item
|
|
185
|
+
// state, parent-managed — <list-ui>[selectable] stamps this instead
|
|
186
|
+
// of leaving selection visible only via aria-selected. Mirrors
|
|
187
|
+
// <segment-ui>'s [selected].
|
|
188
|
+
selected: { type: Boolean, default: false, reflect: true },
|
|
176
189
|
};
|
|
177
190
|
|
|
178
191
|
static template = () => null;
|
package/components/list/list.css
CHANGED
|
@@ -67,7 +67,18 @@
|
|
|
67
67
|
background: var(--a-bg-hover);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
/* [selected] is the declared, reflected state hook (ADR-0056, #1363 B7)
|
|
71
|
+
— list.class.js stamps it in lockstep with aria-selected; ARIA stays
|
|
72
|
+
wiring, not the style hook. Matched on the tag directly (not only
|
|
73
|
+
[role="listitem"]): UIList's adopt-or-stamp (gh#753) lets a
|
|
74
|
+
consumer-authored role (e.g. role="button") survive on <list-item-ui>
|
|
75
|
+
— #items() still selects/stamps it by TAG, so the style hook must
|
|
76
|
+
too, or a role-overridden selected row silently loses its selected
|
|
77
|
+
colors. The role fallback stays for non-list-item-ui children that
|
|
78
|
+
opt into role="listitem" themselves (list-ui also hosts "arbitrary
|
|
79
|
+
children", list.yaml). */
|
|
80
|
+
:scope[selectable] > list-item-ui[selected],
|
|
81
|
+
:scope[selectable] > [role="listitem"][selected] {
|
|
71
82
|
background: var(--list-bg-selected);
|
|
72
83
|
color: var(--list-fg-selected);
|
|
73
84
|
border-inline-start-color: var(--list-border-selected);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `<list-ui>` — Styled flat list with optional row dividers and icons — each row
|
|
3
3
|
is a <list-item-ui> child. Selectable mode via [selectable] +
|
|
4
|
-
[selectedKey] / `
|
|
5
|
-
glyphs. Distinct from <nav-ui> (sidebar navigation, route-aware),
|
|
4
|
+
[selectedKey] / `selection-change` event. Composes <icon-ui> for row
|
|
5
|
+
leading glyphs. Distinct from <nav-ui> (sidebar navigation, route-aware),
|
|
6
6
|
<tree-ui> (hierarchical with arbitrary nesting), and <table-ui>
|
|
7
7
|
(tabular data with columns). Use list-ui for non-navigable,
|
|
8
8
|
non-tabular vertical rows — comment lists, file lists, message
|
|
@@ -41,10 +41,10 @@ so content sits at the list-ui edges (canonical edge-to-edge style).
|
|
|
41
41
|
divider: boolean;
|
|
42
42
|
/** Enable selection on child listitems (roving tabindex + aria-selected). */
|
|
43
43
|
selectable: boolean;
|
|
44
|
-
/** ID (or data-key) of the currently-selected child listitem. */
|
|
44
|
+
/** ID (or data-key) of the currently-selected child listitem — drives each child's [selected] reflected prop (ADR-0056, #1363 B7). Kept as `selectedKey` rather than renamed to `value` (segmented/tabs/ select's parent-selection prop name): list rows are identified by DOM id/data-key, not an option value, and ADR-0056 itself governs only the child's own [selected] state surface, not this naming — a cross-family rename has no ratifying ADR (B5/B9-shaped follow-up). */
|
|
45
45
|
selectedKey: string;
|
|
46
|
-
/** Item spacing */
|
|
47
|
-
spacing:
|
|
46
|
+
/** Item spacing scale — `sm`/`lg` modulate the per-item inset; `md` (default) is the base inset. */
|
|
47
|
+
spacing: 'sm' | 'md' | 'lg';
|
|
48
48
|
|
|
49
49
|
addEventListener(type: 'selection-change', listener: (ev: ListSelectionChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
50
50
|
addEventListener<K extends keyof HTMLElementEventMap>(
|
|
@@ -59,6 +59,8 @@ export class UIListItem extends UIElement {
|
|
|
59
59
|
description: string;
|
|
60
60
|
/** Optional leading icon name (Phosphor). */
|
|
61
61
|
icon: string;
|
|
62
|
+
/** Whether this row is the current selection. Managed by the parent <list-ui>[selectable] — don't set directly; the parent's [selectedKey] is the single source of truth (ADR-0056). */
|
|
63
|
+
selected: boolean;
|
|
62
64
|
/** Primary text. Renders as semibold inline body. */
|
|
63
65
|
text: string;
|
|
64
66
|
}
|
|
@@ -10,8 +10,8 @@ version: 1
|
|
|
10
10
|
description: |
|
|
11
11
|
Styled flat list with optional row dividers and icons — each row
|
|
12
12
|
is a <list-item-ui> child. Selectable mode via [selectable] +
|
|
13
|
-
[selectedKey] / `
|
|
14
|
-
glyphs. Distinct from <nav-ui> (sidebar navigation, route-aware),
|
|
13
|
+
[selectedKey] / `selection-change` event. Composes <icon-ui> for row
|
|
14
|
+
leading glyphs. Distinct from <nav-ui> (sidebar navigation, route-aware),
|
|
15
15
|
<tree-ui> (hierarchical with arbitrary nesting), and <table-ui>
|
|
16
16
|
(tabular data with columns). Use list-ui for non-navigable,
|
|
17
17
|
non-tabular vertical rows — comment lists, file lists, message
|
|
@@ -40,14 +40,22 @@ props:
|
|
|
40
40
|
type: boolean
|
|
41
41
|
default: false
|
|
42
42
|
selectedKey:
|
|
43
|
-
description:
|
|
43
|
+
description: >-
|
|
44
|
+
ID (or data-key) of the currently-selected child listitem — drives
|
|
45
|
+
each child's [selected] reflected prop (ADR-0056, #1363 B7). Kept
|
|
46
|
+
as `selectedKey` rather than renamed to `value` (segmented/tabs/
|
|
47
|
+
select's parent-selection prop name): list rows are identified by
|
|
48
|
+
DOM id/data-key, not an option value, and ADR-0056 itself governs
|
|
49
|
+
only the child's own [selected] state surface, not this naming —
|
|
50
|
+
a cross-family rename has no ratifying ADR (B5/B9-shaped follow-up).
|
|
44
51
|
type: string
|
|
45
52
|
default: ""
|
|
46
53
|
attribute: selected-key
|
|
47
54
|
spacing:
|
|
48
|
-
description: Item spacing
|
|
55
|
+
description: Item spacing scale — `sm`/`lg` modulate the per-item inset; `md` (default) is the base inset.
|
|
49
56
|
type: string
|
|
50
57
|
default: md
|
|
58
|
+
enum: [sm, md, lg]
|
|
51
59
|
events:
|
|
52
60
|
selection-change:
|
|
53
61
|
description: "Fired on selection-change."
|
|
@@ -68,10 +76,12 @@ a2ui:
|
|
|
68
76
|
rules:
|
|
69
77
|
- rule: 'Generic vertical list container — hosts <list-item-ui> or arbitrary children.'
|
|
70
78
|
reason: 'Lowest-friction list primitive.'
|
|
71
|
-
- rule: '
|
|
72
|
-
reason: '
|
|
79
|
+
- rule: 'list-ui supports single selection natively via [selectable] + [selectedKey] (ADR-0056, #1363 B7) — the parent stamps the matching <list-item-ui>''s [selected] + aria-selected and fires selection-change. For route-aware navigation use <nav-ui> instead; for a popover action menu use <menu-ui> instead — both have different interaction contracts than a plain selectable list.'
|
|
80
|
+
reason: 'list-ui selectable is the supported non-navigation, non-menu selection surface; nav-ui/menu-ui remain the right choice for their own contracts.'
|
|
73
81
|
- rule: 'For data-grid / sortable / sticky-header needs use <table-ui> instead.'
|
|
74
82
|
reason: 'Table has different semantics.'
|
|
83
|
+
- rule: 'list-ui carries no fire-and-forget "action" mode. [selectable] keeps a persisted single selection (`selectedKey` / `aria-selected`, roving tabindex); for rows that activate immediately with no persisted selection state use <action-list-ui> + <action-item-ui> instead.'
|
|
84
|
+
reason: 'Container-level decision (#1363 C5): kept separate rather than absorbed as a mode axis — stateful selection and fire-and-forget activation are genuinely different interaction contracts, and list-item-ui''s selection state is under active convergence elsewhere (#1379); rationale in gh#1374 Findings.'
|
|
75
85
|
anti_patterns: []
|
|
76
86
|
examples:
|
|
77
87
|
- name: basic-list
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
*/
|
|
45
45
|
|
|
46
46
|
import { UIElement } from '../../core/element.js';
|
|
47
|
+
import { isNode } from '../../core/dom.js';
|
|
47
48
|
|
|
48
49
|
export class UIListWindow extends UIElement {
|
|
49
50
|
static properties = {
|
|
@@ -616,7 +617,7 @@ export class UIListWindow extends UIElement {
|
|
|
616
617
|
try { content = renderFn(item, index); }
|
|
617
618
|
catch (err) { console.warn('[list-window-ui] render() threw:', err); }
|
|
618
619
|
}
|
|
619
|
-
if (content
|
|
620
|
+
if (isNode(content)) {
|
|
620
621
|
row.appendChild(content);
|
|
621
622
|
} else if (content != null) {
|
|
622
623
|
row.textContent = String(content);
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"wrong": "<mark>matched</mark>"
|
|
41
41
|
}
|
|
42
42
|
],
|
|
43
|
-
"category": "
|
|
43
|
+
"category": "display",
|
|
44
44
|
"composes": [],
|
|
45
45
|
"events": {},
|
|
46
46
|
"examples": [
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"emphasis"
|
|
58
58
|
],
|
|
59
59
|
"name": "UIMark",
|
|
60
|
+
"parts": {},
|
|
60
61
|
"related": [
|
|
61
62
|
"text",
|
|
62
63
|
"tag"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://adiaui.dev/a2ui/v0_9/components/MenuItem.json",
|
|
4
4
|
"title": "MenuItem",
|
|
5
|
-
"description": "Child of `<menu-ui>`. One actionable row inside a menu, with optional leading icon + label +
|
|
5
|
+
"description": "Child of `<menu-ui>`. One actionable row inside a menu, with optional leading icon + label + description + value. (`subtitle` is a deprecated alias for `description` — ADR-0063, gh#1563.)",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"allOf": [
|
|
8
8
|
{
|
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
15
|
"properties": {
|
|
16
|
+
"description": {
|
|
17
|
+
"description": "Optional secondary description line rendered under the label. Canonical spelling (ADR-0063, gh#1563) replacing `subtitle` — converges menu-item onto the ~20-component corpus majority that already names this concept `description`.",
|
|
18
|
+
"type": "string",
|
|
19
|
+
"default": ""
|
|
20
|
+
},
|
|
16
21
|
"component": {
|
|
17
22
|
"const": "MenuItem"
|
|
18
23
|
},
|
|
@@ -27,7 +32,7 @@
|
|
|
27
32
|
"default": ""
|
|
28
33
|
},
|
|
29
34
|
"subtitle": {
|
|
30
|
-
"description": "
|
|
35
|
+
"description": "DEPRECATED (ADR-0063, gh#1563) — use `description` instead. Same type/default/rendered position; kept working as a dual-read compat shim (one-time console.warn when it's the name that resolves). Removed in 0.9.0. (The `subtitle` SLOT below is a separate surface, deliberately left unrenamed in this pass — see its own description.)",
|
|
31
36
|
"type": "string",
|
|
32
37
|
"default": ""
|
|
33
38
|
},
|
|
@@ -68,18 +73,20 @@
|
|
|
68
73
|
"dropdown-item"
|
|
69
74
|
],
|
|
70
75
|
"name": "UIMenuItem",
|
|
76
|
+
"parts": {},
|
|
71
77
|
"related": [
|
|
72
78
|
"Menu",
|
|
73
79
|
"MenuDivider",
|
|
74
80
|
"Button",
|
|
75
|
-
"NavItem"
|
|
81
|
+
"NavItem",
|
|
82
|
+
"ActionItem"
|
|
76
83
|
],
|
|
77
84
|
"slots": {
|
|
78
85
|
"icon": {
|
|
79
86
|
"description": "Custom leading element override; falls through to `[icon]` prop if not slotted."
|
|
80
87
|
},
|
|
81
88
|
"subtitle": {
|
|
82
|
-
"description": "Custom secondary-line content override; falls through to `[
|
|
89
|
+
"description": "Custom secondary-line content override; falls through to the `[description]` prop (or its deprecated `[subtitle]` alias — ADR-0063, gh#1563) if not slotted. The slot's own name is unchanged by that rename — this is a distinct, deliberately-unrenamed surface."
|
|
83
90
|
},
|
|
84
91
|
"text": {
|
|
85
92
|
"description": "Custom label content; falls through to `[text]` prop if not slotted."
|
|
@@ -13,7 +13,7 @@ component: MenuItem
|
|
|
13
13
|
category: navigation
|
|
14
14
|
version: 1
|
|
15
15
|
description: |-
|
|
16
|
-
Child of `<menu-ui>`. One actionable row inside a menu, with optional leading icon + label +
|
|
16
|
+
Child of `<menu-ui>`. One actionable row inside a menu, with optional leading icon + label + description + value. (`subtitle` is a deprecated alias for `description` — ADR-0063, gh#1563.)
|
|
17
17
|
|
|
18
18
|
props:
|
|
19
19
|
icon:
|
|
@@ -25,7 +25,20 @@ props:
|
|
|
25
25
|
type: string
|
|
26
26
|
default: ""
|
|
27
27
|
subtitle:
|
|
28
|
-
description:
|
|
28
|
+
description: >-
|
|
29
|
+
DEPRECATED (ADR-0063, gh#1563) — use `description` instead. Same
|
|
30
|
+
type/default/rendered position; kept working as a dual-read compat
|
|
31
|
+
shim (one-time console.warn when it's the name that resolves).
|
|
32
|
+
Removed in 0.9.0. (The `subtitle` SLOT below is a separate surface,
|
|
33
|
+
deliberately left unrenamed in this pass — see its own description.)
|
|
34
|
+
type: string
|
|
35
|
+
default: ""
|
|
36
|
+
description:
|
|
37
|
+
description: >-
|
|
38
|
+
Optional secondary description line rendered under the label.
|
|
39
|
+
Canonical spelling (ADR-0063, gh#1563) replacing `subtitle` —
|
|
40
|
+
converges menu-item onto the ~20-component corpus majority that
|
|
41
|
+
already names this concept `description`.
|
|
29
42
|
type: string
|
|
30
43
|
default: ""
|
|
31
44
|
value:
|
|
@@ -49,7 +62,11 @@ slots:
|
|
|
49
62
|
text:
|
|
50
63
|
description: Custom label content; falls through to `[text]` prop if not slotted.
|
|
51
64
|
subtitle:
|
|
52
|
-
description:
|
|
65
|
+
description: >-
|
|
66
|
+
Custom secondary-line content override; falls through to the
|
|
67
|
+
`[description]` prop (or its deprecated `[subtitle]` alias — ADR-0063,
|
|
68
|
+
gh#1563) if not slotted. The slot's own name is unchanged by that
|
|
69
|
+
rename — this is a distinct, deliberately-unrenamed surface.
|
|
53
70
|
trailing:
|
|
54
71
|
description: Trailing element pinned to the far edge (shortcut hint, check mark).
|
|
55
72
|
|
|
@@ -79,6 +96,15 @@ a2ui:
|
|
|
79
96
|
Use slot="icon" / slot="text" only when you need custom markup
|
|
80
97
|
(e.g. <avatar-ui slot="icon">, <kbd slot="trailing"> shortcut
|
|
81
98
|
hint).
|
|
99
|
+
- >-
|
|
100
|
+
<action-item-ui> (child of <action-list-ui>) shares this row contract
|
|
101
|
+
(icon/text/subtitle/value/variant/disabled props, icon/text/subtitle/
|
|
102
|
+
trailing slot overrides) for inline, non-popover command rows — use
|
|
103
|
+
it instead when the surface isn't a <menu-ui> popover (#1363 C5).
|
|
104
|
+
NOTE (ADR-0063, gh#1563): <menu-item-ui>'s own `subtitle` PROP is now
|
|
105
|
+
a deprecated alias for `description` — <action-item-ui> still uses
|
|
106
|
+
`subtitle` as its own primary spelling and was NOT renamed in this
|
|
107
|
+
pass (flagged as a discovered follow-up candidate, not fixed here).
|
|
82
108
|
|
|
83
109
|
keywords:
|
|
84
110
|
- menu-item
|
|
@@ -91,6 +117,7 @@ related:
|
|
|
91
117
|
- MenuDivider
|
|
92
118
|
- Button
|
|
93
119
|
- NavItem
|
|
120
|
+
- ActionItem
|
|
94
121
|
|
|
95
122
|
synonyms:
|
|
96
123
|
menu-item: [dropdown-item, menu-row, popover-action]
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"component": {
|
|
17
17
|
"const": "Menu"
|
|
18
18
|
},
|
|
19
|
-
"
|
|
20
|
-
"description": "
|
|
19
|
+
"offset": {
|
|
20
|
+
"description": "Pixel offset between the anchor (trigger) and the menu popover. Renamed from `[gap]` (gh#1335) — a raw-px number can't share a name with the global Scale-grammar `[gap]` attribute (ADR-0053); matches popover-ui's own `[offset]` (same anchorPopover() helper).",
|
|
21
21
|
"type": "number",
|
|
22
22
|
"default": 4
|
|
23
23
|
},
|
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
"right-click"
|
|
82
82
|
],
|
|
83
83
|
"name": "UIMenu",
|
|
84
|
+
"parts": {},
|
|
84
85
|
"related": [
|
|
85
86
|
"MenuItem",
|
|
86
87
|
"MenuDivider",
|
|
@@ -35,7 +35,7 @@ export class UIMenu extends UIElement {
|
|
|
35
35
|
static properties = {
|
|
36
36
|
open: { type: Boolean, default: false, reflect: true },
|
|
37
37
|
placement: { type: String, default: 'bottom-start', reflect: true },
|
|
38
|
-
|
|
38
|
+
offset: { type: Number, default: 4, reflect: true },
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
static template = () => null;
|
|
@@ -103,7 +103,7 @@ export class UIMenu extends UIElement {
|
|
|
103
103
|
this.#anchorCleanup?.();
|
|
104
104
|
this.#anchorCleanup = anchorPopover(trigger, pop, {
|
|
105
105
|
placement: this.placement,
|
|
106
|
-
gap: this.
|
|
106
|
+
gap: this.offset,
|
|
107
107
|
});
|
|
108
108
|
|
|
109
109
|
// Focus first enabled item (only when opened via keyboard).
|
|
@@ -258,7 +258,14 @@ export class UIMenuItem extends UIElement {
|
|
|
258
258
|
static properties = {
|
|
259
259
|
icon: { type: String, default: '', reflect: true },
|
|
260
260
|
text: { type: String, default: '', reflect: true },
|
|
261
|
+
// ADR-0063 (gh#1563) — `subtitle` is DEPRECATED (menu-item was the sole
|
|
262
|
+
// ~20-component-corpus outlier using `subtitle` where every sibling
|
|
263
|
+
// uses `description`); `description` is canonical. `subtitle` stays
|
|
264
|
+
// declared (dual-read compat, 0.8.42). The `subtitle` SLOT (a separate
|
|
265
|
+
// surface — see menu-item.yaml) is deliberately unchanged; only the
|
|
266
|
+
// PROP renames.
|
|
261
267
|
subtitle: { type: String, default: '', reflect: true },
|
|
268
|
+
description: { type: String, default: '', reflect: true },
|
|
262
269
|
value: { type: String, default: '', reflect: true },
|
|
263
270
|
variant: { type: String, default: 'default', reflect: true },
|
|
264
271
|
disabled: { type: Boolean, default: false, reflect: true },
|
|
@@ -266,12 +273,32 @@ export class UIMenuItem extends UIElement {
|
|
|
266
273
|
|
|
267
274
|
static template = () => null;
|
|
268
275
|
|
|
276
|
+
// ADR-0063 (gh#1563) one-shot-per-class deprecation warn for [subtitle].
|
|
277
|
+
static #warnedSubtitle = false;
|
|
278
|
+
|
|
269
279
|
// Set when connected() stamped role="menuitem" itself; a consumer-provided
|
|
270
280
|
// role (e.g. admin-roster's role="menuitemradio", gh#616) is never touched
|
|
271
281
|
// — that consumer also owns tabindex and any checked-state aria.
|
|
272
282
|
#roleStamped = false;
|
|
273
283
|
|
|
274
284
|
connected() {
|
|
285
|
+
// ADR-0063 (gh#1563) compat shim — resolve BEFORE #stamp() reads
|
|
286
|
+
// `this.description`, so there's no wrong-then-right flash. New-name
|
|
287
|
+
// precedence: [description] wins outright when present; only fall
|
|
288
|
+
// back to (and mirror) [subtitle] when [description] is absent.
|
|
289
|
+
if (!this.hasAttribute('description') && this.hasAttribute('subtitle')) {
|
|
290
|
+
this.description = this.subtitle;
|
|
291
|
+
if (!UIMenuItem.#warnedSubtitle) {
|
|
292
|
+
UIMenuItem.#warnedSubtitle = true;
|
|
293
|
+
// eslint-disable-next-line no-console
|
|
294
|
+
console.warn(
|
|
295
|
+
'[AdiaUI] <menu-item-ui [subtitle]> is deprecated — use ' +
|
|
296
|
+
'[description] instead (ADR-0063, gh#1563). Kept working as-is; ' +
|
|
297
|
+
'no behavior change.',
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
275
302
|
// role="menuitem" ONLY when actually inside a menu container. A menu-ui
|
|
276
303
|
// closes by moving its items back into its own light DOM (see #hide()),
|
|
277
304
|
// where there is no role="menu"/menubar ancestor — a bare role="menuitem"
|
|
@@ -324,10 +351,10 @@ export class UIMenuItem extends UIElement {
|
|
|
324
351
|
this.appendChild(span);
|
|
325
352
|
}
|
|
326
353
|
|
|
327
|
-
if (this.
|
|
354
|
+
if (this.description && !this.#ownChild('[slot="subtitle"]')) {
|
|
328
355
|
const sub = this.#stampMark(document.createElement('span'));
|
|
329
356
|
sub.setAttribute('slot', 'subtitle');
|
|
330
|
-
sub.textContent = this.
|
|
357
|
+
sub.textContent = this.description;
|
|
331
358
|
this.appendChild(sub);
|
|
332
359
|
}
|
|
333
360
|
}
|
|
@@ -357,15 +384,16 @@ export class UIMenuItem extends UIElement {
|
|
|
357
384
|
const textEl = this.#ownChild('[slot="text"]');
|
|
358
385
|
if (this.#wasStamped(textEl)) textEl.textContent = this.text;
|
|
359
386
|
|
|
360
|
-
// Sync subtitle
|
|
387
|
+
// Sync subtitle (backed by the `description` prop — ADR-0063, gh#1563)
|
|
388
|
+
// — only touch elements we stamped.
|
|
361
389
|
const subEl = this.#ownChild('[slot="subtitle"]');
|
|
362
|
-
if (this.
|
|
390
|
+
if (this.description) {
|
|
363
391
|
if (subEl) {
|
|
364
|
-
if (this.#wasStamped(subEl)) subEl.textContent = this.
|
|
392
|
+
if (this.#wasStamped(subEl)) subEl.textContent = this.description;
|
|
365
393
|
} else {
|
|
366
394
|
const el = this.#stampMark(document.createElement('span'));
|
|
367
395
|
el.setAttribute('slot', 'subtitle');
|
|
368
|
-
el.textContent = this.
|
|
396
|
+
el.textContent = this.description;
|
|
369
397
|
this.appendChild(el);
|
|
370
398
|
}
|
|
371
399
|
} else if (this.#wasStamped(subEl)) {
|
|
@@ -22,8 +22,8 @@ export interface MenuActionEventDetail {
|
|
|
22
22
|
export type MenuActionEvent = CustomEvent<MenuActionEventDetail>;
|
|
23
23
|
|
|
24
24
|
export class UIMenu extends UIElement {
|
|
25
|
-
/**
|
|
26
|
-
|
|
25
|
+
/** Pixel offset between the anchor (trigger) and the menu popover. Renamed from `[gap]` (gh#1335) — a raw-px number can't share a name with the global Scale-grammar `[gap]` attribute (ADR-0053); matches popover-ui's own `[offset]` (same anchorPopover() helper). */
|
|
26
|
+
offset: number;
|
|
27
27
|
/** Controls visibility via popover API */
|
|
28
28
|
open: boolean;
|
|
29
29
|
/** Preferred position relative to the anchor element */
|
|
@@ -41,11 +41,13 @@ export class UIMenuDivider extends UIElement {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
export class UIMenuItem extends UIElement {
|
|
44
|
+
/** Optional secondary description line rendered under the label. Canonical spelling (ADR-0063, gh#1563) replacing `subtitle` — converges menu-item onto the ~20-component corpus majority that already names this concept `description`. */
|
|
45
|
+
description: string;
|
|
44
46
|
/** Disabled state — blocks pointer + keyboard activation. */
|
|
45
47
|
disabled: boolean;
|
|
46
48
|
/** Optional leading Phosphor icon name. */
|
|
47
49
|
icon: string;
|
|
48
|
-
/**
|
|
50
|
+
/** DEPRECATED (ADR-0063, gh#1563) — use `description` instead. Same type/default/rendered position; kept working as a dual-read compat shim (one-time console.warn when it's the name that resolves). Removed in 0.9.0. (The `subtitle` SLOT below is a separate surface, deliberately left unrenamed in this pass — see its own description.) */
|
|
49
51
|
subtitle: string;
|
|
50
52
|
/** Item label text. */
|
|
51
53
|
text: string;
|
|
@@ -13,8 +13,8 @@ description: Dropdown action menu with roving focus and keyboard navigation. Use
|
|
|
13
13
|
composes:
|
|
14
14
|
- icon-ui # leading affordances on menu items (created in render)
|
|
15
15
|
props:
|
|
16
|
-
|
|
17
|
-
description:
|
|
16
|
+
offset:
|
|
17
|
+
description: Pixel offset between the anchor (trigger) and the menu popover. Renamed from `[gap]` (gh#1335) — a raw-px number can't share a name with the global Scale-grammar `[gap]` attribute (ADR-0053); matches popover-ui's own `[offset]` (same anchorPopover() helper).
|
|
18
18
|
type: number
|
|
19
19
|
default: 4
|
|
20
20
|
open:
|
|
@@ -83,7 +83,7 @@ a2ui:
|
|
|
83
83
|
Set [placement="top-start"] or [placement="top-end"] when the
|
|
84
84
|
trigger sits near the bottom of the viewport (statusbar / footer
|
|
85
85
|
menus); default [placement="bottom-start"] otherwise. Adjust
|
|
86
|
-
[
|
|
86
|
+
[offset] (default 4px) only when chrome demands it.
|
|
87
87
|
anti_patterns: []
|
|
88
88
|
examples:
|
|
89
89
|
- name: basic-menu
|
|
@@ -78,8 +78,20 @@ export class UINav extends UIElement {
|
|
|
78
78
|
if (this.variant !== 'section') this.#updateTooltips();
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Collapsed = explicit [collapsed], or a rail narrower than 96px.
|
|
83
|
+
* linkedom (SSR — gh#1436's render sweep) has no getBoundingClientRect
|
|
84
|
+
* at all, so only the attribute can answer there. (A ZERO rect from a
|
|
85
|
+
* real pre-layout connect is the separate, unswept shape-3 question in
|
|
86
|
+
* ssr-compatibility's failure-shapes.md — not decided here.)
|
|
87
|
+
*/
|
|
88
|
+
get #isCollapsed() {
|
|
89
|
+
return this.collapsed ||
|
|
90
|
+
(typeof this.getBoundingClientRect === 'function' && this.getBoundingClientRect().width <= 96);
|
|
91
|
+
}
|
|
92
|
+
|
|
81
93
|
#updateTooltips() {
|
|
82
|
-
const isCollapsed = this
|
|
94
|
+
const isCollapsed = this.#isCollapsed;
|
|
83
95
|
for (const group of this.querySelectorAll(':scope > nav-group-ui')) {
|
|
84
96
|
const header = group.querySelector(':scope > [slot="header"]');
|
|
85
97
|
if (header) header.title = isCollapsed ? group.text : '';
|
|
@@ -143,8 +155,7 @@ export class UINav extends UIElement {
|
|
|
143
155
|
|
|
144
156
|
const group = e.target.closest('nav-group-ui');
|
|
145
157
|
if (group && this.contains(group)) {
|
|
146
|
-
|
|
147
|
-
if (isCollapsed) {
|
|
158
|
+
if (this.#isCollapsed) {
|
|
148
159
|
// The flyout popover is appended INSIDE the group, so an option
|
|
149
160
|
// click bubbles here after the option's own handler has selected
|
|
150
161
|
// and hidePopover()'d — re-showing would instantly reopen the
|
|
@@ -99,7 +99,9 @@ export class UINavGroup extends UIElement {
|
|
|
99
99
|
// whole subtree includes this host's own [selected], which render()
|
|
100
100
|
// reads anyway; render() writes only the icon's [weight], which the
|
|
101
101
|
// attributeFilter excludes, so the observer can't feed back.
|
|
102
|
-
|
|
102
|
+
// Guarded like the other Observer sites (gh#285 §1 pattern) — SSR shims
|
|
103
|
+
// have no MutationObserver; teardown already uses `?.disconnect()`.
|
|
104
|
+
if (!this.#selectionObserver && typeof MutationObserver !== 'undefined') {
|
|
103
105
|
this.#selectionObserver = new MutationObserver(this.#onChildSelection);
|
|
104
106
|
this.#selectionObserver.observe(this, {
|
|
105
107
|
subtree: true,
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import { UIElement } from '../../core/element.js';
|
|
27
|
+
import { isElement } from '../../core/dom.js';
|
|
27
28
|
|
|
28
29
|
let nextId = 0;
|
|
29
30
|
|
|
@@ -159,6 +160,9 @@ export class UINoodles extends UIElement {
|
|
|
159
160
|
|
|
160
161
|
#scheduleUpdate() {
|
|
161
162
|
if (this.#rafId) return;
|
|
163
|
+
// No rAF (SSR shim — gh#1436's render sweep) → no frame and no layout
|
|
164
|
+
// to measure connectors against; the client redraws on hydrate.
|
|
165
|
+
if (typeof requestAnimationFrame !== 'function') return;
|
|
162
166
|
this.#rafId = requestAnimationFrame(() => {
|
|
163
167
|
this.#rafId = null;
|
|
164
168
|
this.#performUpdate();
|
|
@@ -251,7 +255,7 @@ export class UINoodles extends UIElement {
|
|
|
251
255
|
// ── Element resolution ──────────────────────────────────────
|
|
252
256
|
|
|
253
257
|
#resolveElement(ref) {
|
|
254
|
-
if (ref
|
|
258
|
+
if (isElement(ref)) return ref;
|
|
255
259
|
if (typeof ref === 'string') return this.querySelector(`#${CSS.escape(ref)}`);
|
|
256
260
|
if (typeof ref === 'number') return this.#getPortChildren()[ref] ?? null;
|
|
257
261
|
return null;
|