@ds-mo/ui 12.6.2 → 12.8.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/README.md +44 -115
- package/dist/.build-stamp +1 -1
- package/dist/agent-patterns.json +26 -11
- package/dist/agent.json +285 -49
- 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-card-overview.d.ts +19 -0
- package/dist/angular/ds-card-overview.js +42 -0
- package/dist/angular/ds-menu.d.ts +1 -1
- package/dist/angular/ds-menu.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/components/ds-agent-activity.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-bar-nav.js +1 -1
- package/dist/components/ds-bar-nav.js.map +1 -1
- package/dist/components/ds-bar-title.js +1 -1
- package/dist/components/ds-bar-title.js.map +1 -1
- package/dist/components/ds-bar-workflow.js +1 -1
- package/dist/components/ds-bar-workflow.js.map +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-data-viz-bar.js +1 -1
- package/dist/components/ds-card-data-viz-bar.js.map +1 -1
- package/dist/components/ds-card-data-viz-donut.js +1 -1
- package/dist/components/ds-card-data-viz-donut.js.map +1 -1
- package/dist/components/ds-card-data-viz-line.js +1 -1
- package/dist/components/ds-card-data-viz-line.js.map +1 -1
- package/dist/components/ds-card-overview.d.ts +11 -0
- package/dist/components/ds-card-overview.js +2 -0
- package/dist/components/ds-card-overview.js.map +1 -0
- package/dist/components/ds-card-setting.js +1 -1
- package/dist/components/ds-card-setting.js.map +1 -1
- package/dist/components/ds-card-shell-data-viz.js +1 -1
- package/dist/components/ds-chart-bar-stacked.js +1 -1
- package/dist/components/ds-chart-bar-stacked.js.map +1 -1
- package/dist/components/ds-chart-bar.js +1 -1
- package/dist/components/ds-chart-bar.js.map +1 -1
- package/dist/components/ds-chart-donut.js +1 -1
- package/dist/components/ds-chart-donut.js.map +1 -1
- package/dist/components/ds-chart-legend.js +1 -1
- package/dist/components/ds-chart-line.js +1 -1
- package/dist/components/ds-chart-line.js.map +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-item.js.map +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-divider.js +1 -1
- package/dist/components/ds-empty-state.js +1 -1
- package/dist/components/ds-field.js +1 -1
- package/dist/components/ds-field.js.map +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-bubble.js +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-scroller.js.map +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-bar-nav.js.map +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-mobile-sheet-nav.js.map +1 -1
- package/dist/components/ds-modal.js +1 -1
- package/dist/components/ds-modal.js.map +1 -1
- package/dist/components/ds-panel-nav.js +1 -1
- package/dist/components/ds-panel-nav.js.map +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-tool-search.js.map +1 -1
- package/dist/components/ds-panel-tools.js +1 -1
- package/dist/components/ds-radio.js +1 -1
- package/dist/components/ds-radio.js.map +1 -1
- package/dist/components/ds-scroll-overlay.js +1 -1
- package/dist/components/ds-select-multi.js +1 -1
- package/dist/components/ds-select-multi.js.map +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-app.js.map +1 -1
- package/dist/components/ds-shell-gradient-picker.js +1 -1
- package/dist/components/ds-shell-gradient-swatch.js +1 -1
- package/dist/components/ds-shell-page.js +1 -1
- package/dist/components/ds-shell-page.js.map +1 -1
- package/dist/components/ds-shell-tools.js +1 -1
- package/dist/components/ds-shell-tools.js.map +1 -1
- package/dist/components/ds-skeleton.js +1 -1
- package/dist/components/ds-skeleton.js.map +1 -1
- package/dist/components/ds-slider.js +1 -1
- package/dist/components/ds-slider.js.map +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-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-data-viz.js +1 -1
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/ds-typing-indicator.js +1 -1
- package/dist/components/p-2foAUsDN.js +2 -0
- package/dist/components/p-2foAUsDN.js.map +1 -0
- package/dist/components/{p-Ccj5Op6E.js → p-38PfdMkF.js} +2 -2
- package/dist/components/p-69lHhJiX.js +2 -0
- package/dist/components/p-69lHhJiX.js.map +1 -0
- package/dist/components/p-B6NvVdeO.js +2 -0
- package/dist/components/p-B6NvVdeO.js.map +1 -0
- package/dist/components/p-B6Vuayt6.js +2 -0
- package/dist/components/p-B6Vuayt6.js.map +1 -0
- package/dist/components/p-B6vE3ujd.js +2 -0
- package/dist/components/p-B6vE3ujd.js.map +1 -0
- package/dist/components/p-BBePKRHC.js +2 -0
- package/dist/components/p-BBePKRHC.js.map +1 -0
- package/dist/components/{p-CaRyxTMz.js → p-BFRMwl93.js} +2 -2
- package/dist/components/p-BKOlvCGS.js +2 -0
- package/dist/components/p-BKOlvCGS.js.map +1 -0
- package/dist/components/{p-C7bZ-jiU.js → p-BO5aqZcf.js} +2 -2
- package/dist/components/p-BX0BMhgz.js +2 -0
- package/dist/components/p-BX0BMhgz.js.map +1 -0
- package/dist/components/p-BXaieghV.js +2 -0
- package/dist/components/p-BXaieghV.js.map +1 -0
- package/dist/components/p-BlHzmszE.js +2 -0
- package/dist/components/{p-BkAMkjIR.js.map → p-BlHzmszE.js.map} +1 -1
- package/dist/components/p-By_s1wNN.js +2 -0
- package/dist/components/p-By_s1wNN.js.map +1 -0
- package/dist/components/p-C61yJkfr.js +2 -0
- package/dist/components/p-C61yJkfr.js.map +1 -0
- package/dist/components/{p-DXLWm4PF.js → p-CNgPwd11.js} +2 -2
- package/dist/components/p-CNjOyUQu.js +2 -0
- package/dist/components/p-CNjOyUQu.js.map +1 -0
- package/dist/components/{p-BwGnhInj.js → p-CPwpgUWT.js} +2 -2
- package/dist/components/p-CU2673IJ.js +2 -0
- package/dist/components/p-CU2673IJ.js.map +1 -0
- package/dist/components/{p-B9bxDfZV.js → p-CsX3ICz7.js} +2 -2
- package/dist/components/p-CuwopElg.js +2 -0
- package/dist/components/p-CuwopElg.js.map +1 -0
- package/dist/components/{p-D-xttdpn.js → p-D0e77tkd.js} +2 -2
- package/dist/components/p-D1bNvIpb.js +2 -0
- package/dist/components/p-D1bNvIpb.js.map +1 -0
- package/dist/components/{p-BwsGYxZx.js → p-D9u1_OEZ.js} +2 -2
- package/dist/components/{p-DQDpDYyF.js → p-DB9XJm2c.js} +2 -2
- package/dist/components/{p-CnHrJTD5.js → p-DIFUsoM-.js} +2 -2
- package/dist/components/p-DhKvqh5G.js +2 -0
- package/dist/components/p-DhKvqh5G.js.map +1 -0
- package/dist/components/p-DhLmoCe_.js +2 -0
- package/dist/components/p-DhLmoCe_.js.map +1 -0
- package/dist/components/p-DjbTFy2B.js +2 -0
- package/dist/components/p-DjbTFy2B.js.map +1 -0
- package/dist/components/{p-CWTih3Gc.js → p-DmAHufd5.js} +2 -2
- package/dist/components/p-DzM3SzPz.js +2 -0
- package/dist/components/p-DzM3SzPz.js.map +1 -0
- package/dist/components/{p-DqubRds2.js → p-G3qIxpQj.js} +2 -2
- package/dist/components/p-Re2kPrXm.js +2 -0
- package/dist/components/p-Re2kPrXm.js.map +1 -0
- package/dist/components/{p-DwX7UmLl.js → p-Utr23NC-.js} +2 -2
- package/dist/components/{p-DIoiApa-.js → p-Vdufoj7G.js} +2 -2
- package/dist/components/p-huw1oRbt.js +2 -0
- package/dist/components/p-huw1oRbt.js.map +1 -0
- package/dist/components/p-ukB-dPOK.js +2 -0
- package/dist/components/{p-BY0PzkUp.js.map → p-ukB-dPOK.js.map} +1 -1
- package/dist/components/p-yhj1lIPx.js +2 -0
- package/dist/docs/components.json +760 -87
- package/dist/lib/components/Menu/menu-position.d.ts +6 -6
- package/dist/lib/toast/toast-types.d.ts +3 -3
- package/dist/lib/utils/anchored-position.d.ts +34 -0
- package/dist/lib/utils/choice-popup-alignment.d.ts +2 -2
- package/dist/lib/utils/control-text.d.ts +3 -1
- package/dist/lib/utils/index.d.ts +3 -1
- package/dist/lib/utils/index.js +39 -0
- package/dist/lib/utils/index.js.map +3 -3
- package/dist/lib/utils/metric-change.d.ts +52 -0
- package/dist/lib/utils/token-defaults.d.ts +3 -0
- package/dist/mcp-data/registry/agent-activity.json +1 -1
- package/dist/mcp-data/registry/agent-response.json +1 -1
- 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 +1 -1
- package/dist/mcp-data/registry/badge.json +1 -1
- package/dist/mcp-data/registry/bar-nav.json +3 -3
- package/dist/mcp-data/registry/bar-title.json +3 -3
- package/dist/mcp-data/registry/bar-workflow.json +3 -3
- package/dist/mcp-data/registry/breadcrumb.json +1 -1
- package/dist/mcp-data/registry/button-filled.json +125 -8
- package/dist/mcp-data/registry/button-unfilled.json +50 -5
- package/dist/mcp-data/registry/card-data-viz-bar.json +5 -4
- package/dist/mcp-data/registry/card-data-viz-donut.json +5 -3
- package/dist/mcp-data/registry/card-data-viz-line.json +5 -4
- package/dist/mcp-data/registry/card-overview.json +317 -0
- package/dist/mcp-data/registry/card-setting.json +3 -3
- package/dist/mcp-data/registry/card-shell-data-viz.json +3 -3
- package/dist/mcp-data/registry/chart-bar-stacked.json +14 -9
- package/dist/mcp-data/registry/chart-bar.json +15 -10
- package/dist/mcp-data/registry/chart-donut.json +3 -2
- package/dist/mcp-data/registry/chart-legend.json +1 -1
- package/dist/mcp-data/registry/chart-line.json +15 -10
- package/dist/mcp-data/registry/checkbox.json +10 -10
- package/dist/mcp-data/registry/chip.json +1 -1
- package/dist/mcp-data/registry/code-block.json +1 -1
- package/dist/mcp-data/registry/conversation-list-item.json +3 -3
- package/dist/mcp-data/registry/conversation-list-section.json +1 -1
- package/dist/mcp-data/registry/conversation-list.json +3 -3
- package/dist/mcp-data/registry/divider.json +1 -1
- package/dist/mcp-data/registry/empty-state.json +6 -2
- package/dist/mcp-data/registry/field.json +4 -3
- package/dist/mcp-data/registry/icon.json +1 -1
- package/dist/mcp-data/registry/input.json +9 -8
- 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 +24 -5
- 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 +3 -3
- package/dist/mcp-data/registry/message.json +1 -1
- package/dist/mcp-data/registry/mobile-bar-nav.json +4 -4
- package/dist/mcp-data/registry/mobile-header.json +3 -3
- package/dist/mcp-data/registry/mobile-section-switcher.json +1 -1
- package/dist/mcp-data/registry/mobile-sheet-nav.json +6 -4
- package/dist/mcp-data/registry/modal.json +3 -3
- package/dist/mcp-data/registry/panel-nav.json +3 -3
- package/dist/mcp-data/registry/panel-sub-nav.json +1 -1
- package/dist/mcp-data/registry/panel-tool-header.json +3 -3
- package/dist/mcp-data/registry/panel-tool-search.json +3 -3
- package/dist/mcp-data/registry/panel-tools.json +4 -3
- package/dist/mcp-data/registry/radio.json +10 -10
- package/dist/mcp-data/registry/registry.json +288 -49
- package/dist/mcp-data/registry/scroll-overlay.json +1 -1
- package/dist/mcp-data/registry/select-multi.json +10 -8
- package/dist/mcp-data/registry/select.json +10 -8
- package/dist/mcp-data/registry/shell-app.json +3 -2
- package/dist/mcp-data/registry/shell-gradient-picker.json +1 -1
- package/dist/mcp-data/registry/shell-gradient-swatch.json +1 -1
- package/dist/mcp-data/registry/shell-page.json +5 -4
- package/dist/mcp-data/registry/shell-tools.json +2 -2
- package/dist/mcp-data/registry/skeleton.json +3 -3
- package/dist/mcp-data/registry/slider.json +4 -3
- package/dist/mcp-data/registry/swatch-picker.json +1 -1
- package/dist/mcp-data/registry/switch.json +8 -8
- 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 +2 -2
- package/dist/mcp-data/registry/tooltip-data-viz.json +3 -1
- package/dist/mcp-data/registry/tooltip.json +3 -8
- 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-card-overview.d.ts +12 -0
- package/dist/react/ds-card-overview.js +12 -0
- package/dist/styles/control-elevation.css +38 -2
- package/dist/types/components/ButtonFilled/ButtonFilled.d.ts +33 -1
- package/dist/types/components/ButtonUnfilled/ButtonUnfilled.d.ts +20 -0
- package/dist/types/components/CardOverview/CardOverview.d.ts +59 -0
- package/dist/types/components/CardOverview/card-overview-types.d.ts +32 -0
- package/dist/types/components/CardOverview/index.d.ts +2 -0
- package/dist/types/components/ChartBar/ChartBar.d.ts +11 -0
- package/dist/types/components/ChartBarStacked/ChartBarStacked.d.ts +11 -0
- package/dist/types/components/ChartLine/ChartLine.d.ts +11 -0
- package/dist/types/components/Checkbox/Checkbox.d.ts +1 -1
- package/dist/types/components/Input/Input.d.ts +1 -1
- package/dist/types/components/Menu/Menu.d.ts +11 -5
- package/dist/types/components/Menu/menu-position.d.ts +6 -6
- package/dist/types/components/MobileSheetNav/MobileSheetNav.d.ts +0 -1
- package/dist/types/components/Radio/Radio.d.ts +1 -1
- package/dist/types/components/Select/Select.d.ts +6 -23
- package/dist/types/components/SelectMulti/SelectMulti.d.ts +5 -20
- package/dist/types/components/ShellPage/ShellPage.d.ts +1 -0
- package/dist/types/components/ShellTools/ShellTools.d.ts +1 -0
- package/dist/types/components/Switch/Switch.d.ts +1 -1
- package/dist/types/components/Tooltip/Tooltip.d.ts +1 -4
- package/dist/types/components.d.ts +225 -4
- package/dist/types/toast/toast-types.d.ts +3 -3
- package/dist/types/utils/anchored-position-controller.d.ts +96 -0
- package/dist/types/utils/anchored-position.d.ts +35 -0
- package/dist/types/utils/cartesian-chart-layout.d.ts +13 -0
- package/dist/types/utils/chart-viewport-controller.d.ts +21 -0
- package/dist/types/utils/choice-list-parts.d.ts +4 -0
- package/dist/types/utils/choice-popup-alignment.d.ts +2 -2
- package/dist/types/utils/control-press.d.ts +9 -0
- package/dist/types/utils/control-text.d.ts +3 -1
- package/dist/types/utils/index.d.ts +3 -1
- package/dist/types/utils/metric-change.d.ts +53 -0
- package/dist/types/utils/select-controller.d.ts +67 -0
- package/dist/types/utils/token-defaults.d.ts +3 -0
- package/package.json +3 -3
- package/dist/components/p-B8C_yfLQ.js +0 -2
- package/dist/components/p-B8C_yfLQ.js.map +0 -1
- package/dist/components/p-B9xVWER6.js +0 -2
- package/dist/components/p-B9xVWER6.js.map +0 -1
- package/dist/components/p-BLea0TrP.js +0 -2
- package/dist/components/p-BLea0TrP.js.map +0 -1
- package/dist/components/p-BY0PzkUp.js +0 -2
- package/dist/components/p-BbgPGF2a.js +0 -2
- package/dist/components/p-BbgPGF2a.js.map +0 -1
- package/dist/components/p-BhC1YyId.js +0 -2
- package/dist/components/p-BhC1YyId.js.map +0 -1
- package/dist/components/p-BkAMkjIR.js +0 -2
- package/dist/components/p-C2ym_Ich.js +0 -2
- package/dist/components/p-C_ewSXTT.js +0 -2
- package/dist/components/p-C_ewSXTT.js.map +0 -1
- package/dist/components/p-CiqnkENu.js +0 -2
- package/dist/components/p-CiqnkENu.js.map +0 -1
- package/dist/components/p-Cx-ywr1e.js +0 -2
- package/dist/components/p-Cx-ywr1e.js.map +0 -1
- package/dist/components/p-CydY-v7X.js +0 -2
- package/dist/components/p-CydY-v7X.js.map +0 -1
- package/dist/components/p-DPME1wUJ.js +0 -2
- package/dist/components/p-DPME1wUJ.js.map +0 -1
- package/dist/components/p-DSa0Hnd3.js +0 -2
- package/dist/components/p-DSa0Hnd3.js.map +0 -1
- package/dist/components/p-DUlqUNbE.js +0 -2
- package/dist/components/p-DUlqUNbE.js.map +0 -1
- package/dist/components/p-DWdRSOBV.js +0 -2
- package/dist/components/p-DWdRSOBV.js.map +0 -1
- package/dist/components/p-DYcC5-R9.js +0 -2
- package/dist/components/p-DYcC5-R9.js.map +0 -1
- package/dist/components/p-DbpfpeQT.js +0 -2
- package/dist/components/p-DbpfpeQT.js.map +0 -1
- package/dist/components/p-Dg3xLna0.js +0 -2
- package/dist/components/p-Dg3xLna0.js.map +0 -1
- package/dist/components/p-DuFm-ieS.js +0 -2
- package/dist/components/p-DuFm-ieS.js.map +0 -1
- package/dist/components/p-uQhuDEVt.js +0 -2
- package/dist/components/p-uQhuDEVt.js.map +0 -1
- package/dist/lib/utils/anchored-popup.d.ts +0 -23
- package/dist/types/components/Tooltip/tooltip-position.d.ts +0 -21
- package/dist/types/utils/anchored-popup.d.ts +0 -24
- /package/dist/components/{p-Ccj5Op6E.js.map → p-38PfdMkF.js.map} +0 -0
- /package/dist/components/{p-CaRyxTMz.js.map → p-BFRMwl93.js.map} +0 -0
- /package/dist/components/{p-C7bZ-jiU.js.map → p-BO5aqZcf.js.map} +0 -0
- /package/dist/components/{p-DXLWm4PF.js.map → p-CNgPwd11.js.map} +0 -0
- /package/dist/components/{p-BwGnhInj.js.map → p-CPwpgUWT.js.map} +0 -0
- /package/dist/components/{p-B9bxDfZV.js.map → p-CsX3ICz7.js.map} +0 -0
- /package/dist/components/{p-D-xttdpn.js.map → p-D0e77tkd.js.map} +0 -0
- /package/dist/components/{p-BwsGYxZx.js.map → p-D9u1_OEZ.js.map} +0 -0
- /package/dist/components/{p-DQDpDYyF.js.map → p-DB9XJm2c.js.map} +0 -0
- /package/dist/components/{p-CnHrJTD5.js.map → p-DIFUsoM-.js.map} +0 -0
- /package/dist/components/{p-CWTih3Gc.js.map → p-DmAHufd5.js.map} +0 -0
- /package/dist/components/{p-DqubRds2.js.map → p-G3qIxpQj.js.map} +0 -0
- /package/dist/components/{p-DwX7UmLl.js.map → p-Utr23NC-.js.map} +0 -0
- /package/dist/components/{p-DIoiApa-.js.map → p-Vdufoj7G.js.map} +0 -0
- /package/dist/components/{p-C2ym_Ich.js.map → p-yhj1lIPx.js.map} +0 -0
|
@@ -61,8 +61,9 @@
|
|
|
61
61
|
"Negative values are unsupported and render as zero; the owning product supplies loading, empty, and error states."
|
|
62
62
|
],
|
|
63
63
|
"responsiveBehavior": [
|
|
64
|
-
"
|
|
65
|
-
"
|
|
64
|
+
"Width and height provide the standalone intrinsic viewport; constrained card regions are measured and reflow both axes to their rendered pixel dimensions.",
|
|
65
|
+
"Responsive layout changes stack positions and plot extents without scaling SVG text, strokes, separators, corner radii, or margins.",
|
|
66
|
+
"The parent chooses how many time buckets remain legible at each width.",
|
|
66
67
|
"Pre-format category labels and reduce bucket count before rendering when horizontal space becomes constrained."
|
|
67
68
|
],
|
|
68
69
|
"frameworkCaveats": {
|
|
@@ -99,7 +100,8 @@
|
|
|
99
100
|
"attribute": "height",
|
|
100
101
|
"default": "240",
|
|
101
102
|
"required": false,
|
|
102
|
-
"mutable": false
|
|
103
|
+
"mutable": false,
|
|
104
|
+
"description": "Standalone intrinsic height. Container constraints reflow the plot at rendered pixel size."
|
|
103
105
|
},
|
|
104
106
|
"series": {
|
|
105
107
|
"type": "ChartSeries[]",
|
|
@@ -123,7 +125,8 @@
|
|
|
123
125
|
"attribute": "width",
|
|
124
126
|
"default": "480",
|
|
125
127
|
"required": false,
|
|
126
|
-
"mutable": false
|
|
128
|
+
"mutable": false,
|
|
129
|
+
"description": "Standalone intrinsic width. Container constraints reflow the plot at rendered pixel size."
|
|
127
130
|
}
|
|
128
131
|
},
|
|
129
132
|
"events": [],
|
|
@@ -145,7 +148,8 @@
|
|
|
145
148
|
"attribute": "height",
|
|
146
149
|
"default": "240",
|
|
147
150
|
"required": false,
|
|
148
|
-
"mutable": false
|
|
151
|
+
"mutable": false,
|
|
152
|
+
"description": "Standalone intrinsic height. Container constraints reflow the plot at rendered pixel size."
|
|
149
153
|
},
|
|
150
154
|
"series": {
|
|
151
155
|
"type": "ChartSeries[]",
|
|
@@ -169,7 +173,8 @@
|
|
|
169
173
|
"attribute": "width",
|
|
170
174
|
"default": "480",
|
|
171
175
|
"required": false,
|
|
172
|
-
"mutable": false
|
|
176
|
+
"mutable": false,
|
|
177
|
+
"description": "Standalone intrinsic width. Container constraints reflow the plot at rendered pixel size."
|
|
173
178
|
}
|
|
174
179
|
},
|
|
175
180
|
"events": [],
|
|
@@ -198,7 +203,7 @@
|
|
|
198
203
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: categories, series.",
|
|
199
204
|
"peerDependencies": {
|
|
200
205
|
"required": [
|
|
201
|
-
"@ds-mo/tokens ^
|
|
206
|
+
"@ds-mo/tokens ^5.0.0",
|
|
202
207
|
"@ds-mo/icons ^6.4.0"
|
|
203
208
|
],
|
|
204
209
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -213,12 +218,12 @@
|
|
|
213
218
|
"files": [
|
|
214
219
|
{
|
|
215
220
|
"path": "src/wc/components/ChartBarStacked/ChartBarStacked.css",
|
|
216
|
-
"content": ":host {\n display: inline-flex;\n max-width: 100%;\n font-family: var(--typography-font-family);\n}\n\n.chart-bar-stacked__svg {\n display: block;\n
|
|
221
|
+
"content": ":host {\n display: inline-flex;\n max-width: 100%;\n font-family: var(--typography-font-family);\n}\n\n.chart-bar-stacked__svg {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.chart-bar-stacked__gridline {\n stroke: var(--color-border-tertiary);\n stroke-width: var(--dimension-stroke-width-012);\n vector-effect: non-scaling-stroke;\n}\n\n/* Matches ds-text text-caption regular (SVG cannot host ds-text). */\n.chart-bar-stacked__axis-label {\n fill: var(--color-foreground-secondary);\n font-family: var(--typography-font-family);\n font-size: var(--typography-fontsize-xs);\n font-weight: var(--typography-weight-medium);\n letter-spacing: var(--typography-letterspacing-positive);\n text-transform: uppercase;\n}\n\n.chart-bar-stacked__segment-shape--rounded {\n rx: var(--dimension-radius-025);\n}\n\n.chart-bar-stacked__segment-separator {\n stroke: var(--color-background-primary);\n stroke-width: var(--dimension-stroke-width-012);\n stroke-linecap: butt;\n vector-effect: non-scaling-stroke;\n}\n",
|
|
217
222
|
"type": "registry:ui"
|
|
218
223
|
},
|
|
219
224
|
{
|
|
220
225
|
"path": "src/wc/components/ChartBarStacked/ChartBarStacked.tsx",
|
|
221
|
-
"content": "import { Component, Prop, h, Host } from '@stencil/core';\nimport { scaleBand, scaleLinear } from 'd3-scale';\nimport { categoryColor } from '../../utils/chart-colors';\nimport { formatPercentage } from '../../utils';\nimport type { ChartSeries } from '../../utils/chart-types';\n\nexport type ChartBarStackedVariant = 'stacked' | 'percentage';\n\nconst
|
|
226
|
+
"content": "import { Component, Prop, State, Watch, h, Host } from '@stencil/core';\nimport { scaleBand, scaleLinear } from 'd3-scale';\nimport { categoryColor } from '../../utils/chart-colors';\nimport { formatPercentage } from '../../utils';\nimport { resolveCartesianChartLayout } from '../../utils/cartesian-chart-layout';\nimport {\n ChartViewportController,\n type ChartViewportSize,\n} from '../../utils/chart-viewport-controller';\nimport type { ChartSeries } from '../../utils/chart-types';\n\nexport type ChartBarStackedVariant = 'stacked' | 'percentage';\n\nconst PERCENTAGE_TICKS = [0, 25, 50, 75, 100];\n\n@Component({\n tag: 'ds-chart-bar-stacked',\n styleUrl: 'ChartBarStacked.css',\n scoped: true,\n})\nexport class ChartBarStacked {\n /** Ordered stack series. Set as a JS property (not an HTML attribute). */\n @Prop() series: ChartSeries[] = [];\n /** X-axis labels — must match each series' `data` length. Set as a JS property. */\n @Prop() categories: string[] = [];\n @Prop() variant: ChartBarStackedVariant = 'stacked';\n /** Standalone intrinsic width. Container constraints reflow the plot at rendered pixel size. */\n @Prop() width: number = 480;\n /** Standalone intrinsic height. Container constraints reflow the plot at rendered pixel size. */\n @Prop() height: number = 240;\n\n @State() private viewport: ChartViewportSize | undefined;\n\n private viewportController: ChartViewportController | null = null;\n private svgEl: SVGElement | null = null;\n\n componentDidLoad() {\n this.connectViewportController();\n }\n\n connectedCallback() {\n if (this.svgEl && !this.viewportController) this.connectViewportController();\n }\n\n componentDidRender() {\n if (!this.viewportController) this.connectViewportController();\n }\n\n private connectViewportController() {\n if (!this.svgEl) return;\n this.viewportController = new ChartViewportController(this.svgEl, viewport => {\n if (\n viewport.width !== this.viewport?.width ||\n viewport.height !== this.viewport?.height\n ) {\n this.viewport = viewport;\n }\n });\n this.viewportController.connect();\n }\n\n disconnectedCallback() {\n this.viewportController?.disconnect();\n this.viewportController = null;\n }\n\n @Watch('width')\n @Watch('height')\n handleIntrinsicSizeChange() {\n this.viewport = undefined;\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(() => this.viewportController?.measure());\n }\n }\n\n private valuesForCategory(categoryIndex: number) {\n return this.series.map(series => Math.max(0, series.data[categoryIndex] ?? 0));\n }\n\n private accessibleLabel() {\n return this.categories\n .map((category, categoryIndex) => {\n const values = this.valuesForCategory(categoryIndex);\n const total = values.reduce((sum, value) => sum + value, 0);\n const details = this.series\n .map((series, seriesIndex) => {\n const value = values[seriesIndex];\n const visibleValue = this.variant === 'percentage'\n ? formatPercentage(total ? value / total : 0, 1)\n : String(value);\n return `${series.name}: ${visibleValue}`;\n })\n .join(', ');\n return `${category}: ${details}`;\n })\n .join('; ');\n }\n\n render() {\n const viewportWidth = this.viewport?.width ?? this.width;\n const viewportHeight = this.viewport?.height ?? this.height;\n const { margin, axisLabelGap, categoryLabelOffset } =\n resolveCartesianChartLayout();\n const innerWidth = Math.max(0, viewportWidth - margin.left - margin.right);\n const innerHeight = Math.max(0, viewportHeight - margin.top - margin.bottom);\n const categoryValues = this.categories.map((_, index) => this.valuesForCategory(index));\n const totals = categoryValues.map(values =>\n values.reduce((sum, value) => sum + value, 0)\n );\n const yMax = this.variant === 'percentage' ? 100 : Math.max(0, ...totals);\n\n const xScale = scaleBand()\n .domain(this.categories)\n .range([0, innerWidth])\n .padding(0.35);\n\n const yScale = scaleLinear()\n .domain([0, yMax || 1])\n .range([innerHeight, 0])\n .nice();\n\n const yTicks = this.variant === 'percentage' ? PERCENTAGE_TICKS : yScale.ticks(4);\n\n return (\n <Host class=\"chart-bar-stacked\">\n <svg\n class=\"chart-bar-stacked__svg\"\n ref={element => {\n this.svgEl = element ?? null;\n }}\n width={viewportWidth}\n height={viewportHeight}\n role=\"img\"\n aria-label={this.accessibleLabel()}\n >\n <g transform={`translate(${margin.left}, ${margin.top})`}>\n {yTicks.map(tick => (\n <g key={`grid-${tick}`} transform={`translate(0, ${yScale(tick)})`}>\n <line class=\"chart-bar-stacked__gridline\" x1={0} x2={innerWidth} />\n <text\n class=\"chart-bar-stacked__axis-label\"\n x={-axisLabelGap}\n text-anchor=\"end\"\n dominant-baseline=\"middle\"\n >\n {this.variant === 'percentage' ? `${tick}%` : tick}\n </text>\n </g>\n ))}\n\n {this.categories.map((category, categoryIndex) => {\n const barWidth = xScale.bandwidth();\n const barX = xScale(category) ?? 0;\n const values = categoryValues[categoryIndex];\n const total = totals[categoryIndex];\n const topSeriesIndex = values.reduce(\n (topIndex, value, seriesIndex) => (value > 0 ? seriesIndex : topIndex),\n -1\n );\n let cumulativeValue = 0;\n\n return (\n <g class=\"chart-bar-stacked__stack\" data-category={category} key={category}>\n {this.series.map((series, seriesIndex) => {\n const rawValue = values[seriesIndex];\n const value = this.variant === 'percentage'\n ? total\n ? (rawValue / total) * 100\n : 0\n : rawValue;\n const segmentStart = cumulativeValue;\n const segmentEnd = cumulativeValue + value;\n cumulativeValue = segmentEnd;\n\n const segmentY = yScale(segmentEnd);\n const segmentBottom = yScale(segmentStart);\n const segmentHeight = Math.max(0, segmentBottom - segmentY);\n if (!segmentHeight) return null;\n\n const fill = series.color ?? categoryColor(seriesIndex);\n const isTopSegment = seriesIndex === topSeriesIndex;\n const hasRoundedTop =\n this.variant === 'stacked' && isTopSegment;\n const squareBaseY = segmentY + segmentHeight / 2;\n const squareBaseHeight = segmentHeight / 2;\n\n return (\n <g\n class=\"chart-bar-stacked__segment\"\n data-series={series.name}\n key={series.name}\n >\n <rect\n class={{\n 'chart-bar-stacked__segment-shape': true,\n 'chart-bar-stacked__segment-shape--rounded': hasRoundedTop,\n }}\n x={barX}\n y={segmentY}\n width={barWidth}\n height={segmentHeight}\n fill={fill}\n />\n {hasRoundedTop ? (\n <rect\n class=\"chart-bar-stacked__segment-square-base\"\n x={barX}\n y={squareBaseY}\n width={barWidth}\n height={squareBaseHeight}\n fill={fill}\n />\n ) : null}\n {segmentStart > 0 ? (\n <line\n class=\"chart-bar-stacked__segment-separator\"\n x1={barX}\n x2={barX + barWidth}\n y1={segmentBottom}\n y2={segmentBottom}\n vector-effect=\"non-scaling-stroke\"\n />\n ) : null}\n </g>\n );\n })}\n <text\n class=\"chart-bar-stacked__axis-label\"\n x={barX + barWidth / 2}\n y={innerHeight + categoryLabelOffset}\n text-anchor=\"middle\"\n >\n {category}\n </text>\n </g>\n );\n })}\n </g>\n </svg>\n </Host>\n );\n }\n}\n",
|
|
222
227
|
"type": "registry:ui"
|
|
223
228
|
}
|
|
224
229
|
]
|
|
@@ -60,7 +60,8 @@
|
|
|
60
60
|
"Authored datum colors override the shared categorical palette."
|
|
61
61
|
],
|
|
62
62
|
"responsiveBehavior": [
|
|
63
|
-
"
|
|
63
|
+
"Width and height provide the standalone intrinsic viewport; container constraints are measured and reflow the plot across the available pixels.",
|
|
64
|
+
"Responsive layout changes bar positions and plot extents without scaling SVG text, strokes, corner radii, or margins.",
|
|
64
65
|
"Limit or pre-format long category labels so they remain legible at the chosen width.",
|
|
65
66
|
"Time labels remain ordered, pre-formatted buckets with equal spacing rather than raw continuous timestamps."
|
|
66
67
|
],
|
|
@@ -69,10 +70,10 @@
|
|
|
69
70
|
"Assign data as a JavaScript property; arrays are not supported as HTML attributes."
|
|
70
71
|
],
|
|
71
72
|
"react": [
|
|
72
|
-
"Pass a stable data array and dimensions
|
|
73
|
+
"Pass a stable data array; width and height provide standalone intrinsic dimensions while constrained containers reflow automatically."
|
|
73
74
|
],
|
|
74
75
|
"angular": [
|
|
75
|
-
"Bind data as a property and
|
|
76
|
+
"Bind data as a property; width and height provide standalone intrinsic dimensions while constrained containers reflow automatically."
|
|
76
77
|
]
|
|
77
78
|
},
|
|
78
79
|
"references": [
|
|
@@ -98,7 +99,8 @@
|
|
|
98
99
|
"attribute": "height",
|
|
99
100
|
"default": "240",
|
|
100
101
|
"required": false,
|
|
101
|
-
"mutable": false
|
|
102
|
+
"mutable": false,
|
|
103
|
+
"description": "Standalone intrinsic height. Container constraints reflow the plot at rendered pixel size."
|
|
102
104
|
},
|
|
103
105
|
"width": {
|
|
104
106
|
"type": "number",
|
|
@@ -106,7 +108,8 @@
|
|
|
106
108
|
"attribute": "width",
|
|
107
109
|
"default": "480",
|
|
108
110
|
"required": false,
|
|
109
|
-
"mutable": false
|
|
111
|
+
"mutable": false,
|
|
112
|
+
"description": "Standalone intrinsic width. Container constraints reflow the plot at rendered pixel size."
|
|
110
113
|
}
|
|
111
114
|
},
|
|
112
115
|
"events": [],
|
|
@@ -128,7 +131,8 @@
|
|
|
128
131
|
"attribute": "height",
|
|
129
132
|
"default": "240",
|
|
130
133
|
"required": false,
|
|
131
|
-
"mutable": false
|
|
134
|
+
"mutable": false,
|
|
135
|
+
"description": "Standalone intrinsic height. Container constraints reflow the plot at rendered pixel size."
|
|
132
136
|
},
|
|
133
137
|
"width": {
|
|
134
138
|
"type": "number",
|
|
@@ -136,7 +140,8 @@
|
|
|
136
140
|
"attribute": "width",
|
|
137
141
|
"default": "480",
|
|
138
142
|
"required": false,
|
|
139
|
-
"mutable": false
|
|
143
|
+
"mutable": false,
|
|
144
|
+
"description": "Standalone intrinsic width. Container constraints reflow the plot at rendered pixel size."
|
|
140
145
|
}
|
|
141
146
|
},
|
|
142
147
|
"events": [],
|
|
@@ -165,7 +170,7 @@
|
|
|
165
170
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: data.",
|
|
166
171
|
"peerDependencies": {
|
|
167
172
|
"required": [
|
|
168
|
-
"@ds-mo/tokens ^
|
|
173
|
+
"@ds-mo/tokens ^5.0.0",
|
|
169
174
|
"@ds-mo/icons ^6.4.0"
|
|
170
175
|
],
|
|
171
176
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -180,12 +185,12 @@
|
|
|
180
185
|
"files": [
|
|
181
186
|
{
|
|
182
187
|
"path": "src/wc/components/ChartBar/ChartBar.css",
|
|
183
|
-
"content": ":host {\n display: inline-
|
|
188
|
+
"content": ":host {\n display: inline-block;\n max-width: 100%;\n font-family: var(--typography-font-family);\n}\n\n.chart-bar__svg {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.chart-bar__gridline {\n stroke: var(--color-border-tertiary);\n stroke-width: var(--dimension-stroke-width-012);\n vector-effect: non-scaling-stroke;\n}\n\n/* Matches ds-text text-caption regular (SVG cannot host ds-text). */\n.chart-bar__axis-label {\n fill: var(--color-foreground-secondary);\n font-family: var(--typography-font-family);\n font-size: var(--typography-fontsize-xs);\n font-weight: var(--typography-weight-medium);\n letter-spacing: var(--typography-letterspacing-positive);\n text-transform: uppercase;\n}\n\n.chart-bar__bar--rounded {\n rx: var(--dimension-radius-025);\n}\n",
|
|
184
189
|
"type": "registry:ui"
|
|
185
190
|
},
|
|
186
191
|
{
|
|
187
192
|
"path": "src/wc/components/ChartBar/ChartBar.tsx",
|
|
188
|
-
"content": "import { Component, Prop, h, Host } from '@stencil/core';\nimport { scaleBand, scaleLinear } from 'd3-scale';\nimport { max } from 'd3-array';\nimport { categoryColor } from '../../utils/chart-colors';\nimport
|
|
193
|
+
"content": "import { Component, Prop, State, Watch, h, Host } from '@stencil/core';\nimport { scaleBand, scaleLinear } from 'd3-scale';\nimport { max } from 'd3-array';\nimport { categoryColor } from '../../utils/chart-colors';\nimport { resolveCartesianChartLayout } from '../../utils/cartesian-chart-layout';\nimport {\n ChartViewportController,\n type ChartViewportSize,\n} from '../../utils/chart-viewport-controller';\nimport type { ChartDatum } from '../../utils/chart-types';\n\n@Component({\n tag: 'ds-chart-bar',\n styleUrl: 'ChartBar.css',\n scoped: true,\n})\nexport class ChartBar {\n /** Bars to render. Set as a JS property (not an HTML attribute). */\n @Prop() data: ChartDatum[] = [];\n /** Standalone intrinsic width. Container constraints reflow the plot at rendered pixel size. */\n @Prop() width: number = 480;\n /** Standalone intrinsic height. Container constraints reflow the plot at rendered pixel size. */\n @Prop() height: number = 240;\n\n @State() private viewport: ChartViewportSize | undefined;\n\n private viewportController: ChartViewportController | null = null;\n private svgEl: SVGElement | null = null;\n\n componentDidLoad() {\n this.connectViewportController();\n }\n\n connectedCallback() {\n if (this.svgEl && !this.viewportController) this.connectViewportController();\n }\n\n componentDidRender() {\n if (!this.viewportController) this.connectViewportController();\n }\n\n private connectViewportController() {\n if (!this.svgEl) return;\n this.viewportController = new ChartViewportController(this.svgEl, viewport => {\n if (\n viewport.width !== this.viewport?.width ||\n viewport.height !== this.viewport?.height\n ) {\n this.viewport = viewport;\n }\n });\n this.viewportController.connect();\n }\n\n disconnectedCallback() {\n this.viewportController?.disconnect();\n this.viewportController = null;\n }\n\n @Watch('width')\n @Watch('height')\n handleIntrinsicSizeChange() {\n this.viewport = undefined;\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(() => this.viewportController?.measure());\n }\n }\n\n render() {\n const viewportWidth = this.viewport?.width ?? this.width;\n const viewportHeight = this.viewport?.height ?? this.height;\n const { margin, axisLabelGap, categoryLabelOffset } =\n resolveCartesianChartLayout();\n const innerWidth = Math.max(0, viewportWidth - margin.left - margin.right);\n const innerHeight = Math.max(0, viewportHeight - margin.top - margin.bottom);\n\n const yMax = max(this.data, d => d.value) ?? 0;\n\n const xScale = scaleBand()\n .domain(this.data.map(d => d.label))\n .range([0, innerWidth])\n .padding(0.35);\n\n const yScale = scaleLinear()\n .domain([0, yMax || 1])\n .range([innerHeight, 0])\n .nice();\n\n const yTicks = yScale.ticks(4);\n\n return (\n <Host class=\"chart-bar\">\n <svg\n class=\"chart-bar__svg\"\n ref={element => {\n this.svgEl = element ?? null;\n }}\n width={viewportWidth}\n height={viewportHeight}\n role=\"img\"\n aria-label={this.data.map(d => `${d.label}: ${d.value}`).join(', ')}\n >\n <g transform={`translate(${margin.left}, ${margin.top})`}>\n {yTicks.map(tick => (\n <g key={`grid-${tick}`} transform={`translate(0, ${yScale(tick)})`}>\n <line class=\"chart-bar__gridline\" x1={0} x2={innerWidth} />\n <text\n class=\"chart-bar__axis-label\"\n x={-axisLabelGap}\n text-anchor=\"end\"\n dominant-baseline=\"middle\"\n >\n {tick}\n </text>\n </g>\n ))}\n\n {this.data.map((d, i) => {\n const barWidth = xScale.bandwidth();\n const barX = xScale(d.label) ?? 0;\n const barY = yScale(d.value);\n const barHeight = innerHeight - barY;\n const squareBaseY = barY + barHeight / 2;\n const squareBaseHeight = barHeight / 2;\n const fill = d.color ?? categoryColor(i);\n return (\n <g key={d.label}>\n <rect\n class=\"chart-bar__bar chart-bar__bar--rounded\"\n x={barX}\n y={barY}\n width={barWidth}\n height={barHeight}\n fill={fill}\n />\n <rect\n class=\"chart-bar__bar chart-bar__bar--square-base\"\n x={barX}\n y={squareBaseY}\n width={barWidth}\n height={squareBaseHeight}\n fill={fill}\n />\n <text\n class=\"chart-bar__axis-label\"\n x={barX + barWidth / 2}\n y={innerHeight + categoryLabelOffset}\n text-anchor=\"middle\"\n >\n {d.label}\n </text>\n </g>\n );\n })}\n </g>\n </svg>\n </Host>\n );\n }\n}\n",
|
|
189
194
|
"type": "registry:ui"
|
|
190
195
|
}
|
|
191
196
|
]
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"responsiveBehavior": [
|
|
58
58
|
"Prefer container-fill sizing inside data-viz cards and explicit sizing only in layouts that own a stable diameter.",
|
|
59
59
|
"Fill sizing remains centered and constrained to the shared donut size band.",
|
|
60
|
+
"Changing the measured diameter changes the ring radius without scaling its token-based thickness, typography, focus stroke, or corner treatment.",
|
|
60
61
|
"The owner adapts category count and legend placement for available space."
|
|
61
62
|
],
|
|
62
63
|
"frameworkCaveats": {
|
|
@@ -314,7 +315,7 @@
|
|
|
314
315
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: data.",
|
|
315
316
|
"peerDependencies": {
|
|
316
317
|
"required": [
|
|
317
|
-
"@ds-mo/tokens ^
|
|
318
|
+
"@ds-mo/tokens ^5.0.0",
|
|
318
319
|
"@ds-mo/icons ^6.4.0"
|
|
319
320
|
],
|
|
320
321
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -331,7 +332,7 @@
|
|
|
331
332
|
"files": [
|
|
332
333
|
{
|
|
333
334
|
"path": "src/wc/components/ChartDonut/ChartDonut.css",
|
|
334
|
-
"content": ":host {\n display: inline-block;\n font-family: var(--typography-font-family);\n user-select: none;\n}\n\n:host(.chart-donut--fill) {\n display: block;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.chart-donut__wrapper {\n position: relative;\n overflow: visible;\n}\n\n:host(.chart-donut--fill) .chart-donut__wrapper {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.chart-donut__svg path {\n cursor: default;\n transition: opacity var(--effect-motion-short-2);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .chart-donut__svg path {\n transition: none;\n }\n}\n\n.chart-donut__svg path:focus-visible {\n outline: none;\n stroke: var(--color-interaction-focus);\n stroke-width:
|
|
335
|
+
"content": ":host {\n display: inline-block;\n font-family: var(--typography-font-family);\n user-select: none;\n}\n\n:host(.chart-donut--fill) {\n display: block;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.chart-donut__wrapper {\n position: relative;\n overflow: visible;\n}\n\n:host(.chart-donut--fill) .chart-donut__wrapper {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.chart-donut__svg path {\n cursor: default;\n transition: opacity var(--effect-motion-short-2);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .chart-donut__svg path {\n transition: none;\n }\n}\n\n.chart-donut__svg path:focus-visible {\n outline: none;\n stroke: var(--color-interaction-focus);\n stroke-width: var(--dimension-stroke-width-025);\n vector-effect: non-scaling-stroke;\n}\n\n/* Matches ds-text text-title-large + emphasis (SVG cannot host ds-text). */\n.chart-donut__center-value {\n fill: var(--color-foreground-primary);\n font-family: var(--typography-font-family);\n font-size: var(--typography-fontsize-xl);\n line-height: var(--typography-lineheight-xl);\n font-weight: var(--typography-weight-semibold);\n letter-spacing: var(--typography-letterspacing-negative-double);\n cursor: default;\n pointer-events: none;\n}\n\n/* Matches ds-text text-body-medium regular. */\n.chart-donut__center-caption {\n fill: var(--color-foreground-secondary);\n font-family: var(--typography-font-family);\n font-size: var(--typography-fontsize-md);\n line-height: var(--typography-lineheight-md);\n font-weight: var(--typography-weight-regular);\n letter-spacing: var(--typography-letterspacing-negative-half);\n cursor: default;\n pointer-events: none;\n}\n",
|
|
335
336
|
"type": "registry:ui"
|
|
336
337
|
},
|
|
337
338
|
{
|
|
@@ -276,7 +276,7 @@
|
|
|
276
276
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: items.",
|
|
277
277
|
"peerDependencies": {
|
|
278
278
|
"required": [
|
|
279
|
-
"@ds-mo/tokens ^
|
|
279
|
+
"@ds-mo/tokens ^5.0.0",
|
|
280
280
|
"@ds-mo/icons ^6.4.0"
|
|
281
281
|
],
|
|
282
282
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -55,7 +55,8 @@
|
|
|
55
55
|
"Authored series colors override the shared categorical palette."
|
|
56
56
|
],
|
|
57
57
|
"responsiveBehavior": [
|
|
58
|
-
"
|
|
58
|
+
"Width and height provide the standalone intrinsic viewport; constrained card regions are measured and reflow both axes to their rendered pixel dimensions.",
|
|
59
|
+
"Responsive layout changes point positions and plot extents without scaling SVG text, line strokes, point markers, or margins.",
|
|
59
60
|
"Category positions are always equally spaced, even when labels represent time.",
|
|
60
61
|
"Reduce or pre-format dense labels before passing them; the chart renders authored labels without a continuous time scale."
|
|
61
62
|
],
|
|
@@ -64,10 +65,10 @@
|
|
|
64
65
|
"Assign series and categories as JavaScript properties and keep every series aligned to the category count."
|
|
65
66
|
],
|
|
66
67
|
"react": [
|
|
67
|
-
"Pass stable series and category arrays
|
|
68
|
+
"Pass stable series and category arrays; width and height provide standalone intrinsic dimensions while constrained containers reflow automatically."
|
|
68
69
|
],
|
|
69
70
|
"angular": [
|
|
70
|
-
"Bind series and categories as properties
|
|
71
|
+
"Bind series and categories as properties; width and height provide standalone intrinsic dimensions while constrained containers reflow automatically."
|
|
71
72
|
]
|
|
72
73
|
},
|
|
73
74
|
"references": [
|
|
@@ -93,7 +94,8 @@
|
|
|
93
94
|
"attribute": "height",
|
|
94
95
|
"default": "240",
|
|
95
96
|
"required": false,
|
|
96
|
-
"mutable": false
|
|
97
|
+
"mutable": false,
|
|
98
|
+
"description": "Standalone intrinsic height. Container constraints reflow the plot at rendered pixel size."
|
|
97
99
|
},
|
|
98
100
|
"series": {
|
|
99
101
|
"type": "ChartSeries[]",
|
|
@@ -117,7 +119,8 @@
|
|
|
117
119
|
"attribute": "width",
|
|
118
120
|
"default": "480",
|
|
119
121
|
"required": false,
|
|
120
|
-
"mutable": false
|
|
122
|
+
"mutable": false,
|
|
123
|
+
"description": "Standalone intrinsic width. Container constraints reflow the plot at rendered pixel size."
|
|
121
124
|
}
|
|
122
125
|
},
|
|
123
126
|
"events": [],
|
|
@@ -139,7 +142,8 @@
|
|
|
139
142
|
"attribute": "height",
|
|
140
143
|
"default": "240",
|
|
141
144
|
"required": false,
|
|
142
|
-
"mutable": false
|
|
145
|
+
"mutable": false,
|
|
146
|
+
"description": "Standalone intrinsic height. Container constraints reflow the plot at rendered pixel size."
|
|
143
147
|
},
|
|
144
148
|
"series": {
|
|
145
149
|
"type": "ChartSeries[]",
|
|
@@ -163,7 +167,8 @@
|
|
|
163
167
|
"attribute": "width",
|
|
164
168
|
"default": "480",
|
|
165
169
|
"required": false,
|
|
166
|
-
"mutable": false
|
|
170
|
+
"mutable": false,
|
|
171
|
+
"description": "Standalone intrinsic width. Container constraints reflow the plot at rendered pixel size."
|
|
167
172
|
}
|
|
168
173
|
},
|
|
169
174
|
"events": [],
|
|
@@ -192,7 +197,7 @@
|
|
|
192
197
|
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: categories, series.",
|
|
193
198
|
"peerDependencies": {
|
|
194
199
|
"required": [
|
|
195
|
-
"@ds-mo/tokens ^
|
|
200
|
+
"@ds-mo/tokens ^5.0.0",
|
|
196
201
|
"@ds-mo/icons ^6.4.0"
|
|
197
202
|
],
|
|
198
203
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -207,12 +212,12 @@
|
|
|
207
212
|
"files": [
|
|
208
213
|
{
|
|
209
214
|
"path": "src/wc/components/ChartLine/ChartLine.css",
|
|
210
|
-
"content": ":host {\n display: inline-block;\n max-width: 100%;\n font-family: var(--typography-font-family);\n}\n\n.chart-line__svg {\n display: block;\n
|
|
215
|
+
"content": ":host {\n display: inline-block;\n max-width: 100%;\n font-family: var(--typography-font-family);\n}\n\n.chart-line__svg {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.chart-line__gridline {\n stroke: var(--color-border-tertiary);\n stroke-width: var(--dimension-stroke-width-012);\n vector-effect: non-scaling-stroke;\n}\n\n/* Matches ds-text text-caption regular (SVG cannot host ds-text). */\n.chart-line__axis-label {\n fill: var(--color-foreground-secondary);\n font-family: var(--typography-font-family);\n font-size: var(--typography-fontsize-xs);\n font-weight: var(--typography-weight-medium);\n letter-spacing: var(--typography-letterspacing-positive);\n text-transform: uppercase;\n}\n\n.chart-line__path {\n fill: none;\n stroke-width: var(--dimension-stroke-width-025);\n vector-effect: non-scaling-stroke;\n}\n\n.chart-line__point {\n stroke: var(--color-background-primary);\n stroke-width: var(--dimension-stroke-width-018);\n r: calc(var(--dimension-size-075) / 2);\n vector-effect: non-scaling-stroke;\n}\n",
|
|
211
216
|
"type": "registry:ui"
|
|
212
217
|
},
|
|
213
218
|
{
|
|
214
219
|
"path": "src/wc/components/ChartLine/ChartLine.tsx",
|
|
215
|
-
"content": "import { Component, Prop, h, Host } from '@stencil/core';\nimport { line as lineShape } from 'd3-shape';\nimport { scaleLinear, scalePoint } from 'd3-scale';\nimport { max } from 'd3-array';\nimport { categoryColor } from '../../utils/chart-colors';\nimport
|
|
220
|
+
"content": "import { Component, Prop, State, Watch, h, Host } from '@stencil/core';\nimport { line as lineShape } from 'd3-shape';\nimport { scaleLinear, scalePoint } from 'd3-scale';\nimport { max } from 'd3-array';\nimport { categoryColor } from '../../utils/chart-colors';\nimport { resolveCartesianChartLayout } from '../../utils/cartesian-chart-layout';\nimport {\n ChartViewportController,\n type ChartViewportSize,\n} from '../../utils/chart-viewport-controller';\nimport type { ChartSeries } from '../../utils/chart-types';\n\n@Component({\n tag: 'ds-chart-line',\n styleUrl: 'ChartLine.css',\n scoped: true,\n})\nexport class ChartLine {\n /** One or more series to plot. Set as a JS property (not an HTML attribute). */\n @Prop() series: ChartSeries[] = [];\n /** X-axis labels — must match each series' `data` length. Set as a JS property. */\n @Prop() categories: string[] = [];\n /** Standalone intrinsic width. Container constraints reflow the plot at rendered pixel size. */\n @Prop() width: number = 480;\n /** Standalone intrinsic height. Container constraints reflow the plot at rendered pixel size. */\n @Prop() height: number = 240;\n @Prop() showPoints: boolean = true;\n\n @State() private viewport: ChartViewportSize | undefined;\n\n private viewportController: ChartViewportController | null = null;\n private svgEl: SVGElement | null = null;\n\n componentDidLoad() {\n this.connectViewportController();\n }\n\n connectedCallback() {\n if (this.svgEl && !this.viewportController) this.connectViewportController();\n }\n\n componentDidRender() {\n if (!this.viewportController) this.connectViewportController();\n }\n\n private connectViewportController() {\n if (!this.svgEl) return;\n this.viewportController = new ChartViewportController(this.svgEl, viewport => {\n if (\n viewport.width !== this.viewport?.width ||\n viewport.height !== this.viewport?.height\n ) {\n this.viewport = viewport;\n }\n });\n this.viewportController.connect();\n }\n\n disconnectedCallback() {\n this.viewportController?.disconnect();\n this.viewportController = null;\n }\n\n @Watch('width')\n @Watch('height')\n handleIntrinsicSizeChange() {\n this.viewport = undefined;\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(() => this.viewportController?.measure());\n }\n }\n\n render() {\n const viewportWidth = this.viewport?.width ?? this.width;\n const viewportHeight = this.viewport?.height ?? this.height;\n const { margin, axisLabelGap, categoryLabelOffset } =\n resolveCartesianChartLayout();\n const innerWidth = Math.max(0, viewportWidth - margin.left - margin.right);\n const innerHeight = Math.max(0, viewportHeight - margin.top - margin.bottom);\n\n const allValues = this.series.flatMap(s => s.data);\n const yMax = max(allValues) ?? 0;\n\n const xScale = scalePoint<number>()\n .domain(this.categories.map((_, i) => i))\n .range([0, innerWidth]);\n\n const yScale = scaleLinear()\n .domain([0, yMax || 1])\n .range([innerHeight, 0])\n .nice();\n\n const lineGenerator = lineShape<number>()\n .x((_, i) => xScale(i) ?? 0)\n .y(d => yScale(d));\n\n const yTicks = yScale.ticks(4);\n\n return (\n <Host class=\"chart-line\">\n <svg\n class=\"chart-line__svg\"\n ref={element => {\n this.svgEl = element ?? null;\n }}\n width={viewportWidth}\n height={viewportHeight}\n role=\"img\"\n aria-label={this.series.map(s => s.name).join(', ')}\n >\n <g transform={`translate(${margin.left}, ${margin.top})`}>\n {yTicks.map(tick => (\n <g key={`grid-${tick}`} transform={`translate(0, ${yScale(tick)})`}>\n <line class=\"chart-line__gridline\" x1={0} x2={innerWidth} />\n <text\n class=\"chart-line__axis-label\"\n x={-axisLabelGap}\n text-anchor=\"end\"\n dominant-baseline=\"middle\"\n >\n {tick}\n </text>\n </g>\n ))}\n\n {this.categories.map((label, i) => (\n <text\n key={`x-${label}`}\n class=\"chart-line__axis-label\"\n x={xScale(i) ?? 0}\n y={innerHeight + categoryLabelOffset}\n text-anchor=\"middle\"\n >\n {label}\n </text>\n ))}\n\n {this.series.map((s, si) => {\n const color = s.color ?? categoryColor(si);\n return (\n <g key={s.name}>\n <path class=\"chart-line__path\" d={lineGenerator(s.data) ?? undefined} stroke={color} />\n {this.showPoints &&\n s.data.map((d, i) => (\n <circle\n key={`${s.name}-${i}`}\n class=\"chart-line__point\"\n cx={xScale(i) ?? 0}\n cy={yScale(d)}\n fill={color}\n />\n ))}\n </g>\n );\n })}\n </g>\n </svg>\n </Host>\n );\n }\n}\n",
|
|
216
221
|
"type": "registry:ui"
|
|
217
222
|
}
|
|
218
223
|
]
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
3
|
"name": "checkbox",
|
|
4
4
|
"title": "Checkbox",
|
|
5
|
-
"description": "Form-associated checkbox for independent choices, acknowledgment, or consent, with checked, unchecked, mixed, and
|
|
5
|
+
"description": "Form-associated checkbox for independent choices, acknowledgment, or consent, with checked, unchecked, mixed, and four density states.",
|
|
6
6
|
"type": "registry:ui",
|
|
7
7
|
"meta": {
|
|
8
8
|
"library": "@ds-mo/ui",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"intent": {
|
|
14
14
|
"audience": "general",
|
|
15
15
|
"status": "stable",
|
|
16
|
-
"summary": "Form-associated checkbox for independent choices, acknowledgment, or consent, with checked, unchecked, mixed, and
|
|
16
|
+
"summary": "Form-associated checkbox for independent choices, acknowledgment, or consent, with checked, unchecked, mixed, and four density states.",
|
|
17
17
|
"useWhen": [
|
|
18
18
|
"A user may independently select zero or more choices.",
|
|
19
19
|
"A form requires acknowledgment, consent, or an opt-in value before submission.",
|
|
@@ -53,15 +53,15 @@
|
|
|
53
53
|
"Use presentation mode only inside a composite option that owns selection semantics, focus, and interaction."
|
|
54
54
|
],
|
|
55
55
|
"states": [
|
|
56
|
-
"Unchecked boxes use a tertiary-foreground inset stroke: 1.25px at md, 1px at sm, and 0.75px at xs. Selected and mixed boxes remove the border, use a brand fill, and draw a component-owned check or subtract mark at the same density-specific stroke width.",
|
|
56
|
+
"Unchecked boxes use a tertiary-foreground inset stroke: 1.5px at lg, 1.25px at md, 1px at sm, and 0.75px at xs. Selected and mixed boxes remove the border, use a brand fill, and draw a component-owned check or subtract mark at the same density-specific stroke width.",
|
|
57
57
|
"Activating an indeterminate checkbox clears the mixed state, toggles checked, and emits dsChange with the resulting boolean.",
|
|
58
58
|
"The initial checked and indeterminate values are restored by native form reset; checked values submit under name and unchecked values submit nothing.",
|
|
59
|
-
"Sizes are md with a 16px box in a 20px placement, sm with a 12px box in a 16px placement, and xs with an 8px box in a 12px placement.",
|
|
59
|
+
"Sizes are lg with a 20px box in a 24px placement, md with a 16px box in a 20px placement, sm with a 12px box in a 16px placement, and xs with an 8px box in a 12px placement.",
|
|
60
60
|
"Presentation mode removes checkbox semantics, focus, interaction, label rendering, and form submission while preserving the visual state."
|
|
61
61
|
],
|
|
62
62
|
"responsiveBehavior": [
|
|
63
63
|
"Choose size from the density of the containing row; labels may wrap while the placement box stays fixed.",
|
|
64
|
-
"Use the
|
|
64
|
+
"Use the same density as the shared option icon zone in multi-select rows."
|
|
65
65
|
],
|
|
66
66
|
"frameworkCaveats": {
|
|
67
67
|
"customElements": [
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
},
|
|
170
170
|
"size": {
|
|
171
171
|
"type": "CheckboxSize",
|
|
172
|
-
"resolvedType": "\"md\" | \"sm\" | \"xs\"",
|
|
172
|
+
"resolvedType": "\"lg\" | \"md\" | \"sm\" | \"xs\"",
|
|
173
173
|
"attribute": "size",
|
|
174
174
|
"default": "'md'",
|
|
175
175
|
"required": false,
|
|
@@ -281,7 +281,7 @@
|
|
|
281
281
|
},
|
|
282
282
|
"size": {
|
|
283
283
|
"type": "CheckboxSize",
|
|
284
|
-
"resolvedType": "\"md\" | \"sm\" | \"xs\"",
|
|
284
|
+
"resolvedType": "\"lg\" | \"md\" | \"sm\" | \"xs\"",
|
|
285
285
|
"attribute": "size",
|
|
286
286
|
"default": "'md'",
|
|
287
287
|
"required": false,
|
|
@@ -332,7 +332,7 @@
|
|
|
332
332
|
},
|
|
333
333
|
"peerDependencies": {
|
|
334
334
|
"required": [
|
|
335
|
-
"@ds-mo/tokens ^
|
|
335
|
+
"@ds-mo/tokens ^5.0.0",
|
|
336
336
|
"@ds-mo/icons ^6.4.0"
|
|
337
337
|
],
|
|
338
338
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -349,12 +349,12 @@
|
|
|
349
349
|
"files": [
|
|
350
350
|
{
|
|
351
351
|
"path": "src/wc/components/Checkbox/Checkbox.css",
|
|
352
|
-
"content": "@import '../../utils/control-inactive.css';\n@import '../../utils/control-density.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/interaction-fill.css';\n\n:host {\n display: inline-flex;\n align-items: center;\n box-sizing: border-box;\n gap: var(--ds-control-gap);\n height: var(--ds-control-height);\n padding: 0 var(--ds-control-padding-inline);\n border-radius: var(--ds-control-radius);\n cursor: default;\n user-select: none;\n}\n\n:host(.checkbox--presentation) {\n width: var(--ds-control-icon);\n height: var(--ds-control-icon);\n padding: 0;\n gap: 0;\n pointer-events: none;\n}\n\n/* Inactive: `.ds-control-inactive` (50% opacity). */\n\n:host(.checkbox--md) {\n --_checkbox-box: var(--dimension-iconography-sm);\n --_checkbox-stroke: var(--dimension-stroke-width-015);\n}\n\n:host(.checkbox--sm) {\n --_checkbox-box: var(--dimension-iconography-xs);\n --_checkbox-stroke: var(--dimension-stroke-width-012);\n}\n\n:host(.checkbox--xs) {\n --_checkbox-box: var(--dimension-size-100);\n --_checkbox-stroke: calc(var(--dimension-stroke-width-base) * 3 / 32);\n}\n\n.checkbox__placement {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--ds-control-icon);\n height: var(--ds-control-icon);\n}\n\n.box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: var(--_checkbox-box);\n height: var(--_checkbox-box);\n border: 0;\n border-radius: var(--dimension-radius-025);\n box-shadow: inset 0 0 0 var(--_checkbox-stroke) var(--color-foreground-tertiary);\n transition:\n background-color var(--effect-motion-short-2),\n box-shadow var(--effect-motion-short-2);\n}\n\n.box--marked {\n color: var(--color-foreground-on-bold-background-primary);\n background-color: var(--color-background-bold-brand);\n box-shadow: none;\n}\n\n.checkbox__mark {\n width: 100%;\n height: 100%;\n flex-shrink: 0;\n stroke: currentColor;\n stroke-width: var(--_checkbox-stroke);\n stroke-linecap: butt;\n stroke-linejoin: round;\n}\n\n.checkbox__mark--checked {\n transform: translateY(-0.5px);\n}\n\n.checkbox__label {\n flex: 1;\n min-width: 0;\n padding: 0 var(--ds-control-label-inset);\n}\n",
|
|
352
|
+
"content": "@import '../../utils/control-inactive.css';\n@import '../../utils/control-density.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/interaction-fill.css';\n\n:host {\n display: inline-flex;\n align-items: center;\n box-sizing: border-box;\n gap: var(--ds-control-gap);\n height: var(--ds-control-height);\n padding: 0 var(--ds-control-padding-inline);\n border-radius: var(--ds-control-radius);\n cursor: default;\n user-select: none;\n}\n\n:host(.checkbox--presentation) {\n width: var(--ds-control-icon);\n height: var(--ds-control-icon);\n padding: 0;\n gap: 0;\n pointer-events: none;\n}\n\n/* Inactive: `.ds-control-inactive` (50% opacity). */\n\n:host(.checkbox--lg) {\n --_checkbox-box: var(--dimension-iconography-md);\n --_checkbox-stroke: var(--dimension-stroke-width-018);\n}\n\n:host(.checkbox--md) {\n --_checkbox-box: var(--dimension-iconography-sm);\n --_checkbox-stroke: var(--dimension-stroke-width-015);\n}\n\n:host(.checkbox--sm) {\n --_checkbox-box: var(--dimension-iconography-xs);\n --_checkbox-stroke: var(--dimension-stroke-width-012);\n}\n\n:host(.checkbox--xs) {\n --_checkbox-box: var(--dimension-size-100);\n --_checkbox-stroke: calc(var(--dimension-stroke-width-base) * 3 / 32);\n}\n\n.checkbox__placement {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--ds-control-icon);\n height: var(--ds-control-icon);\n}\n\n.box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: var(--_checkbox-box);\n height: var(--_checkbox-box);\n border: 0;\n border-radius: var(--dimension-radius-025);\n box-shadow: inset 0 0 0 var(--_checkbox-stroke) var(--color-foreground-tertiary);\n transition:\n background-color var(--effect-motion-short-2),\n box-shadow var(--effect-motion-short-2);\n}\n\n.box--marked {\n color: var(--color-foreground-on-bold-background-primary);\n background-color: var(--color-background-bold-brand);\n box-shadow: none;\n}\n\n.checkbox__mark {\n width: 100%;\n height: 100%;\n flex-shrink: 0;\n stroke: currentColor;\n stroke-width: var(--_checkbox-stroke);\n stroke-linecap: butt;\n stroke-linejoin: round;\n}\n\n.checkbox__mark--checked {\n transform: translateY(-0.5px);\n}\n\n.checkbox__label {\n flex: 1;\n min-width: 0;\n padding: 0 var(--ds-control-label-inset);\n}\n",
|
|
353
353
|
"type": "registry:ui"
|
|
354
354
|
},
|
|
355
355
|
{
|
|
356
356
|
"path": "src/wc/components/Checkbox/Checkbox.tsx",
|
|
357
|
-
"content": "import { AttachInternals, Component, Prop, State, Event, EventEmitter, Watch, h, Host } from '@stencil/core';\nimport { DEFAULT_REQUIRED_MESSAGE, setRequiredValidity } from '../../utils';\n\nexport type CheckboxSize = '
|
|
357
|
+
"content": "import { AttachInternals, Component, Prop, State, Event, EventEmitter, Watch, h, Host } from '@stencil/core';\nimport { CONTROL_TEXT_VARIANT, DEFAULT_REQUIRED_MESSAGE, setRequiredValidity } from '../../utils';\n\nexport type CheckboxSize = 'lg' | 'md' | 'sm' | 'xs';\n\nlet idCounter = 0;\n\n@Component({\n tag: 'ds-checkbox',\n styleUrl: 'Checkbox.css',\n scoped: true,\n formAssociated: true,\n})\nexport class Checkbox {\n @AttachInternals() internals!: ElementInternals;\n private labelId = `ds-checkbox-label-${++idCounter}`;\n\n /** Visible label and accessible name. Omitted only in presentation mode. */\n @Prop() label!: string;\n /** Current checked state. */\n @Prop({ mutable: true }) checked: boolean = false;\n /** Visual and placement density. */\n @Prop() size: CheckboxSize = 'md';\n /** Native form field name. */\n @Prop({ reflect: true }) name: string | undefined;\n /** Submitted value when checked. */\n @Prop() value: string = 'on';\n /** Native disabled state. */\n @Prop({ reflect: true }) disabled: boolean = false;\n /** Require the checkbox to be checked for form validity. */\n @Prop({ reflect: true }) required: boolean = false;\n /** Validation message used when a required checkbox is unchecked. */\n @Prop() requiredMessage: string = DEFAULT_REQUIRED_MESSAGE;\n /** Mixed visual state. Activation clears it before toggling checked. */\n @Prop({ mutable: true }) indeterminate: boolean = false;\n /** Design-system inactive state. */\n @Prop() isInactive: boolean = false;\n /** Visual-only indicator for a composite control that owns selection semantics. */\n @Prop() presentation: boolean = false;\n\n /** Emitted after user activation with the new checked state. */\n @Event() dsChange!: EventEmitter<boolean>;\n\n private initialChecked = false;\n private initialIndeterminate = false;\n @State() private formDisabled = false;\n\n componentWillLoad() {\n this.initialChecked = this.checked;\n this.initialIndeterminate = this.indeterminate;\n this.syncFormValue();\n }\n\n @Watch('checked')\n @Watch('value')\n @Watch('disabled')\n @Watch('isInactive')\n @Watch('required')\n @Watch('presentation')\n syncFormValue() {\n const inactive = this.isInactive || this.disabled || this.formDisabled || this.presentation;\n this.internals.setFormValue(!inactive && this.checked ? this.value : null);\n const missing = this.required && !inactive && !this.checked;\n setRequiredValidity(this.internals, missing, this.requiredMessage);\n }\n\n formDisabledCallback(disabled: boolean) {\n this.formDisabled = disabled;\n this.syncFormValue();\n }\n\n formResetCallback() {\n this.checked = this.initialChecked;\n this.indeterminate = this.initialIndeterminate;\n }\n\n private handleActivate = () => {\n if (this.isInactive || this.disabled || this.formDisabled || this.presentation) return;\n if (this.indeterminate) this.indeterminate = false;\n this.checked = !this.checked;\n this.dsChange.emit(this.checked);\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.handleActivate();\n }\n };\n\n render() {\n const inactive = this.isInactive || this.disabled || this.formDisabled;\n const isMarked = this.checked || this.indeterminate;\n const invalid = this.required && !inactive && !this.checked;\n\n return (\n <Host\n role={this.presentation ? undefined : 'checkbox'}\n aria-checked={this.presentation ? undefined : this.indeterminate ? 'mixed' : String(this.checked)}\n aria-disabled={!this.presentation && inactive ? 'true' : undefined}\n aria-required={!this.presentation && this.required ? 'true' : undefined}\n aria-invalid={!this.presentation && invalid ? 'true' : undefined}\n aria-labelledby={this.presentation ? undefined : this.labelId}\n aria-hidden={this.presentation ? 'true' : undefined}\n tabIndex={this.presentation || inactive ? -1 : 0}\n class={{\n checkbox: true,\n 'checkbox--presentation': this.presentation,\n [`checkbox--${this.size}`]: true,\n [`ds-control--${this.size}`]: true,\n 'ds-control-inactive': inactive && !this.presentation,\n 'ds-focus-ring-inset': !this.presentation,\n 'ds-interaction-fill': !inactive && !this.presentation,\n }}\n onClick={this.presentation ? undefined : this.handleActivate}\n onKeyDown={this.presentation ? undefined : this.handleKeyDown}\n >\n <span class=\"checkbox__placement ds-interaction-fill__content\" aria-hidden=\"true\">\n <span class={{ box: true, 'box--marked': isMarked }}>\n {isMarked && (\n // eslint-disable-next-line local/prefer-ds-icon -- Checkbox owns this density-specific state mark and its optical stroke.\n <svg\n class={{\n checkbox__mark: true,\n 'checkbox__mark--checked': !this.indeterminate,\n }}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n focusable=\"false\"\n >\n <path\n d={this.indeterminate ? 'M4 8H12' : 'M3.5 8.25L6.75 11.5L12.5 4.75'}\n vector-effect=\"non-scaling-stroke\"\n />\n </svg>\n )}\n </span>\n </span>\n {!this.presentation && (\n <ds-text\n class=\"checkbox__label ds-interaction-fill__content\"\n as=\"span\"\n variant={CONTROL_TEXT_VARIANT[this.size]}\n textId={this.labelId}\n >\n {this.label}\n </ds-text>\n )}\n </Host>\n );\n }\n}\n",
|
|
358
358
|
"type": "registry:ui"
|
|
359
359
|
}
|
|
360
360
|
]
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"Hover and press use the shared interaction hover and pressed overlays. Only the selected conversation uses the persistent active fill.",
|
|
42
42
|
"The title uses body-medium, not title-small, and the body-small preview truncates after one line. Unread titles use emphasis with primary foreground; read titles use regular weight with secondary foreground.",
|
|
43
43
|
"The actions slot overlays the row at an 8px right inset without changing title or preview measure, and paints above the row interaction wash while that wash remains active.",
|
|
44
|
-
"Contextual actions use the shared md control-elevation wrapper so their transparent backdrop blur is unchanged while the split inset highlight remains above the borderless slotted action."
|
|
44
|
+
"Contextual actions use the shared md control-elevation wrapper so their transparent backdrop blur is unchanged while the split inset highlight remains above the borderless slotted action and the press-scale modifier moves the complete elevated surface."
|
|
45
45
|
],
|
|
46
46
|
"responsiveBehavior": [
|
|
47
47
|
"Long titles and previews truncate without displacing trailing status."
|
|
@@ -253,7 +253,7 @@
|
|
|
253
253
|
},
|
|
254
254
|
"peerDependencies": {
|
|
255
255
|
"required": [
|
|
256
|
-
"@ds-mo/tokens ^
|
|
256
|
+
"@ds-mo/tokens ^5.0.0",
|
|
257
257
|
"@ds-mo/icons ^6.4.0"
|
|
258
258
|
],
|
|
259
259
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
@@ -277,7 +277,7 @@
|
|
|
277
277
|
},
|
|
278
278
|
{
|
|
279
279
|
"path": "src/wc/components/ConversationListItem/ConversationListItem.tsx",
|
|
280
|
-
"content": "import { Component, Element, Event, EventEmitter, h, Host, Prop } from '@stencil/core';\nimport type { ConversationItemState } from '../conversation-types';\n\n@Component({\n tag: 'ds-conversation-list-item',\n styleUrl: 'ConversationListItem.css',\n scoped: true,\n})\nexport class ConversationListItem {\n @Element() el!: HTMLElement;\n\n @Prop() conversationId: string = '';\n /** Visible conversation title. Named to avoid the native HTMLElement.title contract. */\n @Prop() conversationTitle: string = '';\n @Prop() preview: string = '';\n /** ISO timestamp for semantic activity metadata. */\n @Prop() updatedAt: string = '';\n @Prop() selected: boolean = false;\n @Prop() state: ConversationItemState = 'default';\n @Prop() statusLabel: string = '';\n @Prop() unreadCount: number = 0;\n /** Keep the contextual-actions surface visible while its popup is open or closing. */\n @Prop({ reflect: true }) actionsOpen: boolean = false;\n\n @Event() dsSelect!: EventEmitter<{ id: string }>;\n\n private handleClick = () => this.dsSelect.emit({ id: this.conversationId });\n\n private handleActionsSlotChange = (event: Event) => {\n const slot = event.target as HTMLSlotElement;\n this.el.classList.toggle(\n 'conversation-list-item--has-actions',\n slot.assignedElements().length > 0\n );\n };\n\n render() {\n const busy = this.state === 'busy';\n const subtext = busy && this.statusLabel ? this.statusLabel : this.preview;\n const accessibleName = [\n this.conversationTitle,\n subtext,\n this.unreadCount > 0 ? `${this.unreadCount} unread` : '',\n ]\n .filter(Boolean)\n .join('. ');\n\n return (\n <Host\n role=\"listitem\"\n class={{ 'conversation-list-item--actions-open': this.actionsOpen }}\n >\n <div class=\"conversation-list-item__row\">\n <button\n type=\"button\"\n class={{\n 'conversation-list-item': true,\n 'ds-choice-item': true,\n 'ds-control--md': true,\n 'ds-focus-ring-inset': true,\n 'ds-interaction-fill': true,\n 'ds-interaction-fill--selected': this.selected,\n 'conversation-list-item--error': this.state === 'error',\n }}\n aria-label={accessibleName}\n aria-current={this.selected ? 'true' : undefined}\n aria-busy={busy ? 'true' : undefined}\n onClick={this.handleClick}\n >\n <span class=\"conversation-list-item__leading ds-choice-item__icon ds-interaction-fill__content\">\n <slot name=\"leading\" />\n </span>\n <span class=\"conversation-list-item__content ds-choice-item__content ds-interaction-fill__content\">\n <span class=\"conversation-list-item__title-row\">\n <ds-text\n class=\"conversation-list-item__title ds-choice-item__label\"\n as=\"span\"\n variant=\"text-body-medium\"\n emphasis={this.unreadCount > 0}\n color={this.unreadCount > 0 ? 'primary' : 'secondary'}\n lineTruncation={1}\n >\n {this.conversationTitle}\n </ds-text>\n {this.unreadCount > 0 ? (\n <span class=\"conversation-list-item__unread\">\n <ds-badge variant=\"dot\" surface=\"secondary\" />\n </span>\n ) : null}\n </span>\n <span class=\"conversation-list-item__preview-row\">\n {busy ? <ds-loader size=\"sm\" color=\"secondary\" /> : null}\n <ds-text\n class=\"conversation-list-item__preview ds-choice-item__subtext\"\n as=\"span\"\n variant=\"text-body-small\"\n color={this.state === 'error' ? 'negative' : 'secondary'}\n lineTruncation={1}\n >\n {subtext}\n </ds-text>\n </span>\n {this.updatedAt ? (\n <time class=\"conversation-list-item__time ds-visually-hidden\" dateTime={this.updatedAt}>\n {this.updatedAt}\n </time>\n ) : null}\n </span>\n <span class=\"conversation-list-item__trailing ds-interaction-fill__content\">\n <slot name=\"trailing\" />\n </span>\n </button>\n <div class=\"conversation-list-item__actions ds-control-elevation ds-control-elevation--md\">\n <slot name=\"actions\" onSlotchange={this.handleActionsSlotChange} />\n </div>\n </div>\n </Host>\n );\n }\n}\n",
|
|
280
|
+
"content": "import { Component, Element, Event, EventEmitter, h, Host, Prop } from '@stencil/core';\nimport type { ConversationItemState } from '../conversation-types';\n\n@Component({\n tag: 'ds-conversation-list-item',\n styleUrl: 'ConversationListItem.css',\n scoped: true,\n})\nexport class ConversationListItem {\n @Element() el!: HTMLElement;\n\n @Prop() conversationId: string = '';\n /** Visible conversation title. Named to avoid the native HTMLElement.title contract. */\n @Prop() conversationTitle: string = '';\n @Prop() preview: string = '';\n /** ISO timestamp for semantic activity metadata. */\n @Prop() updatedAt: string = '';\n @Prop() selected: boolean = false;\n @Prop() state: ConversationItemState = 'default';\n @Prop() statusLabel: string = '';\n @Prop() unreadCount: number = 0;\n /** Keep the contextual-actions surface visible while its popup is open or closing. */\n @Prop({ reflect: true }) actionsOpen: boolean = false;\n\n @Event() dsSelect!: EventEmitter<{ id: string }>;\n\n private handleClick = () => this.dsSelect.emit({ id: this.conversationId });\n\n private handleActionsSlotChange = (event: Event) => {\n const slot = event.target as HTMLSlotElement;\n this.el.classList.toggle(\n 'conversation-list-item--has-actions',\n slot.assignedElements().length > 0\n );\n };\n\n render() {\n const busy = this.state === 'busy';\n const subtext = busy && this.statusLabel ? this.statusLabel : this.preview;\n const accessibleName = [\n this.conversationTitle,\n subtext,\n this.unreadCount > 0 ? `${this.unreadCount} unread` : '',\n ]\n .filter(Boolean)\n .join('. ');\n\n return (\n <Host\n role=\"listitem\"\n class={{ 'conversation-list-item--actions-open': this.actionsOpen }}\n >\n <div class=\"conversation-list-item__row\">\n <button\n type=\"button\"\n class={{\n 'conversation-list-item': true,\n 'ds-choice-item': true,\n 'ds-control-frame': true,\n 'ds-control--md': true,\n 'ds-focus-ring-inset': true,\n 'ds-interaction-fill': true,\n 'ds-interaction-fill--selected': this.selected,\n 'conversation-list-item--error': this.state === 'error',\n }}\n aria-label={accessibleName}\n aria-current={this.selected ? 'true' : undefined}\n aria-busy={busy ? 'true' : undefined}\n onClick={this.handleClick}\n >\n <span class=\"conversation-list-item__leading ds-choice-item__icon ds-control-icon-box ds-interaction-fill__content\">\n <slot name=\"leading\" />\n </span>\n <span class=\"conversation-list-item__content ds-choice-item__content ds-interaction-fill__content\">\n <span class=\"conversation-list-item__title-row\">\n <ds-text\n class=\"conversation-list-item__title ds-choice-item__label ds-control-label-box\"\n as=\"span\"\n variant=\"text-body-medium\"\n emphasis={this.unreadCount > 0}\n color={this.unreadCount > 0 ? 'primary' : 'secondary'}\n lineTruncation={1}\n >\n {this.conversationTitle}\n </ds-text>\n {this.unreadCount > 0 ? (\n <span class=\"conversation-list-item__unread\">\n <ds-badge variant=\"dot\" surface=\"secondary\" hasRing={false} />\n </span>\n ) : null}\n </span>\n <span class=\"conversation-list-item__preview-row\">\n {busy ? <ds-loader size=\"sm\" color=\"secondary\" /> : null}\n <ds-text\n class=\"conversation-list-item__preview ds-choice-item__subtext ds-control-label-box\"\n as=\"span\"\n variant=\"text-body-small\"\n color={this.state === 'error' ? 'negative' : 'secondary'}\n lineTruncation={1}\n >\n {subtext}\n </ds-text>\n </span>\n {this.updatedAt ? (\n <time class=\"conversation-list-item__time ds-visually-hidden\" dateTime={this.updatedAt}>\n {this.updatedAt}\n </time>\n ) : null}\n </span>\n <span class=\"conversation-list-item__trailing ds-interaction-fill__content\">\n <slot name=\"trailing\" />\n </span>\n </button>\n <div class=\"conversation-list-item__actions ds-control-elevation ds-control-elevation--md ds-control-elevation--press-scale\">\n <slot name=\"actions\" onSlotchange={this.handleActionsSlotChange} />\n </div>\n </div>\n </Host>\n );\n }\n}\n",
|
|
281
281
|
"type": "registry:ui"
|
|
282
282
|
}
|
|
283
283
|
]
|