@ds-mo/ui 12.0.0 → 12.2.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 +18 -1
- package/dist/.build-stamp +1 -1
- package/dist/agent-patterns.json +3 -2
- package/dist/agent.json +314 -41
- package/dist/angular/ds-avatar.d.ts +1 -1
- package/dist/angular/ds-avatar.js +3 -3
- package/dist/angular/ds-bar-workflow.d.ts +28 -0
- package/dist/angular/ds-bar-workflow.js +48 -0
- package/dist/angular/ds-conversation-list.d.ts +1 -1
- package/dist/angular/ds-conversation-list.js +4 -3
- package/dist/angular/ds-scroll-overlay.d.ts +19 -0
- package/dist/angular/ds-scroll-overlay.js +43 -0
- package/dist/angular/index.d.ts +1 -1
- package/dist/angular/index.js +2 -0
- package/dist/angular/proxies.d.ts +2 -0
- package/dist/angular/proxies.js +2 -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-avatar.js +1 -1
- package/dist/components/ds-avatar.js.map +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.d.ts +11 -0
- package/dist/components/ds-bar-workflow.js +2 -0
- package/dist/components/ds-bar-workflow.js.map +1 -0
- 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-donut.js +1 -1
- package/dist/components/ds-card-data-viz-donut.js.map +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-card-shell-data-viz.js +1 -1
- package/dist/components/ds-chart-bar.js +1 -1
- package/dist/components/ds-chart-donut.js +1 -1
- package/dist/components/ds-chart-legend.js +1 -1
- package/dist/components/ds-chart-line.js +1 -1
- package/dist/components/ds-checkbox.js +1 -1
- package/dist/components/ds-chip.js +1 -1
- package/dist/components/ds-chip.js.map +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-section.js.map +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-icon.js +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-input.js.map +1 -1
- package/dist/components/ds-markdown.js +1 -1
- package/dist/components/ds-menu.js +1 -1
- package/dist/components/ds-message-bubble.js +1 -1
- package/dist/components/ds-message-bubble.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-scroller.js.map +1 -1
- package/dist/components/ds-message.js +1 -1
- package/dist/components/ds-modal.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-sub-nav.js.map +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-radio.js +1 -1
- package/dist/components/ds-radio.js.map +1 -1
- package/dist/components/ds-scroll-overlay.d.ts +11 -0
- package/dist/components/ds-scroll-overlay.js +2 -0
- package/dist/components/ds-scroll-overlay.js.map +1 -0
- 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-gradient-picker.js +1 -1
- package/dist/components/ds-shell-gradient-swatch.js +1 -1
- package/dist/components/ds-shell-gradient-swatch.js.map +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-skeleton.js +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-tab-group.js.map +1 -1
- package/dist/components/ds-tag.js +1 -1
- package/dist/components/ds-tag.js.map +1 -1
- package/dist/components/ds-text.js +1 -1
- package/dist/components/ds-toast.js +1 -1
- package/dist/components/ds-tooltip-data-viz.js +1 -1
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/ds-typing-indicator.js +1 -1
- package/dist/components/p-2W-ZjZCR.js +2 -0
- package/dist/components/{p-CwTVEAl2.js.map → p-2W-ZjZCR.js.map} +1 -1
- package/dist/components/p-8OOCLGph.js +2 -0
- package/dist/components/p-8OOCLGph.js.map +1 -0
- package/dist/components/{p-BYHKdFzV.js → p-B8CubPgQ.js} +2 -2
- package/dist/components/{p-DuNZGFkV.js → p-BAfG3M8z.js} +2 -2
- package/dist/components/p-BAfG3M8z.js.map +1 -0
- package/dist/components/p-BE_CDJeL.js +2 -0
- package/dist/components/p-BE_CDJeL.js.map +1 -0
- package/dist/components/{p-BH3es4p7.js → p-BRLDJmkh.js} +2 -2
- package/dist/components/p-BpA9uYKX.js +2 -0
- package/dist/components/p-BpA9uYKX.js.map +1 -0
- package/dist/components/{p-Bs6SS34m.js → p-C0_8K4y7.js} +2 -2
- package/dist/components/{p-BhKhX1er.js → p-CA3kLO7K.js} +2 -2
- package/dist/components/{p-DfIch2Dk.js → p-CCHqsF_H.js} +2 -2
- package/dist/components/p-CG5EX4NW.js +2 -0
- package/dist/components/{p-DABj3qTX.js.map → p-CG5EX4NW.js.map} +1 -1
- package/dist/components/{p-DVk0wxxX.js → p-CHkI3oIS.js} +2 -2
- package/dist/components/{p-liMPkhUP.js → p-CNffejay.js} +2 -2
- package/dist/components/{p-B3YvoGjS.js → p-Cxpl-rzP.js} +2 -2
- package/dist/components/p-CydY-v7X.js +2 -0
- package/dist/components/p-CydY-v7X.js.map +1 -0
- package/dist/components/{p-BkwBtZs3.js → p-D6jK2Hyi.js} +2 -2
- package/dist/components/{p-Cy04lXlc.js → p-DBi1bmOL.js} +2 -2
- package/dist/components/{p-DxeHimqk.js → p-DOCKtrS4.js} +2 -2
- package/dist/components/p-DbpfpeQT.js +2 -0
- package/dist/components/p-DbpfpeQT.js.map +1 -0
- package/dist/components/{p-6vj4kh70.js → p-DcGpdIlT.js} +2 -2
- package/dist/components/p-DyGB97Oy.js +2 -0
- package/dist/components/{p-Dy_sZ-dI.js.map → p-DyGB97Oy.js.map} +1 -1
- package/dist/components/p-GMDGgtY8.js +2 -0
- package/dist/components/{p-BUmDHPr3.js.map → p-GMDGgtY8.js.map} +1 -1
- package/dist/components/{p-Cf2J9MEo.js → p-XgIQ3oI_.js} +2 -2
- package/dist/components/{p-Cf-i-6aE.js → p-ky1msbJ8.js} +2 -2
- package/dist/components/p-xY3TjBF5.js +2 -0
- package/dist/components/{p-DUHcJWTQ.js.map → p-xY3TjBF5.js.map} +1 -1
- package/dist/docs/components.json +685 -56
- package/dist/lib/utils/anchored-popup.d.ts +5 -1
- package/dist/mcp-data/registry/agent-activity.json +1 -1
- package/dist/mcp-data/registry/agent-response.json +10 -5
- 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 +27 -8
- package/dist/mcp-data/registry/badge.json +1 -1
- package/dist/mcp-data/registry/bar-nav.json +1 -1
- package/dist/mcp-data/registry/bar-title.json +13 -8
- package/dist/mcp-data/registry/bar-workflow.json +368 -0
- package/dist/mcp-data/registry/button-filled.json +2 -2
- package/dist/mcp-data/registry/button-unfilled.json +2 -2
- package/dist/mcp-data/registry/card-data-viz-donut.json +1 -1
- package/dist/mcp-data/registry/card-setting.json +1 -1
- package/dist/mcp-data/registry/card-shell-data-viz.json +1 -1
- package/dist/mcp-data/registry/chart-bar.json +1 -1
- package/dist/mcp-data/registry/chart-donut.json +1 -1
- package/dist/mcp-data/registry/chart-legend.json +1 -1
- package/dist/mcp-data/registry/chart-line.json +1 -1
- package/dist/mcp-data/registry/checkbox.json +2 -2
- 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 +2 -2
- package/dist/mcp-data/registry/conversation-list-section.json +3 -3
- package/dist/mcp-data/registry/conversation-list.json +37 -10
- package/dist/mcp-data/registry/divider.json +1 -1
- package/dist/mcp-data/registry/empty-state.json +1 -1
- package/dist/mcp-data/registry/field.json +1 -1
- package/dist/mcp-data/registry/icon.json +2 -2
- package/dist/mcp-data/registry/input.json +1 -1
- package/dist/mcp-data/registry/loader.json +1 -1
- package/dist/mcp-data/registry/markdown.json +16 -11
- package/dist/mcp-data/registry/menu.json +10 -8
- 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 +4 -4
- package/dist/mcp-data/registry/message.json +1 -1
- package/dist/mcp-data/registry/modal.json +1 -1
- package/dist/mcp-data/registry/panel-nav.json +1 -1
- package/dist/mcp-data/registry/panel-sub-nav.json +1 -1
- package/dist/mcp-data/registry/panel-tool-header.json +1 -1
- package/dist/mcp-data/registry/panel-tool-search.json +2 -2
- package/dist/mcp-data/registry/panel-tools.json +1 -1
- package/dist/mcp-data/registry/radio.json +1 -1
- package/dist/mcp-data/registry/registry.json +320 -41
- package/dist/mcp-data/registry/scroll-overlay.json +183 -0
- package/dist/mcp-data/registry/select-multi.json +1 -1
- package/dist/mcp-data/registry/select.json +1 -1
- package/dist/mcp-data/registry/shell-app.json +1 -1
- package/dist/mcp-data/registry/shell-gradient-picker.json +1 -1
- package/dist/mcp-data/registry/shell-gradient-swatch.json +2 -2
- package/dist/mcp-data/registry/shell-page.json +15 -11
- package/dist/mcp-data/registry/skeleton.json +1 -1
- package/dist/mcp-data/registry/slider.json +2 -2
- package/dist/mcp-data/registry/swatch-picker.json +1 -1
- package/dist/mcp-data/registry/switch.json +2 -2
- package/dist/mcp-data/registry/tab-group.json +2 -2
- package/dist/mcp-data/registry/tag.json +1 -1
- package/dist/mcp-data/registry/text.json +1 -1
- package/dist/mcp-data/registry/toast.json +1 -1
- package/dist/mcp-data/registry/tooltip-data-viz.json +1 -1
- package/dist/mcp-data/registry/tooltip.json +1 -1
- package/dist/mcp-data/registry/typing-indicator.json +1 -1
- package/dist/react/components.d.ts +2 -0
- package/dist/react/components.js +2 -0
- package/dist/react/ds-bar-workflow.d.ts +14 -0
- package/dist/react/ds-bar-workflow.js +16 -0
- package/dist/react/ds-scroll-overlay.d.ts +12 -0
- package/dist/react/ds-scroll-overlay.js +12 -0
- package/dist/styles/prose.css +214 -0
- package/dist/types/components/Avatar/Avatar.d.ts +4 -1
- package/dist/types/components/BarTitle/BarTitle.d.ts +2 -0
- package/dist/types/components/BarWorkflow/BarWorkflow.d.ts +37 -0
- package/dist/types/components/BarWorkflow/bar-workflow-types.d.ts +12 -0
- package/dist/types/components/ConversationList/ConversationList.d.ts +12 -0
- package/dist/types/components/Menu/Menu.d.ts +1 -2
- package/dist/types/components/MessageScroller/MessageScroller.d.ts +1 -6
- package/dist/types/components/ScrollOverlay/ScrollOverlay.d.ts +28 -0
- package/dist/types/components/ShellPage/ShellPage.d.ts +5 -0
- package/dist/types/components.d.ts +231 -3
- package/dist/types/stories/isolated-overlay-docs.d.ts +13 -0
- package/dist/types/utils/anchored-popup.d.ts +5 -1
- package/dist/types/utils/scroll-overlay-controller.d.ts +35 -0
- package/package.json +6 -5
- package/dist/components/p-BUmDHPr3.js +0 -2
- package/dist/components/p-BZZwQfmN.js +0 -2
- package/dist/components/p-BZZwQfmN.js.map +0 -1
- package/dist/components/p-CUik7PCi.js +0 -2
- package/dist/components/p-CUik7PCi.js.map +0 -1
- package/dist/components/p-CwTVEAl2.js +0 -2
- package/dist/components/p-DABj3qTX.js +0 -2
- package/dist/components/p-DUHcJWTQ.js +0 -2
- package/dist/components/p-DuNZGFkV.js.map +0 -1
- package/dist/components/p-Dy_sZ-dI.js +0 -2
- package/dist/components/p-l6PmnW_P.js +0 -2
- package/dist/components/p-l6PmnW_P.js.map +0 -1
- package/dist/components/p-xFbUt9Tc.js +0 -2
- package/dist/components/p-xFbUt9Tc.js.map +0 -1
- /package/dist/components/{p-BYHKdFzV.js.map → p-B8CubPgQ.js.map} +0 -0
- /package/dist/components/{p-BH3es4p7.js.map → p-BRLDJmkh.js.map} +0 -0
- /package/dist/components/{p-Bs6SS34m.js.map → p-C0_8K4y7.js.map} +0 -0
- /package/dist/components/{p-BhKhX1er.js.map → p-CA3kLO7K.js.map} +0 -0
- /package/dist/components/{p-DfIch2Dk.js.map → p-CCHqsF_H.js.map} +0 -0
- /package/dist/components/{p-DVk0wxxX.js.map → p-CHkI3oIS.js.map} +0 -0
- /package/dist/components/{p-liMPkhUP.js.map → p-CNffejay.js.map} +0 -0
- /package/dist/components/{p-B3YvoGjS.js.map → p-Cxpl-rzP.js.map} +0 -0
- /package/dist/components/{p-BkwBtZs3.js.map → p-D6jK2Hyi.js.map} +0 -0
- /package/dist/components/{p-Cy04lXlc.js.map → p-DBi1bmOL.js.map} +0 -0
- /package/dist/components/{p-DxeHimqk.js.map → p-DOCKtrS4.js.map} +0 -0
- /package/dist/components/{p-6vj4kh70.js.map → p-DcGpdIlT.js.map} +0 -0
- /package/dist/components/{p-Cf2J9MEo.js.map → p-XgIQ3oI_.js.map} +0 -0
- /package/dist/components/{p-Cf-i-6aE.js.map → p-ky1msbJ8.js.map} +0 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "scroll-overlay",
|
|
4
|
+
"title": "ScrollOverlay",
|
|
5
|
+
"description": "Generic scroll owner for content that moves behind a persistent footer action or composer with an always-active alpha fade.",
|
|
6
|
+
"type": "registry:ui",
|
|
7
|
+
"meta": {
|
|
8
|
+
"library": "@ds-mo/ui",
|
|
9
|
+
"distribution": "npm",
|
|
10
|
+
"storybook": "https://zainadeel.github.io/compomo/?path=/story/scroll-overlay",
|
|
11
|
+
"source": "src/wc/components/ScrollOverlay/ScrollOverlay.tsx",
|
|
12
|
+
"intentStatus": "complete",
|
|
13
|
+
"intent": {
|
|
14
|
+
"audience": "general",
|
|
15
|
+
"status": "experimental",
|
|
16
|
+
"summary": "Generic scroll owner for content that moves behind a persistent footer action or composer with an always-active alpha fade.",
|
|
17
|
+
"useWhen": [
|
|
18
|
+
"A bounded region owns scrolling while footer actions remain overlaid and continuously visible.",
|
|
19
|
+
"The final content must clear a live-height footer while earlier content can move behind it."
|
|
20
|
+
],
|
|
21
|
+
"avoidWhen": [
|
|
22
|
+
"The footer belongs in normal document flow rather than overlaying content.",
|
|
23
|
+
"Another component already owns scrolling and cannot delegate its scrollport to this component."
|
|
24
|
+
],
|
|
25
|
+
"commonlyComposedWith": [
|
|
26
|
+
"component:ds-button-filled",
|
|
27
|
+
"component:ds-message-composer"
|
|
28
|
+
],
|
|
29
|
+
"accessibility": [
|
|
30
|
+
"Provide scrollLabel when the scrollport needs its own named, keyboard-focusable region.",
|
|
31
|
+
"Keep footer actions keyboard accessible and explicitly named; the fade is decorative and never intercepts pointer input."
|
|
32
|
+
],
|
|
33
|
+
"states": [
|
|
34
|
+
"The alpha mask remains active at every scroll position and moves in content coordinates so it stays pinned behind the footer without masking native scrollbars.",
|
|
35
|
+
"The component measures the complete overlay for end clearance, measures its visible child for fade depth, and begins the fade 8px before that visible content.",
|
|
36
|
+
"An md 32px footer action with 8px bottom inset therefore produces a 48px fade; variable-height composers produce a correspondingly taller measured fade."
|
|
37
|
+
],
|
|
38
|
+
"responsiveBehavior": [
|
|
39
|
+
"The scrollport and overlay fill the available width and height; the owner supplies responsive sizing and overlay insets."
|
|
40
|
+
],
|
|
41
|
+
"frameworkCaveats": {
|
|
42
|
+
"customElements": [
|
|
43
|
+
"Place scrollable content in the default slot and one footer wrapper in the overlay slot; use dsScroll only when the application needs position data."
|
|
44
|
+
],
|
|
45
|
+
"react": [
|
|
46
|
+
"Use DsScrollOverlay with ordinary children plus an element carrying slot=\"overlay\"."
|
|
47
|
+
],
|
|
48
|
+
"angular": [
|
|
49
|
+
"Import DsScrollOverlay and project the persistent footer wrapper with slot=\"overlay\"."
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"references": [
|
|
53
|
+
{
|
|
54
|
+
"label": "Storybook examples",
|
|
55
|
+
"path": "src/wc/components/ScrollOverlay/ScrollOverlay.stories.ts"
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
"api": {
|
|
60
|
+
"props": {
|
|
61
|
+
"scrollLabel": {
|
|
62
|
+
"type": "string | undefined",
|
|
63
|
+
"resolvedType": "string | undefined",
|
|
64
|
+
"attribute": "scroll-label",
|
|
65
|
+
"required": false,
|
|
66
|
+
"mutable": false,
|
|
67
|
+
"description": "Optional accessible name. When provided, the scrollport is a focusable region."
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"events": [
|
|
71
|
+
{
|
|
72
|
+
"name": "dsScroll",
|
|
73
|
+
"detail": "ScrollOverlayScrollDetail",
|
|
74
|
+
"bubbles": true,
|
|
75
|
+
"cancelable": true,
|
|
76
|
+
"composed": true,
|
|
77
|
+
"description": "Reports scroll position without exposing the internal scrollport element."
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"methods": [
|
|
81
|
+
{
|
|
82
|
+
"name": "refreshOverlay",
|
|
83
|
+
"signature": "refreshOverlay() => Promise<void>",
|
|
84
|
+
"description": "Re-measure footer geometry after an imperative slotted-content update."
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"name": "scrollToEnd",
|
|
88
|
+
"signature": "scrollToEnd() => Promise<void>",
|
|
89
|
+
"description": "Move the owned scrollport to its live end."
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "scrollToStart",
|
|
93
|
+
"signature": "scrollToStart() => Promise<void>",
|
|
94
|
+
"description": "Move the owned scrollport to its beginning."
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"slots": []
|
|
98
|
+
},
|
|
99
|
+
"props": {
|
|
100
|
+
"scrollLabel": {
|
|
101
|
+
"type": "string | undefined",
|
|
102
|
+
"resolvedType": "string | undefined",
|
|
103
|
+
"attribute": "scroll-label",
|
|
104
|
+
"required": false,
|
|
105
|
+
"mutable": false,
|
|
106
|
+
"description": "Optional accessible name. When provided, the scrollport is a focusable region."
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"events": [
|
|
110
|
+
{
|
|
111
|
+
"name": "dsScroll",
|
|
112
|
+
"detail": "ScrollOverlayScrollDetail",
|
|
113
|
+
"bubbles": true,
|
|
114
|
+
"cancelable": true,
|
|
115
|
+
"composed": true,
|
|
116
|
+
"description": "Reports scroll position without exposing the internal scrollport element."
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"methods": [
|
|
120
|
+
{
|
|
121
|
+
"name": "refreshOverlay",
|
|
122
|
+
"signature": "refreshOverlay() => Promise<void>",
|
|
123
|
+
"description": "Re-measure footer geometry after an imperative slotted-content update."
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"name": "scrollToEnd",
|
|
127
|
+
"signature": "scrollToEnd() => Promise<void>",
|
|
128
|
+
"description": "Move the owned scrollport to its live end."
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"name": "scrollToStart",
|
|
132
|
+
"signature": "scrollToStart() => Promise<void>",
|
|
133
|
+
"description": "Move the owned scrollport to its beginning."
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
"slots": [],
|
|
137
|
+
"exports": {
|
|
138
|
+
"customElement": "ds-scroll-overlay",
|
|
139
|
+
"react": "DsScrollOverlay",
|
|
140
|
+
"angular": "DsScrollOverlay"
|
|
141
|
+
},
|
|
142
|
+
"consumption": {
|
|
143
|
+
"install": "npm install @ds-mo/ui @ds-mo/tokens @ds-mo/icons",
|
|
144
|
+
"cssSetup": "import '@ds-mo/tokens';\nimport '@ds-mo/tokens/reset';\nimport '@ds-mo/tokens/globals';",
|
|
145
|
+
"customElements": {
|
|
146
|
+
"import": "import '@ds-mo/ui/dist/components/ds-scroll-overlay.js';",
|
|
147
|
+
"example": "<ds-scroll-overlay></ds-scroll-overlay>"
|
|
148
|
+
},
|
|
149
|
+
"react": {
|
|
150
|
+
"import": "import { DsScrollOverlay } from '@ds-mo/ui/react';",
|
|
151
|
+
"example": "<DsScrollOverlay />"
|
|
152
|
+
},
|
|
153
|
+
"angular": {
|
|
154
|
+
"import": "import { DsScrollOverlay } from '@ds-mo/ui/angular/ds-scroll-overlay';",
|
|
155
|
+
"example": "<ds-scroll-overlay></ds-scroll-overlay>"
|
|
156
|
+
},
|
|
157
|
+
"peerDependencies": {
|
|
158
|
+
"required": [
|
|
159
|
+
"@ds-mo/tokens ^3.1.1",
|
|
160
|
+
"@ds-mo/icons ^6.4.0"
|
|
161
|
+
],
|
|
162
|
+
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
"dependencies": [
|
|
167
|
+
"@ds-mo/ui",
|
|
168
|
+
"@ds-mo/tokens"
|
|
169
|
+
],
|
|
170
|
+
"registryDependencies": [],
|
|
171
|
+
"files": [
|
|
172
|
+
{
|
|
173
|
+
"path": "src/wc/components/ScrollOverlay/ScrollOverlay.css",
|
|
174
|
+
"content": ":host {\n display: block;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n box-sizing: border-box;\n}\n\n.scroll-overlay {\n position: relative;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.scroll-overlay__viewport {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n overflow: auto;\n overscroll-behavior: contain;\n box-sizing: border-box;\n}\n\n.scroll-overlay__viewport:focus-visible {\n outline: var(--dimension-stroke-width-025) solid var(--color-border-bold-brand);\n outline-offset: calc(-1 * var(--dimension-stroke-width-025));\n}\n\n.scroll-overlay__content {\n display: flex;\n flex-direction: column;\n min-height: 100%;\n padding-block-end: var(--ds-scroll-overlay-block-size, 0);\n box-sizing: border-box;\n}\n\n.scroll-overlay__body {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n flex: 1 0 auto;\n min-height: 0;\n}\n\n.scroll-overlay__overlay {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: var(--dimension-z-index-floating);\n}\n",
|
|
175
|
+
"type": "registry:ui"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"path": "src/wc/components/ScrollOverlay/ScrollOverlay.tsx",
|
|
179
|
+
"content": "import { Component, Element, Event, EventEmitter, h, Host, Method, Prop } from '@stencil/core';\nimport { ScrollOverlayController } from '../../utils/scroll-overlay-controller';\n\nexport interface ScrollOverlayScrollDetail {\n scrollTop: number;\n scrollHeight: number;\n clientHeight: number;\n}\n\n@Component({\n tag: 'ds-scroll-overlay',\n styleUrl: 'ScrollOverlay.css',\n styleUrls: ['../../utils/scroll-edge-fade.css'],\n scoped: true,\n})\nexport class ScrollOverlay {\n @Element() el!: HTMLElement;\n\n /** Optional accessible name. When provided, the scrollport is a focusable region. */\n @Prop() scrollLabel: string | undefined;\n\n /** Reports scroll position without exposing the internal scrollport element. */\n @Event() dsScroll!: EventEmitter<ScrollOverlayScrollDetail>;\n\n private viewport?: HTMLElement;\n private content?: HTMLElement;\n private overlay?: HTMLElement;\n private controller?: ScrollOverlayController;\n\n componentDidLoad(): void {\n if (!this.viewport || !this.content || !this.overlay) return;\n this.controller = new ScrollOverlayController({\n host: this.el,\n viewport: this.viewport,\n content: this.content,\n overlay: this.overlay,\n });\n this.controller.connect();\n }\n\n disconnectedCallback(): void {\n this.controller?.disconnect();\n }\n\n /** Move the owned scrollport to its beginning. */\n @Method()\n async scrollToStart(): Promise<void> {\n this.viewport?.scrollTo({ top: 0, behavior: 'auto' });\n this.controller?.sync();\n }\n\n /** Move the owned scrollport to its live end. */\n @Method()\n async scrollToEnd(): Promise<void> {\n this.viewport?.scrollTo({ top: this.viewport.scrollHeight, behavior: 'auto' });\n this.controller?.sync();\n }\n\n /** Re-measure footer geometry after an imperative slotted-content update. */\n @Method()\n async refreshOverlay(): Promise<void> {\n this.controller?.sync();\n }\n\n private handleScroll = (): void => {\n if (!this.viewport) return;\n this.controller?.sync();\n this.dsScroll.emit({\n scrollTop: this.viewport.scrollTop,\n scrollHeight: this.viewport.scrollHeight,\n clientHeight: this.viewport.clientHeight,\n });\n };\n\n render() {\n const labelled = Boolean(this.scrollLabel?.trim());\n return (\n <Host>\n <div class=\"scroll-overlay\">\n <div\n class=\"scroll-overlay__viewport\"\n ref={element => {\n this.viewport = element;\n }}\n role={labelled ? 'region' : undefined}\n aria-label={labelled ? this.scrollLabel : undefined}\n tabIndex={labelled ? 0 : undefined}\n onScroll={this.handleScroll}\n >\n <div\n class=\"scroll-overlay__content scroll-edge-fade--block-window\"\n ref={element => {\n this.content = element;\n }}\n >\n <div class=\"scroll-overlay__body\">\n <slot />\n </div>\n </div>\n </div>\n <div\n class=\"scroll-overlay__overlay\"\n ref={element => {\n this.overlay = element;\n }}\n >\n <slot name=\"overlay\" />\n </div>\n </div>\n </Host>\n );\n }\n}\n",
|
|
180
|
+
"type": "registry:ui"
|
|
181
|
+
}
|
|
182
|
+
]
|
|
183
|
+
}
|
|
@@ -184,7 +184,7 @@
|
|
|
184
184
|
"peerDependencies": {
|
|
185
185
|
"required": [
|
|
186
186
|
"@ds-mo/tokens ^3.1.1",
|
|
187
|
-
"@ds-mo/icons ^6.
|
|
187
|
+
"@ds-mo/icons ^6.4.0"
|
|
188
188
|
],
|
|
189
189
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
190
190
|
}
|
|
@@ -198,7 +198,7 @@
|
|
|
198
198
|
"files": [
|
|
199
199
|
{
|
|
200
200
|
"path": "src/wc/components/ShellGradientSwatch/ShellGradientSwatch.css",
|
|
201
|
-
"content": "@import '../../utils/focus-ring.css';\n@import '../../utils/control-inactive.css';\n\n/**\n * Swatch — 24×24 orb (size-300). Spacing lives on the picker row.\n *\n * Layer stack (bottom → top):\n * Default: fill → border → interaction (hover/press)\n * Selected: fill → border → interaction → halo → stroke (brand)\n */\n\n:host {\n box-sizing: border-box;\n display: inline-flex;\n flex: 0 0 auto;\n width: var(--dimension-size-300);\n height: var(--dimension-size-300);\n --_swatch-inner-inset: calc(\n var(--dimension-stroke-width-025) + var(--dimension-space-025)\n );\n --_swatch-ring-bg: var(--color-background-primary);\n --_swatch-select-motion: var(--effect-motion-short-3);\n}\n\n.shell-gradient-swatch {\n position: relative;\n box-sizing: border-box;\n width: var(--dimension-size-300);\n height: var(--dimension-size-300);\n padding: 0;\n border: none;\n border-radius: var(--dimension-radius-half);\n background: transparent;\n cursor: pointer;\n flex-shrink: 0;\n isolation: isolate;\n}\n\n.shell-gradient-swatch__fill,\n.shell-gradient-swatch__border,\n.shell-gradient-swatch__interaction,\n.shell-gradient-swatch__halo,\n.shell-gradient-swatch__stroke {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n border-radius: inherit;\n pointer-events: none;\n}\n\n/* 1 — fill */\n.shell-gradient-swatch__fill {\n z-index: 1;\n background-color: var(--color-background-secondary);\n background-image: var(--_swatch-gradient-image);\n background-repeat: no-repeat;\n background-size: cover;\n background-position: 0 0;\n transition:\n top var(--_swatch-select-motion),\n right var(--_swatch-select-motion),\n bottom var(--_swatch-select-motion),\n left var(--_swatch-select-motion);\n}\n\n.shell-gradient-swatch--none .shell-gradient-swatch__fill {\n background-image: none;\n}\n\n.shell-gradient-swatch:not(.shell-gradient-swatch--none) .shell-gradient-swatch__fill {\n opacity: var(--ds-shell-gradient-opacity, 0.1);\n}\n\n/* 2 — secondary border (matches ds-interaction-fill--bordered) */\n.shell-gradient-swatch__border {\n z-index: 2;\n box-shadow: inset 0 0 0 var(--dimension-stroke-width-012) var(--color-border-secondary);\n transition:\n top var(--_swatch-select-motion),\n right var(--_swatch-select-motion),\n bottom var(--_swatch-select-motion),\n left var(--_swatch-select-motion);\n}\n\n/* 3 — hover / press (over border, under selected chrome) */\n.shell-gradient-swatch__interaction {\n z-index: 3;\n background: transparent;\n transition:\n top var(--_swatch-select-motion),\n right var(--_swatch-select-motion),\n bottom var(--_swatch-select-motion),\n left var(--_swatch-select-motion),\n background-color 0s;\n}\n\n.shell-gradient-swatch:hover:not(:disabled) .shell-gradient-swatch__interaction {\n background: var(--color-interaction-hover);\n}\n\n.shell-gradient-swatch:active:not(:disabled) .shell-gradient-swatch__interaction {\n background: var(--color-interaction-pressed);\n}\n\n/* 4 — halo gap (selected only) */\n.shell-gradient-swatch__halo {\n z-index: 4;\n opacity: 0;\n transform: scale(1.2);\n transform-origin: center;\n box-shadow: inset 0 0 0 var(--_swatch-inner-inset) var(--_swatch-ring-bg);\n transition:\n opacity var(--_swatch-select-motion),\n transform var(--_swatch-select-motion);\n}\n\n/* 5 — brand stroke (selected only) */\n.shell-gradient-swatch__stroke {\n z-index: 5;\n opacity: 0;\n transform: scale(1.2);\n transform-origin: center;\n box-shadow: inset 0 0 0 var(--dimension-stroke-width-025) var(--color-border-bold-brand);\n transition:\n opacity var(--_swatch-select-motion),\n transform var(--_swatch-select-motion);\n}\n\n.shell-gradient-swatch--selected .shell-gradient-swatch__fill,\n.shell-gradient-swatch--selected .shell-gradient-swatch__border,\n.shell-gradient-swatch--selected .shell-gradient-swatch__interaction {\n top: var(--_swatch-inner-inset);\n right: var(--_swatch-inner-inset);\n bottom: var(--_swatch-inner-inset);\n left: var(--_swatch-inner-inset);\n}\n\n.shell-gradient-swatch--selected .shell-gradient-swatch__halo,\n.shell-gradient-swatch--selected .shell-gradient-swatch__stroke {\n opacity: 1;\n transform: scale(1);\n}\n\n/* Inactive: `.ds-control-inactive` (
|
|
201
|
+
"content": "@import '../../utils/focus-ring.css';\n@import '../../utils/control-inactive.css';\n\n/**\n * Swatch — 24×24 orb (size-300). Spacing lives on the picker row.\n *\n * Layer stack (bottom → top):\n * Default: fill → border → interaction (hover/press)\n * Selected: fill → border → interaction → halo → stroke (brand)\n */\n\n:host {\n box-sizing: border-box;\n display: inline-flex;\n flex: 0 0 auto;\n width: var(--dimension-size-300);\n height: var(--dimension-size-300);\n --_swatch-inner-inset: calc(\n var(--dimension-stroke-width-025) + var(--dimension-space-025)\n );\n --_swatch-ring-bg: var(--color-background-primary);\n --_swatch-select-motion: var(--effect-motion-short-3);\n}\n\n.shell-gradient-swatch {\n position: relative;\n box-sizing: border-box;\n width: var(--dimension-size-300);\n height: var(--dimension-size-300);\n padding: 0;\n border: none;\n border-radius: var(--dimension-radius-half);\n background: transparent;\n cursor: pointer;\n flex-shrink: 0;\n isolation: isolate;\n}\n\n.shell-gradient-swatch__fill,\n.shell-gradient-swatch__border,\n.shell-gradient-swatch__interaction,\n.shell-gradient-swatch__halo,\n.shell-gradient-swatch__stroke {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n border-radius: inherit;\n pointer-events: none;\n}\n\n/* 1 — fill */\n.shell-gradient-swatch__fill {\n z-index: 1;\n background-color: var(--color-background-secondary);\n background-image: var(--_swatch-gradient-image);\n background-repeat: no-repeat;\n background-size: cover;\n background-position: 0 0;\n transition:\n top var(--_swatch-select-motion),\n right var(--_swatch-select-motion),\n bottom var(--_swatch-select-motion),\n left var(--_swatch-select-motion);\n}\n\n.shell-gradient-swatch--none .shell-gradient-swatch__fill {\n background-image: none;\n}\n\n.shell-gradient-swatch:not(.shell-gradient-swatch--none) .shell-gradient-swatch__fill {\n opacity: var(--ds-shell-gradient-opacity, 0.1);\n}\n\n/* 2 — secondary border (matches ds-interaction-fill--bordered) */\n.shell-gradient-swatch__border {\n z-index: 2;\n box-shadow: inset 0 0 0 var(--dimension-stroke-width-012) var(--color-border-secondary);\n transition:\n top var(--_swatch-select-motion),\n right var(--_swatch-select-motion),\n bottom var(--_swatch-select-motion),\n left var(--_swatch-select-motion);\n}\n\n/* 3 — hover / press (over border, under selected chrome) */\n.shell-gradient-swatch__interaction {\n z-index: 3;\n background: transparent;\n transition:\n top var(--_swatch-select-motion),\n right var(--_swatch-select-motion),\n bottom var(--_swatch-select-motion),\n left var(--_swatch-select-motion),\n background-color 0s;\n}\n\n.shell-gradient-swatch:hover:not(:disabled) .shell-gradient-swatch__interaction {\n background: var(--color-interaction-hover);\n}\n\n.shell-gradient-swatch:active:not(:disabled) .shell-gradient-swatch__interaction {\n background: var(--color-interaction-pressed);\n}\n\n/* 4 — halo gap (selected only) */\n.shell-gradient-swatch__halo {\n z-index: 4;\n opacity: 0;\n transform: scale(1.2);\n transform-origin: center;\n box-shadow: inset 0 0 0 var(--_swatch-inner-inset) var(--_swatch-ring-bg);\n transition:\n opacity var(--_swatch-select-motion),\n transform var(--_swatch-select-motion);\n}\n\n/* 5 — brand stroke (selected only) */\n.shell-gradient-swatch__stroke {\n z-index: 5;\n opacity: 0;\n transform: scale(1.2);\n transform-origin: center;\n box-shadow: inset 0 0 0 var(--dimension-stroke-width-025) var(--color-border-bold-brand);\n transition:\n opacity var(--_swatch-select-motion),\n transform var(--_swatch-select-motion);\n}\n\n.shell-gradient-swatch--selected .shell-gradient-swatch__fill,\n.shell-gradient-swatch--selected .shell-gradient-swatch__border,\n.shell-gradient-swatch--selected .shell-gradient-swatch__interaction {\n top: var(--_swatch-inner-inset);\n right: var(--_swatch-inner-inset);\n bottom: var(--_swatch-inner-inset);\n left: var(--_swatch-inner-inset);\n}\n\n.shell-gradient-swatch--selected .shell-gradient-swatch__halo,\n.shell-gradient-swatch--selected .shell-gradient-swatch__stroke {\n opacity: 1;\n transform: scale(1);\n}\n\n/* Inactive: `.ds-control-inactive` (50% opacity). */\n\n@media (prefers-reduced-motion: reduce) {\n .shell-gradient-swatch__fill,\n .shell-gradient-swatch__border,\n .shell-gradient-swatch__interaction,\n .shell-gradient-swatch__halo,\n .shell-gradient-swatch__stroke {\n transition: none;\n }\n}\n",
|
|
202
202
|
"type": "registry:ui"
|
|
203
203
|
},
|
|
204
204
|
{
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
3
|
"name": "shell-page",
|
|
4
4
|
"title": "ShellPage",
|
|
5
|
-
"description": "The standard routed-page boundary inside ShellApp, owning sticky BarTitle placement, container-aware
|
|
5
|
+
"description": "The standard routed-page boundary inside ShellApp, owning sticky BarTitle or BarWorkflow placement, container-aware BarTitle variants, stable scroll compaction, and optional page-content inset without creating a nested scroll container.",
|
|
6
6
|
"type": "registry:ui",
|
|
7
7
|
"meta": {
|
|
8
8
|
"library": "@ds-mo/ui",
|
|
@@ -13,10 +13,11 @@
|
|
|
13
13
|
"intent": {
|
|
14
14
|
"audience": "general",
|
|
15
15
|
"status": "stable",
|
|
16
|
-
"summary": "The standard routed-page boundary inside ShellApp, owning sticky BarTitle placement, container-aware
|
|
16
|
+
"summary": "The standard routed-page boundary inside ShellApp, owning sticky BarTitle or BarWorkflow placement, container-aware BarTitle variants, stable scroll compaction, and optional page-content inset without creating a nested scroll container.",
|
|
17
17
|
"useWhen": [
|
|
18
18
|
"Rendering a standard routed page inside ShellApp's default content region.",
|
|
19
19
|
"BarTitle should expand at a roomy page top, compact after scroll, or use constrained action layout when the page column narrows.",
|
|
20
|
+
"BarWorkflow needs sticky page-level placement while remaining compact.",
|
|
20
21
|
"Pages need consistent content gutters with an explicit full-bleed option."
|
|
21
22
|
],
|
|
22
23
|
"avoidWhen": [
|
|
@@ -39,6 +40,7 @@
|
|
|
39
40
|
"commonlyComposedWith": [
|
|
40
41
|
"component:ds-shell-app",
|
|
41
42
|
"component:ds-bar-title",
|
|
43
|
+
"component:ds-bar-workflow",
|
|
42
44
|
"component:ds-tab-group"
|
|
43
45
|
],
|
|
44
46
|
"patterns": [
|
|
@@ -46,7 +48,7 @@
|
|
|
46
48
|
],
|
|
47
49
|
"accessibility": [
|
|
48
50
|
"ShellPage exposes the routed page as the main landmark; render exactly one active ShellPage inside ShellApp.",
|
|
49
|
-
"Provide exactly one BarTitle through the header slot so the page has one h1.",
|
|
51
|
+
"Provide exactly one BarTitle or BarWorkflow through the header slot so the page has one h1.",
|
|
50
52
|
"Keep loading, empty, validation, error, progress, success, and failure communication in the default product-content slot.",
|
|
51
53
|
"Responsive variant changes preserve the same heading, controls, accessible names, and keyboard focus targets."
|
|
52
54
|
],
|
|
@@ -54,26 +56,28 @@
|
|
|
54
56
|
"headerPresentation=auto selects expanded, compact, or constrained from ShellPage's own inline capacity and scroll position.",
|
|
55
57
|
"expanded, compact, and constrained are explicit overrides for exceptional layouts and deterministic examples.",
|
|
56
58
|
"contentInset=default supplies standard page gutters; none permits maps, canvases, and other full-bleed content.",
|
|
57
|
-
"The required header slot accepts one BarTitle. The default slot owns router output and all page product content."
|
|
59
|
+
"The required header slot accepts one BarTitle or BarWorkflow. The default slot owns router output and all page product content."
|
|
58
60
|
],
|
|
59
61
|
"responsiveBehavior": [
|
|
60
62
|
"ShellPage observes its own rendered width instead of viewport media queries or ShellApp desktop/tablet modes.",
|
|
61
63
|
"Roomy pages expand at the top and compact after scroll; medium-capacity pages start compact; narrow pages use the constrained header variant.",
|
|
64
|
+
"A newly navigated header resolves current page capacity before it is revealed, so persistent tool or navigation chrome cannot flash the expanded presentation first.",
|
|
62
65
|
"Token-based capacity bands use hysteresis so opening tools or resizing navigation cannot oscillate near a boundary.",
|
|
63
66
|
"Scroll compaction preserves the expanded page flow offset so content never jumps beneath the sticky header.",
|
|
64
|
-
"ShellPage relies on ShellApp's content scroller and never introduces nested scrolling."
|
|
67
|
+
"ShellPage relies on ShellApp's content scroller and never introduces nested scrolling.",
|
|
68
|
+
"BarWorkflow remains compact and is not assigned BarTitle's capacity or scroll variants."
|
|
65
69
|
],
|
|
66
70
|
"frameworkCaveats": {
|
|
67
71
|
"customElements": [
|
|
68
|
-
"Import ShellPage
|
|
72
|
+
"Import ShellPage with BarTitle or BarWorkflow, place one header in slot=header, and render route content as default children.",
|
|
69
73
|
"Do not set BarTitle.variant while ShellPage owns headerPresentation."
|
|
70
74
|
],
|
|
71
75
|
"react": [
|
|
72
|
-
"Render DsBarTitle with slot=header inside DsShellPage and keep routed content as the remaining children.",
|
|
76
|
+
"Render DsBarTitle or DsBarWorkflow with slot=header inside DsShellPage and keep routed content as the remaining children.",
|
|
73
77
|
"Use contentInset none only for deliberately full-bleed page products."
|
|
74
78
|
],
|
|
75
79
|
"angular": [
|
|
76
|
-
"Import the generated standalone DsShellPage
|
|
80
|
+
"Import the generated standalone DsShellPage adapter with DsBarTitle or DsBarWorkflow, preserve slot=header, and place router-outlet in the ShellPage default slot.",
|
|
77
81
|
"Do not add another overflow auto wrapper around the routed page."
|
|
78
82
|
]
|
|
79
83
|
},
|
|
@@ -163,7 +167,7 @@
|
|
|
163
167
|
"peerDependencies": {
|
|
164
168
|
"required": [
|
|
165
169
|
"@ds-mo/tokens ^3.1.1",
|
|
166
|
-
"@ds-mo/icons ^6.
|
|
170
|
+
"@ds-mo/icons ^6.4.0"
|
|
167
171
|
],
|
|
168
172
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
169
173
|
}
|
|
@@ -177,12 +181,12 @@
|
|
|
177
181
|
"files": [
|
|
178
182
|
{
|
|
179
183
|
"path": "src/wc/components/ShellPage/ShellPage.css",
|
|
180
|
-
"content": ":host {\n display: block;\n position: relative;\n min-width: 0;\n min-height: 100%;\n box-sizing: border-box;\n background: var(--color-background-primary);\n}\n\n.shell-page__scroll-sentinel {\n position: absolute;\n inset-block-start: 0;\n inset-inline-start: 0;\n width: var(--dimension-stroke-width-012);\n height: var(--dimension-stroke-width-012);\n pointer-events: none;\n}\n\n.shell-page__sticky-header {\n position: sticky;\n inset-block-start: 0;\n z-index: var(--dimension-z-index-raised);\n min-width: 0;\n background: var(--color-background-primary);\n overflow: visible;\n overflow-anchor: none;\n}\n\n.shell-page__sticky-header ::slotted(ds-bar-title) {\n display: block;\n min-width: 0;\n}\n\n.shell-page__flow-spacer {\n height: var(--ds-shell-page-flow-spacer, 0);\n background: var(--color-background-primary);\n}\n\n.shell-page__content {\n min-width: 0;\n box-sizing: border-box;\n background: var(--color-background-primary);\n}\n\n:host(.shell-page-host--inset-default) .shell-page__content {\n padding: var(--dimension-space-400) var(--dimension-space-400) var(--dimension-space-800);\n}\n\n:host(.shell-page-host--inset-none) .shell-page__content {\n padding: 0;\n}\n",
|
|
184
|
+
"content": ":host {\n display: block;\n position: relative;\n min-width: 0;\n min-height: 100%;\n box-sizing: border-box;\n background: var(--color-background-primary);\n}\n\n.shell-page__scroll-sentinel {\n position: absolute;\n inset-block-start: 0;\n inset-inline-start: 0;\n width: var(--dimension-stroke-width-012);\n height: var(--dimension-stroke-width-012);\n pointer-events: none;\n}\n\n.shell-page__sticky-header {\n position: sticky;\n inset-block-start: 0;\n z-index: var(--dimension-z-index-raised);\n min-width: 0;\n background: var(--color-background-primary);\n overflow: visible;\n overflow-anchor: none;\n}\n\n.shell-page__sticky-header ::slotted(ds-bar-title),\n.shell-page__sticky-header ::slotted(ds-bar-workflow) {\n display: block;\n min-width: 0;\n}\n\n.shell-page__flow-spacer {\n height: var(--ds-shell-page-flow-spacer, 0);\n background: var(--color-background-primary);\n}\n\n.shell-page__content {\n min-width: 0;\n box-sizing: border-box;\n background: var(--color-background-primary);\n}\n\n:host(.shell-page-host--inset-default) .shell-page__content {\n padding: var(--dimension-space-400) var(--dimension-space-400) var(--dimension-space-800);\n}\n\n:host(.shell-page-host--inset-none) .shell-page__content {\n padding: 0;\n}\n",
|
|
181
185
|
"type": "registry:ui"
|
|
182
186
|
},
|
|
183
187
|
{
|
|
184
188
|
"path": "src/wc/components/ShellPage/ShellPage.tsx",
|
|
185
|
-
"content": "import { Component, Element, h, Host, Prop, State } from '@stencil/core';\nimport { createRafCoalescer } from '../../shell/chrome-transition';\nimport { resolveCssLengthPx } from '../../utils/resolve-css-length-px';\nimport type { BarTitleVariant } from '../BarTitle/bar-title-types';\nimport { resolveShellPageCapacity, resolveShellPageHeaderVariant } from './shell-page-responsive';\nimport type {\n ShellPageCapacity,\n ShellPageContentInset,\n ShellPageHeaderPresentation,\n} from './shell-page-types';\n\ntype BarTitleElement = HTMLElement & { variant: BarTitleVariant };\n\n@Component({\n tag: 'ds-shell-page',\n styleUrl: 'ShellPage.css',\n scoped: true,\n})\nexport class ShellPage {\n @Element() el!: HTMLElement;\n\n /** Automatic container/scroll behavior, or an explicit header variant override. */\n @Prop() headerPresentation: ShellPageHeaderPresentation = 'auto';\n\n /** Standard page gutters, or no inset for full-bleed page content. */\n @Prop() contentInset: ShellPageContentInset = 'default';\n\n @State() private capacity: ShellPageCapacity | null = null;\n @State() private pageTopVisible = true;\n\n private sentinelEl: HTMLElement | null = null;\n private spacerEl: HTMLElement | null = null;\n private headerEl: BarTitleElement | null = null;\n private expandedHeaderHeight = 0;\n private resizeObserver: ResizeObserver | null = null;\n private headerResizeObserver: ResizeObserver | null = null;\n private scrollRoot: HTMLElement | Window | null = null;\n private readonly layoutCoalescer = createRafCoalescer(() => this.syncCapacity());\n\n componentDidLoad() {\n this.observeHeader(this.findHeader());\n this.connectObservers();\n this.connectScrollRoot();\n this.layoutCoalescer.schedule();\n }\n\n componentDidRender() {\n this.syncHeaderVariant();\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.headerResizeObserver?.disconnect();\n this.headerResizeObserver = null;\n this.scrollRoot?.removeEventListener('scroll', this.handleScroll);\n this.scrollRoot = null;\n this.layoutCoalescer.cancel();\n }\n\n private get effectiveVariant(): BarTitleVariant {\n return resolveShellPageHeaderVariant(\n this.headerPresentation,\n this.capacity ?? 'roomy',\n this.pageTopVisible\n );\n }\n\n private get isScrollCompacted(): boolean {\n return this.headerPresentation === 'auto' && this.capacity === 'roomy' && !this.pageTopVisible;\n }\n\n private connectObservers() {\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this.layoutCoalescer.schedule());\n this.resizeObserver.observe(this.el);\n }\n }\n\n private composedParent(element: Element): Element | null {\n return (element as HTMLElement).assignedSlot?.parentElement ?? element.parentElement;\n }\n\n private findScrollRoot(): HTMLElement | Window {\n let ancestor = this.composedParent(this.el);\n while (ancestor && ancestor !== document.documentElement) {\n const overflow = getComputedStyle(ancestor).overflowY;\n if (overflow === 'auto' || overflow === 'scroll') return ancestor as HTMLElement;\n ancestor = this.composedParent(ancestor);\n }\n return window;\n }\n\n private connectScrollRoot() {\n this.scrollRoot?.removeEventListener('scroll', this.handleScroll);\n this.scrollRoot = this.findScrollRoot();\n this.scrollRoot.addEventListener('scroll', this.handleScroll, { passive: true });\n this.handleScroll();\n }\n\n private handleScroll = () => {\n if (!this.sentinelEl || !this.scrollRoot) return;\n const rootTop =\n this.scrollRoot === window ? 0 : (this.scrollRoot as HTMLElement).getBoundingClientRect().top;\n this.pageTopVisible = this.sentinelEl.getBoundingClientRect().top >= rootTop;\n };\n\n private findHeader(): BarTitleElement | null {\n return this.el.querySelector<BarTitleElement>('ds-bar-title');\n }\n\n private syncCapacity() {\n const inlineSize = this.el.getBoundingClientRect().width;\n if (inlineSize <= 0) return;\n\n const compactAt = resolveCssLengthPx('--dimension-panel-width-2xl', 0);\n const constrainedAt = resolveCssLengthPx('--dimension-panel-width-lg', 0);\n const hysteresis = resolveCssLengthPx('--dimension-space-100', 0);\n if (compactAt <= 0 || constrainedAt <= 0) return;\n\n const next = resolveShellPageCapacity({\n inlineSize,\n compactAt,\n constrainedAt,\n hysteresis,\n previous: this.capacity,\n });\n if (next !== this.capacity) this.capacity = next;\n else this.syncHeaderVariant();\n }\n\n private get compactHeaderHeight(): number {\n return resolveCssLengthPx('--dimension-size-600', 0);\n }\n\n private setSpacerHeight(height: number) {\n if (!this.spacerEl) return;\n this.spacerEl.style.setProperty('--ds-shell-page-flow-spacer', `${Math.max(0, height)}px`);\n }\n\n private syncHeaderVariant() {\n const header = this.headerEl;\n if (!header) return;\n\n const next = this.effectiveVariant;\n if (header.variant === 'expanded') {\n this.expandedHeaderHeight = header.getBoundingClientRect().height;\n }\n\n this.setSpacerHeight(\n this.isScrollCompacted ? this.expandedHeaderHeight - this.compactHeaderHeight : 0\n );\n\n if (header.variant !== next) header.variant = next;\n }\n\n private observeHeader(header: BarTitleElement | null) {\n this.headerResizeObserver?.disconnect();\n this.headerResizeObserver = null;\n this.headerEl = header;\n this.expandedHeaderHeight = 0;\n this.setSpacerHeight(0);\n\n if (!header) return;\n if (typeof ResizeObserver !== 'undefined') {\n this.headerResizeObserver = new ResizeObserver(() => {\n if (header.variant === 'expanded') {\n this.expandedHeaderHeight = header.getBoundingClientRect().height;\n }\n });\n this.headerResizeObserver.observe(header);\n }\n this.syncHeaderVariant();\n }\n\n private handleHeaderSlotChange = (event: Event) => {\n const slot = event.target as HTMLSlotElement;\n const header = slot\n .assignedElements({ flatten: true })\n .find(element => element.tagName.toLowerCase() === 'ds-bar-title');\n this.observeHeader((header as BarTitleElement | undefined) ?? null);\n };\n\n render() {\n return (\n <Host\n role=\"main\"\n class={{\n 'shell-page-host--inset-default': this.contentInset === 'default',\n 'shell-page-host--inset-none': this.contentInset === 'none',\n [`shell-page-host--header-${this.effectiveVariant}`]: true,\n }}\n >\n <div\n ref={el => {\n this.sentinelEl = el ?? null;\n }}\n class=\"shell-page__scroll-sentinel\"\n aria-hidden=\"true\"\n />\n <div class=\"shell-page__sticky-header\">\n <slot name=\"header\" onSlotchange={this.handleHeaderSlotChange} />\n </div>\n <div\n ref={el => {\n this.spacerEl = el ?? null;\n }}\n class=\"shell-page__flow-spacer\"\n aria-hidden=\"true\"\n />\n <div class=\"shell-page__content\">\n <slot />\n </div>\n </Host>\n );\n }\n}\n",
|
|
189
|
+
"content": "import { Component, Element, h, Host, Prop, State } from '@stencil/core';\nimport { createRafCoalescer } from '../../shell/chrome-transition';\nimport { resolveCssLengthPx } from '../../utils/resolve-css-length-px';\nimport type { BarTitleVariant } from '../BarTitle/bar-title-types';\nimport { resolveShellPageCapacity, resolveShellPageHeaderVariant } from './shell-page-responsive';\nimport type {\n ShellPageCapacity,\n ShellPageContentInset,\n ShellPageHeaderPresentation,\n} from './shell-page-types';\n\ntype BarTitleElement = HTMLElement & { variant: BarTitleVariant };\n\n@Component({\n tag: 'ds-shell-page',\n styleUrl: 'ShellPage.css',\n scoped: true,\n})\nexport class ShellPage {\n private static readonly MAX_HEADER_REVEAL_FRAMES = 12;\n\n @Element() el!: HTMLElement;\n\n /** Automatic container/scroll behavior, or an explicit header variant override. */\n @Prop() headerPresentation: ShellPageHeaderPresentation = 'auto';\n\n /** Standard page gutters, or no inset for full-bleed page content. */\n @Prop() contentInset: ShellPageContentInset = 'default';\n\n @State() private capacity: ShellPageCapacity | null = null;\n @State() private pageTopVisible = true;\n\n private sentinelEl: HTMLElement | null = null;\n private spacerEl: HTMLElement | null = null;\n private headerEl: BarTitleElement | null = null;\n private expandedHeaderHeight = 0;\n private resizeObserver: ResizeObserver | null = null;\n private headerResizeObserver: ResizeObserver | null = null;\n private headerRevealFrame: number | null = null;\n private scrollRoot: HTMLElement | Window | null = null;\n private readonly layoutCoalescer = createRafCoalescer(() => this.syncCapacity());\n\n componentDidLoad() {\n // Resolve the already-laid-out page width before adopting a slotted header.\n // Waiting for the first ResizeObserver/RAF lets BarTitle paint its default\n // expanded variant for one frame when persistent shell chrome narrows a\n // newly navigated page.\n this.syncCapacity();\n this.observeHeader(this.findHeader());\n this.connectObservers();\n this.connectScrollRoot();\n this.layoutCoalescer.schedule();\n }\n\n componentDidRender() {\n this.syncHeaderVariant();\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.headerResizeObserver?.disconnect();\n this.headerResizeObserver = null;\n this.cancelHeaderReveal();\n this.scrollRoot?.removeEventListener('scroll', this.handleScroll);\n this.scrollRoot = null;\n this.layoutCoalescer.cancel();\n }\n\n private get effectiveVariant(): BarTitleVariant {\n return resolveShellPageHeaderVariant(\n this.headerPresentation,\n this.capacity ?? 'roomy',\n this.pageTopVisible\n );\n }\n\n private get isScrollCompacted(): boolean {\n return this.headerPresentation === 'auto' && this.capacity === 'roomy' && !this.pageTopVisible;\n }\n\n private connectObservers() {\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this.layoutCoalescer.schedule());\n this.resizeObserver.observe(this.el);\n }\n }\n\n private composedParent(element: Element): Element | null {\n return (element as HTMLElement).assignedSlot?.parentElement ?? element.parentElement;\n }\n\n private findScrollRoot(): HTMLElement | Window {\n let ancestor = this.composedParent(this.el);\n while (ancestor && ancestor !== document.documentElement) {\n const overflow = getComputedStyle(ancestor).overflowY;\n if (overflow === 'auto' || overflow === 'scroll') return ancestor as HTMLElement;\n ancestor = this.composedParent(ancestor);\n }\n return window;\n }\n\n private connectScrollRoot() {\n this.scrollRoot?.removeEventListener('scroll', this.handleScroll);\n this.scrollRoot = this.findScrollRoot();\n this.scrollRoot.addEventListener('scroll', this.handleScroll, { passive: true });\n this.handleScroll();\n }\n\n private handleScroll = () => {\n if (!this.sentinelEl || !this.scrollRoot) return;\n const rootTop =\n this.scrollRoot === window ? 0 : (this.scrollRoot as HTMLElement).getBoundingClientRect().top;\n this.pageTopVisible = this.sentinelEl.getBoundingClientRect().top >= rootTop;\n };\n\n private findHeader(): BarTitleElement | null {\n return this.el.querySelector<BarTitleElement>('ds-bar-title');\n }\n\n private syncCapacity() {\n const inlineSize = this.el.getBoundingClientRect().width;\n if (inlineSize <= 0) return;\n\n const compactAt = resolveCssLengthPx('--dimension-panel-width-2xl', 0);\n const constrainedAt = resolveCssLengthPx('--dimension-panel-width-lg', 0);\n const hysteresis = resolveCssLengthPx('--dimension-space-100', 0);\n if (compactAt <= 0 || constrainedAt <= 0) return;\n\n const next = resolveShellPageCapacity({\n inlineSize,\n compactAt,\n constrainedAt,\n hysteresis,\n previous: this.capacity,\n });\n if (next !== this.capacity) this.capacity = next;\n else this.syncHeaderVariant();\n }\n\n private get compactHeaderHeight(): number {\n return resolveCssLengthPx('--dimension-size-600', 0);\n }\n\n private setSpacerHeight(height: number) {\n if (!this.spacerEl) return;\n this.spacerEl.style.setProperty('--ds-shell-page-flow-spacer', `${Math.max(0, height)}px`);\n }\n\n private variantClass(variant: BarTitleVariant): string {\n return `bar-title-host--${variant}`;\n }\n\n private cancelHeaderReveal() {\n if (this.headerRevealFrame !== null) cancelAnimationFrame(this.headerRevealFrame);\n this.headerRevealFrame = null;\n this.headerEl?.removeAttribute('data-shell-page-syncing');\n }\n\n private revealHeaderWhenSynced(header: BarTitleElement, variant: BarTitleVariant) {\n // Stencil re-renders within a frame or two of a prop change, but this cap\n // guarantees the header can never stay hidden indefinitely if that\n // assumption ever breaks.\n let framesRemaining = ShellPage.MAX_HEADER_REVEAL_FRAMES;\n const reveal = () => {\n if (this.headerEl !== header) {\n header.removeAttribute('data-shell-page-syncing');\n return;\n }\n framesRemaining -= 1;\n if (framesRemaining <= 0 || header.classList.contains(this.variantClass(variant))) {\n header.removeAttribute('data-shell-page-syncing');\n this.headerRevealFrame = null;\n return;\n }\n this.headerRevealFrame = requestAnimationFrame(reveal);\n };\n this.headerRevealFrame = requestAnimationFrame(reveal);\n }\n\n private syncHeaderVariant(concealUntilSynced = false) {\n const header = this.headerEl;\n if (!header) return;\n\n const next = this.effectiveVariant;\n if (header.variant === 'expanded') {\n this.expandedHeaderHeight = header.getBoundingClientRect().height;\n }\n\n this.setSpacerHeight(\n this.isScrollCompacted ? this.expandedHeaderHeight - this.compactHeaderHeight : 0\n );\n\n const renderedVariantIsStale = !header.classList.contains(this.variantClass(next));\n if (concealUntilSynced && renderedVariantIsStale) {\n header.setAttribute('data-shell-page-syncing', '');\n }\n if (header.variant !== next) header.variant = next;\n if (concealUntilSynced && renderedVariantIsStale) {\n this.revealHeaderWhenSynced(header, next);\n }\n }\n\n private observeHeader(header: BarTitleElement | null) {\n this.cancelHeaderReveal();\n this.headerResizeObserver?.disconnect();\n this.headerResizeObserver = null;\n this.headerEl = header;\n this.expandedHeaderHeight = 0;\n this.setSpacerHeight(0);\n\n if (!header) return;\n if (typeof ResizeObserver !== 'undefined') {\n this.headerResizeObserver = new ResizeObserver(() => {\n if (header.variant === 'expanded') {\n this.expandedHeaderHeight = header.getBoundingClientRect().height;\n }\n });\n this.headerResizeObserver.observe(header);\n }\n this.syncHeaderVariant(true);\n }\n\n private handleHeaderSlotChange = (event: Event) => {\n const slot = event.target as HTMLSlotElement;\n const header = slot\n .assignedElements({ flatten: true })\n .find(element => element.tagName.toLowerCase() === 'ds-bar-title');\n this.observeHeader((header as BarTitleElement | undefined) ?? null);\n };\n\n render() {\n return (\n <Host\n role=\"main\"\n class={{\n 'shell-page-host--inset-default': this.contentInset === 'default',\n 'shell-page-host--inset-none': this.contentInset === 'none',\n [`shell-page-host--header-${this.effectiveVariant}`]: true,\n }}\n >\n <div\n ref={el => {\n this.sentinelEl = el ?? null;\n }}\n class=\"shell-page__scroll-sentinel\"\n aria-hidden=\"true\"\n />\n <div class=\"shell-page__sticky-header\">\n <slot name=\"header\" onSlotchange={this.handleHeaderSlotChange} />\n </div>\n <div\n ref={el => {\n this.spacerEl = el ?? null;\n }}\n class=\"shell-page__flow-spacer\"\n aria-hidden=\"true\"\n />\n <div class=\"shell-page__content\">\n <slot />\n </div>\n </Host>\n );\n }\n}\n",
|
|
186
190
|
"type": "registry:ui"
|
|
187
191
|
},
|
|
188
192
|
{
|
|
@@ -629,7 +629,7 @@
|
|
|
629
629
|
"peerDependencies": {
|
|
630
630
|
"required": [
|
|
631
631
|
"@ds-mo/tokens ^3.1.1",
|
|
632
|
-
"@ds-mo/icons ^6.
|
|
632
|
+
"@ds-mo/icons ^6.4.0"
|
|
633
633
|
],
|
|
634
634
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
635
635
|
}
|
|
@@ -645,7 +645,7 @@
|
|
|
645
645
|
"files": [
|
|
646
646
|
{
|
|
647
647
|
"path": "src/wc/components/Slider/Slider.css",
|
|
648
|
-
"content": "@import '../../utils/control-inactive.css';\n\n:host {\n --ds-slider-control-size: var(--dimension-size-400);\n --ds-slider-thumb-size: var(--dimension-size-200);\n --ds-slider-track-size: var(--dimension-size-100);\n --ds-slider-track-stroke: var(--dimension-stroke-width-012);\n --ds-slider-vertical-length: calc(var(--dimension-size-800) * 3);\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n gap: var(--dimension-space-050);\n width: 100%;\n color: var(--color-foreground-primary);\n}\n\n:host(.slider--sm) {\n --ds-slider-control-size: var(--dimension-size-300);\n --ds-slider-thumb-size: var(--dimension-size-150);\n --ds-slider-track-size: var(--dimension-size-075);\n}\n\n:host(.slider--xs) {\n --ds-slider-control-size: var(--dimension-size-200);\n --ds-slider-thumb-size: var(--dimension-size-100);\n --ds-slider-track-size: var(--dimension-size-050);\n}\n\n:host(.slider--vertical) {\n width: fit-content;\n min-width: var(--dimension-form-width-xs);\n}\n\n.slider__label-row {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--dimension-space-100);\n min-width: 0;\n}\n\n.slider__label {\n min-width: 0;\n}\n\n.slider__value {\n flex-shrink: 0;\n}\n\n.slider__control {\n position: relative;\n width: 100%;\n height: var(--ds-slider-control-size);\n border-radius: var(--dimension-radius-half);\n cursor: pointer;\n touch-action: none;\n user-select: none;\n}\n\n:host(.slider--vertical) .slider__control {\n align-self: center;\n width: var(--ds-slider-control-size);\n height: var(--ds-slider-vertical-length);\n}\n\n:host(.slider--readonly) .slider__control {\n cursor: default;\n}\n\n/* Inactive: `.ds-control-inactive` (
|
|
648
|
+
"content": "@import '../../utils/control-inactive.css';\n\n:host {\n --ds-slider-control-size: var(--dimension-size-400);\n --ds-slider-thumb-size: var(--dimension-size-200);\n --ds-slider-track-size: var(--dimension-size-100);\n --ds-slider-track-stroke: var(--dimension-stroke-width-012);\n --ds-slider-vertical-length: calc(var(--dimension-size-800) * 3);\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n gap: var(--dimension-space-050);\n width: 100%;\n color: var(--color-foreground-primary);\n}\n\n:host(.slider--sm) {\n --ds-slider-control-size: var(--dimension-size-300);\n --ds-slider-thumb-size: var(--dimension-size-150);\n --ds-slider-track-size: var(--dimension-size-075);\n}\n\n:host(.slider--xs) {\n --ds-slider-control-size: var(--dimension-size-200);\n --ds-slider-thumb-size: var(--dimension-size-100);\n --ds-slider-track-size: var(--dimension-size-050);\n}\n\n:host(.slider--vertical) {\n width: fit-content;\n min-width: var(--dimension-form-width-xs);\n}\n\n.slider__label-row {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--dimension-space-100);\n min-width: 0;\n}\n\n.slider__label {\n min-width: 0;\n}\n\n.slider__value {\n flex-shrink: 0;\n}\n\n.slider__control {\n position: relative;\n width: 100%;\n height: var(--ds-slider-control-size);\n border-radius: var(--dimension-radius-half);\n cursor: pointer;\n touch-action: none;\n user-select: none;\n}\n\n:host(.slider--vertical) .slider__control {\n align-self: center;\n width: var(--ds-slider-control-size);\n height: var(--ds-slider-vertical-length);\n}\n\n:host(.slider--readonly) .slider__control {\n cursor: default;\n}\n\n/* Inactive: `.ds-control-inactive` (50% opacity) on the host. */\n:host(.ds-control-inactive) .slider__control {\n cursor: not-allowed;\n}\n\n.slider__rail {\n position: absolute;\n top: 50%;\n right: 0;\n left: 0;\n height: var(--ds-slider-track-size);\n overflow: hidden;\n border-radius: var(--dimension-radius-025);\n background-color: transparent;\n box-shadow: inset 0 0 0 var(--ds-slider-track-stroke) var(--color-border-secondary);\n transform: translateY(-50%);\n pointer-events: none;\n}\n\n:host(.slider--thumb-center) .slider__rail {\n right: calc(var(--ds-slider-thumb-size) / 2);\n left: calc(var(--ds-slider-thumb-size) / 2);\n}\n\n.slider__indicator {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: calc(\n var(--ds-slider-thumb-size) / 2 +\n (var(--ds-slider-end-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size))\n );\n border-radius: inherit;\n background-color: var(--color-background-bold-brand);\n}\n\n:host(.slider--range) .slider__indicator {\n left: calc(\n var(--ds-slider-thumb-size) / 2 +\n (var(--ds-slider-start-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size))\n );\n width: calc(\n ((var(--ds-slider-end-pct, 0) - var(--ds-slider-start-pct, 0)) / 100) *\n (100% - var(--ds-slider-thumb-size))\n );\n}\n\n:host(.slider--thumb-center) .slider__indicator {\n left: calc(var(--ds-slider-start-pct, 0) * 1%);\n width: calc((var(--ds-slider-end-pct, 0) - var(--ds-slider-start-pct, 0)) * 1%);\n}\n\n.slider__thumb {\n position: absolute;\n top: 50%;\n left: calc((var(--ds-slider-thumb-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size)));\n width: var(--ds-slider-thumb-size);\n height: var(--ds-slider-thumb-size);\n transform: translateY(-50%);\n z-index: 1;\n}\n\n.slider__thumb--active {\n z-index: 2;\n}\n\n.slider__input {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n border: 0;\n opacity: 0;\n appearance: none;\n pointer-events: none;\n z-index: 2;\n}\n\n.slider__thumb-visual {\n position: absolute;\n inset: 0;\n box-sizing: border-box;\n overflow: visible;\n border-radius: var(--dimension-radius-025);\n background-color: var(--color-background-primary);\n box-shadow: var(--effect-elevation-elevated-sm);\n pointer-events: none;\n transition:\n background-color var(--effect-motion-short-2),\n box-shadow var(--effect-motion-short-2);\n}\n\n.slider__thumb-wash {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: transparent;\n transition: background-color var(--effect-motion-short-2);\n}\n\n:host(:not(.slider--readonly):not(.ds-control-inactive)) .slider__thumb:hover .slider__thumb-wash {\n background-color: var(--color-interaction-hover);\n}\n\n:host([data-dragging]:not(.slider--readonly):not(.ds-control-inactive))\n .slider__thumb--active .slider__thumb-wash {\n background-color: var(--color-interaction-pressed);\n}\n\n.slider__input:focus-visible + .slider__thumb-visual,\n:host([data-review-focus]) .slider__thumb[data-index='0'] .slider__thumb-visual {\n outline: var(--dimension-stroke-width-025) solid var(--color-interaction-focus);\n outline-offset: var(--dimension-space-025);\n}\n\n:host(.slider--vertical) .slider__rail {\n top: 0;\n right: auto;\n bottom: 0;\n left: 50%;\n width: var(--ds-slider-track-size);\n height: auto;\n transform: translateX(-50%);\n}\n\n:host(.slider--vertical.slider--thumb-center) .slider__rail {\n top: calc(var(--ds-slider-thumb-size) / 2);\n bottom: calc(var(--ds-slider-thumb-size) / 2);\n}\n\n:host(.slider--vertical) .slider__indicator {\n top: auto;\n right: 0;\n bottom: 0;\n left: 0;\n width: auto;\n height: calc(\n var(--ds-slider-thumb-size) / 2 +\n (var(--ds-slider-end-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size))\n );\n}\n\n:host(.slider--vertical.slider--range) .slider__indicator {\n bottom: calc(\n var(--ds-slider-thumb-size) / 2 +\n (var(--ds-slider-start-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size))\n );\n height: calc(\n ((var(--ds-slider-end-pct, 0) - var(--ds-slider-start-pct, 0)) / 100) *\n (100% - var(--ds-slider-thumb-size))\n );\n}\n\n:host(.slider--vertical.slider--thumb-center) .slider__indicator {\n bottom: calc(var(--ds-slider-start-pct, 0) * 1%);\n height: calc((var(--ds-slider-end-pct, 0) - var(--ds-slider-start-pct, 0)) * 1%);\n}\n\n:host(.slider--vertical) .slider__thumb {\n top: auto;\n bottom: calc((var(--ds-slider-thumb-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size)));\n left: 50%;\n transform: translateX(-50%);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .slider__thumb-visual,\n .slider__thumb-wash {\n transition: none;\n }\n}\n",
|
|
649
649
|
"type": "registry:ui"
|
|
650
650
|
},
|
|
651
651
|
{
|
|
@@ -335,7 +335,7 @@
|
|
|
335
335
|
"peerDependencies": {
|
|
336
336
|
"required": [
|
|
337
337
|
"@ds-mo/tokens ^3.1.1",
|
|
338
|
-
"@ds-mo/icons ^6.
|
|
338
|
+
"@ds-mo/icons ^6.4.0"
|
|
339
339
|
],
|
|
340
340
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
341
341
|
}
|
|
@@ -349,7 +349,7 @@
|
|
|
349
349
|
"files": [
|
|
350
350
|
{
|
|
351
351
|
"path": "src/wc/components/Switch/Switch.css",
|
|
352
|
-
"content": "@import '../../utils/focus-ring.css';\n@import '../../utils/control-inactive.css';\n\n:host {\n --ds-switch-width: var(--dimension-size-400);\n --ds-switch-height: var(--dimension-size-250);\n --ds-switch-thumb-size: var(--dimension-size-150);\n --ds-switch-gap: var(--dimension-space-050);\n --ds-switch-stroke: var(--dimension-stroke-width-012);\n --ds-switch-inset: var(--ds-switch-gap);\n --ds-switch-thumb-hover: var(--color-interaction-hover);\n --ds-switch-thumb-pressed: var(--color-interaction-pressed);\n --ds-switch-travel: calc(\n var(--ds-switch-width) - var(--ds-switch-thumb-size) - var(--ds-switch-inset) -\n var(--ds-switch-inset)\n );\n position: relative;\n display: inline-flex;\n width: var(--ds-switch-width);\n height: var(--ds-switch-height);\n padding: 0;\n border: none;\n border-radius: var(--dimension-radius-half);\n box-sizing: border-box;\n flex-shrink: 0;\n overflow: visible;\n cursor: pointer;\n user-select: none;\n outline: none;\n background-color: transparent;\n box-shadow: inset 0 0 0 var(--ds-switch-stroke) var(--color-border-secondary);\n transition:\n background-color var(--effect-motion-short-3),\n box-shadow var(--effect-motion-short-3);\n}\n\n:host(.switch--sm) {\n --ds-switch-width: var(--dimension-size-300);\n --ds-switch-height: var(--dimension-size-200);\n --ds-switch-thumb-size: calc(var(--dimension-size-base) * 5 / 4);\n --ds-switch-gap: calc(var(--dimension-space-025) + var(--dimension-space-012));\n}\n\n:host(.switch--xs) {\n --ds-switch-width: var(--dimension-size-250);\n --ds-switch-height: var(--dimension-size-150);\n --ds-switch-thumb-size: var(--dimension-size-100);\n --ds-switch-gap: var(--dimension-space-025);\n}\n\n:host(.checked) {\n background-color: var(--color-background-bold-brand);\n box-shadow: none;\n}\n\n:host(.switch--readonly),\n:host(.switch--presentation) {\n cursor: default;\n}\n\n:host(.switch--presentation) {\n pointer-events: none;\n}\n\n/* Inactive: `.ds-control-inactive` (
|
|
352
|
+
"content": "@import '../../utils/focus-ring.css';\n@import '../../utils/control-inactive.css';\n\n:host {\n --ds-switch-width: var(--dimension-size-400);\n --ds-switch-height: var(--dimension-size-250);\n --ds-switch-thumb-size: var(--dimension-size-150);\n --ds-switch-gap: var(--dimension-space-050);\n --ds-switch-stroke: var(--dimension-stroke-width-012);\n --ds-switch-inset: var(--ds-switch-gap);\n --ds-switch-thumb-hover: var(--color-interaction-hover);\n --ds-switch-thumb-pressed: var(--color-interaction-pressed);\n --ds-switch-travel: calc(\n var(--ds-switch-width) - var(--ds-switch-thumb-size) - var(--ds-switch-inset) -\n var(--ds-switch-inset)\n );\n position: relative;\n display: inline-flex;\n width: var(--ds-switch-width);\n height: var(--ds-switch-height);\n padding: 0;\n border: none;\n border-radius: var(--dimension-radius-half);\n box-sizing: border-box;\n flex-shrink: 0;\n overflow: visible;\n cursor: pointer;\n user-select: none;\n outline: none;\n background-color: transparent;\n box-shadow: inset 0 0 0 var(--ds-switch-stroke) var(--color-border-secondary);\n transition:\n background-color var(--effect-motion-short-3),\n box-shadow var(--effect-motion-short-3);\n}\n\n:host(.switch--sm) {\n --ds-switch-width: var(--dimension-size-300);\n --ds-switch-height: var(--dimension-size-200);\n --ds-switch-thumb-size: calc(var(--dimension-size-base) * 5 / 4);\n --ds-switch-gap: calc(var(--dimension-space-025) + var(--dimension-space-012));\n}\n\n:host(.switch--xs) {\n --ds-switch-width: var(--dimension-size-250);\n --ds-switch-height: var(--dimension-size-150);\n --ds-switch-thumb-size: var(--dimension-size-100);\n --ds-switch-gap: var(--dimension-space-025);\n}\n\n:host(.checked) {\n background-color: var(--color-background-bold-brand);\n box-shadow: none;\n}\n\n:host(.switch--readonly),\n:host(.switch--presentation) {\n cursor: default;\n}\n\n:host(.switch--presentation) {\n pointer-events: none;\n}\n\n/* Inactive: `.ds-control-inactive` (50% opacity). */\n\n.thumb {\n position: absolute;\n top: 50%;\n left: var(--ds-switch-inset);\n width: var(--ds-switch-thumb-size);\n height: var(--ds-switch-thumb-size);\n border-radius: var(--dimension-radius-half);\n background-color: var(--color-foreground-tertiary);\n box-shadow: none;\n transform: translateY(-50%);\n transition:\n background-color var(--effect-motion-short-3),\n transform var(--effect-motion-short-3);\n pointer-events: none;\n}\n\n.thumb::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: transparent;\n pointer-events: none;\n}\n\n:host(:hover:not(:disabled):not(.ds-control-inactive):not(.switch--readonly):not(.switch--presentation))\n .thumb::after {\n background: var(--ds-switch-thumb-hover);\n}\n\n:host(:active:not(:disabled):not(.ds-control-inactive):not(.switch--readonly):not(.switch--presentation))\n .thumb::after {\n background: var(--ds-switch-thumb-pressed);\n}\n\n:host(.checked) .thumb {\n background-color: var(--color-background-primary);\n box-shadow: none;\n transform: translate3d(var(--ds-switch-travel), -50%, 0);\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n .thumb {\n transition: none;\n }\n}\n",
|
|
353
353
|
"type": "registry:ui"
|
|
354
354
|
},
|
|
355
355
|
{
|
|
@@ -219,7 +219,7 @@
|
|
|
219
219
|
"peerDependencies": {
|
|
220
220
|
"required": [
|
|
221
221
|
"@ds-mo/tokens ^3.1.1",
|
|
222
|
-
"@ds-mo/icons ^6.
|
|
222
|
+
"@ds-mo/icons ^6.4.0"
|
|
223
223
|
],
|
|
224
224
|
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
225
225
|
}
|
|
@@ -238,7 +238,7 @@
|
|
|
238
238
|
"files": [
|
|
239
239
|
{
|
|
240
240
|
"path": "src/wc/components/TabGroup/TabGroup.css",
|
|
241
|
-
"content": "@import '../../utils/control-density.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/interaction-fill.css';\n@import '../../utils/control-inactive.css';\n\n:host {\n display: block;\n --_tab-group-surface-border: var(--color-border-tertiary);\n --_tab-group-divider: var(--color-border-secondary);\n}\n\n:host(.tab-group-host--on-medium) {\n --_tab-group-surface-border: var(--color-border-on-medium-background-tertiary);\n --_tab-group-divider: var(--color-border-on-medium-background-secondary);\n}\n\n:host(.tab-group-host--on-bold) {\n --_tab-group-surface-border: var(--color-border-on-bold-background-tertiary);\n --_tab-group-divider: var(--color-border-on-bold-background-secondary);\n}\n\n:host(.tab-group-host--on-strong) {\n --_tab-group-surface-border: var(--color-border-on-strong-background-tertiary);\n --_tab-group-divider: var(--color-border-on-strong-background-secondary);\n}\n\n:host(.tab-group-host--on-translucent) {\n --_tab-group-surface-border: var(--color-translucent-border-tertiary);\n --_tab-group-divider: var(--color-translucent-border-secondary);\n}\n\n:host(.tab-group-host--on-inverted) {\n --_tab-group-surface-border: var(--color-inverted-border-tertiary);\n --_tab-group-divider: var(--color-inverted-border-secondary);\n}\n\n:host(.tab-group-host--on-media) {\n --_tab-group-surface-border: var(--color-media-border-tertiary);\n --_tab-group-divider: var(--color-media-border-secondary);\n}\n\n:host(.tab-group-host--on-always-dark) {\n --_tab-group-surface-border: var(--color-always-dark-border-tertiary);\n --_tab-group-divider: var(--color-always-dark-border-secondary);\n}\n\n.tab-list {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-050);\n position: relative;\n width: max-content;\n max-width: 100%;\n height: var(--dimension-size-400);\n padding: calc(var(--dimension-space-050) - var(--dimension-stroke-width-012));\n background-color: var(--color-background-secondary);\n border: var(--dimension-stroke-width-012) solid var(--_tab-group-surface-border);\n border-radius: var(--dimension-radius-half);\n box-sizing: border-box;\n}\n\n:host(.tab-group-host--surface) .tab-list {\n background-color: transparent;\n}\n\n.tab {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--ds-control-gap);\n padding: 0 var(--ds-control-padding-inline);\n background-color: transparent;\n border: none;\n border-radius: var(--dimension-radius-half);\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n color: var(--color-foreground-secondary);\n transition: color var(--effect-motion-short-2);\n flex-shrink: 0;\n height: var(--ds-control-height);\n min-width: var(--dimension-size-400);\n box-sizing: border-box;\n --_dot: var(--color-foreground-bold-brand);\n /* Hover/press: `.ds-interaction-fill` — fills cover full 24px box (no layout border). */\n}\n\n.tab--selected {\n color: var(--color-foreground-primary);\n background-color: var(--color-background-primary);\n /* Inset stroke on interaction-fill ::after — stays above hover wash. */\n --ds-interaction-border-width: var(--dimension-stroke-width-012);\n --ds-interaction-border-color: var(--_tab-group-surface-border);\n}\n\n:host(.tab-group-host--surface) .tab--selected {\n background-color: var(--ds-interaction-active);\n}\n\n.tab--selected:not(.ds-interaction-fill) {\n box-shadow: inset 0 0 0 var(--ds-interaction-border-width) var(--ds-interaction-border-color);\n}\n\n/* Inactive: `.ds-control-inactive` (
|
|
241
|
+
"content": "@import '../../utils/control-density.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/interaction-fill.css';\n@import '../../utils/control-inactive.css';\n\n:host {\n display: block;\n --_tab-group-surface-border: var(--color-border-tertiary);\n --_tab-group-divider: var(--color-border-secondary);\n}\n\n:host(.tab-group-host--on-medium) {\n --_tab-group-surface-border: var(--color-border-on-medium-background-tertiary);\n --_tab-group-divider: var(--color-border-on-medium-background-secondary);\n}\n\n:host(.tab-group-host--on-bold) {\n --_tab-group-surface-border: var(--color-border-on-bold-background-tertiary);\n --_tab-group-divider: var(--color-border-on-bold-background-secondary);\n}\n\n:host(.tab-group-host--on-strong) {\n --_tab-group-surface-border: var(--color-border-on-strong-background-tertiary);\n --_tab-group-divider: var(--color-border-on-strong-background-secondary);\n}\n\n:host(.tab-group-host--on-translucent) {\n --_tab-group-surface-border: var(--color-translucent-border-tertiary);\n --_tab-group-divider: var(--color-translucent-border-secondary);\n}\n\n:host(.tab-group-host--on-inverted) {\n --_tab-group-surface-border: var(--color-inverted-border-tertiary);\n --_tab-group-divider: var(--color-inverted-border-secondary);\n}\n\n:host(.tab-group-host--on-media) {\n --_tab-group-surface-border: var(--color-media-border-tertiary);\n --_tab-group-divider: var(--color-media-border-secondary);\n}\n\n:host(.tab-group-host--on-always-dark) {\n --_tab-group-surface-border: var(--color-always-dark-border-tertiary);\n --_tab-group-divider: var(--color-always-dark-border-secondary);\n}\n\n.tab-list {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-050);\n position: relative;\n width: max-content;\n max-width: 100%;\n height: var(--dimension-size-400);\n padding: calc(var(--dimension-space-050) - var(--dimension-stroke-width-012));\n background-color: var(--color-background-secondary);\n border: var(--dimension-stroke-width-012) solid var(--_tab-group-surface-border);\n border-radius: var(--dimension-radius-half);\n box-sizing: border-box;\n}\n\n:host(.tab-group-host--surface) .tab-list {\n background-color: transparent;\n}\n\n.tab {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--ds-control-gap);\n padding: 0 var(--ds-control-padding-inline);\n background-color: transparent;\n border: none;\n border-radius: var(--dimension-radius-half);\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n color: var(--color-foreground-secondary);\n transition: color var(--effect-motion-short-2);\n flex-shrink: 0;\n height: var(--ds-control-height);\n min-width: var(--dimension-size-400);\n box-sizing: border-box;\n --_dot: var(--color-foreground-bold-brand);\n /* Hover/press: `.ds-interaction-fill` — fills cover full 24px box (no layout border). */\n}\n\n.tab--selected {\n color: var(--color-foreground-primary);\n background-color: var(--color-background-primary);\n /* Inset stroke on interaction-fill ::after — stays above hover wash. */\n --ds-interaction-border-width: var(--dimension-stroke-width-012);\n --ds-interaction-border-color: var(--_tab-group-surface-border);\n}\n\n:host(.tab-group-host--surface) .tab--selected {\n background-color: var(--ds-interaction-active);\n}\n\n.tab--selected:not(.ds-interaction-fill) {\n box-shadow: inset 0 0 0 var(--ds-interaction-border-width) var(--ds-interaction-border-color);\n}\n\n/* Inactive: `.ds-control-inactive` (50% opacity) — applied via class in TSX. */\n\n.tab__content {\n position: relative;\n z-index: 2;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--ds-control-gap);\n min-width: 0;\n}\n\n.tab__content--dot {\n padding-right: var(--dimension-space-050);\n}\n\n.tab__label {\n padding: 0 var(--ds-control-label-inset);\n white-space: nowrap;\n}\n\n.tab__icon {\n flex-shrink: 0;\n}\n\n.tab__dot {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n pointer-events: none;\n}\n\n.on-medium {\n color: var(--color-foreground-on-medium-background-secondary);\n}\n\n.on-medium.tab--selected { color: var(--color-foreground-on-medium-background-primary); }\n\n.on-bold {\n color: var(--color-foreground-on-bold-background-secondary);\n}\n\n.on-bold.tab--selected { color: var(--color-foreground-on-bold-background-primary); }\n\n.on-strong {\n color: var(--color-foreground-on-strong-background-secondary);\n}\n\n.on-strong.tab--selected { color: var(--color-foreground-on-strong-background-primary); }\n\n.on-translucent { color: var(--color-translucent-foreground-secondary); }\n\n.on-translucent.tab--selected { color: var(--color-translucent-foreground-primary); }\n\n.on-inverted { color: var(--color-inverted-foreground-secondary); }\n\n.on-inverted.tab--selected { color: var(--color-inverted-foreground-primary); }\n\n.on-media { color: var(--color-media-foreground-secondary); }\n\n.on-media.tab--selected { color: var(--color-media-foreground-primary); }\n\n.on-always-dark {\n color: var(--color-always-dark-foreground-secondary);\n}\n\n.on-always-dark.tab--selected { color: var(--color-always-dark-foreground-primary); }\n\n.tab-divider {\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: var(--dimension-stroke-width-012);\n align-self: center;\n padding: 0;\n flex-shrink: 0;\n pointer-events: none;\n}\n\n.tab-divider__line {\n width: var(--dimension-stroke-width-012);\n height: var(--typography-lineheight-sm);\n flex-shrink: 0;\n background-color: var(--_tab-group-divider);\n}\n",
|
|
242
242
|
"type": "registry:ui"
|
|
243
243
|
},
|
|
244
244
|
{
|