@salesforcedevs/dx-components 1.41.0 → 1.42.0-final-test

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.
Files changed (36) hide show
  1. package/lwc.config.json +4 -2
  2. package/package.json +46 -47
  3. package/src/modules/dx/button/button.css +2 -2
  4. package/src/modules/dx/dropdown/dropdown.css +29 -1
  5. package/src/modules/dx/dropdown/dropdown.html +1 -1
  6. package/src/modules/dx/dropdown/dropdown.ts +16 -1
  7. package/src/modules/dx/dropdownOption/dropdownOption.css +30 -6
  8. package/src/modules/dx/popover/popover.ts +119 -7
  9. package/src/modules/dx/searchResults/searchResults.css +119 -6
  10. package/src/modules/dx/searchResults/searchResults.html +89 -91
  11. package/src/modules/dx/searchResults/searchResults.ts +200 -473
  12. package/src/modules/dx/sidebar/sidebar.css +1 -0
  13. package/src/modules/dx/sidebar/sidebar.html +2 -5
  14. package/src/modules/dx/sidebar/sidebar.ts +44 -29
  15. package/src/modules/dx/sidebarOld/sidebarOld.html +1 -0
  16. package/src/modules/dx/sidebarSearch/sidebarSearch.ts +163 -342
  17. package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.css +61 -23
  18. package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.ts +12 -4
  19. package/src/modules/dx/tree/tree.html +1 -0
  20. package/src/modules/dx/tree/tree.ts +5 -1
  21. package/src/modules/dx/tree/treeHandler.ts +92 -13
  22. package/src/modules/dx/treeItem/treeItem.css +41 -0
  23. package/src/modules/dx/treeItem/treeItem.html +17 -2
  24. package/src/modules/dx/treeItem/treeItem.ts +109 -11
  25. package/src/modules/dx/treeTile/treeTile.css +57 -0
  26. package/src/modules/dx/treeTile/treeTile.ts +12 -3
  27. package/src/modules/dx/typeBadge/typeBadge.ts +23 -2
  28. package/src/modules/dx/versionPicker/versionPicker.css +248 -0
  29. package/src/modules/dx/versionPicker/versionPicker.html +73 -0
  30. package/src/modules/dx/versionPicker/versionPicker.ts +157 -0
  31. package/src/modules/dxHelpers/commonSidebar/commonSidebar.css +3 -3
  32. package/src/modules/dxHelpers/commonTreeItem/commonTreeItem.css +4 -0
  33. package/src/modules/dxHelpers/typeBadge/typeBadge.css +22 -0
  34. package/src/modules/dxUtils/openSearch/openSearch.ts +343 -0
  35. package/src/modules/dxUtils/topicVersion/topicVersion.ts +758 -0
  36. package/LICENSE +0 -12
