@ds-mo/ui 8.3.1 → 9.1.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 +28 -3
- package/dist/.build-stamp +1 -1
- package/dist/agent-patterns.json +233 -0
- package/dist/agent.json +155 -174
- package/dist/angular/ds-menu.d.ts +6 -1
- package/dist/angular/ds-menu.js +7 -4
- package/dist/angular/ds-swatch-picker.d.ts +15 -0
- package/dist/angular/{ds-pagination.js → ds-swatch-picker.js} +15 -15
- package/dist/angular/index.d.ts +1 -1
- package/dist/angular/index.js +1 -2
- package/dist/angular/proxies.d.ts +1 -2
- package/dist/angular/proxies.js +1 -2
- package/dist/components/ds-app-shell.js +1 -1
- package/dist/components/ds-badge.js +1 -1
- package/dist/components/ds-banner.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-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-setting.js +1 -1
- package/dist/components/ds-card-shell-data-viz.js +1 -1
- package/dist/components/ds-card.js +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-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-empty-state.js +1 -1
- package/dist/components/ds-field.js +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-menu.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-nav.js.map +1 -1
- package/dist/components/ds-panel-sub-nav.js +1 -1
- package/dist/components/ds-panel-tools.js +1 -1
- package/dist/components/ds-radio.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-gradient-picker.js +1 -1
- package/dist/components/ds-shell-gradient-picker.js.map +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-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-pagination.d.ts → ds-swatch-picker.d.ts} +4 -4
- package/dist/components/ds-swatch-picker.js +2 -0
- package/dist/components/ds-swatch-picker.js.map +1 -0
- 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-tooltip-data-viz.js +1 -1
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/{p-CysJosvS.js → p-B-zhgAvL.js} +2 -2
- package/dist/components/{p-C21sIElQ.js → p-BLzivrE3.js} +2 -2
- package/dist/components/{p-DAuadHYu.js → p-BbV68F23.js} +2 -2
- package/dist/components/{p-_y99wWNU.js → p-C7RObioO.js} +2 -2
- package/dist/components/{p-DxQ4gzbA.js → p-CZ9wemOA.js} +2 -2
- package/dist/components/{p-BKA6houZ.js → p-CbS_WWs2.js} +2 -2
- package/dist/components/p-D1HFMTdC.js +2 -0
- package/dist/components/p-D1HFMTdC.js.map +1 -0
- package/dist/components/{p-BGcSrHKl.js → p-DT2MK8Kt.js} +2 -2
- package/dist/components/{p-DV23KMU-.js → p-DyZj3k9S.js} +2 -2
- package/dist/components/p-HBIxvS5C.js +2 -0
- package/dist/components/p-HBIxvS5C.js.map +1 -0
- package/dist/components/{p-D6hvtWDk.js → p-KRGBGTu5.js} +2 -2
- package/dist/components/p-l6PmnW_P.js +2 -0
- package/dist/components/p-l6PmnW_P.js.map +1 -0
- package/dist/components/p-tQ1QHeOE.js +2 -0
- package/dist/components/p-tQ1QHeOE.js.map +1 -0
- package/dist/docs/components.json +546 -1024
- package/dist/lib/components/Menu/menu-placement.d.ts +6 -3
- package/dist/lib/shell/index.d.ts +2 -2
- package/dist/lib/shell/index.js +40 -39
- package/dist/lib/shell/index.js.map +3 -3
- package/dist/lib/shell/shell-gradient-presets.d.ts +15 -0
- package/dist/lib/utils/choice-popup-alignment.d.ts +20 -0
- package/dist/lib/utils/index.d.ts +2 -0
- package/dist/lib/utils/index.js +16 -0
- package/dist/lib/utils/index.js.map +3 -3
- package/dist/mcp/cli.js +31409 -0
- package/dist/mcp-data/registry/app-shell.json +210 -0
- package/dist/mcp-data/registry/badge.json +289 -0
- package/dist/mcp-data/registry/banner.json +206 -0
- package/dist/mcp-data/registry/bar-nav.json +341 -0
- package/dist/mcp-data/registry/button-filled.json +386 -0
- package/dist/mcp-data/registry/button-unfilled.json +537 -0
- package/dist/mcp-data/registry/card-data-viz-donut.json +143 -0
- package/dist/mcp-data/registry/card-setting.json +194 -0
- package/dist/mcp-data/registry/card-shell-data-viz.json +173 -0
- package/dist/mcp-data/registry/card.json +126 -0
- package/dist/mcp-data/registry/chart-bar.json +121 -0
- package/dist/mcp-data/registry/chart-donut.json +257 -0
- package/dist/mcp-data/registry/chart-legend.json +209 -0
- package/dist/mcp-data/registry/chart-line.json +153 -0
- package/dist/mcp-data/registry/checkbox.json +361 -0
- package/dist/mcp-data/registry/chip.json +276 -0
- package/dist/mcp-data/registry/divider.json +225 -0
- package/dist/mcp-data/registry/empty-state.json +197 -0
- package/dist/mcp-data/registry/field.json +222 -0
- package/dist/mcp-data/registry/icon.json +242 -0
- package/dist/mcp-data/registry/input.json +597 -0
- package/dist/mcp-data/registry/loader.json +192 -0
- package/dist/mcp-data/registry/menu.json +459 -0
- package/dist/mcp-data/registry/modal.json +150 -0
- package/dist/mcp-data/registry/panel-nav.json +622 -0
- package/dist/mcp-data/registry/panel-sub-nav.json +249 -0
- package/dist/mcp-data/registry/panel-tools.json +374 -0
- package/dist/mcp-data/registry/radio.json +374 -0
- package/dist/mcp-data/registry/registry.json +5389 -0
- package/dist/mcp-data/registry/select-multi.json +755 -0
- package/dist/mcp-data/registry/select.json +740 -0
- package/dist/mcp-data/registry/shell-gradient-picker.json +195 -0
- package/dist/mcp-data/registry/shell-gradient-swatch.json +215 -0
- package/dist/mcp-data/registry/skeleton.json +282 -0
- package/dist/mcp-data/registry/slider.json +657 -0
- package/dist/mcp-data/registry/swatch-picker.json +231 -0
- package/dist/mcp-data/registry/switch.json +361 -0
- package/dist/mcp-data/registry/tab-group.json +255 -0
- package/dist/mcp-data/registry/tag.json +352 -0
- package/dist/mcp-data/registry/text.json +371 -0
- package/dist/mcp-data/registry/tooltip-data-viz.json +158 -0
- package/dist/mcp-data/registry/tooltip.json +311 -0
- package/dist/react/components.d.ts +1 -2
- package/dist/react/components.js +1 -2
- package/dist/react/ds-menu.d.ts +1 -0
- package/dist/react/ds-menu.js +2 -1
- package/dist/react/ds-swatch-picker.d.ts +12 -0
- package/dist/react/ds-swatch-picker.js +12 -0
- package/dist/types/components/Menu/Menu.d.ts +7 -1
- package/dist/types/components/Menu/menu-placement.d.ts +6 -3
- package/dist/types/components/Menu/menu-types.d.ts +14 -1
- package/dist/types/components/ShellGradientPicker/ShellGradientPicker.d.ts +2 -5
- package/dist/types/components/ShellGradientSwatch/ShellGradientSwatch.d.ts +1 -0
- package/dist/types/components/SwatchPicker/SwatchPicker.d.ts +21 -0
- package/dist/types/components/SwatchPicker/swatch-picker-types.d.ts +26 -0
- package/dist/types/components.d.ts +117 -237
- package/dist/types/shell/index.d.ts +2 -2
- package/dist/types/shell/shell-gradient-presets.d.ts +15 -0
- package/dist/types/utils/choice-popup-alignment.d.ts +21 -0
- package/dist/types/utils/index.d.ts +2 -0
- package/package.json +6 -2
- package/dist/angular/ds-pagination.d.ts +0 -15
- package/dist/angular/ds-table.d.ts +0 -33
- package/dist/angular/ds-table.js +0 -48
- package/dist/components/ds-pagination.js +0 -2
- package/dist/components/ds-pagination.js.map +0 -1
- package/dist/components/ds-table.d.ts +0 -11
- package/dist/components/ds-table.js +0 -2
- package/dist/components/ds-table.js.map +0 -1
- package/dist/components/p-CKV6rOGa.js +0 -2
- package/dist/components/p-CKV6rOGa.js.map +0 -1
- package/dist/components/p-CSTr2132.js +0 -2
- package/dist/components/p-CSTr2132.js.map +0 -1
- package/dist/components/p-C_cu-HIT.js +0 -2
- package/dist/components/p-C_cu-HIT.js.map +0 -1
- package/dist/components/p-D0B9uDTP.js +0 -2
- package/dist/components/p-D0B9uDTP.js.map +0 -1
- package/dist/components/p-DhxWfdX0.js +0 -2
- package/dist/components/p-DhxWfdX0.js.map +0 -1
- package/dist/components/p-Pip-LNhl.js +0 -2
- package/dist/components/p-Pip-LNhl.js.map +0 -1
- package/dist/react/ds-pagination.d.ts +0 -12
- package/dist/react/ds-pagination.js +0 -12
- package/dist/react/ds-table.d.ts +0 -21
- package/dist/react/ds-table.js +0 -16
- package/dist/types/components/Pagination/Pagination.d.ts +0 -14
- package/dist/types/components/Table/Table.d.ts +0 -56
- /package/dist/components/{p-CysJosvS.js.map → p-B-zhgAvL.js.map} +0 -0
- /package/dist/components/{p-C21sIElQ.js.map → p-BLzivrE3.js.map} +0 -0
- /package/dist/components/{p-DAuadHYu.js.map → p-BbV68F23.js.map} +0 -0
- /package/dist/components/{p-_y99wWNU.js.map → p-C7RObioO.js.map} +0 -0
- /package/dist/components/{p-DxQ4gzbA.js.map → p-CZ9wemOA.js.map} +0 -0
- /package/dist/components/{p-BKA6houZ.js.map → p-CbS_WWs2.js.map} +0 -0
- /package/dist/components/{p-BGcSrHKl.js.map → p-DT2MK8Kt.js.map} +0 -0
- /package/dist/components/{p-DV23KMU-.js.map → p-DyZj3k9S.js.map} +0 -0
- /package/dist/components/{p-D6hvtWDk.js.map → p-KRGBGTu5.js.map} +0 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "panel-sub-nav",
|
|
4
|
+
"title": "PanelSubNav",
|
|
5
|
+
"description": "Persistent vertical tab navigation for a panel or card side rail, switching adjacent local content with menu-like selected fill and stable text weight.",
|
|
6
|
+
"type": "registry:ui",
|
|
7
|
+
"meta": {
|
|
8
|
+
"library": "@ds-mo/ui",
|
|
9
|
+
"distribution": "npm",
|
|
10
|
+
"storybook": "https://zainadeel.github.io/compomo/?path=/story/panel-sub-nav",
|
|
11
|
+
"source": "src/wc/components/PanelSubNav/PanelSubNav.tsx",
|
|
12
|
+
"intentStatus": "complete",
|
|
13
|
+
"intent": {
|
|
14
|
+
"audience": "general",
|
|
15
|
+
"status": "stable",
|
|
16
|
+
"summary": "Persistent vertical tab navigation for a panel or card side rail, switching adjacent local content with menu-like selected fill and stable text weight.",
|
|
17
|
+
"useWhen": [
|
|
18
|
+
"A panel or card side rail needs a persistent vertical list that switches adjacent local content.",
|
|
19
|
+
"Each concise text label controls an immediately available tabpanel without changing application routes."
|
|
20
|
+
],
|
|
21
|
+
"avoidWhen": [
|
|
22
|
+
"The navigation is not contained in a panel or card side rail.",
|
|
23
|
+
"Local views should be arranged horizontally; use TabGroup instead.",
|
|
24
|
+
"The choices navigate routes in application shell chrome; use PanelNav or BarNav instead.",
|
|
25
|
+
"The choices are temporary commands or contextual options; use Menu instead.",
|
|
26
|
+
"Rows need icons, subtext, notification dots, nested levels, or section headers."
|
|
27
|
+
],
|
|
28
|
+
"alternatives": [
|
|
29
|
+
{
|
|
30
|
+
"when": "Local panel choices fit a horizontal tab row.",
|
|
31
|
+
"component": "component:ds-tab-group",
|
|
32
|
+
"reason": "TabGroup is the horizontal local-view counterpart."
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"when": "The choices are primary application destinations.",
|
|
36
|
+
"component": "component:ds-panel-nav",
|
|
37
|
+
"reason": "PanelNav owns primary application navigation."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"when": "The choices are secondary application routes.",
|
|
41
|
+
"component": "component:ds-bar-nav",
|
|
42
|
+
"reason": "BarNav owns route sections inside AppShell."
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"when": "The choices are transient actions or options.",
|
|
46
|
+
"component": "component:ds-menu",
|
|
47
|
+
"reason": "Menu owns temporary popup collections."
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"commonlyComposedWith": [
|
|
51
|
+
"component:ds-card",
|
|
52
|
+
"component:ds-text"
|
|
53
|
+
],
|
|
54
|
+
"accessibility": [
|
|
55
|
+
"Provide an accessible name with aria-label or aria-labelledby.",
|
|
56
|
+
"Give every item a unique id and the id of its controlled tabpanel.",
|
|
57
|
+
"Keep each controlled tabpanel labelled by its matching item id.",
|
|
58
|
+
"Always provide a valid selected item when enabled items exist so exactly one tab and panel are active.",
|
|
59
|
+
"ArrowUp and ArrowDown move and activate selection; Home and End select the first and last available items.",
|
|
60
|
+
"Do not use selected text weight as the selection cue; active fill and primary foreground communicate selection."
|
|
61
|
+
],
|
|
62
|
+
"states": [
|
|
63
|
+
"The parent owns the canonical selected value and panel visibility, and should update both from dsChange.",
|
|
64
|
+
"A missing, empty, or unknown selected value is invalid when enabled items exist; the component does not choose a fallback selection.",
|
|
65
|
+
"Inactive items remain visible but cannot be focused or selected.",
|
|
66
|
+
"Selection is singular and follows keyboard focus.",
|
|
67
|
+
"The omitted default surface treatment is for primary and secondary parent surfaces and uses the brand-active selected fill; pass faint explicitly on faint surfaces to use the neutral active fill.",
|
|
68
|
+
"Rows contain one text label only and do not express nested navigation or grouped hierarchy."
|
|
69
|
+
],
|
|
70
|
+
"responsiveBehavior": [
|
|
71
|
+
"The component remains vertical at every width.",
|
|
72
|
+
"The consuming panel owns responsive adaptation and decides whether to reposition or replace the side rail."
|
|
73
|
+
],
|
|
74
|
+
"frameworkCaveats": {
|
|
75
|
+
"customElements": [
|
|
76
|
+
"Assign items as a JavaScript property because structured arrays are not represented by HTML attributes.",
|
|
77
|
+
"Keep value synchronized to a valid enabled item and update the controlled panel from dsChange."
|
|
78
|
+
],
|
|
79
|
+
"react": [
|
|
80
|
+
"Pass items as an array through the generated wrapper, keep value controlled, and use onDsChange to synchronize the visible panel."
|
|
81
|
+
],
|
|
82
|
+
"angular": [
|
|
83
|
+
"Bind items and a valid value as properties, and handle dsChange to synchronize the visible panel."
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"api": {
|
|
88
|
+
"props": {
|
|
89
|
+
"ariaLabel": {
|
|
90
|
+
"type": "string | null",
|
|
91
|
+
"resolvedType": "null | string",
|
|
92
|
+
"attribute": "aria-label",
|
|
93
|
+
"default": "null",
|
|
94
|
+
"required": false,
|
|
95
|
+
"mutable": false
|
|
96
|
+
},
|
|
97
|
+
"ariaLabelledby": {
|
|
98
|
+
"type": "string | undefined",
|
|
99
|
+
"resolvedType": "string | undefined",
|
|
100
|
+
"attribute": "aria-labelledby",
|
|
101
|
+
"required": false,
|
|
102
|
+
"mutable": false
|
|
103
|
+
},
|
|
104
|
+
"background": {
|
|
105
|
+
"type": "PanelSubNavBackground | undefined",
|
|
106
|
+
"resolvedType": "\"always-dark\" | \"bold\" | \"faint\" | \"inverted\" | \"media\" | \"medium\" | \"strong\" | \"translucent\" | undefined",
|
|
107
|
+
"attribute": "background",
|
|
108
|
+
"required": false,
|
|
109
|
+
"mutable": false,
|
|
110
|
+
"description": "Actual parent surface context. Omit on primary and secondary surfaces."
|
|
111
|
+
},
|
|
112
|
+
"items": {
|
|
113
|
+
"type": "PanelSubNavItem[]",
|
|
114
|
+
"resolvedType": "PanelSubNavItem[]",
|
|
115
|
+
"default": "[]",
|
|
116
|
+
"required": false,
|
|
117
|
+
"mutable": false,
|
|
118
|
+
"description": "Local panel tabs. Assign this array through the JavaScript property.\nReplace the array reference when items change."
|
|
119
|
+
},
|
|
120
|
+
"value": {
|
|
121
|
+
"type": "string",
|
|
122
|
+
"resolvedType": "string",
|
|
123
|
+
"attribute": "value",
|
|
124
|
+
"default": "''",
|
|
125
|
+
"required": false,
|
|
126
|
+
"mutable": true,
|
|
127
|
+
"description": "Required selected item id when enabled items exist. Keep synchronized with the visible panel."
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
"events": [
|
|
131
|
+
{
|
|
132
|
+
"name": "dsChange",
|
|
133
|
+
"detail": "string",
|
|
134
|
+
"bubbles": true,
|
|
135
|
+
"cancelable": true,
|
|
136
|
+
"composed": true
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"methods": [],
|
|
140
|
+
"slots": []
|
|
141
|
+
},
|
|
142
|
+
"props": {
|
|
143
|
+
"ariaLabel": {
|
|
144
|
+
"type": "string | null",
|
|
145
|
+
"resolvedType": "null | string",
|
|
146
|
+
"attribute": "aria-label",
|
|
147
|
+
"default": "null",
|
|
148
|
+
"required": false,
|
|
149
|
+
"mutable": false
|
|
150
|
+
},
|
|
151
|
+
"ariaLabelledby": {
|
|
152
|
+
"type": "string | undefined",
|
|
153
|
+
"resolvedType": "string | undefined",
|
|
154
|
+
"attribute": "aria-labelledby",
|
|
155
|
+
"required": false,
|
|
156
|
+
"mutable": false
|
|
157
|
+
},
|
|
158
|
+
"background": {
|
|
159
|
+
"type": "PanelSubNavBackground | undefined",
|
|
160
|
+
"resolvedType": "\"always-dark\" | \"bold\" | \"faint\" | \"inverted\" | \"media\" | \"medium\" | \"strong\" | \"translucent\" | undefined",
|
|
161
|
+
"attribute": "background",
|
|
162
|
+
"required": false,
|
|
163
|
+
"mutable": false,
|
|
164
|
+
"description": "Actual parent surface context. Omit on primary and secondary surfaces."
|
|
165
|
+
},
|
|
166
|
+
"items": {
|
|
167
|
+
"type": "PanelSubNavItem[]",
|
|
168
|
+
"resolvedType": "PanelSubNavItem[]",
|
|
169
|
+
"default": "[]",
|
|
170
|
+
"required": false,
|
|
171
|
+
"mutable": false,
|
|
172
|
+
"description": "Local panel tabs. Assign this array through the JavaScript property.\nReplace the array reference when items change."
|
|
173
|
+
},
|
|
174
|
+
"value": {
|
|
175
|
+
"type": "string",
|
|
176
|
+
"resolvedType": "string",
|
|
177
|
+
"attribute": "value",
|
|
178
|
+
"default": "''",
|
|
179
|
+
"required": false,
|
|
180
|
+
"mutable": true,
|
|
181
|
+
"description": "Required selected item id when enabled items exist. Keep synchronized with the visible panel."
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
"events": [
|
|
185
|
+
{
|
|
186
|
+
"name": "dsChange",
|
|
187
|
+
"detail": "string",
|
|
188
|
+
"bubbles": true,
|
|
189
|
+
"cancelable": true,
|
|
190
|
+
"composed": true
|
|
191
|
+
}
|
|
192
|
+
],
|
|
193
|
+
"methods": [],
|
|
194
|
+
"slots": [],
|
|
195
|
+
"exports": {
|
|
196
|
+
"customElement": "ds-panel-sub-nav",
|
|
197
|
+
"react": "DsPanelSubNav",
|
|
198
|
+
"angular": "DsPanelSubNav"
|
|
199
|
+
},
|
|
200
|
+
"consumption": {
|
|
201
|
+
"install": "npm install @ds-mo/ui @ds-mo/tokens @ds-mo/icons",
|
|
202
|
+
"cssSetup": "import '@ds-mo/tokens';\nimport '@ds-mo/tokens/reset';\nimport '@ds-mo/tokens/globals';",
|
|
203
|
+
"customElements": {
|
|
204
|
+
"import": "import '@ds-mo/ui/dist/components/ds-panel-sub-nav.js';",
|
|
205
|
+
"example": "<ds-panel-sub-nav></ds-panel-sub-nav>"
|
|
206
|
+
},
|
|
207
|
+
"react": {
|
|
208
|
+
"import": "import { DsPanelSubNav } from '@ds-mo/ui/react';",
|
|
209
|
+
"example": "<DsPanelSubNav />"
|
|
210
|
+
},
|
|
211
|
+
"angular": {
|
|
212
|
+
"import": "import { DsPanelSubNav } from '@ds-mo/ui/angular/ds-panel-sub-nav';",
|
|
213
|
+
"example": "<ds-panel-sub-nav></ds-panel-sub-nav>"
|
|
214
|
+
},
|
|
215
|
+
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: items.",
|
|
216
|
+
"peerDependencies": {
|
|
217
|
+
"required": [
|
|
218
|
+
"@ds-mo/tokens ^3.1.1",
|
|
219
|
+
"@ds-mo/icons ^6.2.0"
|
|
220
|
+
],
|
|
221
|
+
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
"dependencies": [
|
|
226
|
+
"@ds-mo/ui",
|
|
227
|
+
"@ds-mo/tokens"
|
|
228
|
+
],
|
|
229
|
+
"registryDependencies": [
|
|
230
|
+
"text"
|
|
231
|
+
],
|
|
232
|
+
"files": [
|
|
233
|
+
{
|
|
234
|
+
"path": "src/wc/components/PanelSubNav/PanelSubNav.css",
|
|
235
|
+
"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 width: 100%;\n}\n\n.panel-sub-nav {\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-050);\n width: 100%;\n}\n\n.panel-sub-nav__item {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n gap: var(--ds-control-gap);\n width: 100%;\n height: var(--ds-control-height);\n padding: 0 var(--ds-control-padding-inline);\n box-sizing: border-box;\n border: none;\n border-radius: var(--ds-control-radius);\n background: transparent;\n color: var(--color-foreground-secondary);\n cursor: pointer;\n text-align: left;\n -webkit-user-select: none;\n user-select: none;\n transition: color var(--effect-motion-short-2);\n}\n\n.panel-sub-nav__item--selected {\n color: var(--color-foreground-primary);\n}\n\n.panel-sub-nav__item--on-medium {\n color: var(--color-foreground-on-medium-background-secondary);\n}\n\n.panel-sub-nav__item--on-medium.panel-sub-nav__item--selected {\n color: var(--color-foreground-on-medium-background-primary);\n}\n\n.panel-sub-nav__item--on-bold {\n color: var(--color-foreground-on-bold-background-secondary);\n}\n\n.panel-sub-nav__item--on-bold.panel-sub-nav__item--selected {\n color: var(--color-foreground-on-bold-background-primary);\n}\n\n.panel-sub-nav__item--on-strong {\n color: var(--color-foreground-on-strong-background-secondary);\n}\n\n.panel-sub-nav__item--on-strong.panel-sub-nav__item--selected {\n color: var(--color-foreground-on-strong-background-primary);\n}\n\n.panel-sub-nav__item--on-translucent {\n color: var(--color-translucent-foreground-secondary);\n}\n\n.panel-sub-nav__item--on-translucent.panel-sub-nav__item--selected {\n color: var(--color-translucent-foreground-primary);\n}\n\n.panel-sub-nav__item--on-inverted {\n color: var(--color-inverted-foreground-secondary);\n}\n\n.panel-sub-nav__item--on-inverted.panel-sub-nav__item--selected {\n color: var(--color-inverted-foreground-primary);\n}\n\n.panel-sub-nav__item--on-media {\n color: var(--color-media-foreground-secondary);\n}\n\n.panel-sub-nav__item--on-media.panel-sub-nav__item--selected {\n color: var(--color-media-foreground-primary);\n}\n\n.panel-sub-nav__item--on-always-dark {\n color: var(--color-always-dark-foreground-secondary);\n}\n\n.panel-sub-nav__item--on-always-dark.panel-sub-nav__item--selected {\n color: var(--color-always-dark-foreground-primary);\n}\n\nds-text.panel-sub-nav__label {\n flex: 1;\n min-width: 0;\n padding: 0 var(--ds-control-label-inset);\n}\n",
|
|
236
|
+
"type": "registry:ui"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"path": "src/wc/components/PanelSubNav/PanelSubNav.tsx",
|
|
240
|
+
"content": "import { Component, Prop, Event, EventEmitter, Element, Listen, Watch, h, Host } from '@stencil/core';\nimport type { PanelSubNavItem } from './panel-sub-nav-types';\n\nexport type PanelSubNavBackground =\n | 'faint'\n | 'medium'\n | 'bold'\n | 'strong'\n | 'translucent'\n | 'inverted'\n | 'media'\n | 'always-dark';\n\n@Component({\n tag: 'ds-panel-sub-nav',\n styleUrl: 'PanelSubNav.css',\n scoped: true,\n})\nexport class PanelSubNav {\n @Element() el!: HTMLElement;\n\n /** Required selected item id when enabled items exist. Keep synchronized with the visible panel. */\n @Prop({ mutable: true }) value: string = '';\n /**\n * Local panel tabs. Assign this array through the JavaScript property.\n * Replace the array reference when items change.\n */\n @Prop() items: PanelSubNavItem[] = [];\n /** Actual parent surface context. Omit on primary and secondary surfaces. */\n @Prop() background: PanelSubNavBackground | undefined;\n @Prop({ attribute: 'aria-label' }) ariaLabel: string | null = null;\n @Prop({ attribute: 'aria-labelledby' }) ariaLabelledby: string | undefined;\n\n @Event() dsChange!: EventEmitter<string>;\n\n private get enabledItems(): PanelSubNavItem[] {\n return this.items.filter(item => !item.isInactive);\n }\n\n private get focusableId(): string {\n return this.enabledItems.some(item => item.id === this.value)\n ? this.value\n : (this.enabledItems[0]?.id ?? '');\n }\n\n private selectItem(id: string) {\n this.value = id;\n this.dsChange.emit(id);\n this.focusItem(id);\n }\n\n private focusItem(id: string) {\n const item = this.el.querySelector(`[data-panel-sub-nav-id=\"${id}\"]`) as HTMLElement | null;\n item?.focus({ preventScroll: true });\n }\n\n @Watch('value')\n onValueChange(next: string, previous: string | undefined) {\n if (previous === undefined || next === previous) return;\n\n requestAnimationFrame(() => {\n const active = document.activeElement as HTMLElement | null;\n if (!active || !this.el.contains(active)) return;\n this.focusItem(this.enabledItems.some(item => item.id === next) ? next : this.focusableId);\n });\n }\n\n private findEnabled(from: number, step: 1 | -1): number {\n const length = this.items.length;\n for (let offset = 1; offset <= length; offset++) {\n const index = (from + step * offset + length * offset) % length;\n if (!this.items[index]?.isInactive) return index;\n }\n return from;\n }\n\n @Listen('keydown')\n handleKeyDown(event: KeyboardEvent) {\n if (!this.enabledItems.length) return;\n\n const focusedId = (event.target as Element | null)\n ?.closest<HTMLElement>('[data-panel-sub-nav-id]')\n ?.dataset['panelSubNavId'];\n const focusedIndex = this.items.findIndex(item => item.id === focusedId);\n const selectedIndex = this.items.findIndex(item => item.id === this.value && !item.isInactive);\n const currentIndex = focusedIndex >= 0\n ? focusedIndex\n : selectedIndex >= 0\n ? selectedIndex\n : (event.key === 'ArrowUp' ? 0 : -1);\n let nextIndex: number | null = null;\n\n if (event.key === 'ArrowDown') {\n nextIndex = this.findEnabled(currentIndex, 1);\n } else if (event.key === 'ArrowUp') {\n nextIndex = this.findEnabled(currentIndex, -1);\n } else if (event.key === 'Home') {\n nextIndex = this.items.findIndex(item => !item.isInactive);\n } else if (event.key === 'End') {\n const reversedIndex = [...this.items].reverse().findIndex(item => !item.isInactive);\n nextIndex = reversedIndex < 0 ? null : this.items.length - 1 - reversedIndex;\n }\n\n if (nextIndex === null || nextIndex < 0) return;\n const next = this.items[nextIndex];\n if (!next || next.isInactive) return;\n\n event.preventDefault();\n this.selectItem(next.id);\n }\n\n render() {\n const focusableId = this.focusableId;\n const background = this.background;\n\n return (\n <Host>\n <div\n class=\"panel-sub-nav\"\n role=\"tablist\"\n aria-orientation=\"vertical\"\n aria-label={this.ariaLabel}\n aria-labelledby={this.ariaLabelledby}\n >\n {this.items.map(item => {\n const isSelected = item.id === this.value;\n return (\n <button\n id={item.id}\n type=\"button\"\n role=\"tab\"\n data-panel-sub-nav-id={item.id}\n class={{\n 'panel-sub-nav__item': true,\n 'panel-sub-nav__item--selected': isSelected,\n 'ds-control--md': true,\n 'ds-focus-ring-inset': true,\n 'ds-interaction-fill': !item.isInactive,\n 'ds-interaction-fill--selected': isSelected && !item.isInactive,\n 'ds-interaction-fill--on-faint': background === 'faint',\n 'ds-interaction-fill--on-medium': background === 'medium',\n 'ds-interaction-fill--on-bold': background === 'bold',\n 'ds-interaction-fill--on-strong': background === 'strong',\n 'ds-interaction-fill--on-translucent': background === 'translucent',\n 'ds-interaction-fill--on-inverted': background === 'inverted',\n 'ds-interaction-fill--on-media': background === 'media',\n 'ds-interaction-fill--on-always-dark': background === 'always-dark',\n [`panel-sub-nav__item--on-${background}`]: !!background,\n 'ds-control-inactive': !!item.isInactive,\n }}\n aria-selected={isSelected ? 'true' : 'false'}\n aria-controls={item.panelId}\n aria-disabled={item.isInactive ? 'true' : undefined}\n disabled={item.isInactive}\n tabIndex={item.id === focusableId ? 0 : -1}\n onClick={() => !item.isInactive && this.selectItem(item.id)}\n >\n <ds-text\n class=\"panel-sub-nav__label ds-interaction-fill__content\"\n as=\"span\"\n variant=\"text-body-medium\"\n color=\"inherit\"\n >\n {item.label}\n </ds-text>\n </button>\n );\n })}\n </div>\n </Host>\n );\n }\n}\n",
|
|
241
|
+
"type": "registry:ui"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"path": "src/wc/components/PanelSubNav/panel-sub-nav-types.ts",
|
|
245
|
+
"content": "export interface PanelSubNavItem {\n /** Unique tab id. Also used by the controlled panel's aria-labelledby. */\n id: string;\n label: string;\n /** ID of the tabpanel controlled by this item. */\n panelId: string;\n /** Prevent selection and remove the item from keyboard navigation. */\n isInactive?: boolean;\n}\n",
|
|
246
|
+
"type": "registry:ui"
|
|
247
|
+
}
|
|
248
|
+
]
|
|
249
|
+
}
|