@ds-mo/ui 13.3.0 → 13.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.package-ready.json +1 -1
- package/dist/agent-patterns.json +14 -1
- package/dist/agent.json +126 -28
- package/dist/angular/boolean-value-accessor.js +3 -3
- package/dist/angular/ds-agent-activity.js +3 -3
- package/dist/angular/ds-agent-response.d.ts +1 -1
- package/dist/angular/ds-agent-response.js +5 -5
- package/dist/angular/ds-agent-source-list.js +3 -3
- package/dist/angular/ds-agent-tool-call.js +3 -3
- package/dist/angular/ds-attachment-list.js +3 -3
- package/dist/angular/ds-avatar.js +3 -3
- package/dist/angular/ds-badge.js +3 -3
- package/dist/angular/ds-bar-nav.js +3 -3
- package/dist/angular/ds-bar-title.js +3 -3
- package/dist/angular/ds-bar-workflow.js +3 -3
- package/dist/angular/ds-breadcrumb.js +3 -3
- package/dist/angular/ds-button-filled.js +3 -3
- package/dist/angular/ds-button-unfilled.js +3 -3
- package/dist/angular/ds-card-data-viz.js +3 -3
- package/dist/angular/ds-card-overview.js +3 -3
- package/dist/angular/ds-card-setting.js +3 -3
- package/dist/angular/ds-chart-bar.js +3 -3
- package/dist/angular/ds-chart-donut.js +3 -3
- package/dist/angular/ds-chart-legend.js +3 -3
- package/dist/angular/ds-chart-line.js +3 -3
- package/dist/angular/ds-checkbox.js +3 -3
- package/dist/angular/ds-chip.js +3 -3
- package/dist/angular/ds-code-block.js +3 -3
- package/dist/angular/ds-conversation-list-item.js +3 -3
- package/dist/angular/ds-conversation-list-section.js +3 -3
- package/dist/angular/ds-conversation-list.js +3 -3
- package/dist/angular/ds-divider.js +3 -3
- package/dist/angular/ds-empty-state.js +3 -3
- package/dist/angular/ds-field.js +3 -3
- package/dist/angular/ds-icon.js +3 -3
- package/dist/angular/ds-input.js +3 -3
- package/dist/angular/ds-loader.js +3 -3
- package/dist/angular/ds-markdown.js +3 -3
- package/dist/angular/ds-menu.js +3 -3
- package/dist/angular/ds-message-actions.d.ts +19 -0
- package/dist/angular/ds-message-actions.js +45 -0
- package/dist/angular/ds-message-bubble.js +3 -3
- package/dist/angular/ds-message-composer.js +3 -3
- package/dist/angular/ds-message-scroller.js +3 -3
- package/dist/angular/ds-message.d.ts +1 -1
- package/dist/angular/ds-message.js +5 -5
- package/dist/angular/ds-mobile-bar-nav.js +3 -3
- package/dist/angular/ds-mobile-header.js +3 -3
- package/dist/angular/ds-mobile-section-switcher.js +3 -3
- package/dist/angular/ds-mobile-sheet-nav.js +3 -3
- package/dist/angular/ds-modal.js +3 -3
- package/dist/angular/ds-panel-nav.js +3 -3
- package/dist/angular/ds-panel-sub-nav.js +3 -3
- package/dist/angular/ds-panel-tool-header.js +3 -3
- package/dist/angular/ds-panel-tool-search.js +3 -3
- package/dist/angular/ds-panel-tools.js +3 -3
- package/dist/angular/ds-radio.js +3 -3
- package/dist/angular/ds-scroll-overlay.js +3 -3
- package/dist/angular/ds-select.js +3 -3
- package/dist/angular/ds-shell-app.js +3 -3
- package/dist/angular/ds-shell-page.js +3 -3
- package/dist/angular/ds-shell-tools.js +3 -3
- package/dist/angular/ds-skeleton.js +3 -3
- package/dist/angular/ds-slider.js +3 -3
- package/dist/angular/ds-swatch-picker.js +3 -3
- package/dist/angular/ds-switch.js +3 -3
- package/dist/angular/ds-tab-group.js +3 -3
- package/dist/angular/ds-tag.js +3 -3
- package/dist/angular/ds-text.js +3 -3
- package/dist/angular/ds-toast.js +3 -3
- package/dist/angular/ds-tooltip-data-viz.js +3 -3
- package/dist/angular/ds-tooltip.js +3 -3
- package/dist/angular/ds-typing-indicator.js +3 -3
- package/dist/angular/index.d.ts +1 -1
- package/dist/angular/index.js +1 -0
- package/dist/angular/proxies.d.ts +1 -0
- package/dist/angular/proxies.js +1 -0
- package/dist/angular/radio-value-accessor.js +3 -3
- package/dist/angular/select-value-accessor.js +3 -3
- package/dist/angular/text-value-accessor.js +3 -3
- package/dist/angular/value-accessor.js +3 -3
- package/dist/components/ds-agent-response.js +1 -1
- package/dist/components/ds-agent-response.js.map +1 -1
- package/dist/components/ds-agent-tool-call.js +1 -1
- package/dist/components/ds-attachment-list.js +1 -1
- package/dist/components/ds-bar-nav.js +1 -1
- package/dist/components/ds-bar-title.js +1 -1
- package/dist/components/ds-bar-workflow.js +1 -1
- package/dist/components/ds-card-overview.js +1 -1
- package/dist/components/ds-card-overview.js.map +1 -1
- package/dist/components/ds-chart-donut.js +1 -1
- package/dist/components/ds-chart-line.js +1 -1
- package/dist/components/ds-code-block.js +1 -1
- package/dist/components/ds-conversation-list-item.js +1 -1
- package/dist/components/ds-conversation-list-section.js +1 -1
- package/dist/components/ds-empty-state.js +1 -1
- package/dist/components/ds-field.js +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-input.js.map +1 -1
- package/dist/components/ds-markdown.js +1 -1
- package/dist/components/ds-menu.js +1 -1
- package/dist/components/ds-message-actions.d.ts +11 -0
- package/dist/components/ds-message-actions.js +2 -0
- package/dist/components/ds-message-actions.js.map +1 -0
- package/dist/components/ds-message-composer.js +1 -1
- package/dist/components/ds-message-scroller.js +1 -1
- package/dist/components/ds-message.js +1 -1
- package/dist/components/ds-mobile-bar-nav.js +1 -1
- package/dist/components/ds-mobile-header.js +1 -1
- package/dist/components/ds-mobile-section-switcher.js +1 -1
- package/dist/components/ds-mobile-sheet-nav.js +1 -1
- package/dist/components/ds-panel-nav.js +1 -1
- package/dist/components/ds-panel-tool-header.js +1 -1
- package/dist/components/ds-panel-tool-search.js +1 -1
- package/dist/components/ds-panel-tools.js +1 -1
- package/dist/components/ds-select.js +1 -1
- package/dist/components/ds-select.js.map +1 -1
- package/dist/components/ds-shell-app.js +1 -1
- package/dist/components/ds-shell-page.js +1 -1
- package/dist/components/ds-shell-tools.js +1 -1
- package/dist/components/ds-swatch-picker.js +1 -1
- package/dist/components/ds-toast.js +1 -1
- package/dist/components/ds-tooltip-data-viz.js +1 -1
- package/dist/components/ds-typing-indicator.js +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/components/{p-DEaszb15.js → p-1moOgMI-.js} +2 -2
- package/dist/components/p-4scN0Mgn.js +2 -0
- package/dist/components/{p-dVlKpt8U.js → p-B3PdrMP0.js} +2 -2
- package/dist/components/{p-Beejrd-R.js → p-BN9FZESH.js} +2 -2
- package/dist/components/{p-CAAWaTYD.js → p-BQTJ7ePr.js} +2 -2
- package/dist/components/{p-POvz6PiQ.js → p-BgjtMMye.js} +2 -2
- package/dist/components/p-BnhGV__o.js +2 -0
- package/dist/components/p-BnhGV__o.js.map +1 -0
- package/dist/components/p-BxEOlO5k.js +2 -0
- package/dist/components/p-BxEOlO5k.js.map +1 -0
- package/dist/components/{p-CUWFHTM6.js → p-CIgag7g2.js} +2 -2
- package/dist/components/{p-E7Ds1fQa.js → p-CQ4vAZ9j.js} +2 -2
- package/dist/components/{p-L-JEw-kX.js → p-CUSz0JFa.js} +2 -2
- package/dist/components/{p-xNfMEOpU.js → p-CWItD0gL.js} +2 -2
- package/dist/components/p-CWKrq35a.js +2 -0
- package/dist/components/p-CWKrq35a.js.map +1 -0
- package/dist/components/{p-CyjC57Dk.js → p-CmUGA_q4.js} +2 -2
- package/dist/components/p-CqOswTy8.js +2 -0
- package/dist/components/{p-Bi-21Kvd.js.map → p-CqOswTy8.js.map} +1 -1
- package/dist/components/{p-DKaXlmoQ.js → p-D4bVE7e4.js} +2 -2
- package/dist/components/{p-DAbOfJgz.js → p-D5PN6zdD.js} +2 -2
- package/dist/components/{p-BvvoC1lV.js → p-DXGKfXTh.js} +2 -2
- package/dist/components/{p-krhJI5_Y.js → p-DtV263qO.js} +2 -2
- package/dist/components/{p-vY5ia2gz.js → p-RT1mts9U.js} +2 -2
- package/dist/components/{p-z6c6TMlA.js → p-a6cnCKWk.js} +2 -2
- package/dist/docs/components.json +291 -16
- package/dist/mcp-data/registry/agent-activity.json +1 -1
- package/dist/mcp-data/registry/agent-response.json +25 -4
- package/dist/mcp-data/registry/agent-source-list.json +1 -1
- package/dist/mcp-data/registry/agent-tool-call.json +1 -1
- package/dist/mcp-data/registry/attachment-list.json +1 -1
- package/dist/mcp-data/registry/avatar.json +2 -2
- package/dist/mcp-data/registry/badge.json +1 -1
- package/dist/mcp-data/registry/bar-nav.json +1 -1
- package/dist/mcp-data/registry/bar-title.json +1 -1
- package/dist/mcp-data/registry/bar-workflow.json +1 -1
- package/dist/mcp-data/registry/breadcrumb.json +1 -1
- package/dist/mcp-data/registry/button-filled.json +1 -1
- package/dist/mcp-data/registry/button-unfilled.json +1 -1
- package/dist/mcp-data/registry/card-data-viz.json +1 -1
- package/dist/mcp-data/registry/card-overview.json +33 -35
- package/dist/mcp-data/registry/card-setting.json +1 -1
- package/dist/mcp-data/registry/chart-bar.json +1 -1
- package/dist/mcp-data/registry/chart-donut.json +1 -1
- package/dist/mcp-data/registry/chart-legend.json +1 -1
- package/dist/mcp-data/registry/chart-line.json +1 -1
- package/dist/mcp-data/registry/checkbox.json +1 -1
- package/dist/mcp-data/registry/chip.json +1 -1
- package/dist/mcp-data/registry/code-block.json +2 -2
- package/dist/mcp-data/registry/conversation-list-item.json +1 -1
- package/dist/mcp-data/registry/conversation-list-section.json +1 -1
- package/dist/mcp-data/registry/conversation-list.json +1 -1
- package/dist/mcp-data/registry/divider.json +1 -1
- package/dist/mcp-data/registry/empty-state.json +1 -1
- package/dist/mcp-data/registry/field.json +1 -1
- package/dist/mcp-data/registry/icon.json +1 -1
- package/dist/mcp-data/registry/input.json +6 -6
- package/dist/mcp-data/registry/loader.json +1 -1
- package/dist/mcp-data/registry/markdown.json +1 -1
- package/dist/mcp-data/registry/menu.json +1 -1
- package/dist/mcp-data/registry/message-actions.json +186 -0
- package/dist/mcp-data/registry/message-bubble.json +1 -1
- package/dist/mcp-data/registry/message-composer.json +1 -1
- package/dist/mcp-data/registry/message-scroller.json +1 -1
- package/dist/mcp-data/registry/message.json +28 -7
- package/dist/mcp-data/registry/mobile-bar-nav.json +1 -1
- package/dist/mcp-data/registry/mobile-header.json +1 -1
- package/dist/mcp-data/registry/mobile-section-switcher.json +1 -1
- package/dist/mcp-data/registry/mobile-sheet-nav.json +1 -1
- package/dist/mcp-data/registry/modal.json +1 -1
- package/dist/mcp-data/registry/panel-nav.json +1 -1
- package/dist/mcp-data/registry/panel-sub-nav.json +1 -1
- package/dist/mcp-data/registry/panel-tool-header.json +1 -1
- package/dist/mcp-data/registry/panel-tool-search.json +1 -1
- package/dist/mcp-data/registry/panel-tools.json +1 -1
- package/dist/mcp-data/registry/radio.json +1 -1
- package/dist/mcp-data/registry/registry.json +129 -28
- package/dist/mcp-data/registry/scroll-overlay.json +1 -1
- package/dist/mcp-data/registry/select.json +5 -5
- package/dist/mcp-data/registry/shell-app.json +1 -1
- package/dist/mcp-data/registry/shell-page.json +1 -1
- package/dist/mcp-data/registry/shell-tools.json +1 -1
- package/dist/mcp-data/registry/skeleton.json +1 -1
- package/dist/mcp-data/registry/slider.json +1 -1
- package/dist/mcp-data/registry/swatch-picker.json +1 -1
- package/dist/mcp-data/registry/switch.json +1 -1
- package/dist/mcp-data/registry/tab-group.json +1 -1
- package/dist/mcp-data/registry/tag.json +1 -1
- package/dist/mcp-data/registry/text.json +1 -1
- package/dist/mcp-data/registry/toast.json +1 -1
- package/dist/mcp-data/registry/tooltip-data-viz.json +1 -1
- package/dist/mcp-data/registry/tooltip.json +1 -1
- package/dist/mcp-data/registry/typing-indicator.json +1 -1
- package/dist/react/components.d.ts +1 -0
- package/dist/react/components.js +1 -0
- package/dist/react/ds-agent-activity.d.ts +1 -1
- package/dist/react/ds-agent-activity.js +1 -1
- package/dist/react/ds-agent-response.d.ts +1 -1
- package/dist/react/ds-agent-response.js +1 -1
- package/dist/react/ds-agent-source-list.d.ts +1 -1
- package/dist/react/ds-agent-source-list.js +1 -1
- package/dist/react/ds-agent-tool-call.d.ts +1 -1
- package/dist/react/ds-agent-tool-call.js +1 -1
- package/dist/react/ds-attachment-list.d.ts +1 -1
- package/dist/react/ds-attachment-list.js +1 -1
- package/dist/react/ds-avatar.d.ts +1 -1
- package/dist/react/ds-avatar.js +1 -1
- package/dist/react/ds-badge.d.ts +1 -1
- package/dist/react/ds-badge.js +1 -1
- package/dist/react/ds-bar-nav.d.ts +1 -1
- package/dist/react/ds-bar-nav.js +1 -1
- package/dist/react/ds-bar-title.d.ts +1 -1
- package/dist/react/ds-bar-title.js +1 -1
- package/dist/react/ds-bar-workflow.d.ts +1 -1
- package/dist/react/ds-bar-workflow.js +1 -1
- package/dist/react/ds-breadcrumb.d.ts +1 -1
- package/dist/react/ds-breadcrumb.js +1 -1
- package/dist/react/ds-button-filled.d.ts +1 -1
- package/dist/react/ds-button-filled.js +1 -1
- package/dist/react/ds-button-unfilled.d.ts +1 -1
- package/dist/react/ds-button-unfilled.js +1 -1
- package/dist/react/ds-card-data-viz.d.ts +1 -1
- package/dist/react/ds-card-data-viz.js +1 -1
- package/dist/react/ds-card-overview.d.ts +1 -1
- package/dist/react/ds-card-overview.js +1 -1
- package/dist/react/ds-card-setting.d.ts +1 -1
- package/dist/react/ds-card-setting.js +1 -1
- package/dist/react/ds-chart-bar.d.ts +1 -1
- package/dist/react/ds-chart-bar.js +1 -1
- package/dist/react/ds-chart-donut.d.ts +1 -1
- package/dist/react/ds-chart-donut.js +1 -1
- package/dist/react/ds-chart-legend.d.ts +1 -1
- package/dist/react/ds-chart-legend.js +1 -1
- package/dist/react/ds-chart-line.d.ts +1 -1
- package/dist/react/ds-chart-line.js +1 -1
- package/dist/react/ds-checkbox.d.ts +1 -1
- package/dist/react/ds-checkbox.js +1 -1
- package/dist/react/ds-chip.d.ts +1 -1
- package/dist/react/ds-chip.js +1 -1
- package/dist/react/ds-code-block.d.ts +1 -1
- package/dist/react/ds-code-block.js +1 -1
- package/dist/react/ds-conversation-list-item.d.ts +1 -1
- package/dist/react/ds-conversation-list-item.js +1 -1
- package/dist/react/ds-conversation-list-section.d.ts +1 -1
- package/dist/react/ds-conversation-list-section.js +1 -1
- package/dist/react/ds-conversation-list.d.ts +1 -1
- package/dist/react/ds-conversation-list.js +1 -1
- package/dist/react/ds-divider.d.ts +1 -1
- package/dist/react/ds-divider.js +1 -1
- package/dist/react/ds-empty-state.d.ts +1 -1
- package/dist/react/ds-empty-state.js +1 -1
- package/dist/react/ds-field.d.ts +1 -1
- package/dist/react/ds-field.js +1 -1
- package/dist/react/ds-icon.d.ts +1 -1
- package/dist/react/ds-icon.js +1 -1
- package/dist/react/ds-input.d.ts +1 -1
- package/dist/react/ds-input.js +1 -1
- package/dist/react/ds-loader.d.ts +1 -1
- package/dist/react/ds-loader.js +1 -1
- package/dist/react/ds-markdown.d.ts +1 -1
- package/dist/react/ds-markdown.js +1 -1
- package/dist/react/ds-menu.d.ts +1 -1
- package/dist/react/ds-menu.js +1 -1
- package/dist/react/ds-message-actions.d.ts +13 -0
- package/dist/react/ds-message-actions.js +15 -0
- package/dist/react/ds-message-bubble.d.ts +1 -1
- package/dist/react/ds-message-bubble.js +1 -1
- package/dist/react/ds-message-composer.d.ts +1 -1
- package/dist/react/ds-message-composer.js +1 -1
- package/dist/react/ds-message-scroller.d.ts +1 -1
- package/dist/react/ds-message-scroller.js +1 -1
- package/dist/react/ds-message.d.ts +1 -1
- package/dist/react/ds-message.js +1 -1
- package/dist/react/ds-mobile-bar-nav.d.ts +1 -1
- package/dist/react/ds-mobile-bar-nav.js +1 -1
- package/dist/react/ds-mobile-header.d.ts +1 -1
- package/dist/react/ds-mobile-header.js +1 -1
- package/dist/react/ds-mobile-section-switcher.d.ts +1 -1
- package/dist/react/ds-mobile-section-switcher.js +1 -1
- package/dist/react/ds-mobile-sheet-nav.d.ts +1 -1
- package/dist/react/ds-mobile-sheet-nav.js +1 -1
- package/dist/react/ds-modal.d.ts +1 -1
- package/dist/react/ds-modal.js +1 -1
- package/dist/react/ds-panel-nav.d.ts +1 -1
- package/dist/react/ds-panel-nav.js +1 -1
- package/dist/react/ds-panel-sub-nav.d.ts +1 -1
- package/dist/react/ds-panel-sub-nav.js +1 -1
- package/dist/react/ds-panel-tool-header.d.ts +1 -1
- package/dist/react/ds-panel-tool-header.js +1 -1
- package/dist/react/ds-panel-tool-search.d.ts +1 -1
- package/dist/react/ds-panel-tool-search.js +1 -1
- package/dist/react/ds-panel-tools.d.ts +1 -1
- package/dist/react/ds-panel-tools.js +1 -1
- package/dist/react/ds-radio.d.ts +1 -1
- package/dist/react/ds-radio.js +1 -1
- package/dist/react/ds-scroll-overlay.d.ts +1 -1
- package/dist/react/ds-scroll-overlay.js +1 -1
- package/dist/react/ds-select.d.ts +1 -1
- package/dist/react/ds-select.js +1 -1
- package/dist/react/ds-shell-app.d.ts +1 -1
- package/dist/react/ds-shell-app.js +1 -1
- package/dist/react/ds-shell-page.d.ts +1 -1
- package/dist/react/ds-shell-page.js +1 -1
- package/dist/react/ds-shell-tools.d.ts +1 -1
- package/dist/react/ds-shell-tools.js +1 -1
- package/dist/react/ds-skeleton.d.ts +1 -1
- package/dist/react/ds-skeleton.js +1 -1
- package/dist/react/ds-slider.d.ts +1 -1
- package/dist/react/ds-slider.js +1 -1
- package/dist/react/ds-swatch-picker.d.ts +1 -1
- package/dist/react/ds-swatch-picker.js +1 -1
- package/dist/react/ds-switch.d.ts +1 -1
- package/dist/react/ds-switch.js +1 -1
- package/dist/react/ds-tab-group.d.ts +1 -1
- package/dist/react/ds-tab-group.js +1 -1
- package/dist/react/ds-tag.d.ts +1 -1
- package/dist/react/ds-tag.js +1 -1
- package/dist/react/ds-text.d.ts +1 -1
- package/dist/react/ds-text.js +1 -1
- package/dist/react/ds-toast.d.ts +1 -1
- package/dist/react/ds-toast.js +1 -1
- package/dist/react/ds-tooltip-data-viz.d.ts +1 -1
- package/dist/react/ds-tooltip-data-viz.js +1 -1
- package/dist/react/ds-tooltip.d.ts +1 -1
- package/dist/react/ds-tooltip.js +1 -1
- package/dist/react/ds-typing-indicator.d.ts +1 -1
- package/dist/react/ds-typing-indicator.js +1 -1
- package/dist/react/react-runtime.d.ts +17 -0
- package/dist/react/react-runtime.js +13 -0
- package/dist/types/components/AgentResponse/AgentResponse.d.ts +3 -1
- package/dist/types/components/CardOverview/CardOverview.d.ts +11 -10
- package/dist/types/components/CardOverview/card-overview-controller.d.ts +13 -1
- package/dist/types/components/CardOverview/card-overview-types.d.ts +8 -2
- package/dist/types/components/CardOverview/index.d.ts +1 -1
- package/dist/types/components/CodeBlock/CodeBlock.d.ts +3 -1
- package/dist/types/components/Input/Input.d.ts +1 -1
- package/dist/types/components/Message/Message.d.ts +4 -1
- package/dist/types/components/MessageActions/MessageActions.d.ts +18 -0
- package/dist/types/components/Select/Select.d.ts +1 -1
- package/dist/types/components/conversation-types.d.ts +5 -0
- package/dist/types/components.d.ts +88 -18
- package/dist/types/utils/clipboard.d.ts +31 -0
- package/package.json +5 -8
- package/dist/components/p-B_A4g4Xe.js +0 -2
- package/dist/components/p-B_A4g4Xe.js.map +0 -1
- package/dist/components/p-Bi-21Kvd.js +0 -2
- package/dist/components/p-DV-tK5TR.js +0 -2
- package/dist/components/p-awaBUdlz.js +0 -2
- package/dist/components/p-awaBUdlz.js.map +0 -1
- /package/dist/components/{p-DEaszb15.js.map → p-1moOgMI-.js.map} +0 -0
- /package/dist/components/{p-DV-tK5TR.js.map → p-4scN0Mgn.js.map} +0 -0
- /package/dist/components/{p-dVlKpt8U.js.map → p-B3PdrMP0.js.map} +0 -0
- /package/dist/components/{p-Beejrd-R.js.map → p-BN9FZESH.js.map} +0 -0
- /package/dist/components/{p-CAAWaTYD.js.map → p-BQTJ7ePr.js.map} +0 -0
- /package/dist/components/{p-POvz6PiQ.js.map → p-BgjtMMye.js.map} +0 -0
- /package/dist/components/{p-CUWFHTM6.js.map → p-CIgag7g2.js.map} +0 -0
- /package/dist/components/{p-E7Ds1fQa.js.map → p-CQ4vAZ9j.js.map} +0 -0
- /package/dist/components/{p-L-JEw-kX.js.map → p-CUSz0JFa.js.map} +0 -0
- /package/dist/components/{p-xNfMEOpU.js.map → p-CWItD0gL.js.map} +0 -0
- /package/dist/components/{p-CyjC57Dk.js.map → p-CmUGA_q4.js.map} +0 -0
- /package/dist/components/{p-DKaXlmoQ.js.map → p-D4bVE7e4.js.map} +0 -0
- /package/dist/components/{p-DAbOfJgz.js.map → p-D5PN6zdD.js.map} +0 -0
- /package/dist/components/{p-BvvoC1lV.js.map → p-DXGKfXTh.js.map} +0 -0
- /package/dist/components/{p-krhJI5_Y.js.map → p-DtV263qO.js.map} +0 -0
- /package/dist/components/{p-vY5ia2gz.js.map → p-RT1mts9U.js.map} +0 -0
- /package/dist/components/{p-z6c6TMlA.js.map → p-a6cnCKWk.js.map} +0 -0
|
@@ -284,7 +284,7 @@
|
|
|
284
284
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: dashboardGroups, settingsGroups.",
|
|
285
285
|
"peerDependencies": {
|
|
286
286
|
"required": [
|
|
287
|
-
"@ds-mo/tokens ^5.1.
|
|
287
|
+
"@ds-mo/tokens ^5.1.1",
|
|
288
288
|
"@ds-mo/icons ^6.4.0"
|
|
289
289
|
],
|
|
290
290
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: items.",
|
|
216
216
|
"peerDependencies": {
|
|
217
217
|
"required": [
|
|
218
|
-
"@ds-mo/tokens ^5.1.
|
|
218
|
+
"@ds-mo/tokens ^5.1.1",
|
|
219
219
|
"@ds-mo/icons ^6.4.0"
|
|
220
220
|
],
|
|
221
221
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -312,7 +312,7 @@
|
|
|
312
312
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: actions.",
|
|
313
313
|
"peerDependencies": {
|
|
314
314
|
"required": [
|
|
315
|
-
"@ds-mo/tokens ^5.1.
|
|
315
|
+
"@ds-mo/tokens ^5.1.1",
|
|
316
316
|
"@ds-mo/icons ^6.4.0"
|
|
317
317
|
],
|
|
318
318
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -438,7 +438,7 @@
|
|
|
438
438
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: headers, items.",
|
|
439
439
|
"peerDependencies": {
|
|
440
440
|
"required": [
|
|
441
|
-
"@ds-mo/tokens ^5.1.
|
|
441
|
+
"@ds-mo/tokens ^5.1.1",
|
|
442
442
|
"@ds-mo/icons ^6.4.0"
|
|
443
443
|
],
|
|
444
444
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -345,7 +345,7 @@
|
|
|
345
345
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: options.",
|
|
346
346
|
"peerDependencies": {
|
|
347
347
|
"required": [
|
|
348
|
-
"@ds-mo/tokens ^5.1.
|
|
348
|
+
"@ds-mo/tokens ^5.1.1",
|
|
349
349
|
"@ds-mo/icons ^6.4.0"
|
|
350
350
|
],
|
|
351
351
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"themeSetup": "Set data-theme=\"dark\" on <html> for dark mode. Light is default.",
|
|
13
13
|
"peerDependencies": {
|
|
14
14
|
"required": [
|
|
15
|
-
"@ds-mo/tokens ^5.1.
|
|
15
|
+
"@ds-mo/tokens ^5.1.1",
|
|
16
16
|
"@ds-mo/icons ^6.4.0"
|
|
17
17
|
],
|
|
18
18
|
"optional": [],
|
|
@@ -122,6 +122,7 @@
|
|
|
122
122
|
],
|
|
123
123
|
"commonlyComposedWith": [
|
|
124
124
|
"component:ds-message",
|
|
125
|
+
"component:ds-message-actions",
|
|
125
126
|
"component:ds-markdown",
|
|
126
127
|
"component:ds-agent-activity",
|
|
127
128
|
"component:ds-agent-tool-call",
|
|
@@ -132,12 +133,14 @@
|
|
|
132
133
|
],
|
|
133
134
|
"accessibility": [
|
|
134
135
|
"Part order matches authored reading order and remains inside generic message semantics.",
|
|
135
|
-
"Streaming state supplements rather than replaces meaningful textual status."
|
|
136
|
+
"Streaming state supplements rather than replaces meaningful textual status.",
|
|
137
|
+
"Forwarded metadata actions retain Message ordering, keyboard reveal, and touch visibility."
|
|
136
138
|
],
|
|
137
139
|
"states": [
|
|
138
140
|
"The owner replaces immutable part arrays as scripted or live output changes.",
|
|
139
141
|
"AgentResponse renders directly in Message without borrowing a plain MessageBubble surface.",
|
|
140
|
-
"Markdown parts use the optional safe renderer; prose CSS owns only semantic-tree styling and never response ordering or streaming state."
|
|
142
|
+
"Markdown parts use the optional safe renderer; prose CSS owns only semantic-tree styling and never response ordering or streaming state.",
|
|
143
|
+
"The application may compose MessageActions for completed-response Copy and controlled feedback while retaining persistent retry or recovery controls in the separate actions slot."
|
|
141
144
|
],
|
|
142
145
|
"responsiveBehavior": [
|
|
143
146
|
"Rich content uses the available transcript width while respecting readable measure and local overflow constraints."
|
|
@@ -162,6 +165,10 @@
|
|
|
162
165
|
"type": "string",
|
|
163
166
|
"required": false
|
|
164
167
|
},
|
|
168
|
+
"metadataVisibility": {
|
|
169
|
+
"type": "MessageMetadataVisibility",
|
|
170
|
+
"required": false
|
|
171
|
+
},
|
|
165
172
|
"parts": {
|
|
166
173
|
"type": "AgentResponsePart[]",
|
|
167
174
|
"required": false
|
|
@@ -451,7 +458,7 @@
|
|
|
451
458
|
"intentStatus": "complete",
|
|
452
459
|
"intent": {
|
|
453
460
|
"audience": "general",
|
|
454
|
-
"status": "
|
|
461
|
+
"status": "stable",
|
|
455
462
|
"summary": "Compact icon avatar for visually identifying a person, group, channel, or conversation type.",
|
|
456
463
|
"useWhen": [
|
|
457
464
|
"A list or message composition needs a consistent circular identity marker represented by an icon at md, sm, or xs control density."
|
|
@@ -1839,7 +1846,7 @@
|
|
|
1839
1846
|
{
|
|
1840
1847
|
"name": "card-overview",
|
|
1841
1848
|
"title": "CardOverview",
|
|
1842
|
-
"description": "Page-level summary
|
|
1849
|
+
"description": "Page-level summary with a persistent 48px reporting bar above an equal-track grid of an optional safety score and comparable measures, plus an elevated page-controlled collapse surface.",
|
|
1843
1850
|
"type": "registry:ui",
|
|
1844
1851
|
"meta": {
|
|
1845
1852
|
"library": "@ds-mo/ui",
|
|
@@ -1850,7 +1857,7 @@
|
|
|
1850
1857
|
"intent": {
|
|
1851
1858
|
"audience": "general",
|
|
1852
1859
|
"status": "experimental",
|
|
1853
|
-
"summary": "Page-level summary
|
|
1860
|
+
"summary": "Page-level summary with a persistent 48px reporting bar above an equal-track grid of an optional safety score and comparable measures, plus an elevated page-controlled collapse surface.",
|
|
1854
1861
|
"useWhen": [
|
|
1855
1862
|
"A page opens with one headline figure that the surrounding measures explain.",
|
|
1856
1863
|
"Every measure is compared against the same period, so one caption describes the comparison for all of them.",
|
|
@@ -1882,8 +1889,7 @@
|
|
|
1882
1889
|
],
|
|
1883
1890
|
"accessibility": [
|
|
1884
1891
|
"The bar is a labelled region; set overviewLabel to name what is being summarised, such as Safety summary.",
|
|
1885
|
-
"
|
|
1886
|
-
"Colour never carries the trend meaning alone; the arrow direction and the value are both present.",
|
|
1892
|
+
"Colour never carries trend meaning alone; the arrow direction and formatted change value are both included in the accessible text.",
|
|
1887
1893
|
"Measures become selectable only when they are not inactive. Selectable measures form one roving tab stop, so the grid is a single stop and arrow keys move between measures.",
|
|
1888
1894
|
"Set labelTooltip when a measure's label needs qualifying rather than shortening the label into something ambiguous.",
|
|
1889
1895
|
"While loading, the region exposes a busy state and renders skeletons whose type metrics match the resolved content."
|
|
@@ -1892,20 +1898,21 @@
|
|
|
1892
1898
|
"Score and measures are supplied as data; the component owns their type treatment so summary bars stay consistent across pages.",
|
|
1893
1899
|
"Trend is supplied already resolved as a direction, a formatted value, and a tone. Whether a rise reads well is a product decision, so the component never infers tone from the numbers. Derive it with resolveMetricTrend.",
|
|
1894
1900
|
"Omit a trend when there is nothing to report; resolveMetricTrend returns null in that case so no zero change is rendered.",
|
|
1895
|
-
"Omit score to render
|
|
1901
|
+
"Omit score to render a centered Score unavailable cell with a tertiary border and no score fill. Set scoreErrorMessage to replace that copy while the measures remain readable.",
|
|
1896
1902
|
"Loading replaces the score and the measures with skeletons and does not alter the slotted period control.",
|
|
1897
|
-
"At most
|
|
1898
|
-
"The period
|
|
1899
|
-
"
|
|
1900
|
-
"
|
|
1903
|
+
"At most seven measures are shown. Keep larger collections outside the summary bar rather than turning it into a dense dashboard.",
|
|
1904
|
+
"The period and filter controls are slotted rather than owned. Use the period slot when the current range is selectable; otherwise periodLabel supplies fixed current copy in the same md control-frame and label-inset anatomy. Use the filter slot for the application-owned comparison-window control. Slotted Selects use hasBorder false so the 48px bar owns their surrounding boundary.",
|
|
1905
|
+
"A numeric safety score infers fair from 0–50, good from 51–80, and excellent from 81–100. The level can be supplied explicitly when the displayed value is not numeric. The deprecated band field is ignored.",
|
|
1906
|
+
"The safety score is the first grid cell and uses the same track, 8px outer inset, 6px inner padding, dividers, and responsive behavior as metric cells. The display value removes 12px from both block edges of its line box so it does not increase the shared row height. Score remains nonselectable and excluded from metric roving focus.",
|
|
1907
|
+
"During page-controlled scroll collapse, the component preserves its expanded flow height and stationary reporting bar while the metric grid moves and clips beneath it. Elevation remains fitted to the visible surface.",
|
|
1908
|
+
"compact is exactly 48px high and renders only the reporting bar. It omits Score, measures, and footer."
|
|
1901
1909
|
],
|
|
1902
1910
|
"responsiveBehavior": [
|
|
1903
|
-
"The measure grid reflows to fewer columns and finally stacks
|
|
1911
|
+
"The measure grid reflows to fewer columns and finally stacks without horizontal scrolling. Even cell totals prefer complete rows; odd totals retain the densest fitting layout and may leave an orphan in the final row.",
|
|
1904
1912
|
"Every occupied grid track has the same width. When a final row is incomplete, its measures keep the same width as the row above and the unused tracks remain empty.",
|
|
1905
1913
|
"Set metricMinWidth to change the width a measure may shrink to before the grid drops a column.",
|
|
1906
|
-
"The score
|
|
1907
|
-
"
|
|
1908
|
-
"In that stacked summary, the score and trend share one line at the start, while the score band is hidden to preserve space. The period control stays at the upper end, while the current period and comparison sit on separate right-aligned lines beside the score.",
|
|
1914
|
+
"The safety score participates in the same equal-width tracks as measures rather than occupying a separate rail.",
|
|
1915
|
+
"The reporting bar owns an exact 8px inset on every edge. Fixed current copy and slotted controls begin at that inset; their labels share md control-frame geometry and truncate before changing the 48px height.",
|
|
1909
1916
|
"Every measure occupies a full-width row in the stacked state.",
|
|
1910
1917
|
"Set layout to stacked when the owning page shell enters a responsive mode before the card's own container reaches its narrow threshold.",
|
|
1911
1918
|
"CardOverview does not observe scroll, choose sticky offsets, or switch its own presentation. The page owner supplies collapse progress, keeps the card sticky at the appropriate shell inset, and swaps to compact at the 48px endpoint.",
|
|
@@ -1914,7 +1921,7 @@
|
|
|
1914
1921
|
"frameworkCaveats": {
|
|
1915
1922
|
"customElements": [
|
|
1916
1923
|
"Assign score and metrics as JavaScript properties; both are objects and cannot be expressed as HTML attributes.",
|
|
1917
|
-
"Place the period control in the filter slot; the component reserves
|
|
1924
|
+
"Place an optional current-range control in the period slot and the comparison-window control in the filter slot; the component reserves their layout but never computes or renders controls.",
|
|
1918
1925
|
"When driving scroll collapse, update scrollCollapseProgress from page-owned geometry and swap to a separate compact presentation at the endpoint."
|
|
1919
1926
|
],
|
|
1920
1927
|
"react": [
|
|
@@ -1925,7 +1932,7 @@
|
|
|
1925
1932
|
"angular": [
|
|
1926
1933
|
"Bind [score] and [metrics] as properties and read the selected measure from $event.detail on (dsMetricSelect).",
|
|
1927
1934
|
"Derive each trend with resolveMetricTrend so tone stays an explicit product decision.",
|
|
1928
|
-
"Keep sticky geometry and [scrollCollapseProgress] in the page owner; CardOverview only renders the visual collapse."
|
|
1935
|
+
"Keep date math, sticky geometry, and [scrollCollapseProgress] in the page owner; CardOverview only renders the supplied composition and visual collapse."
|
|
1929
1936
|
]
|
|
1930
1937
|
},
|
|
1931
1938
|
"references": [
|
|
@@ -2000,11 +2007,9 @@
|
|
|
2000
2007
|
},
|
|
2001
2008
|
"dependencies": [
|
|
2002
2009
|
"@ds-mo/ui",
|
|
2003
|
-
"@ds-mo/tokens"
|
|
2004
|
-
"@ds-mo/icons"
|
|
2010
|
+
"@ds-mo/tokens"
|
|
2005
2011
|
],
|
|
2006
2012
|
"registryDependencies": [
|
|
2007
|
-
"icon",
|
|
2008
2013
|
"skeleton",
|
|
2009
2014
|
"text",
|
|
2010
2015
|
"tooltip"
|
|
@@ -3823,7 +3828,7 @@
|
|
|
3823
3828
|
],
|
|
3824
3829
|
"states": [
|
|
3825
3830
|
"Every size applies one complete control-density recipe across frame height, inline padding, icon zones, text-container inset, gap, and radius; supporting error content follows the shared 4px field flow.",
|
|
3826
|
-
"The normal field boundary uses the shared secondary inset border. Focus promotes it to the thicker bold-brand inset stroke, while error uses the thicker bold-negative inset stroke without changing geometry.",
|
|
3831
|
+
"The normal field boundary uses the shared secondary inset border. Focus promotes it to the thicker bold-brand inset stroke, while error uses the thicker bold-negative inset stroke without changing geometry. Set hasBorder to false only in chrome that supplies enough surrounding structure; the control then remains borderless at rest, while focused, and while invalid, with semantics and supporting error copy unchanged.",
|
|
3827
3832
|
"Placeholder text is secondary at rest and quaternary while the editable field is focused because it becomes decorative once typing begins.",
|
|
3828
3833
|
"Entered values use the parent surface's primary foreground; prefix icons, suffix content, and resting placeholder text use its secondary foreground.",
|
|
3829
3834
|
"Search fields show a standard borderless CrossCircle icon action only while they contain a value. Clearing emits the empty value and restores focus to the native field.",
|
|
@@ -4376,7 +4381,7 @@
|
|
|
4376
4381
|
{
|
|
4377
4382
|
"name": "message",
|
|
4378
4383
|
"title": "Message",
|
|
4379
|
-
"description": "Channel-neutral message row owning direction, grouping, author, time, delivery metadata, and
|
|
4384
|
+
"description": "Channel-neutral message row owning direction, grouping, author, time, delivery metadata, and persistent or metadata action regions.",
|
|
4380
4385
|
"type": "registry:ui",
|
|
4381
4386
|
"meta": {
|
|
4382
4387
|
"library": "@ds-mo/ui",
|
|
@@ -4387,7 +4392,7 @@
|
|
|
4387
4392
|
"intent": {
|
|
4388
4393
|
"audience": "general",
|
|
4389
4394
|
"status": "experimental",
|
|
4390
|
-
"summary": "Channel-neutral message row owning direction, grouping, author, time, delivery metadata, and
|
|
4395
|
+
"summary": "Channel-neutral message row owning direction, grouping, author, time, delivery metadata, and persistent or metadata action regions.",
|
|
4391
4396
|
"useWhen": [
|
|
4392
4397
|
"A transcript contains messages that need consistent incoming, outgoing, or system layout."
|
|
4393
4398
|
],
|
|
@@ -4396,6 +4401,7 @@
|
|
|
4396
4401
|
],
|
|
4397
4402
|
"commonlyComposedWith": [
|
|
4398
4403
|
"component:ds-message-bubble",
|
|
4404
|
+
"component:ds-message-actions",
|
|
4399
4405
|
"component:ds-message-scroller"
|
|
4400
4406
|
],
|
|
4401
4407
|
"patterns": [
|
|
@@ -4403,14 +4409,16 @@
|
|
|
4403
4409
|
],
|
|
4404
4410
|
"accessibility": [
|
|
4405
4411
|
"Author and time metadata remain textual when they are necessary to interpret the transcript.",
|
|
4406
|
-
"Delivery failure uses negative Failed to send text in the footer while the message bubble keeps its normal outgoing treatment; when time is also visible, a tertiary middle dot separates the failure label and timestamp."
|
|
4412
|
+
"Delivery failure uses negative Failed to send text in the footer while the message bubble keeps its normal outgoing treatment; when time is also visible, a tertiary middle dot separates the failure label and timestamp.",
|
|
4413
|
+
"Hover-only metadata rows remain keyboard reachable, reveal on focus, and stay visible for touch and coarse-pointer input."
|
|
4407
4414
|
],
|
|
4408
4415
|
"states": [
|
|
4409
4416
|
"Pass an ISO timestamp. Message keeps the full value in dateTime and formats the visible value as a localized time; applications must not render a raw ISO string as visible transcript metadata.",
|
|
4410
4417
|
"A visible incoming author uses body-small emphasis with primary foreground; timestamp and delivery metadata remain caption text.",
|
|
4411
4418
|
"Visible author, bubble content, and timestamp or delivery footer use consistent 4px vertical gaps.",
|
|
4412
4419
|
"Grouping joins adjacent bubble corners, shows the incoming author only at the start, and shows delivery/time metadata only at the end. Outgoing author remains in the accessible message label without repeating a visible You label.",
|
|
4413
|
-
"Set showAuthor false only when the product makes participant and assistant roles visually self-evident; continue passing author so the accessible message label remains specific."
|
|
4420
|
+
"Set showAuthor false only when the product makes participant and assistant roles visually self-evident; continue passing author so the accessible message label remains specific.",
|
|
4421
|
+
"Metadata actions precede incoming timestamps and follow outgoing timestamps. In hover mode the complete reserved footer—delivery, timestamp, and actions—fades as one unit without changing geometry; the persistent actions slot retains separate message-level controls."
|
|
4414
4422
|
],
|
|
4415
4423
|
"responsiveBehavior": [
|
|
4416
4424
|
"Outgoing and incoming rows adapt to available width while preserving their directional alignment."
|
|
@@ -4443,6 +4451,10 @@
|
|
|
4443
4451
|
"type": "string",
|
|
4444
4452
|
"required": false
|
|
4445
4453
|
},
|
|
4454
|
+
"metadataVisibility": {
|
|
4455
|
+
"type": "MessageMetadataVisibility",
|
|
4456
|
+
"required": false
|
|
4457
|
+
},
|
|
4446
4458
|
"scrollAnchor": {
|
|
4447
4459
|
"type": "boolean",
|
|
4448
4460
|
"required": false
|
|
@@ -4476,6 +4488,95 @@
|
|
|
4476
4488
|
"text"
|
|
4477
4489
|
]
|
|
4478
4490
|
},
|
|
4491
|
+
{
|
|
4492
|
+
"name": "message-actions",
|
|
4493
|
+
"title": "MessageActions",
|
|
4494
|
+
"description": "Reusable message-level Copy and controlled response-feedback actions with consistent compact presentation and browser clipboard feedback.",
|
|
4495
|
+
"type": "registry:ui",
|
|
4496
|
+
"meta": {
|
|
4497
|
+
"library": "@ds-mo/ui",
|
|
4498
|
+
"distribution": "npm",
|
|
4499
|
+
"storybook": "https://zainadeel.github.io/compomo/?path=/story/message-actions",
|
|
4500
|
+
"source": "src/wc/components/MessageActions/MessageActions.tsx",
|
|
4501
|
+
"intentStatus": "complete",
|
|
4502
|
+
"intent": {
|
|
4503
|
+
"audience": "specialized",
|
|
4504
|
+
"status": "experimental",
|
|
4505
|
+
"summary": "Reusable message-level Copy and controlled response-feedback actions with consistent compact presentation and browser clipboard feedback.",
|
|
4506
|
+
"useWhen": [
|
|
4507
|
+
"A message metadata row needs Copy alone or Copy with mutually exclusive positive and negative response feedback."
|
|
4508
|
+
],
|
|
4509
|
+
"avoidWhen": [
|
|
4510
|
+
"The action executes, retries, regenerates, approves, edits, or otherwise changes message content."
|
|
4511
|
+
],
|
|
4512
|
+
"commonlyComposedWith": [
|
|
4513
|
+
"component:ds-message",
|
|
4514
|
+
"component:ds-agent-response",
|
|
4515
|
+
"component:ds-button-unfilled"
|
|
4516
|
+
],
|
|
4517
|
+
"patterns": [
|
|
4518
|
+
"pattern:conversation",
|
|
4519
|
+
"pattern:agent-chat"
|
|
4520
|
+
],
|
|
4521
|
+
"accessibility": [
|
|
4522
|
+
"Every icon action has a matching tooltip and accessible name.",
|
|
4523
|
+
"Feedback uses genuine pressed toggle semantics and Copy announces its temporary Copied state through the control name."
|
|
4524
|
+
],
|
|
4525
|
+
"states": [
|
|
4526
|
+
"The component owns clipboard execution and temporary copied feedback while the application supplies the exact copyable text.",
|
|
4527
|
+
"Feedback is controlled: the component emits the requested positive, negative, or cleared value while the application owns persistence and consequences.",
|
|
4528
|
+
"Copy, positive feedback, and negative feedback retain one stable order."
|
|
4529
|
+
],
|
|
4530
|
+
"responsiveBehavior": [
|
|
4531
|
+
"The compact action group follows the visibility and metadata placement policy of its owning Message."
|
|
4532
|
+
],
|
|
4533
|
+
"references": [
|
|
4534
|
+
{
|
|
4535
|
+
"label": "Message metadata composition",
|
|
4536
|
+
"path": "src/wc/components/Message/Message.stories.ts"
|
|
4537
|
+
}
|
|
4538
|
+
]
|
|
4539
|
+
},
|
|
4540
|
+
"props": {
|
|
4541
|
+
"copyText": {
|
|
4542
|
+
"type": "string | undefined",
|
|
4543
|
+
"required": false
|
|
4544
|
+
},
|
|
4545
|
+
"feedback": {
|
|
4546
|
+
"type": "MessageFeedback | undefined",
|
|
4547
|
+
"required": false
|
|
4548
|
+
},
|
|
4549
|
+
"feedbackEnabled": {
|
|
4550
|
+
"type": "boolean",
|
|
4551
|
+
"required": false
|
|
4552
|
+
}
|
|
4553
|
+
},
|
|
4554
|
+
"events": [
|
|
4555
|
+
{
|
|
4556
|
+
"name": "dsCopyResult",
|
|
4557
|
+
"detail": "MessageCopyResultEventDetail"
|
|
4558
|
+
},
|
|
4559
|
+
{
|
|
4560
|
+
"name": "dsFeedbackChange",
|
|
4561
|
+
"detail": "MessageFeedback | undefined"
|
|
4562
|
+
}
|
|
4563
|
+
],
|
|
4564
|
+
"slots": [],
|
|
4565
|
+
"exports": {
|
|
4566
|
+
"customElement": "ds-message-actions",
|
|
4567
|
+
"react": "DsMessageActions",
|
|
4568
|
+
"angular": "DsMessageActions"
|
|
4569
|
+
}
|
|
4570
|
+
},
|
|
4571
|
+
"dependencies": [
|
|
4572
|
+
"@ds-mo/ui",
|
|
4573
|
+
"@ds-mo/tokens"
|
|
4574
|
+
],
|
|
4575
|
+
"registryDependencies": [
|
|
4576
|
+
"button-unfilled",
|
|
4577
|
+
"tooltip"
|
|
4578
|
+
]
|
|
4579
|
+
},
|
|
4479
4580
|
{
|
|
4480
4581
|
"name": "message-bubble",
|
|
4481
4582
|
"title": "MessageBubble",
|
|
@@ -6504,7 +6605,7 @@
|
|
|
6504
6605
|
"An empty filtered list composes the message-only body variant of EmptyState. Keep the default neutral no-results message unless localized product guidance makes the outcome clearer.",
|
|
6505
6606
|
"Enable searchable for more than roughly 20 options, user-managed listings, large domains such as addresses, or sets users cannot efficiently scan. Local matching includes option labels, subtext, and section headings; the owner resolves remote data before assigning options.",
|
|
6506
6607
|
"Validation timing belongs to the form owner and may be immediate or deferred until blur or submit; the Select exposes validity and error presentation without imposing that policy.",
|
|
6507
|
-
"The error trigger uses a 1.5px bold-negative inset stroke so invalid state remains distinguishable from the normal 1px border without changing control geometry.",
|
|
6608
|
+
"The error trigger uses a 1.5px bold-negative inset stroke so invalid state remains distinguishable from the normal 1px border without changing control geometry. Set hasBorder to false for chrome where the trigger must remain borderless at rest, when selected or focused, and when invalid; error semantics and supporting copy remain available.",
|
|
6508
6609
|
"An initially empty option set is not an expected Select use case. The no-results state describes a search with no matches, not a source with no choices.",
|
|
6509
6610
|
"Use options for a flat list or sections for grouped choices; when sections are present they take precedence.",
|
|
6510
6611
|
"The background prop describes the actual parent surface and uses the same surface set as ButtonUnfilled."
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"An empty filtered list composes the message-only body variant of EmptyState. Keep the default neutral no-results message unless localized product guidance makes the outcome clearer.",
|
|
75
75
|
"Enable searchable for more than roughly 20 options, user-managed listings, large domains such as addresses, or sets users cannot efficiently scan. Local matching includes option labels, subtext, and section headings; the owner resolves remote data before assigning options.",
|
|
76
76
|
"Validation timing belongs to the form owner and may be immediate or deferred until blur or submit; the Select exposes validity and error presentation without imposing that policy.",
|
|
77
|
-
"The error trigger uses a 1.5px bold-negative inset stroke so invalid state remains distinguishable from the normal 1px border without changing control geometry.",
|
|
77
|
+
"The error trigger uses a 1.5px bold-negative inset stroke so invalid state remains distinguishable from the normal 1px border without changing control geometry. Set hasBorder to false for chrome where the trigger must remain borderless at rest, when selected or focused, and when invalid; error semantics and supporting copy remain available.",
|
|
78
78
|
"An initially empty option set is not an expected Select use case. The no-results state describes a search with no matches, not a source with no choices.",
|
|
79
79
|
"Use options for a flat list or sections for grouped choices; when sections are present they take precedence.",
|
|
80
80
|
"The background prop describes the actual parent surface and uses the same surface set as ButtonUnfilled."
|
|
@@ -201,7 +201,7 @@
|
|
|
201
201
|
"default": "true",
|
|
202
202
|
"required": false,
|
|
203
203
|
"mutable": false,
|
|
204
|
-
"description": "Show the surface-aware inset border."
|
|
204
|
+
"description": "Show the surface-aware inset border, including focused and invalid strokes."
|
|
205
205
|
},
|
|
206
206
|
"icon": {
|
|
207
207
|
"type": "string | undefined",
|
|
@@ -507,7 +507,7 @@
|
|
|
507
507
|
"default": "true",
|
|
508
508
|
"required": false,
|
|
509
509
|
"mutable": false,
|
|
510
|
-
"description": "Show the surface-aware inset border."
|
|
510
|
+
"description": "Show the surface-aware inset border, including focused and invalid strokes."
|
|
511
511
|
},
|
|
512
512
|
"icon": {
|
|
513
513
|
"type": "string | undefined",
|
|
@@ -741,7 +741,7 @@
|
|
|
741
741
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: options, sections.",
|
|
742
742
|
"peerDependencies": {
|
|
743
743
|
"required": [
|
|
744
|
-
"@ds-mo/tokens ^5.1.
|
|
744
|
+
"@ds-mo/tokens ^5.1.1",
|
|
745
745
|
"@ds-mo/icons ^6.4.0"
|
|
746
746
|
],
|
|
747
747
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -770,7 +770,7 @@
|
|
|
770
770
|
},
|
|
771
771
|
{
|
|
772
772
|
"path": "src/wc/components/Select/Select.tsx",
|
|
773
|
-
"content": "import {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\nimport {\n controlWidthClass,\n CONTROL_SUPPORTING_TEXT_VARIANT,\n CONTROL_TEXT_VARIANT,\n DEFAULT_REQUIRED_MESSAGE,\n restoreStringArrayFormState,\n restoreStringFormState,\n setFormControlValue,\n setRepeatedFormControlValue,\n setRequiredValidity,\n type ControlWidth,\n} from '../../utils';\nimport { ChoiceFooter, ChoiceOptionRow, ChoiceSearch } from '../../utils/choice-list-parts';\nimport {\n choiceBackgroundClassMap,\n choiceListUsesIcons,\n choiceListUsesSubtext,\n enabledChoiceIndexes,\n filterChoiceSections,\n flattenChoiceSections,\n resolveChoiceSections,\n type ChoiceBackground,\n type ChoiceOption,\n type ChoiceSection,\n} from '../../utils/choice-list';\nimport { SelectController } from '../../utils/select-controller';\n\nexport type SelectOption = ChoiceOption;\nexport type SelectSection = ChoiceSection;\nexport type SelectBackground = ChoiceBackground;\nexport type SelectSize = 'lg' | 'md' | 'sm' | 'xs';\nexport type SelectWidth = ControlWidth;\nexport type SelectValue = string | string[];\n\nconst ICON_SIZE: Record<SelectSize, 'lg' | 'md' | 'sm' | 'xs'> = {\n lg: 'lg',\n md: 'md',\n sm: 'sm',\n xs: 'xs',\n};\n\nlet selectId = 0;\n\n@Component({\n tag: 'ds-select',\n styleUrl: 'Select.css',\n scoped: true,\n formAssociated: true,\n})\nexport class Select {\n @Element() el!: HTMLElement;\n @AttachInternals() internals!: ElementInternals;\n\n /** Flat choices. Assign arrays through the JavaScript property. */\n @Prop() options: SelectOption[] = [];\n /** Grouped choices; takes precedence over options. Assign through JavaScript. */\n @Prop() sections: SelectSection[] = [];\n /** Enable independent multi-value selection while keeping the popup open. */\n @Prop({ reflect: true }) multiple: boolean = false;\n /** Selected scalar or array value according to `multiple`. */\n @Prop({ mutable: true }) value: SelectValue = '';\n /** Controlled popup visibility. */\n @Prop({ mutable: true, reflect: true }) open: boolean = false;\n /** Native form field name. */\n @Prop({ reflect: true }) name: string | undefined;\n /** Native disabled state. */\n @Prop({ reflect: true }) disabled: boolean = false;\n /** Require one valid selected value. */\n @Prop({ reflect: true }) required: boolean = false;\n /** Validation message used when required is missing. */\n @Prop() requiredMessage: string = DEFAULT_REQUIRED_MESSAGE;\n /** Trigger text shown when no valid value is selected. */\n @Prop() placeholder: string = 'Select';\n /** Control density. */\n @Prop() size: SelectSize = 'md';\n /** Width fit — hug content (default) or fill the parent. */\n @Prop() width: SelectWidth = 'hug';\n /** Shared inactive treatment; removes interaction and form submission. */\n @Prop() isInactive: boolean = false;\n /** Replace the prefix with a loader and disable option interaction. */\n @Prop() isLoading: boolean = false;\n /** Show the selected interaction fill when a valid value exists. */\n @Prop() activeFill: boolean = true;\n /** Show the surface-aware inset border. */\n @Prop() hasBorder: boolean = true;\n /** Optional trigger prefix icon name. */\n @Prop() icon: string | undefined;\n /** Show the clear footer action when a value exists. */\n @Prop() allowClear: boolean = true;\n /** Localized clear action label. */\n @Prop() clearLabel: string = 'Clear';\n /** Localized noun displayed after the selected count in multiple mode. */\n @Prop() selectedLabel: string = 'selected';\n /** Show immediate local filtering over option labels, subtext, and section headings. */\n @Prop() searchable: boolean = false;\n /** Localized search-field placeholder and accessible name. */\n @Prop() searchPlaceholder: string = 'Search';\n /** Localized empty-filter result text. */\n @Prop() noResultsText: string = 'No results found';\n /** Accessible loading status label. */\n @Prop() loadingLabel: string = 'Loading';\n /** Actual parent surface context; omit on primary and secondary surfaces. */\n @Prop() background: SelectBackground | undefined;\n /** Show invalid visual state. */\n @Prop() error: boolean = false;\n /** Error text rendered below the trigger when error is true. */\n @Prop() errorMessage: string | undefined;\n /** ID applied to the internal combobox trigger for external labels. */\n @Prop() inputId: string | undefined;\n /** Direct accessible name when no external label is available. */\n @Prop({ attribute: 'aria-label' }) ariaLabel: string | null = null;\n /** IDs of elements that label the combobox. */\n @Prop({ attribute: 'aria-labelledby' }) ariaLabelledby: string | undefined;\n /** Additional IDs that describe the combobox. */\n @Prop({ attribute: 'aria-describedby' }) ariaDescribedby: string | undefined;\n\n /** Emitted after selection or clearing with the next scalar or array value. */\n @Event() dsChange!: EventEmitter<SelectValue>;\n /** Emitted after the footer clear action. */\n @Event() dsClear!: EventEmitter<void>;\n /** Emitted whenever popup visibility changes. */\n @Event() dsOpenChange!: EventEmitter<boolean>;\n\n @State() private activeIndex = -1;\n @State() private searchTerm = '';\n @State() private formDisabled = false;\n @State() private position = { x: 0, y: 0 };\n @State() private positionReady = false;\n @State() private focusRingVisible = false;\n\n private readonly generatedId = `ds-select-${++selectId}`;\n private readonly listboxId = `${this.generatedId}-listbox`;\n private readonly errorId = `${this.generatedId}-error`;\n private initialValue: SelectValue = '';\n private readonly controller = this.createController();\n\n private createController() {\n // eslint-disable-next-line @typescript-eslint/no-this-alias -- adapter getters preserve reactive component ownership without inheritance.\n const owner = this;\n return new SelectController<SelectOption>({\n get host() {\n return owner.el;\n },\n generatedId: owner.generatedId,\n get options() {\n return owner.visibleOptions;\n },\n get searchable() {\n return owner.searchable;\n },\n get isLoading() {\n return owner.isLoading;\n },\n get isDisabled() {\n return owner.isDisabled;\n },\n get preferredIndex() {\n if (owner.multiple) return -1;\n return owner.visibleOptions.findIndex(\n option => option.value === owner.scalarValue && !option.isInactive\n );\n },\n get open() {\n return owner.open;\n },\n set open(value) {\n owner.open = value;\n },\n get activeIndex() {\n return owner.activeIndex;\n },\n set activeIndex(value) {\n owner.activeIndex = value;\n },\n get searchTerm() {\n return owner.searchTerm;\n },\n set searchTerm(value) {\n owner.searchTerm = value;\n },\n get focusRingVisible() {\n return owner.focusRingVisible;\n },\n set focusRingVisible(value) {\n owner.focusRingVisible = value;\n },\n get position() {\n return owner.position;\n },\n set position(value) {\n owner.position = value;\n },\n get positionReady() {\n return owner.positionReady;\n },\n set positionReady(value) {\n owner.positionReady = value;\n },\n selectOption: option => owner.selectOption(option),\n });\n }\n\n componentWillLoad() {\n this.value = this.normalizeValueForMode(this.value);\n this.initialValue = Array.isArray(this.value) ? [...this.value] : this.value;\n this.syncFormValue();\n }\n\n componentDidLoad() {\n this.controller.connect();\n }\n\n disconnectedCallback() {\n this.controller.disconnect();\n }\n\n @Watch('value')\n @Watch('multiple')\n @Watch('disabled')\n @Watch('isInactive')\n @Watch('required')\n @Watch('name')\n @Watch('options')\n @Watch('sections')\n syncFormValue() {\n if (\n (this.multiple && !Array.isArray(this.value)) ||\n (!this.multiple && Array.isArray(this.value))\n ) {\n this.value = this.normalizeValueForMode(this.value);\n }\n const inactive = this.isDisabled;\n if (this.multiple) {\n const values = this.resolvedValues;\n setRepeatedFormControlValue(this.internals, this.name, values, { inactive });\n } else {\n const value = this.hasSelection ? this.scalarValue : '';\n setFormControlValue(this.internals, value, { inactive });\n }\n const missing = this.required && !inactive && !this.hasSelection;\n setRequiredValidity(this.internals, missing, this.requiredMessage);\n this.controller.optionsChanged();\n }\n\n @Watch('isLoading')\n onLoadingChange() {\n this.controller.loadingChanged();\n }\n\n @Watch('open')\n onOpenChange(open: boolean) {\n this.dsOpenChange.emit(open);\n this.controller.openChanged(open);\n }\n\n @Watch('searchTerm')\n onSearchTermChange() {\n this.controller.searchChanged();\n }\n\n @Watch('activeIndex')\n onActiveIndexChange() {\n this.controller.activeIndexChanged();\n }\n\n formDisabledCallback(disabled: boolean) {\n this.formDisabled = disabled;\n this.syncFormValue();\n }\n\n formResetCallback() {\n this.value = this.normalizeValueForMode(this.initialValue);\n this.closePopup();\n }\n\n formStateRestoreCallback(state: string | File | FormData | null) {\n if (!this.multiple) {\n this.value = restoreStringFormState(state);\n return;\n }\n this.value = restoreStringArrayFormState(state);\n }\n\n @Method()\n async setFocus() {\n this.controller.setFocus();\n }\n\n private get isDisabled(): boolean {\n return this.disabled || this.isInactive || this.formDisabled;\n }\n\n private normalizeValueForMode(value: SelectValue): SelectValue {\n if (this.multiple) {\n return Array.isArray(value) ? [...value] : value ? [value] : [];\n }\n return Array.isArray(value) ? value[0] ?? '' : value;\n }\n\n private get allSections(): SelectSection[] {\n return resolveChoiceSections(this.options, this.sections);\n }\n\n private get allOptions(): SelectOption[] {\n return flattenChoiceSections(this.allSections);\n }\n\n private get visibleSections(): SelectSection[] {\n return this.searchable\n ? filterChoiceSections(this.allSections, this.searchTerm)\n : this.allSections;\n }\n\n private get visibleOptions(): SelectOption[] {\n return flattenChoiceSections(this.visibleSections);\n }\n\n private get scalarValue(): string {\n return typeof this.value === 'string' ? this.value : '';\n }\n\n private get resolvedValues(): string[] {\n if (!this.multiple || !Array.isArray(this.value)) return [];\n const valid = new Set(this.allOptions.map(option => option.value));\n return [...new Set(this.value.filter(value => valid.has(value)))];\n }\n\n private get selectedOption(): SelectOption | undefined {\n if (this.multiple) return undefined;\n return this.allOptions.find(option => option.value === this.scalarValue);\n }\n\n private get hasSelection(): boolean {\n return this.multiple ? this.resolvedValues.length > 0 : Boolean(this.selectedOption);\n }\n\n private get activeOptionId(): string | undefined {\n return this.controller.activeOptionId;\n }\n\n private closePopup(restoreFocus = false) {\n this.controller.closePopup(restoreFocus);\n }\n\n private openPopup(focusVisible: boolean, edge?: 'first' | 'last') {\n this.controller.openPopup(focusVisible, edge);\n }\n\n private selectOption(option: SelectOption) {\n if (option.isInactive || this.isLoading) return;\n if (this.multiple) {\n const current = this.resolvedValues;\n const next = current.includes(option.value)\n ? current.filter(value => value !== option.value)\n : [...current, option.value];\n this.value = next;\n this.dsChange.emit([...next]);\n return;\n }\n this.value = option.value;\n this.dsChange.emit(option.value);\n this.controller.closePopup(true);\n }\n\n private clearSelection = (event: Event) => {\n event.preventDefault();\n event.stopPropagation();\n this.value = this.multiple ? [] : '';\n this.dsChange.emit(this.multiple ? [] : '');\n this.dsClear.emit();\n if (!this.multiple) {\n const enabled = enabledChoiceIndexes(this.visibleOptions);\n this.activeIndex = enabled[0] ?? -1;\n }\n this.controller.focusSearchOrTrigger();\n };\n\n private readonly handleListKeyDown = this.controller.handleListKeyDown;\n private readonly handleTriggerKeyDown = this.controller.handleTriggerKeyDown;\n\n private renderOption(\n option: SelectOption,\n index: number,\n usesIcons: boolean,\n usesSubtext: boolean\n ) {\n const selected = this.multiple\n ? this.resolvedValues.includes(option.value)\n : option.value === this.scalarValue;\n const active = index === this.activeIndex;\n return (\n <ChoiceOptionRow\n size={this.size}\n id={`${this.generatedId}-option-${index}`}\n option={option}\n selected={selected}\n active={active}\n focusRingVisible={this.focusRingVisible}\n usesSubtext={usesSubtext}\n leading={\n this.multiple ? (\n <span\n class=\"ds-choice-item__icon ds-control-icon-box ds-interaction-fill__content\"\n aria-hidden=\"true\"\n >\n <ds-checkbox\n class=\"select-option__checkbox\"\n label=\"\"\n size={this.size}\n checked={selected}\n presentation\n />\n </span>\n ) : usesIcons && option.icon ? (\n <span\n class=\"ds-choice-item__icon ds-control-icon-box ds-interaction-fill__content\"\n aria-hidden=\"true\"\n >\n <ds-icon name={option.icon} size={this.size} color=\"inherit\" />\n </span>\n ) : undefined\n }\n onHover={() => {\n this.focusRingVisible = false;\n this.activeIndex = index;\n }}\n onSelect={() => this.selectOption(option)}\n />\n );\n }\n\n render() {\n const inactive = this.isDisabled;\n const showPlaceholder = !this.hasSelection;\n const count = this.resolvedValues.length;\n const label = this.multiple\n ? `${this.placeholder}${count > 0 ? ` · ${count}` : ''}`\n : showPlaceholder\n ? this.placeholder\n : this.selectedOption?.label;\n const textVariant = CONTROL_TEXT_VARIANT[this.size];\n const iconSize = ICON_SIZE[this.size];\n const usesOptionIcons = !this.multiple && choiceListUsesIcons(this.allOptions);\n const usesOptionSubtext = choiceListUsesSubtext(this.allOptions);\n const showError = this.error && Boolean(this.errorMessage);\n const describedBy =\n [this.ariaDescribedby, showError ? this.errorId : undefined].filter(Boolean).join(' ') ||\n undefined;\n const popupStyle = {\n position: 'fixed',\n left: '0',\n top: '0',\n transform: `translate(${Math.round(this.position.x)}px, ${Math.round(this.position.y)}px)`,\n zIndex: 'var(--dimension-z-index-floating)',\n visibility: this.positionReady ? 'visible' : 'hidden',\n };\n let flatIndex = 0;\n\n return (\n <Host\n class={{\n 'select-host': true,\n 'select-host--multiple': this.multiple,\n 'ds-field-stack': true,\n 'ds-control-inactive': inactive,\n [`ds-control--${this.size}`]: true,\n ...controlWidthClass(this.width),\n [`select-host--background-${this.background}`]: !!this.background,\n }}\n >\n <button\n ref={element => {\n this.controller.setTriggerElement((element as HTMLButtonElement) ?? null);\n }}\n id={this.inputId ?? this.generatedId}\n type=\"button\"\n class={{\n trigger: true,\n 'ds-control-frame': true,\n 'ds-focus-ring-inset': true,\n 'ds-interaction-fill': true,\n 'ds-interaction-fill--selected': !inactive && this.activeFill && this.hasSelection,\n 'trigger--bordered': this.hasBorder || this.error,\n 'trigger--placeholder': showPlaceholder && !this.multiple,\n 'trigger--has-value': this.hasSelection,\n 'wrapper--error': this.error,\n [`ds-control--${this.size}`]: true,\n ...choiceBackgroundClassMap(this.background),\n }}\n disabled={inactive}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={String(this.open)}\n aria-controls={this.open ? this.listboxId : undefined}\n aria-activedescendant={this.open && !this.searchable ? this.activeOptionId : undefined}\n aria-label={this.ariaLabel}\n aria-labelledby={this.ariaLabelledby}\n aria-describedby={describedBy}\n aria-invalid={this.error ? 'true' : undefined}\n aria-required={this.required || undefined}\n aria-busy={this.isLoading ? 'true' : undefined}\n onClick={() => (this.open ? this.closePopup() : this.openPopup(false))}\n onKeyDown={this.handleTriggerKeyDown}\n >\n {(this.icon || this.isLoading) && (\n <span\n class=\"trigger__prefix ds-control-icon-box ds-interaction-fill__content\"\n aria-hidden=\"true\"\n >\n {this.isLoading ? (\n <ds-loader size={iconSize} color=\"inherit\" />\n ) : (\n <ds-icon name={this.icon} size={iconSize} color=\"inherit\" />\n )}\n </span>\n )}\n <ds-text\n class=\"trigger__label ds-control-label-box ds-interaction-fill__content\"\n as=\"span\"\n variant={textVariant}\n color=\"inherit\"\n lineTruncation={1}\n >\n {label}\n </ds-text>\n <span\n class=\"trigger__chevron ds-control-icon-box ds-interaction-fill__content\"\n aria-hidden=\"true\"\n >\n <ds-icon name=\"ChevronDown\" size={iconSize} color=\"inherit\" />\n </span>\n </button>\n\n {this.open && (\n <div\n popover=\"manual\"\n ref={element => {\n this.controller.setPopupElement((element as HTMLDivElement) ?? null);\n }}\n class=\"select-popup ds-choice-popup\"\n style={popupStyle}\n >\n {this.searchable && (\n <ChoiceSearch\n size={this.size}\n value={this.searchTerm}\n placeholder={this.searchPlaceholder}\n controls={this.listboxId}\n activeDescendant={this.activeOptionId}\n inputRef={this.controller.setSearchElement}\n clearLabel={this.clearLabel}\n onValueChange={value => {\n this.searchTerm = value;\n }}\n onKeyDown={event => this.handleListKeyDown(event)}\n />\n )}\n <div\n id={this.listboxId}\n class=\"ds-choice-list\"\n role=\"listbox\"\n aria-multiselectable={this.multiple ? 'true' : undefined}\n aria-label={this.ariaLabel ?? this.placeholder}\n aria-busy={this.isLoading ? 'true' : undefined}\n >\n {this.isLoading ? (\n <div\n class=\"ds-choice-loading ds-empty-region\"\n role=\"option\"\n aria-selected=\"false\"\n aria-disabled=\"true\"\n aria-label={this.loadingLabel}\n aria-live=\"polite\"\n >\n <ds-loader size={this.size} color=\"inherit\" />\n </div>\n ) : this.visibleOptions.length === 0 ? (\n <div\n class=\"ds-choice-empty ds-empty-region\"\n role=\"option\"\n aria-selected=\"false\"\n aria-disabled=\"true\"\n aria-label={this.noResultsText}\n aria-live=\"polite\"\n >\n <ds-empty-state body={this.noResultsText} />\n </div>\n ) : (\n this.visibleSections.map(section => (\n <div\n class={{\n 'ds-choice-section': true,\n 'ds-chrome-column': true,\n 'ds-chrome-space--sm': true,\n 'ds-choice-section--divided': !!section.divider,\n }}\n role={section.header ? 'group' : undefined}\n aria-label={section.header}\n >\n {section.header && (\n <ds-text\n class={`ds-choice-section__header ds-control--${this.size}`}\n as=\"span\"\n variant={CONTROL_SUPPORTING_TEXT_VARIANT[this.size]}\n emphasis\n color=\"primary\"\n aria-hidden=\"true\"\n >\n {section.header}\n </ds-text>\n )}\n {section.options.map(option =>\n this.renderOption(option, flatIndex++, usesOptionIcons, usesOptionSubtext)\n )}\n </div>\n ))\n )}\n </div>\n {this.allowClear && this.hasSelection && !this.isLoading && (\n <ChoiceFooter\n size={this.size}\n summary={\n this.multiple ? `${count} ${this.selectedLabel}` : undefined\n }\n clearLabel={this.clearLabel}\n onClear={this.clearSelection}\n />\n )}\n </div>\n )}\n\n {showError && (\n <ds-text\n class=\"error-text\"\n as=\"div\"\n variant=\"text-body-small\"\n color=\"negative\"\n textId={this.errorId}\n role=\"alert\"\n >\n {this.errorMessage}\n </ds-text>\n )}\n </Host>\n );\n }\n}\n",
|
|
773
|
+
"content": "import {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\nimport {\n controlWidthClass,\n CONTROL_SUPPORTING_TEXT_VARIANT,\n CONTROL_TEXT_VARIANT,\n DEFAULT_REQUIRED_MESSAGE,\n restoreStringArrayFormState,\n restoreStringFormState,\n setFormControlValue,\n setRepeatedFormControlValue,\n setRequiredValidity,\n type ControlWidth,\n} from '../../utils';\nimport { ChoiceFooter, ChoiceOptionRow, ChoiceSearch } from '../../utils/choice-list-parts';\nimport {\n choiceBackgroundClassMap,\n choiceListUsesIcons,\n choiceListUsesSubtext,\n enabledChoiceIndexes,\n filterChoiceSections,\n flattenChoiceSections,\n resolveChoiceSections,\n type ChoiceBackground,\n type ChoiceOption,\n type ChoiceSection,\n} from '../../utils/choice-list';\nimport { SelectController } from '../../utils/select-controller';\n\nexport type SelectOption = ChoiceOption;\nexport type SelectSection = ChoiceSection;\nexport type SelectBackground = ChoiceBackground;\nexport type SelectSize = 'lg' | 'md' | 'sm' | 'xs';\nexport type SelectWidth = ControlWidth;\nexport type SelectValue = string | string[];\n\nconst ICON_SIZE: Record<SelectSize, 'lg' | 'md' | 'sm' | 'xs'> = {\n lg: 'lg',\n md: 'md',\n sm: 'sm',\n xs: 'xs',\n};\n\nlet selectId = 0;\n\n@Component({\n tag: 'ds-select',\n styleUrl: 'Select.css',\n scoped: true,\n formAssociated: true,\n})\nexport class Select {\n @Element() el!: HTMLElement;\n @AttachInternals() internals!: ElementInternals;\n\n /** Flat choices. Assign arrays through the JavaScript property. */\n @Prop() options: SelectOption[] = [];\n /** Grouped choices; takes precedence over options. Assign through JavaScript. */\n @Prop() sections: SelectSection[] = [];\n /** Enable independent multi-value selection while keeping the popup open. */\n @Prop({ reflect: true }) multiple: boolean = false;\n /** Selected scalar or array value according to `multiple`. */\n @Prop({ mutable: true }) value: SelectValue = '';\n /** Controlled popup visibility. */\n @Prop({ mutable: true, reflect: true }) open: boolean = false;\n /** Native form field name. */\n @Prop({ reflect: true }) name: string | undefined;\n /** Native disabled state. */\n @Prop({ reflect: true }) disabled: boolean = false;\n /** Require one valid selected value. */\n @Prop({ reflect: true }) required: boolean = false;\n /** Validation message used when required is missing. */\n @Prop() requiredMessage: string = DEFAULT_REQUIRED_MESSAGE;\n /** Trigger text shown when no valid value is selected. */\n @Prop() placeholder: string = 'Select';\n /** Control density. */\n @Prop() size: SelectSize = 'md';\n /** Width fit — hug content (default) or fill the parent. */\n @Prop() width: SelectWidth = 'hug';\n /** Shared inactive treatment; removes interaction and form submission. */\n @Prop() isInactive: boolean = false;\n /** Replace the prefix with a loader and disable option interaction. */\n @Prop() isLoading: boolean = false;\n /** Show the selected interaction fill when a valid value exists. */\n @Prop() activeFill: boolean = true;\n /** Show the surface-aware inset border, including focused and invalid strokes. */\n @Prop() hasBorder: boolean = true;\n /** Optional trigger prefix icon name. */\n @Prop() icon: string | undefined;\n /** Show the clear footer action when a value exists. */\n @Prop() allowClear: boolean = true;\n /** Localized clear action label. */\n @Prop() clearLabel: string = 'Clear';\n /** Localized noun displayed after the selected count in multiple mode. */\n @Prop() selectedLabel: string = 'selected';\n /** Show immediate local filtering over option labels, subtext, and section headings. */\n @Prop() searchable: boolean = false;\n /** Localized search-field placeholder and accessible name. */\n @Prop() searchPlaceholder: string = 'Search';\n /** Localized empty-filter result text. */\n @Prop() noResultsText: string = 'No results found';\n /** Accessible loading status label. */\n @Prop() loadingLabel: string = 'Loading';\n /** Actual parent surface context; omit on primary and secondary surfaces. */\n @Prop() background: SelectBackground | undefined;\n /** Show invalid visual state. */\n @Prop() error: boolean = false;\n /** Error text rendered below the trigger when error is true. */\n @Prop() errorMessage: string | undefined;\n /** ID applied to the internal combobox trigger for external labels. */\n @Prop() inputId: string | undefined;\n /** Direct accessible name when no external label is available. */\n @Prop({ attribute: 'aria-label' }) ariaLabel: string | null = null;\n /** IDs of elements that label the combobox. */\n @Prop({ attribute: 'aria-labelledby' }) ariaLabelledby: string | undefined;\n /** Additional IDs that describe the combobox. */\n @Prop({ attribute: 'aria-describedby' }) ariaDescribedby: string | undefined;\n\n /** Emitted after selection or clearing with the next scalar or array value. */\n @Event() dsChange!: EventEmitter<SelectValue>;\n /** Emitted after the footer clear action. */\n @Event() dsClear!: EventEmitter<void>;\n /** Emitted whenever popup visibility changes. */\n @Event() dsOpenChange!: EventEmitter<boolean>;\n\n @State() private activeIndex = -1;\n @State() private searchTerm = '';\n @State() private formDisabled = false;\n @State() private position = { x: 0, y: 0 };\n @State() private positionReady = false;\n @State() private focusRingVisible = false;\n\n private readonly generatedId = `ds-select-${++selectId}`;\n private readonly listboxId = `${this.generatedId}-listbox`;\n private readonly errorId = `${this.generatedId}-error`;\n private initialValue: SelectValue = '';\n private readonly controller = this.createController();\n\n private createController() {\n // eslint-disable-next-line @typescript-eslint/no-this-alias -- adapter getters preserve reactive component ownership without inheritance.\n const owner = this;\n return new SelectController<SelectOption>({\n get host() {\n return owner.el;\n },\n generatedId: owner.generatedId,\n get options() {\n return owner.visibleOptions;\n },\n get searchable() {\n return owner.searchable;\n },\n get isLoading() {\n return owner.isLoading;\n },\n get isDisabled() {\n return owner.isDisabled;\n },\n get preferredIndex() {\n if (owner.multiple) return -1;\n return owner.visibleOptions.findIndex(\n option => option.value === owner.scalarValue && !option.isInactive\n );\n },\n get open() {\n return owner.open;\n },\n set open(value) {\n owner.open = value;\n },\n get activeIndex() {\n return owner.activeIndex;\n },\n set activeIndex(value) {\n owner.activeIndex = value;\n },\n get searchTerm() {\n return owner.searchTerm;\n },\n set searchTerm(value) {\n owner.searchTerm = value;\n },\n get focusRingVisible() {\n return owner.focusRingVisible;\n },\n set focusRingVisible(value) {\n owner.focusRingVisible = value;\n },\n get position() {\n return owner.position;\n },\n set position(value) {\n owner.position = value;\n },\n get positionReady() {\n return owner.positionReady;\n },\n set positionReady(value) {\n owner.positionReady = value;\n },\n selectOption: option => owner.selectOption(option),\n });\n }\n\n componentWillLoad() {\n this.value = this.normalizeValueForMode(this.value);\n this.initialValue = Array.isArray(this.value) ? [...this.value] : this.value;\n this.syncFormValue();\n }\n\n componentDidLoad() {\n this.controller.connect();\n }\n\n disconnectedCallback() {\n this.controller.disconnect();\n }\n\n @Watch('value')\n @Watch('multiple')\n @Watch('disabled')\n @Watch('isInactive')\n @Watch('required')\n @Watch('name')\n @Watch('options')\n @Watch('sections')\n syncFormValue() {\n if (\n (this.multiple && !Array.isArray(this.value)) ||\n (!this.multiple && Array.isArray(this.value))\n ) {\n this.value = this.normalizeValueForMode(this.value);\n }\n const inactive = this.isDisabled;\n if (this.multiple) {\n const values = this.resolvedValues;\n setRepeatedFormControlValue(this.internals, this.name, values, { inactive });\n } else {\n const value = this.hasSelection ? this.scalarValue : '';\n setFormControlValue(this.internals, value, { inactive });\n }\n const missing = this.required && !inactive && !this.hasSelection;\n setRequiredValidity(this.internals, missing, this.requiredMessage);\n this.controller.optionsChanged();\n }\n\n @Watch('isLoading')\n onLoadingChange() {\n this.controller.loadingChanged();\n }\n\n @Watch('open')\n onOpenChange(open: boolean) {\n this.dsOpenChange.emit(open);\n this.controller.openChanged(open);\n }\n\n @Watch('searchTerm')\n onSearchTermChange() {\n this.controller.searchChanged();\n }\n\n @Watch('activeIndex')\n onActiveIndexChange() {\n this.controller.activeIndexChanged();\n }\n\n formDisabledCallback(disabled: boolean) {\n this.formDisabled = disabled;\n this.syncFormValue();\n }\n\n formResetCallback() {\n this.value = this.normalizeValueForMode(this.initialValue);\n this.closePopup();\n }\n\n formStateRestoreCallback(state: string | File | FormData | null) {\n if (!this.multiple) {\n this.value = restoreStringFormState(state);\n return;\n }\n this.value = restoreStringArrayFormState(state);\n }\n\n @Method()\n async setFocus() {\n this.controller.setFocus();\n }\n\n private get isDisabled(): boolean {\n return this.disabled || this.isInactive || this.formDisabled;\n }\n\n private normalizeValueForMode(value: SelectValue): SelectValue {\n if (this.multiple) {\n return Array.isArray(value) ? [...value] : value ? [value] : [];\n }\n return Array.isArray(value) ? value[0] ?? '' : value;\n }\n\n private get allSections(): SelectSection[] {\n return resolveChoiceSections(this.options, this.sections);\n }\n\n private get allOptions(): SelectOption[] {\n return flattenChoiceSections(this.allSections);\n }\n\n private get visibleSections(): SelectSection[] {\n return this.searchable\n ? filterChoiceSections(this.allSections, this.searchTerm)\n : this.allSections;\n }\n\n private get visibleOptions(): SelectOption[] {\n return flattenChoiceSections(this.visibleSections);\n }\n\n private get scalarValue(): string {\n return typeof this.value === 'string' ? this.value : '';\n }\n\n private get resolvedValues(): string[] {\n if (!this.multiple || !Array.isArray(this.value)) return [];\n const valid = new Set(this.allOptions.map(option => option.value));\n return [...new Set(this.value.filter(value => valid.has(value)))];\n }\n\n private get selectedOption(): SelectOption | undefined {\n if (this.multiple) return undefined;\n return this.allOptions.find(option => option.value === this.scalarValue);\n }\n\n private get hasSelection(): boolean {\n return this.multiple ? this.resolvedValues.length > 0 : Boolean(this.selectedOption);\n }\n\n private get activeOptionId(): string | undefined {\n return this.controller.activeOptionId;\n }\n\n private closePopup(restoreFocus = false) {\n this.controller.closePopup(restoreFocus);\n }\n\n private openPopup(focusVisible: boolean, edge?: 'first' | 'last') {\n this.controller.openPopup(focusVisible, edge);\n }\n\n private selectOption(option: SelectOption) {\n if (option.isInactive || this.isLoading) return;\n if (this.multiple) {\n const current = this.resolvedValues;\n const next = current.includes(option.value)\n ? current.filter(value => value !== option.value)\n : [...current, option.value];\n this.value = next;\n this.dsChange.emit([...next]);\n return;\n }\n this.value = option.value;\n this.dsChange.emit(option.value);\n this.controller.closePopup(true);\n }\n\n private clearSelection = (event: Event) => {\n event.preventDefault();\n event.stopPropagation();\n this.value = this.multiple ? [] : '';\n this.dsChange.emit(this.multiple ? [] : '');\n this.dsClear.emit();\n if (!this.multiple) {\n const enabled = enabledChoiceIndexes(this.visibleOptions);\n this.activeIndex = enabled[0] ?? -1;\n }\n this.controller.focusSearchOrTrigger();\n };\n\n private readonly handleListKeyDown = this.controller.handleListKeyDown;\n private readonly handleTriggerKeyDown = this.controller.handleTriggerKeyDown;\n\n private renderOption(\n option: SelectOption,\n index: number,\n usesIcons: boolean,\n usesSubtext: boolean\n ) {\n const selected = this.multiple\n ? this.resolvedValues.includes(option.value)\n : option.value === this.scalarValue;\n const active = index === this.activeIndex;\n return (\n <ChoiceOptionRow\n size={this.size}\n id={`${this.generatedId}-option-${index}`}\n option={option}\n selected={selected}\n active={active}\n focusRingVisible={this.focusRingVisible}\n usesSubtext={usesSubtext}\n leading={\n this.multiple ? (\n <span\n class=\"ds-choice-item__icon ds-control-icon-box ds-interaction-fill__content\"\n aria-hidden=\"true\"\n >\n <ds-checkbox\n class=\"select-option__checkbox\"\n label=\"\"\n size={this.size}\n checked={selected}\n presentation\n />\n </span>\n ) : usesIcons && option.icon ? (\n <span\n class=\"ds-choice-item__icon ds-control-icon-box ds-interaction-fill__content\"\n aria-hidden=\"true\"\n >\n <ds-icon name={option.icon} size={this.size} color=\"inherit\" />\n </span>\n ) : undefined\n }\n onHover={() => {\n this.focusRingVisible = false;\n this.activeIndex = index;\n }}\n onSelect={() => this.selectOption(option)}\n />\n );\n }\n\n render() {\n const inactive = this.isDisabled;\n const showPlaceholder = !this.hasSelection;\n const count = this.resolvedValues.length;\n const label = this.multiple\n ? `${this.placeholder}${count > 0 ? ` · ${count}` : ''}`\n : showPlaceholder\n ? this.placeholder\n : this.selectedOption?.label;\n const textVariant = CONTROL_TEXT_VARIANT[this.size];\n const iconSize = ICON_SIZE[this.size];\n const usesOptionIcons = !this.multiple && choiceListUsesIcons(this.allOptions);\n const usesOptionSubtext = choiceListUsesSubtext(this.allOptions);\n const showError = this.error && Boolean(this.errorMessage);\n const describedBy =\n [this.ariaDescribedby, showError ? this.errorId : undefined].filter(Boolean).join(' ') ||\n undefined;\n const popupStyle = {\n position: 'fixed',\n left: '0',\n top: '0',\n transform: `translate(${Math.round(this.position.x)}px, ${Math.round(this.position.y)}px)`,\n zIndex: 'var(--dimension-z-index-floating)',\n visibility: this.positionReady ? 'visible' : 'hidden',\n };\n let flatIndex = 0;\n\n return (\n <Host\n class={{\n 'select-host': true,\n 'select-host--multiple': this.multiple,\n 'ds-field-stack': true,\n 'ds-control-inactive': inactive,\n [`ds-control--${this.size}`]: true,\n ...controlWidthClass(this.width),\n [`select-host--background-${this.background}`]: !!this.background,\n }}\n >\n <button\n ref={element => {\n this.controller.setTriggerElement((element as HTMLButtonElement) ?? null);\n }}\n id={this.inputId ?? this.generatedId}\n type=\"button\"\n class={{\n trigger: true,\n 'ds-control-frame': true,\n 'ds-focus-ring-inset': true,\n 'ds-interaction-fill': true,\n 'ds-interaction-fill--selected': !inactive && this.activeFill && this.hasSelection,\n 'trigger--bordered': this.hasBorder,\n 'trigger--placeholder': showPlaceholder && !this.multiple,\n 'trigger--has-value': this.hasSelection,\n 'wrapper--error': this.hasBorder && this.error,\n [`ds-control--${this.size}`]: true,\n ...choiceBackgroundClassMap(this.background),\n }}\n disabled={inactive}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={String(this.open)}\n aria-controls={this.open ? this.listboxId : undefined}\n aria-activedescendant={this.open && !this.searchable ? this.activeOptionId : undefined}\n aria-label={this.ariaLabel}\n aria-labelledby={this.ariaLabelledby}\n aria-describedby={describedBy}\n aria-invalid={this.error ? 'true' : undefined}\n aria-required={this.required || undefined}\n aria-busy={this.isLoading ? 'true' : undefined}\n onClick={() => (this.open ? this.closePopup() : this.openPopup(false))}\n onKeyDown={this.handleTriggerKeyDown}\n >\n {(this.icon || this.isLoading) && (\n <span\n class=\"trigger__prefix ds-control-icon-box ds-interaction-fill__content\"\n aria-hidden=\"true\"\n >\n {this.isLoading ? (\n <ds-loader size={iconSize} color=\"inherit\" />\n ) : (\n <ds-icon name={this.icon} size={iconSize} color=\"inherit\" />\n )}\n </span>\n )}\n <ds-text\n class=\"trigger__label ds-control-label-box ds-interaction-fill__content\"\n as=\"span\"\n variant={textVariant}\n color=\"inherit\"\n lineTruncation={1}\n >\n {label}\n </ds-text>\n <span\n class=\"trigger__chevron ds-control-icon-box ds-interaction-fill__content\"\n aria-hidden=\"true\"\n >\n <ds-icon name=\"ChevronDown\" size={iconSize} color=\"inherit\" />\n </span>\n </button>\n\n {this.open && (\n <div\n popover=\"manual\"\n ref={element => {\n this.controller.setPopupElement((element as HTMLDivElement) ?? null);\n }}\n class=\"select-popup ds-choice-popup\"\n style={popupStyle}\n >\n {this.searchable && (\n <ChoiceSearch\n size={this.size}\n value={this.searchTerm}\n placeholder={this.searchPlaceholder}\n controls={this.listboxId}\n activeDescendant={this.activeOptionId}\n inputRef={this.controller.setSearchElement}\n clearLabel={this.clearLabel}\n onValueChange={value => {\n this.searchTerm = value;\n }}\n onKeyDown={event => this.handleListKeyDown(event)}\n />\n )}\n <div\n id={this.listboxId}\n class=\"ds-choice-list\"\n role=\"listbox\"\n aria-multiselectable={this.multiple ? 'true' : undefined}\n aria-label={this.ariaLabel ?? this.placeholder}\n aria-busy={this.isLoading ? 'true' : undefined}\n >\n {this.isLoading ? (\n <div\n class=\"ds-choice-loading ds-empty-region\"\n role=\"option\"\n aria-selected=\"false\"\n aria-disabled=\"true\"\n aria-label={this.loadingLabel}\n aria-live=\"polite\"\n >\n <ds-loader size={this.size} color=\"inherit\" />\n </div>\n ) : this.visibleOptions.length === 0 ? (\n <div\n class=\"ds-choice-empty ds-empty-region\"\n role=\"option\"\n aria-selected=\"false\"\n aria-disabled=\"true\"\n aria-label={this.noResultsText}\n aria-live=\"polite\"\n >\n <ds-empty-state body={this.noResultsText} />\n </div>\n ) : (\n this.visibleSections.map(section => (\n <div\n class={{\n 'ds-choice-section': true,\n 'ds-chrome-column': true,\n 'ds-chrome-space--sm': true,\n 'ds-choice-section--divided': !!section.divider,\n }}\n role={section.header ? 'group' : undefined}\n aria-label={section.header}\n >\n {section.header && (\n <ds-text\n class={`ds-choice-section__header ds-control--${this.size}`}\n as=\"span\"\n variant={CONTROL_SUPPORTING_TEXT_VARIANT[this.size]}\n emphasis\n color=\"primary\"\n aria-hidden=\"true\"\n >\n {section.header}\n </ds-text>\n )}\n {section.options.map(option =>\n this.renderOption(option, flatIndex++, usesOptionIcons, usesOptionSubtext)\n )}\n </div>\n ))\n )}\n </div>\n {this.allowClear && this.hasSelection && !this.isLoading && (\n <ChoiceFooter\n size={this.size}\n summary={\n this.multiple ? `${count} ${this.selectedLabel}` : undefined\n }\n clearLabel={this.clearLabel}\n onClear={this.clearSelection}\n />\n )}\n </div>\n )}\n\n {showError && (\n <ds-text\n class=\"error-text\"\n as=\"div\"\n variant=\"text-body-small\"\n color=\"negative\"\n textId={this.errorId}\n role=\"alert\"\n >\n {this.errorMessage}\n </ds-text>\n )}\n </Host>\n );\n }\n}\n",
|
|
774
774
|
"type": "registry:ui"
|
|
775
775
|
}
|
|
776
776
|
]
|
|
@@ -556,7 +556,7 @@
|
|
|
556
556
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: navigation, pageChrome, tools.",
|
|
557
557
|
"peerDependencies": {
|
|
558
558
|
"required": [
|
|
559
|
-
"@ds-mo/tokens ^5.1.
|
|
559
|
+
"@ds-mo/tokens ^5.1.1",
|
|
560
560
|
"@ds-mo/icons ^6.4.0"
|
|
561
561
|
],
|
|
562
562
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -390,7 +390,7 @@
|
|
|
390
390
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: headers, items.",
|
|
391
391
|
"peerDependencies": {
|
|
392
392
|
"required": [
|
|
393
|
-
"@ds-mo/tokens ^5.1.
|
|
393
|
+
"@ds-mo/tokens ^5.1.1",
|
|
394
394
|
"@ds-mo/icons ^6.4.0"
|
|
395
395
|
],
|
|
396
396
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|