@@ -28,10 +28,12 @@ export default class TreeTile extends LightningElement {
28
28
  @api isExpanded = false;
29
29
  @api hasChildren = false;
30
30
  @api isSelected = false;
31
+ @api isContainedSelection = false;
31
32
  @api href!: string;
32
33
  @api showArrow = false;
33
34
  @api target!: string;
34
35
  @api isExternalLink = false;
36
+ @api hasVersionPicker = false;
35
37
 
36
38
  get tileAriaLevel() {
37
39
  return this.treeNode.level + 2;
@@ -43,18 +45,21 @@ export default class TreeTile extends LightningElement {
43
45
  * screen reader users (WCAG 2.4.4)
44
46
  */
45
47
  get linkAriaLabel(): string | null {
46
- if (!this.treeNode.redirectToChild || !this.treeNode.link?.href) {
48
+ if (!this.treeNode.redirectToChild) {
47
49
  return null;
48
50
  }
49
51
  /**
50
52
  * The redirect can target a deep descendant, so walk the first-child
51
53
  * chain to the node that owns the destination link and name it.
54
+ * The destination href may live on this anchor (parent-only topics do
55
+ * not copy it onto the parent node).
52
56
  */
53
57
  let destination = this.treeNode.children?.[0];
54
58
  while (destination?.redirectToChild) {
55
59
  destination = destination.children?.[0];
56
60
  }
57
- return destination?.link?.href === this.treeNode.link.href
61
+ const triggerHref = this.href || this.treeNode.link?.href;
62
+ return destination?.link?.href && destination.link.href === triggerHref
58
63
  ? `${this.treeNode.label}, opens ${destination.label}`
59
64
  : null;
60
65
  }
@@ -101,7 +106,11 @@ export default class TreeTile extends LightningElement {
101
106
  "tile-root": this.isRoot,
102
107
  "tile-with-children": !this.isRoot && this.hasChildren,
103
108
  "tile-root-with-child": this.isRoot && this.showArrow,
104
- "sidebar-item-selected": this.isSelected
109
+ "sidebar-item-selected":
110
+ this.isSelected && !this.isContainedSelection,
111
+ "sidebar-item-selected-text":
112
+ this.isSelected && this.isContainedSelection,
113
+ "tile-with-version-picker": this.hasVersionPicker
105
114
  });
106
115
  }
107
116
 
@@ -7,6 +7,7 @@ import {
7
7
  IconSprite,
8
8
  IconData,
9
9
  IconSymbol,
10
+ StatusBadgeVariant,
10
11
  TypeBadgeSize
11
12
  } from "typings/custom";
12
13
  import { colorToDxColors, buildStyleColorVariables } from "dxUtils/css";
@@ -20,9 +21,16 @@ import {
20
21
  getContentTypeColorVariables
21
22
  } from "dxUtils/contentTypes";
22
23
 
24
+ // Opt-in solid status variants (status-success/-warning/-error).
25
+ export const STATUS_BADGE_VARIANTS: StatusBadgeVariant[] = [
26
+ "status-success",
27
+ "status-warning",
28
+ "status-error"
29
+ ];
30
+
23
31
  export default class TypeBadge extends LightningElement {
24
32
  @api size: TypeBadgeSize = "default";
25
- @api variant: Brand | ContentType = "default";
33
+ @api variant: Brand | ContentType | StatusBadgeVariant = "default";
26
34
  @api color?: Color;
27
35
  @api dark?: false;
28
36
 
@@ -87,11 +95,24 @@ export default class TypeBadge extends LightningElement {
87
95
  return isContentType(this.variant);
88
96
  }
89
97
 
98
+ private get isStatus(): boolean {
99
+ return STATUS_BADGE_VARIANTS.includes(
100
+ this.variant as StatusBadgeVariant
101
+ );
102
+ }
103
+
90
104
  private get className(): string {
91
- return cx("dx-badge", `size-${this.size}`);
105
+ return cx(
106
+ "dx-badge",
107
+ `size-${this.size}`,
108
+ this.isStatus && this.variant
109
+ );
92
110
  }
93
111
 
94
112
  private get style(): string {
113
+ if (this.isStatus) {
114
+ return "";
115
+ }
95
116
  if (this.dark) {
96
117
  return buildStyleColorVariables({
97
118
  background: "--dx-g-purple-vibrant-40",
@@ -0,0 +1,248 @@
1
+ @import "dxHelpers/reset";
2
+
3
+ /* NOTE: dx-version-picker-width is used by both dx-button and dx-dropdown to maintain a consistent width. */
4
+ :host {
5
+ /* Always positioned so the popover's containing block stays the picker.
6
+ Toggling position with aria-expanded lets the menu jump to the sidebar
7
+ (top of the ToC) for a frame before LWC hides it. */
8
+ position: relative;
9
+
10
+ --dx-c-dropdown-option-font-weight: normal;
11
+ --dx-c-dropdown-option-font-size: var(--dx-g-text-base);
12
+ --dx-c-dropdown-option-label-color: var(--dx-g-gray-10);
13
+ --dx-c-dropdown-option-active-label-color: var(--dx-g-gray-10);
14
+ --dx-c-dropdown-option-padding: var(--dx-g-spacing-sm)
15
+ var(--dx-g-spacing-lg);
16
+ --dx-c-popover-padding: var(--dx-g-spacing-sm) 0;
17
+ --popover-container-open-transform: translateY(4px);
18
+ --dx-c-version-picker-focus-ring: 0 0 0 2px white,
19
+ 0 0 0 4px var(--dx-g-blue-vibrant-60);
20
+ }
21
+
22
+ /* Open menus must stack above later sibling pickers in the sidebar. */
23
+ :host(:has([aria-expanded="true"])) {
24
+ z-index: 2;
25
+ }
26
+
27
+ .version-picker-container {
28
+ /* Override --dx-version-picker-padding to change the inset (e.g. when the
29
+ picker sits inside an already-padded container). */
30
+ padding: var(
31
+ --dx-version-picker-padding,
32
+ var(--dx-g-spacing-sm) var(--dx-g-spacing-lg) var(--dx-g-spacing-sm)
33
+ var(--dx-g-global-header-padding-horizontal)
34
+ );
35
+
36
+ /* Override --dx-version-picker-divider (e.g. `none`) to restyle dividers. */
37
+ border-top: var(--dx-version-picker-divider, 1px solid var(--dx-g-gray-90));
38
+ border-bottom: var(
39
+ --dx-version-picker-divider,
40
+ 1px solid var(--dx-g-gray-90)
41
+ );
42
+ }
43
+
44
+ /* Inline sidebar variant: drop the header-slot chrome so the picker sits
45
+ beside a tree node without extra padding or divider lines. */
46
+ .version-picker-container-small {
47
+ display: flex;
48
+ align-items: center;
49
+ padding: 0;
50
+ border: none;
51
+ }
52
+
53
+ .version-picker-button {
54
+ display: flex;
55
+ width: var(--dx-version-picker-width, 296px);
56
+ overflow: visible;
57
+
58
+ --dx-c-button-horizontal-spacing: var(--dx-g-spacing-sm);
59
+ --dx-g-button-icon-color: var(--dx-g-gray-50);
60
+ }
61
+
62
+ .version-picker-button:hover,
63
+ .version-picker-button[aria-expanded="true"] {
64
+ --dx-g-button-icon-color: var(--dx-g-blue-vibrant-20);
65
+ }
66
+
67
+ /**
68
+ * NOTE: This CSS ensures the span inside the button stays within the parent's width, avoiding overflow.
69
+ * Not keeping this in common component to ensure that existing functionality works as it is.
70
+ */
71
+ dx-button::part(content) {
72
+ width: inherit;
73
+ overflow: hidden;
74
+ }
75
+
76
+ /* Border width stays 1px in every state. Hover, open, and focus paint the
77
+ 2px blue stroke with an inset shadow so the box does not grow.
78
+ Tertiary's hover border is overridden. */
79
+ .version-picker-button::part(container) {
80
+ box-sizing: border-box;
81
+ background: white;
82
+ border: 1px solid var(--dx-g-gray-50);
83
+ border-radius: var(--dx-g-spacing-xs);
84
+ box-shadow: none;
85
+ color: var(--dx-g-gray-10);
86
+ outline: none;
87
+ transition: var(--dx-g-transition-hue-1x), box-shadow 0.15s linear;
88
+ }
89
+
90
+ /* Hover only (not open): 2px #032D60 on #EEF4FF, no ring.
91
+ Border color matches the fill so the 1px border does not add a third
92
+ pixel around the inset stroke.
93
+ :focus-visible is included so click-open + Escape (which upgrades the
94
+ trigger to keyboard focus) still looks like hover while the pointer is on
95
+ the picker. */
96
+ .version-picker-button:hover:not([aria-expanded="true"])::part(container),
97
+ .version-picker-button:hover:not([aria-expanded="true"])::part(
98
+ container
99
+ ):focus-visible {
100
+ background: var(--dx-g-blue-vibrant-95);
101
+ border: 1px solid var(--dx-g-blue-vibrant-95);
102
+ box-shadow: inset 0 0 0 2px var(--dx-g-blue-vibrant-20);
103
+ }
104
+
105
+ /* Open keeps the fill and the 2px stroke. The focus ring is keyboard-only,
106
+ on the closed picker below. */
107
+ .version-picker-button[aria-expanded="true"]::part(container) {
108
+ background: var(--dx-g-blue-vibrant-95);
109
+ border: 1px solid var(--dx-g-blue-vibrant-95);
110
+ border-radius: var(--dx-g-spacing-xs);
111
+ box-shadow: inset 0 0 0 2px var(--dx-g-blue-vibrant-20);
112
+ }
113
+
114
+ /* Keyboard focus while closed. */
115
+ .version-picker-button:not([aria-expanded="true"])::part(
116
+ container
117
+ ):focus-visible {
118
+ --dx-g-button-icon-color: var(--dx-g-blue-vibrant-20);
119
+
120
+ background: var(--dx-g-blue-vibrant-95);
121
+ border: 1px solid var(--dx-g-blue-vibrant-95);
122
+ border-radius: var(--dx-g-spacing-xs);
123
+ box-shadow: inset 0 0 0 2px var(--dx-g-blue-vibrant-20),
124
+ var(--dx-c-version-picker-focus-ring);
125
+ }
126
+
127
+ .selected-version {
128
+ display: flex;
129
+ flex-direction: row;
130
+ align-items: center;
131
+ }
132
+
133
+ .selected-version-label {
134
+ flex: 1;
135
+ overflow: hidden;
136
+ text-align: left;
137
+ text-overflow: ellipsis;
138
+ white-space: nowrap;
139
+ }
140
+
141
+ dx-type-badge.latest-badge,
142
+ dx-type-badge.not-latest-badge {
143
+ margin-left: var(--dx-g-spacing-sm);
144
+ }
145
+
146
+ /* ------------------------------------------------------------------ *
147
+ * Small "dot" variant (opt-in via `small`). Additive
148
+ * ------------------------------------------------------------------ */
149
+
150
+ /* Menu is capped at the ToC width (296px), not the 104px trigger, so options
151
+ keep the same 16px / 8px 24px / gray-10 type as the default picker. */
152
+ .version-picker-dropdown-small {
153
+ --dx-c-dropdown-option-font-size: var(--dx-g-text-base);
154
+ --dx-c-dropdown-option-padding: var(--dx-g-spacing-sm)
155
+ var(--dx-g-spacing-lg);
156
+ --dx-c-dropdown-option-label-color: var(--dx-g-gray-10);
157
+ --dx-c-dropdown-option-border-radius: 0;
158
+ --dx-c-popover-border: none;
159
+
160
+ /* Hug the labels (down to the shortest) but never wider than the ToC
161
+ content: 296px on desktop, and on the smallest breakpoint the sidebar
162
+ variable grows with the viewport up to 720px. Long labels wrap inside
163
+ that cap. */
164
+ --dx-c-dropdown-menu-max-width: var(--dx-version-picker-width, 296px);
165
+ --dx-c-dropdown-fit-white-space: normal;
166
+ --dx-c-dropdown-fit-overflow: hidden;
167
+ --dx-c-dropdown-fit-text-overflow: clip;
168
+ --dx-c-dropdown-option-overflow-wrap: anywhere;
169
+ }
170
+
171
+ .version-picker-button-small {
172
+ width: fit-content;
173
+ max-width: 104px;
174
+
175
+ --dx-c-button-font-size: var(--dx-g-text-xs);
176
+ --dx-c-button-font-weight: var(--dx-g-font-normal);
177
+ --dx-c-button-line-height: var(--dx-g-spacing-lg);
178
+ --dx-c-button-icon-gap: var(--dx-g-spacing-2xs);
179
+ }
180
+
181
+ /* min-width: 0 on each flex ancestor lets the label truncate: a flex item's
182
+ default min-width: auto refuses to shrink below its content and overrides the
183
+ host's max-width, so without this the trigger overflows instead. */
184
+ .version-picker-button-small::part(content) {
185
+ display: flex;
186
+ flex: 1;
187
+ min-width: 0;
188
+ width: auto;
189
+ overflow: hidden;
190
+ }
191
+
192
+ /* width:100% re-ties to the 104px-capped host (container is width:inherit,
193
+ which copies width but not max-width). Border/bg/states are shared above. */
194
+ .version-picker-button-small::part(container) {
195
+ width: 100%;
196
+ height: var(--dx-g-spacing-lg);
197
+ padding: 0 var(--dx-g-spacing-xs);
198
+ }
199
+
200
+ .selected-version-small {
201
+ flex: 1;
202
+ min-width: 0;
203
+ }
204
+
205
+ .version-picker-dot {
206
+ flex: 0 0 auto;
207
+ width: var(--dx-g-spacing-sm);
208
+ height: var(--dx-g-spacing-sm);
209
+ margin-right: var(--dx-g-spacing-xs);
210
+ border-radius: 50%;
211
+ }
212
+
213
+ .version-picker-dot-latest {
214
+ background: var(--dx-g-green-vibrant-60);
215
+ }
216
+
217
+ .version-picker-dot-not-latest {
218
+ background: var(--dx-g-yellow-vibrant-80);
219
+ }
220
+
221
+ /* inline-block (not flex) so the label can truncate; line-height centers it. */
222
+ .version-picker-readonly {
223
+ box-sizing: border-box;
224
+ display: inline-block;
225
+ width: var(--dx-version-picker-width, 296px);
226
+ height: var(--dx-g-spacing-xl);
227
+ margin: 0;
228
+ padding: 0 var(--dx-g-spacing-sm);
229
+ border: 1px solid var(--dx-g-gray-80);
230
+ border-radius: var(--dx-g-spacing-xs);
231
+ overflow: hidden;
232
+ color: var(--dx-g-gray-10);
233
+ text-overflow: ellipsis;
234
+ white-space: nowrap;
235
+ font: var(--dx-g-font-normal) var(--dx-g-text-sm) / var(--dx-g-spacing-xl)
236
+ var(--dx-g-font-sans),
237
+ sans-serif;
238
+ }
239
+
240
+ .version-picker-readonly-small {
241
+ width: fit-content;
242
+ max-width: 104px;
243
+ height: var(--dx-g-spacing-lg);
244
+ padding: 0 var(--dx-g-spacing-xs);
245
+ font: var(--dx-g-font-normal) var(--dx-g-text-xs) / var(--dx-g-spacing-lg)
246
+ var(--dx-g-font-sans),
247
+ sans-serif;
248
+ }
@@ -0,0 +1,73 @@
1
+ <template>
2
+ <div lwc:if={showVersionPicker} class={containerClass}>
3
+ <!-- Small read-only: plain value, no dropdown -->
4
+ <p
5
+ lwc:if={readOnly}
6
+ class={readOnlyClass}
7
+ title={selectedVersion.label}
8
+ >
9
+ {selectedVersion.label}
10
+ </p>
11
+
12
+ <dx-dropdown
13
+ lwc:else
14
+ class={dropdownClass}
15
+ options={versions}
16
+ analytics-event="custEv_docVersionSelect"
17
+ analytics-payload={analyticsPayload}
18
+ value={selectedVersion.id}
19
+ width-mode={dropdownWidthMode}
20
+ onchange={onVersionChange}
21
+ >
22
+ <dx-button
23
+ class={triggerClass}
24
+ variant="tertiary"
25
+ size="small"
26
+ font="sans"
27
+ icon-symbol="chevrondown"
28
+ icon-size={triggerIconSize}
29
+ aria-label={triggerAriaLabel}
30
+ >
31
+ <div class={selectedVersionClass}>
32
+ <!-- Small: leading colored dot -->
33
+ <template lwc:if={small}>
34
+ <template lwc:if={showLatestTag}>
35
+ <span class={dotClass} aria-hidden="true"></span>
36
+ </template>
37
+ <p
38
+ class="selected-version-label"
39
+ title={selectedVersion.label}
40
+ >
41
+ {selectedVersion.label}
42
+ </p>
43
+ </template>
44
+ <!-- Default: trailing Latest/Not-Latest badge -->
45
+ <template lwc:else>
46
+ <p
47
+ class="selected-version-label"
48
+ title={selectedVersion.label}
49
+ >
50
+ {selectedVersion.label}
51
+ </p>
52
+ <template lwc:if={showLatestTag}>
53
+ <dx-type-badge
54
+ class="latest-badge"
55
+ lwc:if={latestVersion}
56
+ variant="status-success"
57
+ value="Latest"
58
+ size="small"
59
+ ></dx-type-badge>
60
+ <dx-type-badge
61
+ class="not-latest-badge"
62
+ lwc:else
63
+ variant="status-warning"
64
+ value="Not Latest"
65
+ size="small"
66
+ ></dx-type-badge>
67
+ </template>
68
+ </template>
69
+ </div>
70
+ </dx-button>
71
+ </dx-dropdown>
72
+ </div>
73
+ </template>
@@ -0,0 +1,157 @@
1
+ import { LightningElement, api, track } from "lwc";
2
+ import cx from "classnames";
3
+
4
+ import { AnalyticsPayload, OptionWithNested } from "typings/custom";
5
+
6
+ import { toJson, normalizeBoolean } from "dxUtils/normalizers";
7
+
8
+ export default class VersionPicker extends LightningElement {
9
+ @api analyticsEvent?: string;
10
+ @api analyticsPayload?: AnalyticsPayload;
11
+
12
+ @track private _versions!: OptionWithNested[];
13
+ private _selectedVersion?: OptionWithNested;
14
+ private _latestVersion: boolean = false;
15
+ private _hideBadge: boolean = false;
16
+ private _small: boolean = false;
17
+ private _readOnly: boolean = false;
18
+
19
+ @api
20
+ get versions() {
21
+ return this._versions;
22
+ }
23
+
24
+ set versions(value: OptionWithNested[]) {
25
+ this._versions = toJson(value);
26
+ }
27
+
28
+ @api
29
+ get selectedVersion(): OptionWithNested | undefined {
30
+ return this._selectedVersion || this.versions[0];
31
+ }
32
+
33
+ set selectedVersion(value: OptionWithNested) {
34
+ if (value) {
35
+ this._selectedVersion = toJson(value);
36
+ }
37
+ }
38
+
39
+ @api
40
+ get latestVersion() {
41
+ return this._latestVersion;
42
+ }
43
+
44
+ set latestVersion(value) {
45
+ this._latestVersion = normalizeBoolean(value);
46
+ }
47
+
48
+ @api
49
+ get hideBadge() {
50
+ return this._hideBadge;
51
+ }
52
+
53
+ set hideBadge(value) {
54
+ this._hideBadge = normalizeBoolean(value);
55
+ }
56
+
57
+ // Opt-in compact "dot" variant (24px, abbreviated label). Off by default so
58
+ // existing consumers render the default trigger unchanged.
59
+ @api
60
+ get small() {
61
+ return this._small;
62
+ }
63
+
64
+ set small(value) {
65
+ this._small = normalizeBoolean(value);
66
+ }
67
+
68
+ // Opt-in read-only state: plain value, no dropdown menu.
69
+ @api
70
+ get readOnly() {
71
+ return this._readOnly;
72
+ }
73
+
74
+ set readOnly(value) {
75
+ this._readOnly = normalizeBoolean(value);
76
+ }
77
+
78
+ private get showVersionPicker() {
79
+ return this._versions && this._versions.length !== 0;
80
+ }
81
+
82
+ private get containerClass(): string {
83
+ return this.small
84
+ ? "version-picker-container-small"
85
+ : "version-picker-container";
86
+ }
87
+
88
+ private get showLatestTag(): boolean {
89
+ return !this.hideBadge;
90
+ }
91
+
92
+ private get readOnlyClass(): string {
93
+ return cx(
94
+ "version-picker-readonly",
95
+ this.small && "version-picker-readonly-small"
96
+ );
97
+ }
98
+
99
+ private get dotClass(): string {
100
+ return `version-picker-dot ${
101
+ this.latestVersion
102
+ ? "version-picker-dot-latest"
103
+ : "version-picker-dot-not-latest"
104
+ }`;
105
+ }
106
+
107
+ // Accessible name for the small trigger: includes the latest state so it
108
+ // isn't conveyed by the dot's color alone (WCAG 1.4.1). Omits the state
109
+ // when the indicator is hidden.
110
+ private get smallTriggerAriaLabel(): string {
111
+ const label = this.selectedVersion?.label ?? "";
112
+ if (!this.showLatestTag) {
113
+ return label;
114
+ }
115
+ return `${label}, ${this.latestVersion ? "Latest" : "Not Latest"}`;
116
+ }
117
+
118
+ // --- Per-variant values for the shared dropdown/button markup below. The
119
+ // small variant opts into extra classes and a compact chevron.
120
+
121
+ // Not cx(): the default must have NO class attribute (cx returns "", which
122
+ // would render class="" and break the frozen consumer snapshots).
123
+ private get dropdownClass(): string | undefined {
124
+ return this.small ? "version-picker-dropdown-small" : undefined;
125
+ }
126
+
127
+ // "full" matches the trigger (ToC width). "fit-end" sizes to the labels,
128
+ // caps at the ToC width, and opens inward.
129
+ private get dropdownWidthMode(): "full" | "fit-end" {
130
+ return this.small ? "fit-end" : "full";
131
+ }
132
+
133
+ private get triggerClass(): string {
134
+ return cx(
135
+ "version-picker-button",
136
+ this.small && "version-picker-button-small"
137
+ );
138
+ }
139
+
140
+ private get triggerIconSize(): string {
141
+ return this.small ? "xsmall" : "medium";
142
+ }
143
+
144
+ // Default returns "" (dx-button's own default) so the trigger's rendered
145
+ // aria-label is unchanged for the default variant.
146
+ private get triggerAriaLabel(): string {
147
+ return this.small ? this.smallTriggerAriaLabel : "";
148
+ }
149
+
150
+ private get selectedVersionClass(): string {
151
+ return cx("selected-version", this.small && "selected-version-small");
152
+ }
153
+
154
+ private onVersionChange(e: CustomEvent) {
155
+ this.dispatchEvent(new CustomEvent("change", { detail: e.detail }));
156
+ }
157
+ }
@@ -11,7 +11,7 @@
11
11
  --dx-c-sidebar-button-border-hover: var(--dx-g-blue-vibrant-50);
12
12
  --dx-c-sidebar-left-padding: var(--dx-g-global-header-padding-horizontal);
13
13
  --dx-c-sidebar-vertical-padding: var(--dx-g-spacing-md);
14
- --doc-version-picker-width: 296px;
14
+ --dx-version-picker-width: 296px;
15
15
  }
16
16
 
17
17
  .header {
@@ -170,9 +170,9 @@
170
170
  margin-bottom: var(--dx-g-spacing-2xl);
171
171
  }
172
172
 
173
- @media screen and (max-width: 767px) {
173
+ @media screen and (max-width: 768px) {
174
174
  :host {
175
- --doc-version-picker-width: calc(
175
+ --dx-version-picker-width: calc(
176
176
  100vw - var(--dx-c-sidebar-left-padding) - var(--dx-g-spacing-lg)
177
177
  );
178
178
  }
@@ -13,6 +13,10 @@
13
13
  color: var(--dx-g-blue-vibrant-40) !important;
14
14
  }
15
15
 
16
+ .sidebar-item-selected-text {
17
+ color: var(--dx-g-blue-vibrant-40) !important;
18
+ }
19
+
16
20
  .sidebar-item {
17
21
  padding: 6px var(--dx-g-spacing-lg) 6px
18
22
  var(--dx-g-global-header-padding-horizontal);
@@ -26,6 +26,28 @@
26
26
  --height: var(--dx-g-spacing-mlg);
27
27
  }
28
28
 
29
+ .dx-badge.status-success,
30
+ .dx-badge.status-warning,
31
+ .dx-badge.status-error {
32
+ /* No spacing token maps to 10px; status badges need this exact padding. */
33
+ --horizontal-spacing: 10px;
34
+ }
35
+
36
+ .dx-badge.status-success {
37
+ --color: var(--sds-g-gray-1);
38
+ --background: var(--dx-g-green-vibrant-50);
39
+ }
40
+
41
+ .dx-badge.status-warning {
42
+ --color: var(--dx-g-gray-15);
43
+ --background: var(--dx-g-yellow-vibrant-80);
44
+ }
45
+
46
+ .dx-badge.status-error {
47
+ --color: var(--sds-g-gray-1);
48
+ --background: var(--dx-g-red-vibrant-40);
49
+ }
50
+
29
51
  svg,
30
52
  dx-icon {
31
53
  margin-right: var(--dx-g-spacing-sm);