@ds-mo/ui 14.17.1 → 14.18.1
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/README.md +7 -0
- package/dist/.package-ready.json +1 -1
- package/dist/agent-patterns.json +9 -8
- package/dist/agent.json +103 -45
- package/dist/angular/ds-button-filled.d.ts +1 -1
- package/dist/angular/ds-button-filled.js +3 -3
- package/dist/angular/ds-button-unfilled.d.ts +1 -1
- package/dist/angular/ds-button-unfilled.js +3 -3
- package/dist/angular/ds-filter-menu.d.ts +1 -1
- package/dist/angular/ds-filter-menu.js +3 -3
- package/dist/angular/ds-input.d.ts +1 -1
- package/dist/angular/ds-input.js +3 -3
- package/dist/angular/ds-menu.d.ts +1 -1
- package/dist/angular/ds-menu.js +3 -3
- package/dist/angular/ds-mobile-bar-nav.d.ts +1 -1
- package/dist/angular/ds-mobile-bar-nav.js +3 -3
- package/dist/angular/ds-panel-tool-header.d.ts +3 -8
- package/dist/angular/ds-panel-tools.d.ts +3 -8
- package/dist/angular/ds-select.d.ts +1 -1
- package/dist/angular/ds-select.js +3 -3
- package/dist/angular/ds-tooltip.d.ts +1 -1
- package/dist/angular/ds-tooltip.js +3 -3
- package/dist/components/ds-agent-activity.js +1 -1
- package/dist/components/ds-agent-questionnaire.js +1 -1
- package/dist/components/ds-agent-response.js +1 -1
- package/dist/components/ds-agent-source-list.js +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-badge.js +1 -1
- package/dist/components/ds-banner.js +1 -1
- package/dist/components/ds-banner.js.map +1 -1
- package/dist/components/ds-bar-action.js +1 -1
- package/dist/components/ds-bar-action.js.map +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-breadcrumb.js +1 -1
- package/dist/components/ds-button-filled.js +1 -1
- package/dist/components/ds-button-unfilled.js +1 -1
- package/dist/components/ds-card-chart.js +1 -1
- package/dist/components/ds-card-chart.js.map +1 -1
- package/dist/components/ds-card-overview.js +1 -1
- package/dist/components/ds-card-setting.js +1 -1
- package/dist/components/ds-card-setting.js.map +1 -1
- package/dist/components/ds-chart-legend.js +1 -1
- package/dist/components/ds-chart.js +1 -1
- package/dist/components/ds-checkbox.js +1 -1
- package/dist/components/ds-chip.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-conversation-list.js +1 -1
- package/dist/components/ds-conversation-list.js.map +1 -1
- package/dist/components/ds-empty-state.js +1 -1
- package/dist/components/ds-field.js +1 -1
- package/dist/components/ds-filter-menu.js +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-markdown.js +1 -1
- package/dist/components/ds-menu.js +1 -1
- package/dist/components/ds-message-actions.js +1 -1
- package/dist/components/ds-message-actions.js.map +1 -1
- package/dist/components/ds-message-composer.js +1 -1
- package/dist/components/ds-message-composer.js.map +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-modal.js +1 -1
- package/dist/components/ds-pagination.js +1 -1
- package/dist/components/ds-panel-nav.js +1 -1
- package/dist/components/ds-panel-sub-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-paper-texture.js +1 -1
- package/dist/components/ds-radio.js +1 -1
- package/dist/components/ds-select.js +1 -1
- package/dist/components/ds-shell-app.js +1 -1
- package/dist/components/ds-shell-app.js.map +1 -1
- package/dist/components/ds-shell-page.js +1 -1
- package/dist/components/ds-shell-tools.js +1 -1
- package/dist/components/ds-skeleton.js +1 -1
- package/dist/components/ds-slider.js +1 -1
- package/dist/components/ds-swatch-picker.js +1 -1
- package/dist/components/ds-switch.js +1 -1
- package/dist/components/ds-tab-group.js +1 -1
- package/dist/components/ds-table-filter.js +1 -1
- package/dist/components/ds-table-filter.js.map +1 -1
- package/dist/components/ds-table-saved-views.js +1 -1
- package/dist/components/ds-table-sort.js +1 -1
- package/dist/components/ds-table-sort.js.map +1 -1
- package/dist/components/ds-table-toolbar.js +1 -1
- package/dist/components/ds-table-toolbar.js.map +1 -1
- package/dist/components/ds-table.js +1 -1
- package/dist/components/ds-table.js.map +1 -1
- package/dist/components/ds-tag.js +1 -1
- package/dist/components/ds-text.js +1 -1
- package/dist/components/ds-toast.js +1 -1
- package/dist/components/ds-toast.js.map +1 -1
- package/dist/components/ds-tooltip-chart.js +1 -1
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/ds-typing-indicator.js +1 -1
- package/dist/components/ds-typing-indicator.js.map +1 -1
- package/dist/components/{p-C0X2zKbB.js → p-1Hu9jlju.js} +2 -2
- package/dist/components/{p-DQqOzDEq.js → p-B00PEE6t.js} +2 -2
- package/dist/components/p-B0Byw6OX.js +2 -0
- package/dist/components/p-B0Byw6OX.js.map +1 -0
- package/dist/components/{p-D1YhYulL.js → p-B1JRCDHS.js} +2 -2
- package/dist/components/p-BBG6Sswb.js +2 -0
- package/dist/components/{p-23u3lIr1.js.map → p-BBG6Sswb.js.map} +1 -1
- package/dist/components/{p-D8Qd6gkf.js → p-BCOl1x0_.js} +2 -2
- package/dist/components/{p-Dg9qiMDa.js → p-BHVOiWz5.js} +2 -2
- package/dist/components/p-BPG0r_mC.js +2 -0
- package/dist/components/p-BPG0r_mC.js.map +1 -0
- package/dist/components/p-BUDAwJVV.js +2 -0
- package/dist/components/p-BUDAwJVV.js.map +1 -0
- package/dist/components/{p-DHuyj-9J.js → p-BXN-e7vF.js} +2 -2
- package/dist/components/{p-Bn8NryHK.js → p-B_jZIC9R.js} +2 -2
- package/dist/components/{p-7tZx4ukz.js → p-Bbb9A3NV.js} +2 -2
- package/dist/components/p-Bece5KH3.js +2 -0
- package/dist/components/p-Bece5KH3.js.map +1 -0
- package/dist/components/{p-ruPTIV6t.js → p-BhYS_Ump.js} +2 -2
- package/dist/components/p-Bkh7scMQ.js +2 -0
- package/dist/components/{p-DsJW5W3W.js.map → p-Bkh7scMQ.js.map} +1 -1
- package/dist/components/{p-B0PEg5RF.js → p-BknXYAEc.js} +2 -2
- package/dist/components/{p-C4TgWJi9.js → p-Bu3dOjpW.js} +2 -2
- package/dist/components/{p-BVlfQ8xZ.js → p-C-Y7gYgz.js} +2 -2
- package/dist/components/p-C-Y7gYgz.js.map +1 -0
- package/dist/components/{p-DAqSoyd4.js → p-C6R5Lft0.js} +2 -2
- package/dist/components/{p-PD1Vfg0t.js → p-C9gC4haA.js} +2 -2
- package/dist/components/{p-BGXqFq2C.js → p-CAnnQL1F.js} +2 -2
- package/dist/components/p-CE2IKOsy.js +2 -0
- package/dist/components/p-CE2IKOsy.js.map +1 -0
- package/dist/components/p-CKVHrOEp.js +2 -0
- package/dist/components/{p-DIEK54fV.js.map → p-CKVHrOEp.js.map} +1 -1
- package/dist/components/{p-BHz78C8h.js → p-CLVxgTme.js} +2 -2
- package/dist/components/p-CY4YFAT3.js +2 -0
- package/dist/components/p-CY4YFAT3.js.map +1 -0
- package/dist/components/{p-y4jhIkRc.js → p-Cg0kimXZ.js} +2 -2
- package/dist/components/p-CqQFowZd.js +2 -0
- package/dist/components/p-CqQFowZd.js.map +1 -0
- package/dist/components/{p-BhYWdbEp.js → p-CsBICYmt.js} +2 -2
- package/dist/components/p-CwjVgUqy.js +2 -0
- package/dist/components/p-CwjVgUqy.js.map +1 -0
- package/dist/components/{p-BHDkJmrC.js → p-D123Jvp-.js} +2 -2
- package/dist/components/p-D1eEgwcP.js +2 -0
- package/dist/components/p-D1eEgwcP.js.map +1 -0
- package/dist/components/{p-CzcWZiH-.js → p-D3fMaUJ3.js} +2 -2
- package/dist/components/p-D7R4yE2C.js +2 -0
- package/dist/components/{p-DEjh3klB.js.map → p-D7R4yE2C.js.map} +1 -1
- package/dist/components/{p-DZ55e3j9.js → p-D7haeL5y.js} +2 -2
- package/dist/components/p-D7haeL5y.js.map +1 -0
- package/dist/components/{p-D2z2DgtX.js → p-DAvh38E4.js} +2 -2
- package/dist/components/{p-CMFvaY05.js → p-DBue3ISk.js} +2 -2
- package/dist/components/{p-rrFMAZkj.js → p-DDgeXGbB.js} +2 -2
- package/dist/components/p-DNpLDbWY.js +2 -0
- package/dist/components/p-DNpLDbWY.js.map +1 -0
- package/dist/components/{p-U8JIZzI2.js → p-DUdOmSFR.js} +2 -2
- package/dist/components/p-DUdOmSFR.js.map +1 -0
- package/dist/components/p-DtndC9f1.js +2 -0
- package/dist/components/p-DtndC9f1.js.map +1 -0
- package/dist/components/{p-Be1sY58w.js → p-H5T258T-.js} +2 -2
- package/dist/components/p-H5T258T-.js.map +1 -0
- package/dist/components/p-HB_cf_aR.js +2 -0
- package/dist/components/{p-DNJTN_s0.js.map → p-HB_cf_aR.js.map} +1 -1
- package/dist/components/p-LK-jpxwq.js +2 -0
- package/dist/components/p-LK-jpxwq.js.map +1 -0
- package/dist/components/p-ag6Io-kL.js +2 -0
- package/dist/components/p-ag6Io-kL.js.map +1 -0
- package/dist/components/p-iMuFgSoM.js +2 -0
- package/dist/components/p-iMuFgSoM.js.map +1 -0
- package/dist/components/{p-DSIOINBK.js → p-uI6z53BE.js} +2 -2
- package/dist/docs/components.json +456 -55
- package/dist/lib/components/ButtonFilled/ButtonFilled.d.ts +2 -0
- package/dist/lib/components/PanelTools/panel-tools-types.d.ts +14 -2
- package/dist/lib/shell/index.d.ts +1 -1
- package/dist/lib/shell/index.js +17 -25
- package/dist/lib/shell/index.js.map +2 -2
- package/dist/lib/shell/shell-responsive.d.ts +6 -1
- package/dist/lib/utils/anchored-position.d.ts +8 -2
- package/dist/lib/utils/button-render.d.ts +1 -0
- package/dist/mcp-data/registry/badge.json +7 -9
- package/dist/mcp-data/registry/banner.json +2 -2
- package/dist/mcp-data/registry/bar-action.json +2 -2
- package/dist/mcp-data/registry/button-filled.json +20 -1
- package/dist/mcp-data/registry/button-unfilled.json +23 -3
- package/dist/mcp-data/registry/conversation-list.json +2 -2
- package/dist/mcp-data/registry/filter-menu.json +22 -7
- package/dist/mcp-data/registry/input.json +24 -4
- package/dist/mcp-data/registry/menu.json +23 -4
- package/dist/mcp-data/registry/message-composer.json +2 -2
- package/dist/mcp-data/registry/mobile-bar-nav.json +57 -6
- package/dist/mcp-data/registry/pagination.json +5 -4
- package/dist/mcp-data/registry/panel-nav.json +1 -1
- package/dist/mcp-data/registry/panel-tool-header.json +3 -3
- package/dist/mcp-data/registry/panel-tools.json +8 -7
- package/dist/mcp-data/registry/registry.json +102 -44
- package/dist/mcp-data/registry/select.json +18 -4
- package/dist/mcp-data/registry/shell-app.json +7 -6
- package/dist/mcp-data/registry/shell-tools.json +4 -4
- package/dist/mcp-data/registry/table-filter.json +3 -3
- package/dist/mcp-data/registry/table-sort.json +5 -4
- package/dist/mcp-data/registry/table-toolbar.json +10 -9
- package/dist/mcp-data/registry/table.json +24 -4
- package/dist/mcp-data/registry/toast.json +2 -2
- package/dist/mcp-data/registry/tooltip.json +20 -3
- package/dist/mcp-data/registry/typing-indicator.json +4 -4
- package/dist/react/ds-panel-tool-header.d.ts +2 -5
- package/dist/react/ds-panel-tools.d.ts +2 -5
- package/dist/styles/table.css +30 -10
- package/dist/types/components/Badge/Badge.d.ts +2 -16
- package/dist/types/components/Banner/Banner.d.ts +0 -1
- package/dist/types/components/BarAction/BarAction.d.ts +0 -7
- package/dist/types/components/ButtonFilled/ButtonFilled.d.ts +2 -0
- package/dist/types/components/ButtonUnfilled/ButtonUnfilled.d.ts +2 -0
- package/dist/types/components/ConversationList/ConversationList.d.ts +1 -0
- package/dist/types/components/FilterMenu/FilterMenu.d.ts +5 -5
- package/dist/types/components/Input/Input.d.ts +7 -0
- package/dist/types/components/Menu/Menu.d.ts +4 -4
- package/dist/types/components/MessageComposer/MessageComposer.d.ts +0 -3
- package/dist/types/components/MobileBarNav/MobileBarNav.d.ts +4 -0
- package/dist/types/components/Pagination/Pagination.d.ts +8 -0
- package/dist/types/components/PanelToolHeader/PanelToolHeader.d.ts +2 -5
- package/dist/types/components/PanelTools/PanelTools.d.ts +2 -5
- package/dist/types/components/PanelTools/panel-tools-types.d.ts +14 -2
- package/dist/types/components/Select/Select.d.ts +3 -0
- package/dist/types/components/Table/Table.d.ts +2 -13
- package/dist/types/components/Table/table-body-renderer.d.ts +36 -0
- package/dist/types/components/Table/table-load-view.d.ts +17 -0
- package/dist/types/components/Table/table-row-view.d.ts +26 -0
- package/dist/types/components/Table/table-skeleton-view.d.ts +12 -0
- package/dist/types/components/TableToolbar/TableToolbar.d.ts +5 -0
- package/dist/types/components/Tooltip/Tooltip.d.ts +3 -0
- package/dist/types/components.d.ts +112 -23
- package/dist/types/shell/index.d.ts +1 -1
- package/dist/types/shell/shell-responsive.d.ts +6 -1
- package/dist/types/utils/anchored-overlay-boundary.d.ts +14 -0
- package/dist/types/utils/anchored-overlay-interaction-controller.d.ts +26 -0
- package/dist/types/utils/anchored-position-controller.d.ts +14 -0
- package/dist/types/utils/anchored-position.d.ts +8 -2
- package/dist/types/utils/button-render.d.ts +1 -0
- package/dist/types/utils/select-controller.d.ts +1 -0
- package/dist/vue/ds-button-filled.js +1 -0
- package/dist/vue/ds-button-unfilled.js +1 -0
- package/dist/vue/ds-filter-menu.js +1 -0
- package/dist/vue/ds-input.js +1 -0
- package/dist/vue/ds-menu.js +1 -0
- package/dist/vue/ds-mobile-bar-nav.js +3 -0
- package/dist/vue/ds-select.js +1 -0
- package/dist/vue/ds-tooltip.js +1 -0
- package/package.json +4 -1
- package/dist/components/p-23u3lIr1.js +0 -2
- package/dist/components/p-Asi9h3pa.js +0 -2
- package/dist/components/p-Asi9h3pa.js.map +0 -1
- package/dist/components/p-BBxcMVqk.js +0 -2
- package/dist/components/p-BBxcMVqk.js.map +0 -1
- package/dist/components/p-BEvBJ65v.js +0 -2
- package/dist/components/p-BEvBJ65v.js.map +0 -1
- package/dist/components/p-BFSLT0yc.js +0 -2
- package/dist/components/p-BFSLT0yc.js.map +0 -1
- package/dist/components/p-BVlfQ8xZ.js.map +0 -1
- package/dist/components/p-BX0BMhgz.js +0 -2
- package/dist/components/p-BX0BMhgz.js.map +0 -1
- package/dist/components/p-Be1sY58w.js.map +0 -1
- package/dist/components/p-Bh67XbfB.js +0 -2
- package/dist/components/p-Bh67XbfB.js.map +0 -1
- package/dist/components/p-CKmfuK7k.js +0 -2
- package/dist/components/p-CKmfuK7k.js.map +0 -1
- package/dist/components/p-D4K9CE8a.js +0 -2
- package/dist/components/p-D4K9CE8a.js.map +0 -1
- package/dist/components/p-DEjh3klB.js +0 -2
- package/dist/components/p-DIEK54fV.js +0 -2
- package/dist/components/p-DNJTN_s0.js +0 -2
- package/dist/components/p-DOqnJVos.js +0 -2
- package/dist/components/p-DOqnJVos.js.map +0 -1
- package/dist/components/p-DZ55e3j9.js.map +0 -1
- package/dist/components/p-DhKvqh5G.js +0 -2
- package/dist/components/p-DhKvqh5G.js.map +0 -1
- package/dist/components/p-Dr4AgJbV.js +0 -2
- package/dist/components/p-Dr4AgJbV.js.map +0 -1
- package/dist/components/p-DsJW5W3W.js +0 -2
- package/dist/components/p-NzGRAPcF.js +0 -2
- package/dist/components/p-NzGRAPcF.js.map +0 -1
- package/dist/components/p-U8JIZzI2.js.map +0 -1
- package/dist/components/p-ZZzC52Ea.js +0 -2
- package/dist/components/p-ZZzC52Ea.js.map +0 -1
- package/dist/components/p-__lNIImO.js +0 -2
- package/dist/components/p-__lNIImO.js.map +0 -1
- package/dist/components/p-a6qP60zb.js +0 -2
- package/dist/components/p-a6qP60zb.js.map +0 -1
- package/dist/types/shell/badge-gradient-ring.d.ts +0 -28
- /package/dist/components/{p-C0X2zKbB.js.map → p-1Hu9jlju.js.map} +0 -0
- /package/dist/components/{p-DQqOzDEq.js.map → p-B00PEE6t.js.map} +0 -0
- /package/dist/components/{p-D1YhYulL.js.map → p-B1JRCDHS.js.map} +0 -0
- /package/dist/components/{p-D8Qd6gkf.js.map → p-BCOl1x0_.js.map} +0 -0
- /package/dist/components/{p-Dg9qiMDa.js.map → p-BHVOiWz5.js.map} +0 -0
- /package/dist/components/{p-DHuyj-9J.js.map → p-BXN-e7vF.js.map} +0 -0
- /package/dist/components/{p-Bn8NryHK.js.map → p-B_jZIC9R.js.map} +0 -0
- /package/dist/components/{p-7tZx4ukz.js.map → p-Bbb9A3NV.js.map} +0 -0
- /package/dist/components/{p-ruPTIV6t.js.map → p-BhYS_Ump.js.map} +0 -0
- /package/dist/components/{p-B0PEg5RF.js.map → p-BknXYAEc.js.map} +0 -0
- /package/dist/components/{p-C4TgWJi9.js.map → p-Bu3dOjpW.js.map} +0 -0
- /package/dist/components/{p-DAqSoyd4.js.map → p-C6R5Lft0.js.map} +0 -0
- /package/dist/components/{p-PD1Vfg0t.js.map → p-C9gC4haA.js.map} +0 -0
- /package/dist/components/{p-BGXqFq2C.js.map → p-CAnnQL1F.js.map} +0 -0
- /package/dist/components/{p-BHz78C8h.js.map → p-CLVxgTme.js.map} +0 -0
- /package/dist/components/{p-y4jhIkRc.js.map → p-Cg0kimXZ.js.map} +0 -0
- /package/dist/components/{p-BhYWdbEp.js.map → p-CsBICYmt.js.map} +0 -0
- /package/dist/components/{p-BHDkJmrC.js.map → p-D123Jvp-.js.map} +0 -0
- /package/dist/components/{p-CzcWZiH-.js.map → p-D3fMaUJ3.js.map} +0 -0
- /package/dist/components/{p-D2z2DgtX.js.map → p-DAvh38E4.js.map} +0 -0
- /package/dist/components/{p-CMFvaY05.js.map → p-DBue3ISk.js.map} +0 -0
- /package/dist/components/{p-rrFMAZkj.js.map → p-DDgeXGbB.js.map} +0 -0
- /package/dist/components/{p-DSIOINBK.js.map → p-uI6z53BE.js.map} +0 -0
|
@@ -26,6 +26,8 @@ export declare class ButtonFilled {
|
|
|
26
26
|
width: ButtonFilledWidth;
|
|
27
27
|
/** Visible text for `label` / `icon-label` variants. */
|
|
28
28
|
label: string;
|
|
29
|
+
/** Whether the visible label uses the emphasized weight. */
|
|
30
|
+
labelEmphasis: boolean;
|
|
29
31
|
/** Icon name passed to <ds-icon> for `icon` / `icon-label` variants. */
|
|
30
32
|
icon: string;
|
|
31
33
|
/** Semantic colour intent. */
|
|
@@ -15,14 +15,14 @@ export interface PanelToolsItem {
|
|
|
15
15
|
icon: string;
|
|
16
16
|
/** Visible and accessible fallback label for custom tool ids. */
|
|
17
17
|
label?: string;
|
|
18
|
-
/** Explicit rail region; canonical
|
|
18
|
+
/** Explicit rail region; canonical Agents/Help placement is the fallback. */
|
|
19
19
|
railPlacement?: 'header' | 'body' | 'footer';
|
|
20
20
|
/** Stable ordering within the selected rail region. */
|
|
21
21
|
order?: number;
|
|
22
22
|
/** Optional shortcut label displayed by the tooltip. */
|
|
23
23
|
shortcutKey?: string;
|
|
24
24
|
/** Mobile destination recipe; canonical ids retain their explicit defaults. */
|
|
25
|
-
mobileDestination?: 'search' | 'inbox' | 'messages' | 'agents' | 'help';
|
|
25
|
+
mobileDestination?: 'search' | 'inbox' | 'activity' | 'messages' | 'agents' | 'help';
|
|
26
26
|
/** Whether this rail button is currently pressed/active. */
|
|
27
27
|
selected?: boolean;
|
|
28
28
|
/** Show a notification dot. */
|
|
@@ -43,6 +43,18 @@ export interface PanelToolsHeaderAction {
|
|
|
43
43
|
pressed?: boolean;
|
|
44
44
|
isInactive?: boolean;
|
|
45
45
|
}
|
|
46
|
+
export interface PanelToolsHeaderActionDetail {
|
|
47
|
+
tool: PanelToolsToolId;
|
|
48
|
+
id: string;
|
|
49
|
+
/** Rendered header action host. Pass this to an external overlay's element anchor prop. */
|
|
50
|
+
anchor?: HTMLElement;
|
|
51
|
+
}
|
|
52
|
+
export interface PanelToolHeaderActionDetail {
|
|
53
|
+
id: string;
|
|
54
|
+
originalEvent: MouseEvent;
|
|
55
|
+
/** Rendered action host, suitable for anchoring an external overlay across a shadow boundary. */
|
|
56
|
+
anchor: HTMLElement;
|
|
57
|
+
}
|
|
46
58
|
export interface PanelToolsHeaderConfig {
|
|
47
59
|
title?: string;
|
|
48
60
|
showBack?: boolean;
|
|
@@ -3,7 +3,7 @@ export type { PanelNavGroup, PanelNavItem, } from '../components/PanelNav/panel-
|
|
|
3
3
|
export type { BarNavTab } from '../components/BarNav/bar-nav-types';
|
|
4
4
|
export type { ShellPageContentInset, ShellPageContentSurface, } from '../components/ShellPage/shell-page-types';
|
|
5
5
|
export type { ShellAppComposition, ShellNavigationConfig, ShellNavigationSelectDetail, ShellPageChromeConfig, ShellToolsConfig, } from '../components/ShellApp/shell-app-types';
|
|
6
|
-
export type { PanelToolsHeaderAction, PanelToolsHeaderConfig, PanelToolsHeaders, PanelToolsItem, PanelToolsToolId, } from '../components/PanelTools/panel-tools-types';
|
|
6
|
+
export type { PanelToolsHeaderAction, PanelToolsHeaderActionDetail, PanelToolHeaderActionDetail, PanelToolsHeaderConfig, PanelToolsHeaders, PanelToolsItem, PanelToolsToolId, } from '../components/PanelTools/panel-tools-types';
|
|
7
7
|
export { PANEL_TOOLS_DEFAULT_ITEMS } from '../components/PanelTools/panel-tools-types';
|
|
8
8
|
export { NAV_STYLE_HINT_ATTR, readNavStyleAttr, setNavStyleHint, clearNavStyleHint, } from './nav-chrome';
|
|
9
9
|
export type { MenuPlacement } from '../components/Menu/menu-placement';
|
package/dist/lib/shell/index.js
CHANGED
|
@@ -17,52 +17,44 @@ var PANEL_TOOLS_SHORTCUTS = {
|
|
|
17
17
|
};
|
|
18
18
|
var PANEL_TOOLS_DEFAULT_ITEMS = [
|
|
19
19
|
{
|
|
20
|
-
id: "
|
|
21
|
-
icon: "
|
|
22
|
-
label: PANEL_TOOLS_LABELS.
|
|
20
|
+
id: "agents",
|
|
21
|
+
icon: "AI",
|
|
22
|
+
label: PANEL_TOOLS_LABELS.agents,
|
|
23
23
|
railPlacement: "header",
|
|
24
24
|
order: 0,
|
|
25
|
-
shortcutKey: PANEL_TOOLS_SHORTCUTS.
|
|
26
|
-
mobileDestination: "
|
|
25
|
+
shortcutKey: PANEL_TOOLS_SHORTCUTS.agents,
|
|
26
|
+
mobileDestination: "agents"
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
29
|
id: "messages",
|
|
30
30
|
icon: "MessageBubbleStack",
|
|
31
31
|
label: PANEL_TOOLS_LABELS.messages,
|
|
32
|
-
order:
|
|
32
|
+
order: 0,
|
|
33
33
|
shortcutKey: PANEL_TOOLS_SHORTCUTS.messages,
|
|
34
34
|
mobileDestination: "messages"
|
|
35
35
|
},
|
|
36
|
-
{
|
|
37
|
-
id: "agents",
|
|
38
|
-
icon: "AI",
|
|
39
|
-
label: PANEL_TOOLS_LABELS.agents,
|
|
40
|
-
order: 2,
|
|
41
|
-
shortcutKey: PANEL_TOOLS_SHORTCUTS.agents,
|
|
42
|
-
mobileDestination: "agents"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
id: "stacks",
|
|
46
|
-
icon: "ViewMenu",
|
|
47
|
-
label: PANEL_TOOLS_LABELS.stacks,
|
|
48
|
-
order: 3,
|
|
49
|
-
shortcutKey: PANEL_TOOLS_SHORTCUTS.stacks,
|
|
50
|
-
mobileDestination: "inbox"
|
|
51
|
-
},
|
|
52
36
|
{
|
|
53
37
|
id: "activity",
|
|
54
38
|
icon: "Bell",
|
|
55
39
|
label: PANEL_TOOLS_LABELS.activity,
|
|
56
|
-
order:
|
|
40
|
+
order: 1,
|
|
57
41
|
shortcutKey: PANEL_TOOLS_SHORTCUTS.activity,
|
|
58
|
-
mobileDestination: "
|
|
42
|
+
mobileDestination: "activity"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "search",
|
|
46
|
+
icon: "MagnifyingGlass",
|
|
47
|
+
label: PANEL_TOOLS_LABELS.search,
|
|
48
|
+
order: 2,
|
|
49
|
+
shortcutKey: PANEL_TOOLS_SHORTCUTS.search,
|
|
50
|
+
mobileDestination: "search"
|
|
59
51
|
},
|
|
60
52
|
{
|
|
61
53
|
id: "help",
|
|
62
54
|
icon: "CircleQuestion",
|
|
63
55
|
label: PANEL_TOOLS_LABELS.help,
|
|
64
56
|
railPlacement: "footer",
|
|
65
|
-
order:
|
|
57
|
+
order: 0,
|
|
66
58
|
shortcutKey: PANEL_TOOLS_SHORTCUTS.help,
|
|
67
59
|
mobileDestination: "help"
|
|
68
60
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/wc/components/PanelTools/panel-tools-types.ts", "../../../src/wc/shell/nav-chrome.ts", "../../../src/wc/components/Menu/menu-placement.ts", "../../../src/wc/shell/shell-gradient-presets.ts", "../../../src/wc/shell/shell-responsive.ts"],
|
|
4
|
-
"sourcesContent": ["/** Application-owned tool id for the shell rail and responsive tool views. */\nexport type PanelToolsToolId = string;\n\n/** Canonical Motive shell recipe used when item metadata is omitted. */\nexport type CanonicalPanelToolsToolId =\n | 'search'\n | 'messages'\n | 'agents'\n | 'stacks'\n | 'activity'\n | 'help';\n\nexport const PANEL_TOOLS_TOOL_IDS: CanonicalPanelToolsToolId[] = [\n 'search',\n 'messages',\n 'agents',\n 'stacks',\n 'activity',\n 'help',\n];\n\n/** Rail header slot \u2014 mirrors panel-nav M logo row. */\nexport const PANEL_TOOLS_PRIMARY_TOOL_ID: CanonicalPanelToolsToolId = 'search';\n\n/** Rail footer slot \u2014 flush to the bottom of the tools column. */\nexport const PANEL_TOOLS_FOOTER_TOOL_ID: CanonicalPanelToolsToolId = 'help';\n\nexport const PANEL_TOOLS_LABELS: Record<CanonicalPanelToolsToolId, string> = {\n search: 'Search',\n messages: 'Messages',\n stacks: 'Stacks',\n activity: 'Activity',\n agents: 'Agents',\n help: 'Help & Support',\n};\n\nexport const PANEL_TOOLS_SHORTCUTS: Partial<Record<CanonicalPanelToolsToolId, string>> = {\n search: 'K',\n agents: 'A',\n messages: 'M',\n stacks: 'S',\n activity: 'N',\n help: '/',\n};\n\nexport interface PanelToolsItem {\n id: PanelToolsToolId;\n /** Icon name for <ds-icon>. */\n icon: string;\n /** Visible and accessible fallback label for custom tool ids. */\n label?: string;\n /** Explicit rail region; canonical Search/Help placement is the fallback. */\n railPlacement?: 'header' | 'body' | 'footer';\n /** Stable ordering within the selected rail region. */\n order?: number;\n /** Optional shortcut label displayed by the tooltip. */\n shortcutKey?: string;\n /** Mobile destination recipe; canonical ids retain their explicit defaults. */\n mobileDestination?: 'search' | 'inbox' | 'messages' | 'agents' | 'help';\n /** Whether this rail button is currently pressed/active. */\n selected?: boolean;\n /** Show a notification dot. */\n dot?: boolean;\n isInactive?: boolean;\n ariaLabel?: string;\n}\n\n/** Canonical shell recipe used by Lab and by managed ShellApp examples. */\nexport const PANEL_TOOLS_DEFAULT_ITEMS: PanelToolsItem[] = [\n {\n id: 'search',\n icon: 'MagnifyingGlass',\n label: PANEL_TOOLS_LABELS.search,\n railPlacement: 'header',\n order: 0,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.search,\n mobileDestination: 'search',\n },\n {\n id: 'messages',\n icon: 'MessageBubbleStack',\n label: PANEL_TOOLS_LABELS.messages,\n order: 1,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.messages,\n mobileDestination: 'messages',\n },\n {\n id: 'agents',\n icon: 'AI',\n label: PANEL_TOOLS_LABELS.agents,\n order: 2,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.agents,\n mobileDestination: 'agents',\n },\n {\n id: 'stacks',\n icon: 'ViewMenu',\n label: PANEL_TOOLS_LABELS.stacks,\n order: 3,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.stacks,\n mobileDestination: 'inbox',\n },\n {\n id: 'activity',\n icon: 'Bell',\n label: PANEL_TOOLS_LABELS.activity,\n order: 4,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.activity,\n mobileDestination: 'inbox',\n },\n {\n id: 'help',\n icon: 'CircleQuestion',\n label: PANEL_TOOLS_LABELS.help,\n railPlacement: 'footer',\n order: 5,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.help,\n mobileDestination: 'help',\n },\n];\n\nexport interface PanelToolsHeaderAction {\n id: string;\n icon: string;\n ariaLabel: string;\n triggerId?: string;\n controls?: string;\n expanded?: boolean;\n haspopup?: 'menu' | 'dialog' | 'listbox' | 'tree' | 'grid';\n pressed?: boolean;\n isInactive?: boolean;\n}\n\nexport interface PanelToolsHeaderConfig {\n title?: string;\n showBack?: boolean;\n backIcon?: string;\n backAriaLabel?: string;\n actions?: PanelToolsHeaderAction[];\n}\n\n/** Per-tool header state. The application replaces the object when a tool changes depth or actions. */\nexport type PanelToolsHeaders = Partial<Record<PanelToolsToolId, PanelToolsHeaderConfig>>;\n", "/** Nav chrome style slot \u2014 dashboard vs settings. Colors unified for now; texture hooks use the class. */\nexport type NavChromeStyle = 'dashboard' | 'settings';\n\n/** Document hint for first paint before framework props land. */\nexport const NAV_STYLE_HINT_ATTR = 'data-nav-style';\n\nexport function readNavStyleAttr(attr: string | null): NavChromeStyle | undefined {\n if (attr === 'dashboard' || attr === 'settings') return attr;\n return undefined;\n}\n\nexport function setNavStyleHint(style: NavChromeStyle): void {\n if (typeof document === 'undefined') return;\n document.documentElement.setAttribute(NAV_STYLE_HINT_ATTR, style);\n}\n\nexport function clearNavStyleHint(): void {\n if (typeof document === 'undefined') return;\n document.documentElement.removeAttribute(NAV_STYLE_HINT_ATTR);\n}\n\nexport function resolveNavChromeStyle(\n styleProp: NavChromeStyle,\n hostAttr: string | null,\n docHint?: string | null,\n): NavChromeStyle {\n const fromHost = readNavStyleAttr(hostAttr);\n if (fromHost) return fromHost;\n\n const hint =\n docHint !== undefined\n ? docHint\n : typeof document !== 'undefined'\n ? document.documentElement.getAttribute(NAV_STYLE_HINT_ATTR)\n : null;\n const fromHint = readNavStyleAttr(hint);\n if (fromHint) return fromHint;\n\n return styleProp;\n}\n\nexport function shouldResyncNavChromeStyle(\n renderedStyle: NavChromeStyle,\n style: NavChromeStyle,\n): boolean {\n return renderedStyle !== style;\n}\n", "import type { ChoicePopupAnchorAlignment } from '../../utils/choice-popup-alignment';\nimport type { MenuAlign, MenuSide } from './menu-position';\n\n/** Placement props bindable on `ds-menu` (side, align, offsets). */\nexport interface MenuPlacement {\n side: MenuSide;\n align: MenuAlign;\n anchorAlignment: ChoicePopupAnchorAlignment;\n sideOffset: number | string;\n alignOffset: number | string;\n}\n\n/**\n * Canonical `ds-menu` placement for the **panel-nav footer user menu**.\n * Anchor from `dsNavUserAction` detail `{ anchor }` (id `ds-panel-nav-user-menu-anchor`).\n *\n * Not for BarNav overflow menus \u2014 those use `side=\"bottom\"` / `align=\"end\"` internally.\n * `align: 'end'` bottom-aligns the last choice cell on the anchor; the side offset nudges into the content area:\n * - `sideOffset` space-100 + space-050 (12px): 4px past the panel-nav outer edge (anchor is ~8px inset).\n * - `anchorAlignment: 'choice-cell'`: the shared section inset puts the last row edge on the footer user row.\n */\nexport const PANEL_NAV_USER_MENU_PLACEMENT = {\n side: 'right',\n align: 'end',\n anchorAlignment: 'choice-cell',\n sideOffset: 'calc(var(--dimension-space-100) + var(--dimension-space-050))',\n alignOffset: 0,\n} as const satisfies MenuPlacement;\n\n/**\n * Canonical placement for a menu opened by a PanelTools header action.\n * Matches BarNav overflow: the 32px trigger is 8px inside the 48px header, so\n * a 12px side offset places the popup 4px below the header edge. Choice-cell\n * alignment keeps the final menu item edge aligned with the trigger.\n */\nexport const PANEL_TOOLS_HEADER_MENU_PLACEMENT = {\n side: 'bottom',\n align: 'end',\n anchorAlignment: 'choice-cell',\n sideOffset: 'calc(var(--dimension-space-100) + var(--dimension-space-050))',\n alignOffset: 0,\n} as const satisfies MenuPlacement;\n", "/** Built-in shell chrome wash presets. */\nexport type ShellGradientPreset = 'none' | 'cool' | 'neutral' | 'warm' | 'fresh';\n\nexport const SHELL_GRADIENT_PRESETS: ShellGradientPreset[] = [\n 'none',\n 'cool',\n 'neutral',\n 'warm',\n 'fresh',\n];\n\n/** Wash presets shown after the `none` option in pickers. */\nexport const SHELL_GRADIENT_WASH_PRESETS: Exclude<ShellGradientPreset, 'none'>[] = [\n 'cool',\n 'neutral',\n 'warm',\n 'fresh',\n];\n\n/** Default wash when `gradient-preset` is omitted. */\nexport const DEFAULT_SHELL_GRADIENT_PRESET: ShellGradientPreset = 'neutral';\n\nexport const SHELL_GRADIENT_PRESET_LABELS: Record<ShellGradientPreset, string> = {\n none: 'None',\n cool: 'Cool',\n neutral: 'Neutral',\n warm: 'Warm',\n fresh: 'Fresh',\n};\n\nexport interface ShellGradientStop {\n color: string;\n position: number;\n}\n\nexport interface ShellGradientRecipe {\n opacity: number;\n stops: readonly ShellGradientStop[];\n}\n\nexport interface ShellGradientPickerPreview {\n backgroundColor: string;\n backgroundImage?: string;\n opacity?: number;\n}\n\nexport interface ShellGradientPickerOption {\n value: ShellGradientPreset;\n label: string;\n preview: ShellGradientPickerPreview;\n}\n\nexport interface ShellGradientPickerSection {\n options: ShellGradientPickerOption[];\n}\n\nconst SHELL_GRADIENT_RECIPES: Record<Exclude<ShellGradientPreset, 'none'>, ShellGradientRecipe> = {\n cool: {\n opacity: 0.1,\n stops: [\n { color: 'var(--color-background-transparent)', position: 0 },\n { color: 'var(--color-color-intent-blue-strong-background)', position: 100 },\n ],\n },\n neutral: {\n opacity: 0.1,\n stops: [\n { color: 'var(--color-background-transparent)', position: 0 },\n { color: 'var(--color-color-intent-grey-strong-background)', position: 100 },\n ],\n },\n warm: {\n opacity: 0.1,\n stops: [\n { color: 'var(--color-background-transparent)', position: 0 },\n { color: 'var(--color-color-intent-yellow-strong-background)', position: 100 },\n ],\n },\n fresh: {\n opacity: 0.4,\n stops: [\n { color: 'var(--color-color-intent-cyan-faint-background)', position: 0 },\n { color: 'var(--color-background-transparent)', position: 47 },\n { color: 'var(--color-background-transparent)', position: 58 },\n { color: 'var(--color-color-intent-red-faint-background)', position: 83 },\n { color: 'var(--color-color-intent-pink-faint-background)', position: 100 },\n ],\n },\n};\n\nconst GRADIENT_GEOMETRY = '100% 100% at 0% 0%';\n\nexport function shellGradientPresetStopToken(preset: ShellGradientPreset): string | null {\n if (preset === 'none') return null;\n const stops = SHELL_GRADIENT_RECIPES[preset].stops;\n return stops[stops.length - 1]?.color ?? null;\n}\n\nexport function shellGradientPresetRecipe(preset: ShellGradientPreset): ShellGradientRecipe | null {\n const normalized = normalizeShellGradientPreset(preset);\n return normalized === 'none' ? null : SHELL_GRADIENT_RECIPES[normalized];\n}\n\nexport function shellGradientPresetOpacity(preset: ShellGradientPreset): string {\n return String(shellGradientPresetRecipe(preset)?.opacity ?? 0);\n}\n\nexport function isShellGradientPreset(value: string): value is ShellGradientPreset {\n return (SHELL_GRADIENT_PRESETS as string[]).includes(value);\n}\n\n/**\n * Coerce unknown/absent presets to the default. Runtime values escape the\n * type: removing the reflected `gradient-preset` attribute (e.g. an Angular\n * `[attr.gradient-preset]=\"null\"` binding) drives the prop to null past its\n * field default \u2014 without normalization the stop lookup interpolates the\n * literal string \"undefined\" into CSS and the wash silently disappears.\n */\nexport function normalizeShellGradientPreset(\n value: string | null | undefined,\n): ShellGradientPreset {\n return value != null && isShellGradientPreset(value) ? value : DEFAULT_SHELL_GRADIENT_PRESET;\n}\n\n/** Radial wash for a preset \u2014 transparent at top-left into the intent stop. `none` returns no image. */\nexport function buildShellRadialGradientForPreset(preset: ShellGradientPreset): string {\n const normalized = normalizeShellGradientPreset(preset);\n if (normalized === 'none') return 'none';\n\n return buildShellRadialGradientFromStops(SHELL_GRADIENT_RECIPES[normalized].stops);\n}\n\n/** Build the production shell geometry from an ordered set of design-time stops. */\nexport function buildShellRadialGradientFromStops(stops: readonly ShellGradientStop[]): string {\n const serialized = stops.map(stop => `${stop.color} ${stop.position}%`).join(', ');\n return `radial-gradient(${GRADIENT_GEOMETRY}, ${serialized})`;\n}\n\n/** Generic SwatchPicker sections for the fixed shell appearance presets. */\nexport function shellGradientPickerSections(): ShellGradientPickerSection[] {\n return [\n {\n options: [{\n value: 'none',\n label: SHELL_GRADIENT_PRESET_LABELS.none,\n preview: {\n backgroundColor: 'var(--color-background-secondary)',\n },\n }],\n },\n {\n options: SHELL_GRADIENT_WASH_PRESETS.map(preset => ({\n value: preset,\n label: SHELL_GRADIENT_PRESET_LABELS[preset],\n preview: {\n backgroundColor: 'var(--color-background-secondary)',\n backgroundImage: buildShellRadialGradientForPreset(preset),\n opacity: Number(shellGradientPresetOpacity(preset)),\n },\n })),\n },\n ];\n}\n", "import type { PanelToolsToolId } from '../components/PanelTools/panel-tools-types';\n\nexport type ShellResponsiveMode = 'desktop' | 'tablet' | 'mobile';\nexport type MobileDestination = 'area' | 'search' | 'inbox' | 'messages' | 'agents' | 'help';\nexport type ShellInboxToolId = PanelToolsToolId;\n\nexport const SHELL_DESKTOP_BREAKPOINT = 1200;\nexport const SHELL_MOBILE_BREAKPOINT = 768;\nexport const SHELL_DEFAULT_INBOX_TOOL: ShellInboxToolId = 'activity';\n\nexport function resolveShellResponsiveMode(width: number): ShellResponsiveMode {\n if (width >= SHELL_DESKTOP_BREAKPOINT) return 'desktop';\n if (width >= SHELL_MOBILE_BREAKPOINT) return 'tablet';\n return 'mobile';\n}\n\nexport function resolveManagedShellPageCapacity(\n mode: ShellResponsiveMode\n): 'roomy' | 'compact' | 'constrained' {\n return mode === 'desktop' ? 'roomy' : 'compact';\n}\n\nexport function shellMobileDestinationForTool(\n open: boolean,\n tool: PanelToolsToolId | ''\n): MobileDestination {\n if (!open || !tool) return 'area';\n if (tool === 'help') return 'help';\n if (tool === 'search') return 'search';\n if (tool === 'messages') return 'messages';\n if (tool === 'agents') return 'agents';\n return 'inbox';\n}\n\nexport function isShellInboxTool(tool: string): tool is ShellInboxToolId {\n return tool === 'stacks' || tool === 'activity';\n}\n\nexport function resolveAvailableInboxTool(\n preferred: string,\n available: readonly PanelToolsToolId[]\n): ShellInboxToolId | '' {\n const inbox = available.filter(isShellInboxTool);\n if (isShellInboxTool(preferred) && inbox.includes(preferred)) return preferred;\n if (inbox.includes(SHELL_DEFAULT_INBOX_TOOL)) return SHELL_DEFAULT_INBOX_TOOL;\n return inbox[0] ?? '';\n}\n\n/** Active-destination reselects are inert unless they also dismiss the Menu pane. */\nexport function shouldEmitMobileDestinationChange(\n active: MobileDestination,\n next: MobileDestination,\n navigationOpen: boolean\n): boolean {\n return navigationOpen || active !== next;\n}\n"],
|
|
5
|
-
"mappings": ";AA2BO,IAAM,qBAAgE;AAAA,EAC3E,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,MAAM;AACR;AAEO,IAAM,wBAA4E;AAAA,EACvF,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,MAAM;AACR;AAyBO,IAAM,4BAA8C;AAAA,EACzD;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO,mBAAmB;AAAA,IAC1B,eAAe;AAAA,IACf,OAAO;AAAA,IACP,aAAa,sBAAsB;AAAA,IACnC,mBAAmB;AAAA,EACrB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO,mBAAmB;AAAA,IAC1B,OAAO;AAAA,IACP,aAAa,sBAAsB;AAAA,IACnC,mBAAmB;AAAA,EACrB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO,mBAAmB;AAAA,IAC1B,OAAO;AAAA,IACP,aAAa,sBAAsB;AAAA,IACnC,mBAAmB;AAAA,EACrB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO,mBAAmB;AAAA,IAC1B,OAAO;AAAA,IACP,aAAa,sBAAsB;AAAA,IACnC,mBAAmB;AAAA,EACrB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO,mBAAmB;AAAA,IAC1B,
|
|
4
|
+
"sourcesContent": ["/** Application-owned tool id for the shell rail and responsive tool views. */\nexport type PanelToolsToolId = string;\n\n/** Canonical Motive shell recipe used when item metadata is omitted. */\nexport type CanonicalPanelToolsToolId =\n | 'search'\n | 'messages'\n | 'agents'\n | 'stacks'\n | 'activity'\n | 'help';\n\nexport const PANEL_TOOLS_TOOL_IDS: CanonicalPanelToolsToolId[] = [\n 'agents',\n 'messages',\n 'activity',\n 'search',\n 'stacks',\n 'help',\n];\n\n/** Rail header slot \u2014 mirrors panel-nav M logo row. */\nexport const PANEL_TOOLS_PRIMARY_TOOL_ID: CanonicalPanelToolsToolId = 'agents';\n\n/** Rail footer slot \u2014 flush to the bottom of the tools column. */\nexport const PANEL_TOOLS_FOOTER_TOOL_ID: CanonicalPanelToolsToolId = 'help';\n\nexport const PANEL_TOOLS_LABELS: Record<CanonicalPanelToolsToolId, string> = {\n search: 'Search',\n messages: 'Messages',\n stacks: 'Stacks',\n activity: 'Activity',\n agents: 'Agents',\n help: 'Help & Support',\n};\n\nexport const PANEL_TOOLS_SHORTCUTS: Partial<Record<CanonicalPanelToolsToolId, string>> = {\n search: 'K',\n agents: 'A',\n messages: 'M',\n stacks: 'S',\n activity: 'N',\n help: '/',\n};\n\nexport interface PanelToolsItem {\n id: PanelToolsToolId;\n /** Icon name for <ds-icon>. */\n icon: string;\n /** Visible and accessible fallback label for custom tool ids. */\n label?: string;\n /** Explicit rail region; canonical Agents/Help placement is the fallback. */\n railPlacement?: 'header' | 'body' | 'footer';\n /** Stable ordering within the selected rail region. */\n order?: number;\n /** Optional shortcut label displayed by the tooltip. */\n shortcutKey?: string;\n /** Mobile destination recipe; canonical ids retain their explicit defaults. */\n mobileDestination?: 'search' | 'inbox' | 'activity' | 'messages' | 'agents' | 'help';\n /** Whether this rail button is currently pressed/active. */\n selected?: boolean;\n /** Show a notification dot. */\n dot?: boolean;\n isInactive?: boolean;\n ariaLabel?: string;\n}\n\n/** Canonical shell recipe used by Lab and by managed ShellApp examples. */\nexport const PANEL_TOOLS_DEFAULT_ITEMS: PanelToolsItem[] = [\n {\n id: 'agents',\n icon: 'AI',\n label: PANEL_TOOLS_LABELS.agents,\n railPlacement: 'header',\n order: 0,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.agents,\n mobileDestination: 'agents',\n },\n {\n id: 'messages',\n icon: 'MessageBubbleStack',\n label: PANEL_TOOLS_LABELS.messages,\n order: 0,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.messages,\n mobileDestination: 'messages',\n },\n {\n id: 'activity',\n icon: 'Bell',\n label: PANEL_TOOLS_LABELS.activity,\n order: 1,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.activity,\n mobileDestination: 'activity',\n },\n {\n id: 'search',\n icon: 'MagnifyingGlass',\n label: PANEL_TOOLS_LABELS.search,\n order: 2,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.search,\n mobileDestination: 'search',\n },\n {\n id: 'help',\n icon: 'CircleQuestion',\n label: PANEL_TOOLS_LABELS.help,\n railPlacement: 'footer',\n order: 0,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.help,\n mobileDestination: 'help',\n },\n];\n\nexport interface PanelToolsHeaderAction {\n id: string;\n icon: string;\n ariaLabel: string;\n triggerId?: string;\n controls?: string;\n expanded?: boolean;\n haspopup?: 'menu' | 'dialog' | 'listbox' | 'tree' | 'grid';\n pressed?: boolean;\n isInactive?: boolean;\n}\n\nexport interface PanelToolsHeaderActionDetail {\n tool: PanelToolsToolId;\n id: string;\n /** Rendered header action host. Pass this to an external overlay's element anchor prop. */\n anchor?: HTMLElement;\n}\n\nexport interface PanelToolHeaderActionDetail {\n id: string;\n originalEvent: MouseEvent;\n /** Rendered action host, suitable for anchoring an external overlay across a shadow boundary. */\n anchor: HTMLElement;\n}\n\nexport interface PanelToolsHeaderConfig {\n title?: string;\n showBack?: boolean;\n backIcon?: string;\n backAriaLabel?: string;\n actions?: PanelToolsHeaderAction[];\n}\n\n/** Per-tool header state. The application replaces the object when a tool changes depth or actions. */\nexport type PanelToolsHeaders = Partial<Record<PanelToolsToolId, PanelToolsHeaderConfig>>;\n", "/** Nav chrome style slot \u2014 dashboard vs settings. Colors unified for now; texture hooks use the class. */\nexport type NavChromeStyle = 'dashboard' | 'settings';\n\n/** Document hint for first paint before framework props land. */\nexport const NAV_STYLE_HINT_ATTR = 'data-nav-style';\n\nexport function readNavStyleAttr(attr: string | null): NavChromeStyle | undefined {\n if (attr === 'dashboard' || attr === 'settings') return attr;\n return undefined;\n}\n\nexport function setNavStyleHint(style: NavChromeStyle): void {\n if (typeof document === 'undefined') return;\n document.documentElement.setAttribute(NAV_STYLE_HINT_ATTR, style);\n}\n\nexport function clearNavStyleHint(): void {\n if (typeof document === 'undefined') return;\n document.documentElement.removeAttribute(NAV_STYLE_HINT_ATTR);\n}\n\nexport function resolveNavChromeStyle(\n styleProp: NavChromeStyle,\n hostAttr: string | null,\n docHint?: string | null,\n): NavChromeStyle {\n const fromHost = readNavStyleAttr(hostAttr);\n if (fromHost) return fromHost;\n\n const hint =\n docHint !== undefined\n ? docHint\n : typeof document !== 'undefined'\n ? document.documentElement.getAttribute(NAV_STYLE_HINT_ATTR)\n : null;\n const fromHint = readNavStyleAttr(hint);\n if (fromHint) return fromHint;\n\n return styleProp;\n}\n\nexport function shouldResyncNavChromeStyle(\n renderedStyle: NavChromeStyle,\n style: NavChromeStyle,\n): boolean {\n return renderedStyle !== style;\n}\n", "import type { ChoicePopupAnchorAlignment } from '../../utils/choice-popup-alignment';\nimport type { MenuAlign, MenuSide } from './menu-position';\n\n/** Placement props bindable on `ds-menu` (side, align, offsets). */\nexport interface MenuPlacement {\n side: MenuSide;\n align: MenuAlign;\n anchorAlignment: ChoicePopupAnchorAlignment;\n sideOffset: number | string;\n alignOffset: number | string;\n}\n\n/**\n * Canonical `ds-menu` placement for the **panel-nav footer user menu**.\n * Anchor from `dsNavUserAction` detail `{ anchor }` (id `ds-panel-nav-user-menu-anchor`).\n *\n * Not for BarNav overflow menus \u2014 those use `side=\"bottom\"` / `align=\"end\"` internally.\n * `align: 'end'` bottom-aligns the last choice cell on the anchor; the side offset nudges into the content area:\n * - `sideOffset` space-100 + space-050 (12px): 4px past the panel-nav outer edge (anchor is ~8px inset).\n * - `anchorAlignment: 'choice-cell'`: the shared section inset puts the last row edge on the footer user row.\n */\nexport const PANEL_NAV_USER_MENU_PLACEMENT = {\n side: 'right',\n align: 'end',\n anchorAlignment: 'choice-cell',\n sideOffset: 'calc(var(--dimension-space-100) + var(--dimension-space-050))',\n alignOffset: 0,\n} as const satisfies MenuPlacement;\n\n/**\n * Canonical placement for a menu opened by a PanelTools header action.\n * Matches BarNav overflow: the 32px trigger is 8px inside the 48px header, so\n * a 12px side offset places the popup 4px below the header edge. Choice-cell\n * alignment keeps the final menu item edge aligned with the trigger.\n */\nexport const PANEL_TOOLS_HEADER_MENU_PLACEMENT = {\n side: 'bottom',\n align: 'end',\n anchorAlignment: 'choice-cell',\n sideOffset: 'calc(var(--dimension-space-100) + var(--dimension-space-050))',\n alignOffset: 0,\n} as const satisfies MenuPlacement;\n", "/** Built-in shell chrome wash presets. */\nexport type ShellGradientPreset = 'none' | 'cool' | 'neutral' | 'warm' | 'fresh';\n\nexport const SHELL_GRADIENT_PRESETS: ShellGradientPreset[] = [\n 'none',\n 'cool',\n 'neutral',\n 'warm',\n 'fresh',\n];\n\n/** Wash presets shown after the `none` option in pickers. */\nexport const SHELL_GRADIENT_WASH_PRESETS: Exclude<ShellGradientPreset, 'none'>[] = [\n 'cool',\n 'neutral',\n 'warm',\n 'fresh',\n];\n\n/** Default wash when `gradient-preset` is omitted. */\nexport const DEFAULT_SHELL_GRADIENT_PRESET: ShellGradientPreset = 'neutral';\n\nexport const SHELL_GRADIENT_PRESET_LABELS: Record<ShellGradientPreset, string> = {\n none: 'None',\n cool: 'Cool',\n neutral: 'Neutral',\n warm: 'Warm',\n fresh: 'Fresh',\n};\n\nexport interface ShellGradientStop {\n color: string;\n position: number;\n}\n\nexport interface ShellGradientRecipe {\n opacity: number;\n stops: readonly ShellGradientStop[];\n}\n\nexport interface ShellGradientPickerPreview {\n backgroundColor: string;\n backgroundImage?: string;\n opacity?: number;\n}\n\nexport interface ShellGradientPickerOption {\n value: ShellGradientPreset;\n label: string;\n preview: ShellGradientPickerPreview;\n}\n\nexport interface ShellGradientPickerSection {\n options: ShellGradientPickerOption[];\n}\n\nconst SHELL_GRADIENT_RECIPES: Record<Exclude<ShellGradientPreset, 'none'>, ShellGradientRecipe> = {\n cool: {\n opacity: 0.1,\n stops: [\n { color: 'var(--color-background-transparent)', position: 0 },\n { color: 'var(--color-color-intent-blue-strong-background)', position: 100 },\n ],\n },\n neutral: {\n opacity: 0.1,\n stops: [\n { color: 'var(--color-background-transparent)', position: 0 },\n { color: 'var(--color-color-intent-grey-strong-background)', position: 100 },\n ],\n },\n warm: {\n opacity: 0.1,\n stops: [\n { color: 'var(--color-background-transparent)', position: 0 },\n { color: 'var(--color-color-intent-yellow-strong-background)', position: 100 },\n ],\n },\n fresh: {\n opacity: 0.4,\n stops: [\n { color: 'var(--color-color-intent-cyan-faint-background)', position: 0 },\n { color: 'var(--color-background-transparent)', position: 47 },\n { color: 'var(--color-background-transparent)', position: 58 },\n { color: 'var(--color-color-intent-red-faint-background)', position: 83 },\n { color: 'var(--color-color-intent-pink-faint-background)', position: 100 },\n ],\n },\n};\n\nconst GRADIENT_GEOMETRY = '100% 100% at 0% 0%';\n\nexport function shellGradientPresetStopToken(preset: ShellGradientPreset): string | null {\n if (preset === 'none') return null;\n const stops = SHELL_GRADIENT_RECIPES[preset].stops;\n return stops[stops.length - 1]?.color ?? null;\n}\n\nexport function shellGradientPresetRecipe(preset: ShellGradientPreset): ShellGradientRecipe | null {\n const normalized = normalizeShellGradientPreset(preset);\n return normalized === 'none' ? null : SHELL_GRADIENT_RECIPES[normalized];\n}\n\nexport function shellGradientPresetOpacity(preset: ShellGradientPreset): string {\n return String(shellGradientPresetRecipe(preset)?.opacity ?? 0);\n}\n\nexport function isShellGradientPreset(value: string): value is ShellGradientPreset {\n return (SHELL_GRADIENT_PRESETS as string[]).includes(value);\n}\n\n/**\n * Coerce unknown/absent presets to the default. Runtime values escape the\n * type: removing the reflected `gradient-preset` attribute (e.g. an Angular\n * `[attr.gradient-preset]=\"null\"` binding) drives the prop to null past its\n * field default \u2014 without normalization the stop lookup interpolates the\n * literal string \"undefined\" into CSS and the wash silently disappears.\n */\nexport function normalizeShellGradientPreset(\n value: string | null | undefined,\n): ShellGradientPreset {\n return value != null && isShellGradientPreset(value) ? value : DEFAULT_SHELL_GRADIENT_PRESET;\n}\n\n/** Radial wash for a preset \u2014 transparent at top-left into the intent stop. `none` returns no image. */\nexport function buildShellRadialGradientForPreset(preset: ShellGradientPreset): string {\n const normalized = normalizeShellGradientPreset(preset);\n if (normalized === 'none') return 'none';\n\n return buildShellRadialGradientFromStops(SHELL_GRADIENT_RECIPES[normalized].stops);\n}\n\n/** Build the production shell geometry from an ordered set of design-time stops. */\nexport function buildShellRadialGradientFromStops(stops: readonly ShellGradientStop[]): string {\n const serialized = stops.map(stop => `${stop.color} ${stop.position}%`).join(', ');\n return `radial-gradient(${GRADIENT_GEOMETRY}, ${serialized})`;\n}\n\n/** Generic SwatchPicker sections for the fixed shell appearance presets. */\nexport function shellGradientPickerSections(): ShellGradientPickerSection[] {\n return [\n {\n options: [{\n value: 'none',\n label: SHELL_GRADIENT_PRESET_LABELS.none,\n preview: {\n backgroundColor: 'var(--color-background-secondary)',\n },\n }],\n },\n {\n options: SHELL_GRADIENT_WASH_PRESETS.map(preset => ({\n value: preset,\n label: SHELL_GRADIENT_PRESET_LABELS[preset],\n preview: {\n backgroundColor: 'var(--color-background-secondary)',\n backgroundImage: buildShellRadialGradientForPreset(preset),\n opacity: Number(shellGradientPresetOpacity(preset)),\n },\n })),\n },\n ];\n}\n", "import type { PanelToolsToolId } from '../components/PanelTools/panel-tools-types';\n\nexport type ShellResponsiveMode = 'desktop' | 'tablet' | 'mobile';\nexport type MobileDestination =\n | 'area'\n | 'search'\n | 'inbox'\n | 'activity'\n | 'messages'\n | 'agents'\n | 'help';\nexport type ShellInboxToolId = PanelToolsToolId;\n\nexport const SHELL_DESKTOP_BREAKPOINT = 1200;\nexport const SHELL_MOBILE_BREAKPOINT = 768;\nexport const SHELL_DEFAULT_INBOX_TOOL: ShellInboxToolId = 'activity';\n\nexport function resolveShellResponsiveMode(width: number): ShellResponsiveMode {\n if (width >= SHELL_DESKTOP_BREAKPOINT) return 'desktop';\n if (width >= SHELL_MOBILE_BREAKPOINT) return 'tablet';\n return 'mobile';\n}\n\nexport function resolveManagedShellPageCapacity(\n mode: ShellResponsiveMode\n): 'roomy' | 'compact' | 'constrained' {\n return mode === 'desktop' ? 'roomy' : 'compact';\n}\n\nexport function shellMobileDestinationForTool(\n open: boolean,\n tool: PanelToolsToolId | ''\n): MobileDestination {\n if (!open || !tool) return 'area';\n if (tool === 'help') return 'help';\n if (tool === 'search') return 'search';\n if (tool === 'messages') return 'messages';\n if (tool === 'agents') return 'agents';\n return 'inbox';\n}\n\n/** Explicit item metadata wins over the legacy canonical Stacks/Activity grouping. */\nexport function itemUsesShellInbox(item: {\n id: PanelToolsToolId;\n mobileDestination?: MobileDestination;\n}): boolean {\n return item.mobileDestination === 'inbox' ||\n (item.mobileDestination === undefined && isShellInboxTool(item.id));\n}\n\nexport function isShellInboxTool(tool: string): tool is ShellInboxToolId {\n return tool === 'stacks' || tool === 'activity';\n}\n\nexport function resolveAvailableInboxTool(\n preferred: string,\n available: readonly PanelToolsToolId[]\n): ShellInboxToolId | '' {\n const inbox = available.filter(isShellInboxTool);\n if (isShellInboxTool(preferred) && inbox.includes(preferred)) return preferred;\n if (inbox.includes(SHELL_DEFAULT_INBOX_TOOL)) return SHELL_DEFAULT_INBOX_TOOL;\n return inbox[0] ?? '';\n}\n\n/** Active-destination reselects are inert unless they also dismiss the Menu pane. */\nexport function shouldEmitMobileDestinationChange(\n active: MobileDestination,\n next: MobileDestination,\n navigationOpen: boolean\n): boolean {\n return navigationOpen || active !== next;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PanelToolsToolId } from '../components/PanelTools/panel-tools-types';
|
|
2
2
|
export type ShellResponsiveMode = 'desktop' | 'tablet' | 'mobile';
|
|
3
|
-
export type MobileDestination = 'area' | 'search' | 'inbox' | 'messages' | 'agents' | 'help';
|
|
3
|
+
export type MobileDestination = 'area' | 'search' | 'inbox' | 'activity' | 'messages' | 'agents' | 'help';
|
|
4
4
|
export type ShellInboxToolId = PanelToolsToolId;
|
|
5
5
|
export declare const SHELL_DESKTOP_BREAKPOINT = 1200;
|
|
6
6
|
export declare const SHELL_MOBILE_BREAKPOINT = 768;
|
|
@@ -8,6 +8,11 @@ export declare const SHELL_DEFAULT_INBOX_TOOL: ShellInboxToolId;
|
|
|
8
8
|
export declare function resolveShellResponsiveMode(width: number): ShellResponsiveMode;
|
|
9
9
|
export declare function resolveManagedShellPageCapacity(mode: ShellResponsiveMode): 'roomy' | 'compact' | 'constrained';
|
|
10
10
|
export declare function shellMobileDestinationForTool(open: boolean, tool: PanelToolsToolId | ''): MobileDestination;
|
|
11
|
+
/** Explicit item metadata wins over the legacy canonical Stacks/Activity grouping. */
|
|
12
|
+
export declare function itemUsesShellInbox(item: {
|
|
13
|
+
id: PanelToolsToolId;
|
|
14
|
+
mobileDestination?: MobileDestination;
|
|
15
|
+
}): boolean;
|
|
11
16
|
export declare function isShellInboxTool(tool: string): tool is ShellInboxToolId;
|
|
12
17
|
export declare function resolveAvailableInboxTool(preferred: string, available: readonly PanelToolsToolId[]): ShellInboxToolId | '';
|
|
13
18
|
/** Active-destination reselects are inert unless they also dismiss the Menu pane. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type AnchoredSide = 'top' | 'right' | 'bottom' | 'left';
|
|
2
2
|
export type AnchoredAlign = 'start' | 'center' | 'end';
|
|
3
|
+
export type AnchoredCollisionRect = Pick<DOMRectReadOnly, 'top' | 'left' | 'right' | 'bottom' | 'width' | 'height'>;
|
|
3
4
|
export interface AnchoredPositionInput {
|
|
4
5
|
anchorRect: Pick<DOMRectReadOnly, 'top' | 'left' | 'right' | 'bottom' | 'width' | 'height'>;
|
|
5
6
|
popupWidth: number;
|
|
@@ -11,20 +12,25 @@ export interface AnchoredPositionInput {
|
|
|
11
12
|
viewportPadPx: number;
|
|
12
13
|
viewportWidth: number;
|
|
13
14
|
viewportHeight: number;
|
|
15
|
+
/** Optional page or panel collision rectangle in viewport-fixed coordinates. */
|
|
16
|
+
collisionRect?: AnchoredCollisionRect;
|
|
14
17
|
}
|
|
15
18
|
export interface AnchoredPosition {
|
|
16
19
|
x: number;
|
|
17
20
|
y: number;
|
|
18
21
|
/** Side actually used, which differs from the request when placement flipped. */
|
|
19
22
|
resolvedSide: AnchoredSide;
|
|
23
|
+
/** Vertical room available on the resolved side inside the padded viewport. */
|
|
24
|
+
availableHeight: number;
|
|
20
25
|
}
|
|
21
26
|
/**
|
|
22
27
|
* Pure viewport-fixed anchored-popup layout math shared by every element-anchored
|
|
23
28
|
* overlay: menus, selects, tooltips, and anchored toasts.
|
|
24
29
|
*
|
|
25
|
-
* `side` is preferred. When the popup spills past the padded
|
|
30
|
+
* `side` is preferred. When the popup spills past the padded collision boundary and
|
|
26
31
|
* the opposite side spills less, placement flips on the main axis; the result is
|
|
27
|
-
* then clamped into
|
|
32
|
+
* then clamped into that boundary on both axes. The viewport is the fallback when
|
|
33
|
+
* no page or panel collision rectangle is supplied. Cross-axis `align` is applied
|
|
28
34
|
* before clamping so `alignOffsetPx` stays an additive nudge.
|
|
29
35
|
*
|
|
30
36
|
* Callers own their own anchor semantics — inner-cell alignment offsets and
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"Badge keeps one brand treatment; semantic severity belongs to another component or adjacent content.",
|
|
63
63
|
"Use the ring only when Badge overlaps an icon or other content. Disable it in a reserved safe-area slot.",
|
|
64
64
|
"When enabled, the ring matches the immediate backing surface for both variants. Use a direct ring override only for a component-local fill that no surface preset represents.",
|
|
65
|
-
"
|
|
65
|
+
"Shell gradient rings follow the inherited ShellApp chrome context automatically; an explicit composition override may force either the gradient or flat ring treatment."
|
|
66
66
|
],
|
|
67
67
|
"responsiveBehavior": [
|
|
68
68
|
"The owning control or layout positions Badge and decides whether notification indicators remain visible, condense, or move at responsive breakpoints.",
|
|
@@ -107,12 +107,11 @@
|
|
|
107
107
|
},
|
|
108
108
|
"gradientBackground": {
|
|
109
109
|
"type": "boolean",
|
|
110
|
-
"resolvedType": "boolean",
|
|
110
|
+
"resolvedType": "boolean | undefined",
|
|
111
111
|
"attribute": "gradient-background",
|
|
112
|
-
"default": "false",
|
|
113
112
|
"required": false,
|
|
114
113
|
"mutable": false,
|
|
115
|
-
"description": "Ring samples the shell gradient stack (base fill + wash) instead of a flat\n`box-shadow`.
|
|
114
|
+
"description": "Ring samples the shell gradient stack (base fill + wash) instead of a flat\n`box-shadow`. Omit to inherit ShellApp context; set true or false to override.\n\nThe attribute must NOT start with `on` — Stencil's setAccessor routes any\nunknown `on*` member down the event-listener path during attribute\nreflection, calling addEventListener with a non-listener and throwing."
|
|
116
115
|
},
|
|
117
116
|
"hasRing": {
|
|
118
117
|
"type": "boolean",
|
|
@@ -183,12 +182,11 @@
|
|
|
183
182
|
},
|
|
184
183
|
"gradientBackground": {
|
|
185
184
|
"type": "boolean",
|
|
186
|
-
"resolvedType": "boolean",
|
|
185
|
+
"resolvedType": "boolean | undefined",
|
|
187
186
|
"attribute": "gradient-background",
|
|
188
|
-
"default": "false",
|
|
189
187
|
"required": false,
|
|
190
188
|
"mutable": false,
|
|
191
|
-
"description": "Ring samples the shell gradient stack (base fill + wash) instead of a flat\n`box-shadow`.
|
|
189
|
+
"description": "Ring samples the shell gradient stack (base fill + wash) instead of a flat\n`box-shadow`. Omit to inherit ShellApp context; set true or false to override.\n\nThe attribute must NOT start with `on` — Stencil's setAccessor routes any\nunknown `on*` member down the event-listener path during attribute\nreflection, calling addEventListener with a non-listener and throwing."
|
|
192
190
|
},
|
|
193
191
|
"hasRing": {
|
|
194
192
|
"type": "boolean",
|
|
@@ -282,12 +280,12 @@
|
|
|
282
280
|
"files": [
|
|
283
281
|
{
|
|
284
282
|
"path": "src/wc/components/Badge/Badge.css",
|
|
285
|
-
"content": "@import '../../utils/visually-hidden.css';\n@import '../../utils/forced-colors.css';\n\n:host {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n vertical-align: middle;\n\n --_badge-bg: var(--color-background-bold-brand);\n --_badge-fg: var(--color-foreground-on-bold-background-primary);\n --_badge-ring: var(--color-background-secondary);\n --_badge-ring-width: var(--dimension-stroke-width-018);\n}\n\n.badge__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n box-sizing: border-box;\n color: var(--_badge-fg);\n background: var(--_badge-bg);\n box-shadow: 0 0 0 var(--_badge-ring-width) var(--_badge-ring);\n white-space: nowrap;\n}\n\n:host(.badge--no-ring) {\n --_badge-ring-width: 0;\n}\n\n\n:host(.badge--dot) .badge__mark {\n width: var(--dimension-size-075);\n height: var(--dimension-size-075);\n border-radius: var(--dimension-radius-half);\n}\n\n:host(.badge--counter) .badge__mark {\n width: auto;\n min-width: var(--dimension-size-150);\n height: var(--dimension-size-150);\n padding: 0 var(--dimension-space-025);\n border-radius: var(--dimension-radius-half);\n}\n\n/* Shell gradient ring — base fill + wash donut (option 3). */\n
|
|
283
|
+
"content": "@import '../../utils/visually-hidden.css';\n@import '../../utils/forced-colors.css';\n\n:host {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n container-name: ds-badge-gradient;\n pointer-events: none;\n vertical-align: middle;\n\n --_badge-bg: var(--color-background-bold-brand);\n --_badge-fg: var(--color-foreground-on-bold-background-primary);\n --_badge-ring: var(--color-background-secondary);\n --_badge-ring-width: var(--dimension-stroke-width-018);\n --_badge-gradient-context: var(--ds-shell-gradient-context, flat);\n}\n\n:host(.badge--force-gradient-background) {\n --_badge-gradient-context: gradient;\n}\n\n:host(.badge--force-flat-background) {\n --_badge-gradient-context: flat;\n}\n\n.badge__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n box-sizing: border-box;\n color: var(--_badge-fg);\n background: var(--_badge-bg);\n box-shadow: 0 0 0 var(--_badge-ring-width) var(--_badge-ring);\n white-space: nowrap;\n}\n\n:host(.badge--no-ring) {\n --_badge-ring-width: 0;\n}\n\n\n:host(.badge--dot) .badge__mark {\n width: var(--dimension-size-075);\n height: var(--dimension-size-075);\n border-radius: var(--dimension-radius-half);\n}\n\n:host(.badge--counter) .badge__mark {\n width: auto;\n min-width: var(--dimension-size-150);\n height: var(--dimension-size-150);\n padding: 0 var(--dimension-space-025);\n border-radius: var(--dimension-radius-half);\n}\n\n/* Shell gradient ring — base fill + wash donut (option 3). */\n@container ds-badge-gradient style(--_badge-gradient-context: gradient) {\n /* Match the scoped base rule's specificity; Stencil does not yet scope style-query selectors. */\n .badge__mark.badge__mark {\n position: relative;\n z-index: 0;\n box-shadow: none;\n isolation: isolate;\n }\n\n .badge__mark::before,\n .badge__mark::after {\n content: '';\n position: absolute;\n inset: calc(-1 * var(--_badge-ring-width));\n border-radius: inherit;\n box-sizing: border-box;\n padding: var(--_badge-ring-width);\n pointer-events: none;\n /* stylelint-disable color-no-hex -- mask luminance stops for ring cutout, not theme colors */\n -webkit-mask:\n linear-gradient(#fff 0 0) content-box,\n linear-gradient(#fff 0 0);\n -webkit-mask-composite: xor;\n mask:\n linear-gradient(#fff 0 0) content-box,\n linear-gradient(#fff 0 0);\n /* stylelint-enable color-no-hex */\n mask-composite: exclude;\n }\n\n .badge__mark::before {\n z-index: -2;\n background-color: var(--_badge-ring);\n }\n\n .badge__mark::after {\n z-index: -1;\n background-image: var(--ds-shell-gradient-image, none);\n background-size: var(--ds-shell-gradient-size, auto);\n background-position: 0 0;\n background-repeat: no-repeat;\n background-attachment: fixed;\n opacity: var(--ds-shell-gradient-opacity, 1);\n }\n}\n\n@media (forced-colors: active) {\n .badge__mark {\n color: var(--ds-forced-color-on-selected);\n background: var(--ds-forced-color-selected);\n box-shadow: none;\n outline: var(--_badge-ring-width) solid var(--ds-forced-color-surface);\n }\n\n .badge__mark::before,\n .badge__mark::after {\n display: none;\n }\n}\n",
|
|
286
284
|
"type": "registry:ui"
|
|
287
285
|
},
|
|
288
286
|
{
|
|
289
287
|
"path": "src/wc/components/Badge/Badge.tsx",
|
|
290
|
-
"content": "import { Component, Prop,
|
|
288
|
+
"content": "import { Component, Prop, h, Host } from '@stencil/core';\n\nexport type BadgeVariant = 'counter' | 'dot';\nexport type BadgeSurface =\n | 'primary'\n | 'secondary'\n | 'faint'\n | 'medium'\n | 'bold'\n | 'strong'\n | 'translucent'\n | 'inverted'\n | 'media'\n | 'navigation'\n | 'always-dark';\n\nconst SURFACE_RING: Record<BadgeSurface, string> = {\n primary: 'var(--color-background-primary)',\n secondary: 'var(--color-background-secondary)',\n faint: 'var(--color-background-faint-neutral)',\n medium: 'var(--color-background-medium-neutral)',\n bold: 'var(--color-background-bold-neutral)',\n strong: 'var(--color-background-strong-neutral)',\n translucent: 'var(--color-translucent-translucent)',\n inverted: 'var(--color-inverted-background)',\n media: 'var(--color-media-background)',\n navigation: 'var(--color-navigation-background)',\n 'always-dark': 'var(--color-always-dark-background)',\n};\n\n@Component({\n tag: 'ds-badge',\n styleUrl: 'Badge.css',\n scoped: true,\n})\nexport class Badge {\n /** Render as a compact counter or notification dot. */\n @Prop() variant: BadgeVariant = 'counter';\n\n /** Count shown for counter badges. Count 0 hides the badge. */\n @Prop() count: number = 0;\n\n /** Highest count shown before compacting to \"{max}+\". */\n @Prop() max: number = 9;\n\n /** Immediate backing surface matched by the ring around either variant. */\n @Prop() surface: BadgeSurface = 'primary';\n\n /** Direct ring background override for component-local surfaces. */\n @Prop() background: string | undefined;\n\n /** Show the separation ring when the badge overlaps an icon or other content. */\n @Prop() hasRing: boolean = true;\n\n /**\n * Ring samples the shell gradient stack (base fill + wash) instead of a flat\n * `box-shadow`. Omit to inherit ShellApp context; set true or false to override.\n *\n * The attribute must NOT start with `on` — Stencil's setAccessor routes any\n * unknown `on*` member down the event-listener path during attribute\n * reflection, calling addEventListener with a non-listener and throwing.\n */\n @Prop({ attribute: 'gradient-background', reflect: true }) gradientBackground?: boolean;\n\n /** Contextual supplemental text. Omit when the owner hides the badge from assistive technology. */\n @Prop() label: string | undefined;\n\n render() {\n const isDot = this.variant === 'dot';\n\n if (!isDot && this.count <= 0) return <Host style={{ display: 'none' }} />;\n\n const display = this.count > this.max ? `${this.max}+` : String(this.count);\n const ring = this.background ?? SURFACE_RING[this.surface];\n\n return (\n <Host\n class={{\n badge: true,\n 'badge--counter': !isDot,\n 'badge--dot': isDot,\n 'badge--no-ring': !this.hasRing,\n 'badge--force-gradient-background': this.gradientBackground === true,\n 'badge--force-flat-background': this.gradientBackground === false,\n }}\n style={{ '--_badge-ring': ring }}\n >\n <span class=\"badge__mark\" aria-hidden=\"true\">\n {!isDot && (\n <ds-text as=\"span\" variant=\"text-caption\" emphasis color=\"inherit\">\n {display}\n </ds-text>\n )}\n </span>\n {this.label && <span class=\"badge__a11y ds-visually-hidden\">{this.label}</span>}\n </Host>\n );\n }\n}\n",
|
|
291
289
|
"type": "registry:ui"
|
|
292
290
|
}
|
|
293
291
|
]
|
|
@@ -326,12 +326,12 @@
|
|
|
326
326
|
"files": [
|
|
327
327
|
{
|
|
328
328
|
"path": "src/wc/components/Banner/Banner.css",
|
|
329
|
-
"content": "@import '../../utils/forced-colors.css';\n@import '../../utils/chrome-header.css';\n\n:host {\n display: grid;\n overflow: hidden;\n min-width: 0;\n grid-template-rows:
|
|
329
|
+
"content": "@import '../../utils/forced-colors.css';\n@import '../../utils/chrome-header.css';\n\n:host {\n display: grid;\n overflow: hidden;\n min-width: 0;\n grid-template-rows: 1fr;\n transition: grid-template-rows var(--effect-animation-duration-short-3)\n var(--_banner-motion-easing);\n\n --ds-banner-background: var(--color-background-faint-neutral);\n --ds-banner-heading: var(--color-foreground-primary);\n --ds-banner-description: var(--color-foreground-secondary);\n --ds-banner-border: var(--color-border-tertiary);\n --_banner-motion-easing: var(--effect-animation-easing-ease-in-out, ease);\n --_banner-surface-translate: 0%;\n}\n\n:host(.banner--open) {\n --_banner-motion-easing: var(--effect-animation-easing-ease-out, ease-out);\n}\n\n:host(.banner--closing) {\n --_banner-motion-easing: var(--effect-animation-easing-ease-in, ease-in);\n --_banner-surface-translate: -100%;\n grid-template-rows: 0fr;\n}\n\n:host(.banner--hidden) {\n --_banner-surface-translate: -100%;\n\n display: none;\n visibility: hidden;\n grid-template-rows: 0fr;\n}\n\n.banner-overflow {\n min-height: 0;\n overflow: visible;\n}\n\n.banner-surface {\n display: flex;\n position: relative;\n width: 100%;\n padding-inline-end: calc(var(--dimension-size-400) + var(--dimension-space-200));\n color: var(--ds-banner-description);\n background-color: var(--ds-banner-background);\n border-bottom: var(--dimension-stroke-width-012) solid var(--ds-banner-border);\n transform: translateY(var(--_banner-surface-translate));\n transition: transform var(--effect-animation-duration-short-3) var(--_banner-motion-easing);\n}\n\n@starting-style {\n :host(.banner--open) {\n grid-template-rows: 0fr;\n }\n}\n\n.banner-copy {\n flex-basis: var(--dimension-card-width-sm);\n}\n\n:host(.banner--orientation-horizontal) .banner-surface {\n flex-wrap: nowrap;\n}\n\n:host(.banner--orientation-vertical) .banner-copy {\n flex-basis: 100%;\n}\n\n.banner-copy-flow {\n box-sizing: border-box;\n min-width: 0;\n padding-inline: var(--ds-control-label-inset, var(--dimension-space-025));\n color: var(--ds-banner-description);\n}\n\n.banner-heading {\n display: inline-block;\n width: auto;\n max-width: 100%;\n margin-inline-end: var(--dimension-space-100);\n vertical-align: baseline;\n color: var(--ds-banner-heading);\n}\n\n.banner-description {\n color: var(--ds-banner-description);\n}\n\n.banner-actions {\n display: flex;\n align-items: center;\n flex: 0 0 auto;\n flex-wrap: nowrap;\n min-width: 0;\n gap: var(--dimension-space-100);\n}\n\n.banner-actions slot {\n display: contents;\n}\n\n.banner-actions ::slotted(:not(ds-button-unfilled)),\n.banner-actions ::slotted(ds-button-unfilled:nth-of-type(n + 3)) {\n display: none;\n}\n\n.banner-actions--empty {\n display: none;\n}\n\n.banner-trailing {\n align-self: flex-start;\n flex-wrap: nowrap;\n}\n\n:host(.banner--orientation-vertical:not(.banner--has-actions)) .banner-trailing {\n display: contents;\n}\n\n:host(.banner--orientation-vertical.banner--has-actions) .banner-trailing {\n margin-inline: var(--dimension-space-100) auto;\n padding-block-end: var(--dimension-space-100);\n box-sizing: border-box;\n}\n\n:host(.banner--orientation-vertical) .banner-description {\n display: block;\n}\n\n:host(.banner--orientation-vertical) .banner-heading + .banner-description {\n margin-block-start: var(--dimension-space-050);\n}\n\n.banner-close {\n flex: 0 0 auto;\n}\n\n.banner-dismiss {\n position: absolute;\n inset-block-start: var(--dimension-space-100);\n inset-inline-end: var(--dimension-space-100);\n}\n\n:host(.banner--intent-neutral) {\n --ds-banner-faint-background: var(--color-background-faint-neutral);\n}\n\n:host(.banner--intent-brand) {\n --ds-banner-faint-background: var(--color-background-faint-brand);\n}\n\n:host(.banner--intent-positive) {\n --ds-banner-faint-background: var(--color-background-faint-positive);\n}\n\n:host(.banner--intent-warning) {\n --ds-banner-faint-background: var(--color-background-faint-warning);\n}\n\n:host(.banner--intent-caution) {\n --ds-banner-faint-background: var(--color-background-faint-caution);\n}\n\n:host(.banner--intent-negative) {\n --ds-banner-faint-background: var(--color-background-faint-negative);\n}\n\n:host(.banner--contrast-faint) {\n --ds-banner-background: var(--ds-banner-faint-background);\n --ds-banner-heading: var(--color-foreground-primary);\n --ds-banner-description: var(--color-foreground-secondary);\n --ds-banner-border: var(--color-border-tertiary);\n}\n\n:host(.banner--contrast-medium) {\n --ds-banner-background: var(--color-background-medium-neutral);\n --ds-banner-heading: var(--color-foreground-on-medium-background-primary);\n --ds-banner-description: var(--color-foreground-on-medium-background-secondary);\n --ds-banner-border: var(--color-border-on-medium-background-tertiary);\n}\n\n:host(.banner--intent-brand.banner--contrast-medium) { --ds-banner-background: var(--color-background-medium-brand); }\n:host(.banner--intent-positive.banner--contrast-medium) { --ds-banner-background: var(--color-background-medium-positive); }\n:host(.banner--intent-warning.banner--contrast-medium) { --ds-banner-background: var(--color-background-medium-warning); }\n:host(.banner--intent-caution.banner--contrast-medium) { --ds-banner-background: var(--color-background-medium-caution); }\n:host(.banner--intent-negative.banner--contrast-medium) { --ds-banner-background: var(--color-background-medium-negative); }\n\n:host(.banner--contrast-strong) {\n --ds-banner-background: var(--color-background-strong-neutral);\n --ds-banner-heading: var(--color-foreground-on-strong-background-primary);\n --ds-banner-description: var(--color-foreground-on-strong-background-secondary);\n --ds-banner-border: var(--color-border-on-strong-background-tertiary);\n}\n\n:host(.banner--intent-brand.banner--contrast-strong) { --ds-banner-background: var(--color-background-strong-brand); }\n:host(.banner--intent-positive.banner--contrast-strong) { --ds-banner-background: var(--color-background-strong-positive); }\n:host(.banner--intent-warning.banner--contrast-strong) { --ds-banner-background: var(--color-background-strong-warning); }\n:host(.banner--intent-caution.banner--contrast-strong) { --ds-banner-background: var(--color-background-strong-caution); }\n:host(.banner--intent-negative.banner--contrast-strong) { --ds-banner-background: var(--color-background-strong-negative); }\n\n:host(.banner--contrast-bold) {\n --ds-banner-background: var(--color-background-bold-neutral);\n --ds-banner-heading: var(--color-foreground-on-bold-background-primary);\n --ds-banner-description: var(--color-foreground-on-bold-background-secondary);\n --ds-banner-border: var(--color-border-on-bold-background-tertiary);\n}\n\n:host(.banner--intent-brand.banner--contrast-bold) { --ds-banner-background: var(--color-background-bold-brand); }\n:host(.banner--intent-positive.banner--contrast-bold) { --ds-banner-background: var(--color-background-bold-positive); }\n:host(.banner--intent-warning.banner--contrast-bold) { --ds-banner-background: var(--color-background-bold-warning); }\n:host(.banner--intent-caution.banner--contrast-bold) { --ds-banner-background: var(--color-background-bold-caution); }\n:host(.banner--intent-negative.banner--contrast-bold) { --ds-banner-background: var(--color-background-bold-negative); }\n\n@media (prefers-reduced-motion: reduce) {\n :host,\n .banner-surface {\n transition: none;\n }\n}\n\n@media (forced-colors: active) {\n .banner-surface {\n color: var(--ds-forced-color-content);\n background-color: var(--ds-forced-color-surface);\n border-bottom-color: var(--ds-forced-color-content);\n }\n\n .banner-heading,\n .banner-description {\n color: var(--ds-forced-color-content);\n }\n}\n",
|
|
330
330
|
"type": "registry:ui"
|
|
331
331
|
},
|
|
332
332
|
{
|
|
333
333
|
"path": "src/wc/components/Banner/Banner.tsx",
|
|
334
|
-
"content": "import {\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\nimport { resolveMotionTimeMs, TOKEN_DEFAULTS } from '../../utils';\n\nexport type BannerIntent =\n | 'neutral'\n | 'brand'\n | 'positive'\n | 'warning'\n | 'caution'\n | 'negative';\n\nexport type BannerContrast = 'faint' | 'medium' | 'strong' | 'bold';\nexport type BannerAnnouncement = 'none' | 'polite' | 'assertive';\nexport type BannerOrientation = 'horizontal' | 'vertical';\n\ntype BannerPhase = 'closed' | 'open' | 'closing';\n\n@Component({\n tag: 'ds-banner',\n styleUrl: 'Banner.css',\n scoped: true,\n})\nexport class Banner {\n @Element() el!: HTMLElement;\n\n /** Required explanatory copy. */\n @Prop() description!: string;\n /** Optional visual heading rendered before the description. */\n @Prop() heading: string = '';\n /** Semantic color family. */\n @Prop({ reflect: true }) intent: BannerIntent = 'neutral';\n /** Surface fill weight. */\n @Prop({ reflect: true }) contrast: BannerContrast = 'faint';\n /** Copy and action-lane arrangement, selected by the application. */\n @Prop({ reflect: true }) orientation: BannerOrientation = 'horizontal';\n /** Controlled visibility. Keep the element mounted until dsAfterClose when unmounting. */\n @Prop({ reflect: true }) open: boolean = true;\n /** Localized accessible label for the close control. */\n @Prop() dismissLabel: string = 'Dismiss banner';\n /** Live-region urgency, independent of visual intent. */\n @Prop() announcement: BannerAnnouncement = 'none';\n\n /** Emitted when the close control requests dismissal. The application controls open. */\n @Event() dsClose!: EventEmitter<MouseEvent>;\n /** Emitted once after controlled exit motion and layout collapse complete. */\n @Event() dsAfterClose!: EventEmitter<void>;\n\n @State() private rendered = false;\n @State() private phase: BannerPhase = 'closed';\n @State() private hasActions = false;\n\n private loaded = false;\n private transitionTimer: ReturnType<typeof setTimeout> | null = null;\n private
|
|
334
|
+
"content": "import {\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\nimport { resolveMotionTimeMs, TOKEN_DEFAULTS } from '../../utils';\n\nexport type BannerIntent =\n | 'neutral'\n | 'brand'\n | 'positive'\n | 'warning'\n | 'caution'\n | 'negative';\n\nexport type BannerContrast = 'faint' | 'medium' | 'strong' | 'bold';\nexport type BannerAnnouncement = 'none' | 'polite' | 'assertive';\nexport type BannerOrientation = 'horizontal' | 'vertical';\n\ntype BannerPhase = 'closed' | 'open' | 'closing';\n\n@Component({\n tag: 'ds-banner',\n styleUrl: 'Banner.css',\n scoped: true,\n})\nexport class Banner {\n @Element() el!: HTMLElement;\n\n /** Required explanatory copy. */\n @Prop() description!: string;\n /** Optional visual heading rendered before the description. */\n @Prop() heading: string = '';\n /** Semantic color family. */\n @Prop({ reflect: true }) intent: BannerIntent = 'neutral';\n /** Surface fill weight. */\n @Prop({ reflect: true }) contrast: BannerContrast = 'faint';\n /** Copy and action-lane arrangement, selected by the application. */\n @Prop({ reflect: true }) orientation: BannerOrientation = 'horizontal';\n /** Controlled visibility. Keep the element mounted until dsAfterClose when unmounting. */\n @Prop({ reflect: true }) open: boolean = true;\n /** Localized accessible label for the close control. */\n @Prop() dismissLabel: string = 'Dismiss banner';\n /** Live-region urgency, independent of visual intent. */\n @Prop() announcement: BannerAnnouncement = 'none';\n\n /** Emitted when the close control requests dismissal. The application controls open. */\n @Event() dsClose!: EventEmitter<MouseEvent>;\n /** Emitted once after controlled exit motion and layout collapse complete. */\n @Event() dsAfterClose!: EventEmitter<void>;\n\n @State() private rendered = false;\n @State() private phase: BannerPhase = 'closed';\n @State() private hasActions = false;\n\n private loaded = false;\n private transitionTimer: ReturnType<typeof setTimeout> | null = null;\n private closePending = false;\n\n componentWillLoad() {\n this.rendered = this.open;\n this.phase = this.open ? 'open' : 'closed';\n }\n\n componentDidLoad() {\n this.loaded = true;\n this.updateActionsPresence();\n }\n\n disconnectedCallback() {\n this.clearTransitionWork();\n }\n\n @Watch('open')\n onOpenChange(isOpen: boolean) {\n if (!this.loaded) return;\n if (isOpen) this.startOpen();\n else this.startClose();\n }\n\n private get closeMotionMs(): number {\n return resolveMotionTimeMs(\n TOKEN_DEFAULTS.motionShort3,\n TOKEN_DEFAULTS.animationDurationShort3,\n );\n }\n\n private clearTransitionWork() {\n if (this.transitionTimer) clearTimeout(this.transitionTimer);\n this.transitionTimer = null;\n }\n\n private startOpen() {\n this.clearTransitionWork();\n this.closePending = false;\n this.rendered = true;\n this.phase = 'open';\n }\n\n private startClose() {\n this.clearTransitionWork();\n if (!this.rendered || this.phase === 'closed') {\n this.rendered = false;\n return;\n }\n\n this.closePending = true;\n this.phase = 'closing';\n const duration = this.closeMotionMs;\n if (duration <= 0) {\n this.finishClose();\n return;\n }\n this.transitionTimer = setTimeout(() => {\n this.transitionTimer = null;\n this.finishClose();\n }, duration);\n }\n\n private finishClose() {\n if (this.open || !this.closePending) return;\n this.closePending = false;\n this.rendered = false;\n this.phase = 'closed';\n this.dsAfterClose.emit();\n }\n\n private updateActionsPresence(slot?: HTMLSlotElement) {\n const actions = slot\n ? slot.assignedElements().filter(element => element.tagName === 'DS-BUTTON-UNFILLED')\n : Array.from(this.el.querySelectorAll('ds-button-unfilled[slot=\"actions\"]'));\n this.hasActions = actions.length > 0;\n }\n\n private requestClose(event: CustomEvent<MouseEvent>) {\n if (!this.open || this.phase === 'closing') return;\n this.dsClose.emit(event.detail);\n }\n\n private get role(): 'status' | 'alert' | undefined {\n if (this.announcement === 'polite') return 'status';\n if (this.announcement === 'assertive') return 'alert';\n return undefined;\n }\n\n private get ariaLive(): 'polite' | 'assertive' | undefined {\n return this.announcement === 'none' ? undefined : this.announcement;\n }\n\n render() {\n const closing = this.phase === 'closing';\n const hostClass = {\n banner: true,\n 'banner--open': this.phase === 'open',\n 'banner--closing': closing,\n 'banner--hidden': !this.rendered,\n 'banner--has-actions': this.hasActions,\n [`banner--orientation-${this.orientation}`]: true,\n [`banner--intent-${this.intent}`]: true,\n [`banner--contrast-${this.contrast}`]: true,\n };\n\n return (\n <Host class={hostClass}>\n <div class=\"banner-overflow\">\n <section\n class=\"banner-surface ds-chrome-header ds-chrome-header--wrapping\"\n role={this.role}\n aria-live={this.ariaLive}\n aria-atomic={this.announcement === 'none' ? undefined : 'true'}\n aria-hidden={closing ? 'true' : undefined}\n inert={closing ? true : undefined}\n data-phase={this.phase}\n >\n {/* eslint-disable-next-line local/prefer-direct-ds-text -- The header-copy lane owns the 6px container inset separately from the inline text flow's 2px inset. */}\n <div class=\"banner-copy ds-chrome-header__copy ds-chrome-header__copy--wrapping ds-control--md\">\n <ds-text\n class=\"banner-copy-flow\"\n as=\"div\"\n variant=\"text-body-medium\"\n color=\"inherit\"\n >\n {this.heading && (\n <ds-text\n class=\"banner-heading\"\n as=\"span\"\n variant=\"text-title-small\"\n color=\"inherit\"\n >\n {this.heading}\n </ds-text>\n )}\n <span class=\"banner-description\">{this.description}</span>\n </ds-text>\n </div>\n <div class=\"banner-trailing ds-chrome-header__trailing\">\n <div class={{ 'banner-actions': true, 'banner-actions--empty': !this.hasActions }}>\n <slot\n name=\"actions\"\n onSlotchange={(event: Event) =>\n this.updateActionsPresence(event.currentTarget as HTMLSlotElement)\n }\n />\n </div>\n <div class=\"banner-dismiss\">\n <ds-tooltip label={this.dismissLabel} side=\"bottom\" size=\"sm\">\n <ds-button-unfilled\n class=\"banner-close\"\n variant=\"icon\"\n icon=\"Cross\"\n size=\"md\"\n type=\"button\"\n background={this.contrast}\n aria-label={this.dismissLabel}\n hasBorder={false}\n activeFill={false}\n onDsClick={(event: CustomEvent<MouseEvent>) => this.requestClose(event)}\n />\n </ds-tooltip>\n </div>\n </div>\n </section>\n </div>\n </Host>\n );\n }\n}\n",
|
|
335
335
|
"type": "registry:ui"
|
|
336
336
|
}
|
|
337
337
|
]
|
|
@@ -230,12 +230,12 @@
|
|
|
230
230
|
"files": [
|
|
231
231
|
{
|
|
232
232
|
"path": "src/wc/components/BarAction/BarAction.css",
|
|
233
|
-
"content": "@import '../../styles/control-elevation.css';\n@import '../../utils/chrome-layout.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/forced-colors.css';\n@import '../../utils/text-decoration.css';\n@import '../../utils/visually-hidden.css';\n\n:host {\n display: block;\n min-width: 0;\n box-sizing: border-box;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.bar-action {\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n height: var(--dimension-size-600);\n border-radius: var(--dimension-radius-125);\n background: var(--color-background-bold-brand);\n color: var(--color-foreground-on-bold-background-secondary);\n --ds-focus-ring-color: var(--color-interaction-on-bold-background-focus);\n}\n\n.bar-action[hidden],\n.bar-action__actions
|
|
233
|
+
"content": "@import '../../styles/control-elevation.css';\n@import '../../utils/chrome-layout.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/forced-colors.css';\n@import '../../utils/text-decoration.css';\n@import '../../utils/visually-hidden.css';\n\n:host {\n display: block;\n min-width: 0;\n box-sizing: border-box;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.bar-action {\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n height: var(--dimension-size-600);\n border-radius: var(--dimension-radius-125);\n background: var(--color-background-bold-brand);\n color: var(--color-foreground-on-bold-background-secondary);\n --ds-focus-ring-color: var(--color-interaction-on-bold-background-focus);\n}\n\n.bar-action[hidden],\n.bar-action__actions:not(:has([slot='actions'])) {\n display: none;\n}\n\n.bar-action__copy,\n.bar-action__actions {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: var(--dimension-space-050);\n}\n\n.bar-action__copy {\n flex: 1 1 auto;\n padding-inline: var(--dimension-space-100);\n}\n\n.bar-action__count {\n flex: 0 1 auto;\n min-width: 0;\n}\n\n.bar-action__separator,\n.bar-action__clear,\n.bar-action__actions {\n flex: 0 0 auto;\n}\n\n.bar-action__actions {\n margin-inline-start: auto;\n}\n\n.bar-action__actions slot {\n display: contents;\n}\n\n.bar-action__clear {\n appearance: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-block-size: var(--dimension-size-400);\n margin: 0;\n padding: var(--dimension-space-025);\n border: 0;\n border-radius: var(--dimension-radius-050);\n background: transparent;\n cursor: pointer;\n}\n\n@media (forced-colors: active) {\n .bar-action {\n --ds-control-elevation-shadow: none;\n --ds-control-elevation-highlight: none;\n outline: var(--dimension-stroke-width-012) solid var(--ds-forced-color-control-boundary);\n outline-offset: calc(-1 * var(--dimension-stroke-width-012));\n }\n}\n",
|
|
234
234
|
"type": "registry:ui"
|
|
235
235
|
},
|
|
236
236
|
{
|
|
237
237
|
"path": "src/wc/components/BarAction/BarAction.tsx",
|
|
238
|
-
"content": "import {\n Component,\n
|
|
238
|
+
"content": "import {\n Component,\n Event,\n EventEmitter,\n h,\n Host,\n Prop,\n} from '@stencil/core';\n\n@Component({\n tag: 'ds-bar-action',\n styleUrl: 'BarAction.css',\n scoped: true,\n})\nexport class BarAction {\n /** Number of selected items. The bar is hidden while this is below one. */\n @Prop() count: number = 0;\n\n /** Localized noun shown after the count. */\n @Prop() selectedLabel: string = 'selected';\n\n /** Visible Clear control label. */\n @Prop() clearLabel: string = 'Clear';\n\n /** Accessible name for the selected-set action group. */\n @Prop() label: string = 'Selected item actions';\n\n /** Emitted when Clear is activated. The application owns the selected identities. */\n @Event() dsClear!: EventEmitter<MouseEvent>;\n\n private get resolvedCount(): number {\n if (!Number.isFinite(this.count)) return 0;\n return Math.max(0, Math.trunc(this.count));\n }\n\n private get isVisible(): boolean {\n return this.resolvedCount >= 1;\n }\n\n private handleClear = (event: MouseEvent) => {\n this.dsClear.emit(event);\n };\n\n render() {\n const countLabel = `${this.resolvedCount} ${this.selectedLabel}`;\n return (\n <Host>\n <div\n class=\"bar-action ds-chrome-row ds-chrome-space--md ds-control-elevation ds-control-elevation--md\"\n hidden={!this.isVisible || undefined}\n role=\"group\"\n aria-label={this.label}\n >\n <div class=\"bar-action__copy\">\n <ds-text\n class=\"bar-action__count\"\n as=\"span\"\n variant=\"text-body-medium\"\n color=\"inherit\"\n fontFeature=\"tabular-nums\"\n lineTruncation={1}\n >\n {countLabel}\n </ds-text>\n <ds-text\n class=\"bar-action__separator\"\n as=\"span\"\n variant=\"text-body-medium\"\n color=\"inherit\"\n aria-hidden=\"true\"\n >\n ·\n </ds-text>\n <button\n class=\"bar-action__clear ds-text-action ds-text-action--on-bold ds-focus-ring\"\n type=\"button\"\n onClick={this.handleClear}\n >\n <ds-text as=\"span\" variant=\"text-body-medium\" color=\"inherit\">\n {this.clearLabel}\n </ds-text>\n </button>\n </div>\n <div class=\"bar-action__actions\">\n <slot name=\"actions\" />\n </div>\n </div>\n <span\n class=\"bar-action__status ds-visually-hidden\"\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n {this.isVisible ? countLabel : ''}\n </span>\n </Host>\n );\n }\n}\n",
|
|
239
239
|
"type": "registry:ui"
|
|
240
240
|
}
|
|
241
241
|
]
|