@ds-mo/ui 2.4.0 → 2.5.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.
Files changed (60) hide show
  1. package/dist/.build-stamp +1 -1
  2. package/dist/components/ds-app-shell.js +1 -1
  3. package/dist/components/ds-app-shell.js.map +1 -1
  4. package/dist/components/ds-bar-nav.js +1 -1
  5. package/dist/components/ds-bar-nav.js.map +1 -1
  6. package/dist/components/ds-menu.js +1 -1
  7. package/dist/components/ds-panel-tools.js +1 -1
  8. package/dist/components/ds-panel-tools.js.map +1 -1
  9. package/dist/components/ds-select.js +1 -1
  10. package/dist/components/ds-select.js.map +1 -1
  11. package/dist/components/ds-shell-gradient-picker.d.ts +11 -0
  12. package/dist/components/ds-shell-gradient-picker.js +2 -0
  13. package/dist/components/ds-shell-gradient-picker.js.map +1 -0
  14. package/dist/components/ds-shell-gradient-swatch.d.ts +11 -0
  15. package/dist/components/ds-shell-gradient-swatch.js +2 -0
  16. package/dist/components/ds-shell-gradient-swatch.js.map +1 -0
  17. package/dist/components/ds-slider.js +1 -1
  18. package/dist/components/ds-toggle.js +1 -1
  19. package/dist/components/p-BU5fKLdO.js +2 -0
  20. package/dist/components/p-BU5fKLdO.js.map +1 -0
  21. package/dist/components/p-BgiK3sHs.js +2 -0
  22. package/dist/components/p-BgiK3sHs.js.map +1 -0
  23. package/dist/components/p-CLmK4lRE.js +2 -0
  24. package/dist/components/p-CLmK4lRE.js.map +1 -0
  25. package/dist/components/p-DKG6W4pb.js +2 -0
  26. package/dist/components/p-DKG6W4pb.js.map +1 -0
  27. package/dist/types/components/AppShell/AppShell.d.ts +7 -1
  28. package/dist/types/components/Menu/Menu.d.ts +4 -0
  29. package/dist/types/components/Menu/menu-types.d.ts +10 -1
  30. package/dist/types/components/PanelTools/PanelTools.d.ts +1 -1
  31. package/dist/types/components/ShellGradientPicker/ShellGradientPicker.d.ts +10 -0
  32. package/dist/types/components/ShellGradientSwatch/ShellGradientSwatch.d.ts +14 -0
  33. package/dist/types/components/ShellGradientSwatch/shell-gradient-swatch-types.d.ts +4 -0
  34. package/dist/types/components.d.ts +130 -3
  35. package/dist/types/nav/index.d.ts +2 -0
  36. package/dist/types/nav/shell-gradient-presets.d.ts +11 -0
  37. package/dist/types/nav/shell-gradient.d.ts +7 -4
  38. package/dist/types/nav/shell-shortcuts.d.ts +4 -4
  39. package/package.json +2 -2
  40. package/src/angular/index.ts +2 -0
  41. package/src/angular/proxies.ts +69 -3
  42. package/src/react/components.ts +2 -0
  43. package/src/react/ds-menu.ts +5 -3
  44. package/src/react/ds-shell-gradient-picker.ts +27 -0
  45. package/src/react/ds-shell-gradient-swatch.ts +27 -0
  46. package/src/wc/components/AppShell/AppShell.tsx +14 -2
  47. package/src/wc/components/BarNav/bar-nav-tabs-menu-utils.ts +2 -2
  48. package/src/wc/components/Menu/Menu.tsx +27 -4
  49. package/src/wc/components/Menu/menu-types.ts +19 -1
  50. package/src/wc/components/PanelTools/PanelTools.tsx +1 -1
  51. package/src/wc/components/ShellGradientPicker/ShellGradientPicker.tsx +49 -0
  52. package/src/wc/components/ShellGradientSwatch/ShellGradientSwatch.tsx +53 -0
  53. package/src/wc/components/ShellGradientSwatch/shell-gradient-swatch-types.ts +16 -0
  54. package/src/wc/components.d.ts +130 -3
  55. package/src/wc/nav/index.ts +9 -0
  56. package/src/wc/nav/shell-gradient-presets.ts +35 -0
  57. package/src/wc/nav/shell-gradient.ts +26 -8
  58. package/src/wc/nav/shell-shortcuts.ts +6 -6
  59. package/dist/components/p-YzIqPOqL.js +0 -2
  60. package/dist/components/p-YzIqPOqL.js.map +0 -1
@@ -2,6 +2,8 @@ import { Component, Prop, State, Event, EventEmitter, Element, Watch, Listen, h,
2
2
  import { resolveCssLengthPx, resolveCssTimeMs, TOKEN_DEFAULTS } from '../../utils';
3
3
  import { computeMenuPosition, type MenuAlign, type MenuSide } from './menu-position';
4
4
  import type { MenuItemData, MenuSection } from './menu-types';
5
+ import { isMenuGradientPickerSection } from './menu-types';
6
+ import type { ShellGradientPreset } from '../../nav/shell-gradient-presets';
5
7
 
6
8
  /** rAF retries while the popup mounts or the anchor resolves. */
7
9
  const POSITION_RETRY_BUDGET = 8;
@@ -41,6 +43,8 @@ export class Menu {
41
43
 
42
44
  @Event() dsClose!: EventEmitter<void>;
43
45
  @Event() dsSelect!: EventEmitter<MenuItemData>;
46
+ /** Emitted when a `gradient-picker` section swatch is chosen. */
47
+ @Event() dsGradientSelect!: EventEmitter<ShellGradientPreset>;
44
48
 
45
49
  private clickOutsideHandler: ((e: MouseEvent) => void) | null = null;
46
50
  private scrollResizeHandler: (() => void) | null = null;
@@ -136,7 +140,9 @@ export class Menu {
136
140
  }
137
141
 
138
142
  private get flatItems(): MenuItemData[] {
139
- return this.activeSections.flatMap(s => s.items);
143
+ return this.activeSections.flatMap(section =>
144
+ isMenuGradientPickerSection(section) ? [] : section.items,
145
+ );
140
146
  }
141
147
 
142
148
  private cancelPositionRetry() {
@@ -309,6 +315,10 @@ export class Menu {
309
315
  this.close();
310
316
  }
311
317
 
318
+ private handleGradientSelect(preset: ShellGradientPreset) {
319
+ this.dsGradientSelect.emit(preset);
320
+ }
321
+
312
322
  render() {
313
323
  if (!this.shouldRender) return <Host style={{ display: 'contents' }} />;
314
324
 
@@ -339,7 +349,11 @@ export class Menu {
339
349
  {sections.map((section, si) => (
340
350
  <div
341
351
  key={si}
342
- class={{ 'menu-section': true, 'menu-section--divided': si < sections.length - 1 }}
352
+ class={{
353
+ 'menu-section': true,
354
+ 'menu-section--divided': si < sections.length - 1,
355
+ 'menu-section--gradient-picker': isMenuGradientPickerSection(section),
356
+ }}
343
357
  role={section.header ? 'group' : undefined}
344
358
  aria-label={section.header}
345
359
  >
@@ -348,7 +362,16 @@ export class Menu {
348
362
  <span class="text-body-small-emphasis section-label">{section.header}</span>
349
363
  </div>
350
364
  )}
351
- {section.items.map(item => {
365
+ {isMenuGradientPickerSection(section) ? (
366
+ <ds-shell-gradient-picker
367
+ value={section.value}
368
+ onDsChange={(e: CustomEvent<ShellGradientPreset>) => {
369
+ e.stopPropagation();
370
+ this.handleGradientSelect(e.detail);
371
+ }}
372
+ />
373
+ ) : (
374
+ section.items.map(item => {
352
375
  const idx = flatIdx++;
353
376
  const isFocused = this.focusedIndex === idx;
354
377
  return (
@@ -387,7 +410,7 @@ export class Menu {
387
410
  )}
388
411
  </button>
389
412
  );
390
- })}
413
+ }))}
391
414
  </div>
392
415
  ))}
393
416
  </div>
@@ -1,3 +1,5 @@
1
+ import type { ShellGradientPreset } from '../../nav/shell-gradient-presets';
2
+
1
3
  export type { MenuAlign, MenuSide } from './menu-position';
2
4
 
3
5
  export interface MenuItemData {
@@ -11,7 +13,23 @@ export interface MenuItemData {
11
13
  toggleValue?: boolean;
12
14
  }
13
15
 
14
- export interface MenuSection {
16
+ export interface MenuItemsSection {
15
17
  header?: string;
16
18
  items: MenuItemData[];
17
19
  }
20
+
21
+ export interface MenuGradientPickerSection {
22
+ header?: string;
23
+ variant: 'gradient-picker';
24
+ value: ShellGradientPreset;
25
+ }
26
+
27
+ export type MenuSection = MenuItemsSection | MenuGradientPickerSection;
28
+
29
+ export function isMenuGradientPickerSection(
30
+ section: MenuSection,
31
+ ): section is MenuGradientPickerSection {
32
+ return 'variant' in section && section.variant === 'gradient-picker';
33
+ }
34
+
35
+ export type { ShellGradientPreset };
@@ -148,7 +148,7 @@ export class PanelTools {
148
148
  this.dsToolChange.emit({ id, selected: next.selected });
149
149
  };
150
150
 
151
- /** Toggle any rail tool open/closed — shell shortcuts ⌘/Ctrl+K/A/S/M/N call this. */
151
+ /** Toggle any rail tool open/closed — shell shortcuts K/A/S/M/N call this. */
152
152
  @Method()
153
153
  async activateTool(id: PanelToolsToolId) {
154
154
  const item = this.railItems.find(entry => entry.id === id);
@@ -0,0 +1,49 @@
1
+ import { Component, Prop, Event, EventEmitter, h, Host } from '@stencil/core';
2
+ import {
3
+ SHELL_GRADIENT_PRESETS,
4
+ DEFAULT_SHELL_GRADIENT_PRESET,
5
+ type ShellGradientPreset,
6
+ } from '../ShellGradientSwatch/shell-gradient-swatch-types';
7
+
8
+ @Component({
9
+ tag: 'ds-shell-gradient-picker',
10
+ styleUrl: 'ShellGradientPicker.css',
11
+ scoped: true,
12
+ })
13
+ export class ShellGradientPicker {
14
+ /** Active shell wash preset. */
15
+ @Prop({ mutable: true, reflect: true }) value: ShellGradientPreset =
16
+ DEFAULT_SHELL_GRADIENT_PRESET;
17
+
18
+ @Event() dsChange!: EventEmitter<ShellGradientPreset>;
19
+
20
+ private handleSwatchSelect = (preset: ShellGradientPreset) => {
21
+ if (preset === this.value) return;
22
+ this.value = preset;
23
+ this.dsChange.emit(preset);
24
+ };
25
+
26
+ render() {
27
+ return (
28
+ <Host>
29
+ <div
30
+ class="shell-gradient-picker"
31
+ role="radiogroup"
32
+ aria-label="Shell gradient theme"
33
+ >
34
+ {SHELL_GRADIENT_PRESETS.map(preset => (
35
+ <ds-shell-gradient-swatch
36
+ key={preset}
37
+ preset={preset}
38
+ selected={this.value === preset}
39
+ onDsSelect={(e: CustomEvent<ShellGradientPreset>) => {
40
+ e.stopPropagation();
41
+ this.handleSwatchSelect(e.detail);
42
+ }}
43
+ />
44
+ ))}
45
+ </div>
46
+ </Host>
47
+ );
48
+ }
49
+ }
@@ -0,0 +1,53 @@
1
+ import { Component, Prop, Event, EventEmitter, h, Host } from '@stencil/core';
2
+ import {
3
+ SHELL_GRADIENT_PRESET_LABELS,
4
+ buildShellRadialGradientForPreset,
5
+ DEFAULT_SHELL_GRADIENT_PRESET,
6
+ type ShellGradientPreset,
7
+ } from './shell-gradient-swatch-types';
8
+
9
+ @Component({
10
+ tag: 'ds-shell-gradient-swatch',
11
+ styleUrl: 'ShellGradientSwatch.css',
12
+ scoped: true,
13
+ })
14
+ export class ShellGradientSwatch {
15
+ /** Wash preset this orb previews. */
16
+ @Prop({ reflect: true }) preset: ShellGradientPreset = DEFAULT_SHELL_GRADIENT_PRESET;
17
+
18
+ /** Selected state — shows an inset brand ring. */
19
+ @Prop({ reflect: true }) selected = false;
20
+
21
+ @Prop() inactive = false;
22
+
23
+ @Prop({ attribute: 'aria-label' }) ariaLabel: string | undefined;
24
+
25
+ @Event() dsSelect!: EventEmitter<ShellGradientPreset>;
26
+
27
+ private handleClick = () => {
28
+ if (this.inactive) return;
29
+ this.dsSelect.emit(this.preset);
30
+ };
31
+
32
+ render() {
33
+ const label = this.ariaLabel ?? SHELL_GRADIENT_PRESET_LABELS[this.preset];
34
+
35
+ return (
36
+ <Host>
37
+ <button
38
+ type="button"
39
+ class={{
40
+ 'shell-gradient-swatch': true,
41
+ 'ds-focus-ring-inset': true,
42
+ 'shell-gradient-swatch--selected': this.selected,
43
+ }}
44
+ style={{ backgroundImage: buildShellRadialGradientForPreset(this.preset) }}
45
+ aria-label={label}
46
+ aria-pressed={this.selected ? 'true' : 'false'}
47
+ disabled={this.inactive}
48
+ onClick={this.handleClick}
49
+ />
50
+ </Host>
51
+ );
52
+ }
53
+ }
@@ -0,0 +1,16 @@
1
+ import type { ShellGradientPreset } from '../../nav/shell-gradient-presets';
2
+ import {
3
+ SHELL_GRADIENT_PRESET_LABELS,
4
+ buildShellRadialGradientForPreset,
5
+ } from '../../nav/shell-gradient-presets';
6
+
7
+ export type { ShellGradientPreset };
8
+
9
+ export {
10
+ DEFAULT_SHELL_GRADIENT_PRESET,
11
+ SHELL_GRADIENT_PRESETS,
12
+ SHELL_GRADIENT_PRESET_LABELS,
13
+ buildShellRadialGradientForPreset,
14
+ isShellGradientPreset,
15
+ shellGradientPresetStopToken,
16
+ } from '../../nav/shell-gradient-presets';
@@ -7,6 +7,7 @@
7
7
  import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
8
8
  import { AccordionItemData } from "./components/Accordion/Accordion";
9
9
  import { NavChromeStyle } from "./nav/nav-chrome";
10
+ import { ShellGradientPreset } from "./nav/shell-gradient-presets";
10
11
  import { BadgeSurface, BadgeVariant } from "./components/Badge/Badge";
11
12
  import { BannerContrast, BannerIntent } from "./components/Banner/Banner";
12
13
  import { BarNavTab } from "./components/BarNav/bar-nav-types";
@@ -31,6 +32,7 @@ import { PanelToolsItem, PanelToolsToolId } from "./components/PanelTools/panel-
31
32
  import { RadioOption } from "./components/RadioGroup/RadioGroup";
32
33
  import { ScrollbarVariant } from "./components/Scrollbar/Scrollbar";
33
34
  import { SelectOption } from "./components/Select/Select";
35
+ import { ShellGradientPreset as ShellGradientPreset1 } from "./components/ShellGradientSwatch/shell-gradient-swatch-types";
34
36
  import { SkeletonVariant } from "./components/Skeleton/Skeleton";
35
37
  import { SurfaceBackground, SurfaceContrast, SurfaceElement, SurfaceElevation, SurfaceIntent, SurfaceRadius } from "./components/Surface/Surface";
36
38
  import { TabItem } from "./components/TabGroup/tab-item-utils";
@@ -45,6 +47,7 @@ import { ToggleGroupBackground, ToggleGroupElevation, ToggleGroupItem, ToggleGro
45
47
  import { TooltipAlign, TooltipSide } from "./components/Tooltip/Tooltip";
46
48
  export { AccordionItemData } from "./components/Accordion/Accordion";
47
49
  export { NavChromeStyle } from "./nav/nav-chrome";
50
+ export { ShellGradientPreset } from "./nav/shell-gradient-presets";
48
51
  export { BadgeSurface, BadgeVariant } from "./components/Badge/Badge";
49
52
  export { BannerContrast, BannerIntent } from "./components/Banner/Banner";
50
53
  export { BarNavTab } from "./components/BarNav/bar-nav-types";
@@ -69,6 +72,7 @@ export { PanelToolsItem, PanelToolsToolId } from "./components/PanelTools/panel-
69
72
  export { RadioOption } from "./components/RadioGroup/RadioGroup";
70
73
  export { ScrollbarVariant } from "./components/Scrollbar/Scrollbar";
71
74
  export { SelectOption } from "./components/Select/Select";
75
+ export { ShellGradientPreset as ShellGradientPreset1 } from "./components/ShellGradientSwatch/shell-gradient-swatch-types";
72
76
  export { SkeletonVariant } from "./components/Skeleton/Skeleton";
73
77
  export { SurfaceBackground, SurfaceContrast, SurfaceElement, SurfaceElevation, SurfaceIntent, SurfaceRadius } from "./components/Surface/Surface";
74
78
  export { TabItem } from "./components/TabGroup/tab-item-utils";
@@ -103,6 +107,11 @@ export namespace Components {
103
107
  * @default false
104
108
  */
105
109
  "gradient": boolean;
110
+ /**
111
+ * Built-in shell wash preset when `gradient` is true. `cool` (blue), `neutral` (grey), `warm` (yellow). `gradientSrc` overrides when set.
112
+ * @default DEFAULT_SHELL_GRADIENT_PRESET
113
+ */
114
+ "gradientPreset": ShellGradientPreset;
106
115
  /**
107
116
  * Optional custom gradient for `background-image` (e.g. SVG URL). When set, overrides the built-in radial wash.
108
117
  * @default ''
@@ -119,7 +128,7 @@ export namespace Components {
119
128
  */
120
129
  "navStyle": NavChromeStyle;
121
130
  /**
122
- * When `true` (default), registers global shell keyboard shortcuts. Tool chords (⌘/Ctrl+K/A/S/M/N) toggle their drawer open and closed; ⌘/Ctrl+[ toggles panel nav; ⌘/Ctrl+] closes any open tool drawer.
131
+ * When `true` (default), registers global shell keyboard shortcuts. `[` toggles panel nav; `]` closes tools; K/A/S/M/N toggle tool drawers. Modifiers are ignored so browser chords like ⌘N stay native.
123
132
  * @default true
124
133
  */
125
134
  "shortcutsEnabled": boolean;
@@ -719,7 +728,7 @@ export namespace Components {
719
728
  }
720
729
  interface DsPanelTools {
721
730
  /**
722
- * Toggle any rail tool open/closed — shell shortcuts ⌘/Ctrl+K/A/S/M/N call this.
731
+ * Toggle any rail tool open/closed — shell shortcuts K/A/S/M/N call this.
723
732
  */
724
733
  "activateTool": (id: PanelToolsToolId) => Promise<void>;
725
734
  /**
@@ -802,6 +811,30 @@ export namespace Components {
802
811
  */
803
812
  "value": string;
804
813
  }
814
+ interface DsShellGradientPicker {
815
+ /**
816
+ * Active shell wash preset.
817
+ * @default DEFAULT_SHELL_GRADIENT_PRESET
818
+ */
819
+ "value": ShellGradientPreset1;
820
+ }
821
+ interface DsShellGradientSwatch {
822
+ "ariaLabel": string | undefined;
823
+ /**
824
+ * @default false
825
+ */
826
+ "inactive": boolean;
827
+ /**
828
+ * Wash preset this orb previews.
829
+ * @default DEFAULT_SHELL_GRADIENT_PRESET
830
+ */
831
+ "preset": ShellGradientPreset1;
832
+ /**
833
+ * Selected state — shows an inset brand ring.
834
+ * @default false
835
+ */
836
+ "selected": boolean;
837
+ }
805
838
  interface DsSkeleton {
806
839
  /**
807
840
  * Height as a CSS value string or number (px).
@@ -1212,6 +1245,14 @@ export interface DsSelectCustomEvent<T> extends CustomEvent<T> {
1212
1245
  detail: T;
1213
1246
  target: HTMLDsSelectElement;
1214
1247
  }
1248
+ export interface DsShellGradientPickerCustomEvent<T> extends CustomEvent<T> {
1249
+ detail: T;
1250
+ target: HTMLDsShellGradientPickerElement;
1251
+ }
1252
+ export interface DsShellGradientSwatchCustomEvent<T> extends CustomEvent<T> {
1253
+ detail: T;
1254
+ target: HTMLDsShellGradientSwatchElement;
1255
+ }
1215
1256
  export interface DsSliderCustomEvent<T> extends CustomEvent<T> {
1216
1257
  detail: T;
1217
1258
  target: HTMLDsSliderElement;
@@ -1480,6 +1521,7 @@ declare global {
1480
1521
  interface HTMLDsMenuElementEventMap {
1481
1522
  "dsClose": void;
1482
1523
  "dsSelect": MenuItemData;
1524
+ "dsGradientSelect": ShellGradientPreset;
1483
1525
  }
1484
1526
  interface HTMLDsMenuElement extends Components.DsMenu, HTMLStencilElement {
1485
1527
  addEventListener<K extends keyof HTMLDsMenuElementEventMap>(type: K, listener: (this: HTMLDsMenuElement, ev: DsMenuCustomEvent<HTMLDsMenuElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
@@ -1613,6 +1655,40 @@ declare global {
1613
1655
  prototype: HTMLDsSelectElement;
1614
1656
  new (): HTMLDsSelectElement;
1615
1657
  };
1658
+ interface HTMLDsShellGradientPickerElementEventMap {
1659
+ "dsChange": ShellGradientPreset1;
1660
+ }
1661
+ interface HTMLDsShellGradientPickerElement extends Components.DsShellGradientPicker, HTMLStencilElement {
1662
+ addEventListener<K extends keyof HTMLDsShellGradientPickerElementEventMap>(type: K, listener: (this: HTMLDsShellGradientPickerElement, ev: DsShellGradientPickerCustomEvent<HTMLDsShellGradientPickerElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
1663
+ addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
1664
+ addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
1665
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
1666
+ removeEventListener<K extends keyof HTMLDsShellGradientPickerElementEventMap>(type: K, listener: (this: HTMLDsShellGradientPickerElement, ev: DsShellGradientPickerCustomEvent<HTMLDsShellGradientPickerElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
1667
+ removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
1668
+ removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
1669
+ removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
1670
+ }
1671
+ var HTMLDsShellGradientPickerElement: {
1672
+ prototype: HTMLDsShellGradientPickerElement;
1673
+ new (): HTMLDsShellGradientPickerElement;
1674
+ };
1675
+ interface HTMLDsShellGradientSwatchElementEventMap {
1676
+ "dsSelect": ShellGradientPreset1;
1677
+ }
1678
+ interface HTMLDsShellGradientSwatchElement extends Components.DsShellGradientSwatch, HTMLStencilElement {
1679
+ addEventListener<K extends keyof HTMLDsShellGradientSwatchElementEventMap>(type: K, listener: (this: HTMLDsShellGradientSwatchElement, ev: DsShellGradientSwatchCustomEvent<HTMLDsShellGradientSwatchElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
1680
+ addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
1681
+ addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
1682
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
1683
+ removeEventListener<K extends keyof HTMLDsShellGradientSwatchElementEventMap>(type: K, listener: (this: HTMLDsShellGradientSwatchElement, ev: DsShellGradientSwatchCustomEvent<HTMLDsShellGradientSwatchElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
1684
+ removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
1685
+ removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
1686
+ removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
1687
+ }
1688
+ var HTMLDsShellGradientSwatchElement: {
1689
+ prototype: HTMLDsShellGradientSwatchElement;
1690
+ new (): HTMLDsShellGradientSwatchElement;
1691
+ };
1616
1692
  interface HTMLDsSkeletonElement extends Components.DsSkeleton, HTMLStencilElement {
1617
1693
  }
1618
1694
  var HTMLDsSkeletonElement: {
@@ -1800,6 +1876,8 @@ declare global {
1800
1876
  "ds-radio-group": HTMLDsRadioGroupElement;
1801
1877
  "ds-scrollbar": HTMLDsScrollbarElement;
1802
1878
  "ds-select": HTMLDsSelectElement;
1879
+ "ds-shell-gradient-picker": HTMLDsShellGradientPickerElement;
1880
+ "ds-shell-gradient-swatch": HTMLDsShellGradientSwatchElement;
1803
1881
  "ds-skeleton": HTMLDsSkeletonElement;
1804
1882
  "ds-slider": HTMLDsSliderElement;
1805
1883
  "ds-surface": HTMLDsSurfaceElement;
@@ -1840,6 +1918,11 @@ declare namespace LocalJSX {
1840
1918
  * @default false
1841
1919
  */
1842
1920
  "gradient"?: boolean;
1921
+ /**
1922
+ * Built-in shell wash preset when `gradient` is true. `cool` (blue), `neutral` (grey), `warm` (yellow). `gradientSrc` overrides when set.
1923
+ * @default DEFAULT_SHELL_GRADIENT_PRESET
1924
+ */
1925
+ "gradientPreset"?: ShellGradientPreset;
1843
1926
  /**
1844
1927
  * Optional custom gradient for `background-image` (e.g. SVG URL). When set, overrides the built-in radial wash.
1845
1928
  * @default ''
@@ -1856,7 +1939,7 @@ declare namespace LocalJSX {
1856
1939
  */
1857
1940
  "navStyle"?: NavChromeStyle;
1858
1941
  /**
1859
- * When `true` (default), registers global shell keyboard shortcuts. Tool chords (⌘/Ctrl+K/A/S/M/N) toggle their drawer open and closed; ⌘/Ctrl+[ toggles panel nav; ⌘/Ctrl+] closes any open tool drawer.
1942
+ * When `true` (default), registers global shell keyboard shortcuts. `[` toggles panel nav; `]` closes tools; K/A/S/M/N toggle tool drawers. Modifiers are ignored so browser chords like ⌘N stay native.
1860
1943
  * @default true
1861
1944
  */
1862
1945
  "shortcutsEnabled"?: boolean;
@@ -2374,6 +2457,10 @@ declare namespace LocalJSX {
2374
2457
  "menuWidth"?: string | undefined;
2375
2458
  "minWidth"?: string | undefined;
2376
2459
  "onDsClose"?: (event: DsMenuCustomEvent<void>) => void;
2460
+ /**
2461
+ * Emitted when a `gradient-picker` section swatch is chosen.
2462
+ */
2463
+ "onDsGradientSelect"?: (event: DsMenuCustomEvent<ShellGradientPreset>) => void;
2377
2464
  "onDsSelect"?: (event: DsMenuCustomEvent<MenuItemData>) => void;
2378
2465
  /**
2379
2466
  * @default false
@@ -2597,6 +2684,32 @@ declare namespace LocalJSX {
2597
2684
  */
2598
2685
  "value"?: string;
2599
2686
  }
2687
+ interface DsShellGradientPicker {
2688
+ "onDsChange"?: (event: DsShellGradientPickerCustomEvent<ShellGradientPreset1>) => void;
2689
+ /**
2690
+ * Active shell wash preset.
2691
+ * @default DEFAULT_SHELL_GRADIENT_PRESET
2692
+ */
2693
+ "value"?: ShellGradientPreset1;
2694
+ }
2695
+ interface DsShellGradientSwatch {
2696
+ "ariaLabel"?: string | undefined;
2697
+ /**
2698
+ * @default false
2699
+ */
2700
+ "inactive"?: boolean;
2701
+ "onDsSelect"?: (event: DsShellGradientSwatchCustomEvent<ShellGradientPreset1>) => void;
2702
+ /**
2703
+ * Wash preset this orb previews.
2704
+ * @default DEFAULT_SHELL_GRADIENT_PRESET
2705
+ */
2706
+ "preset"?: ShellGradientPreset1;
2707
+ /**
2708
+ * Selected state — shows an inset brand ring.
2709
+ * @default false
2710
+ */
2711
+ "selected"?: boolean;
2712
+ }
2600
2713
  interface DsSkeleton {
2601
2714
  /**
2602
2715
  * Height as a CSS value string or number (px).
@@ -2964,6 +3077,7 @@ declare namespace LocalJSX {
2964
3077
  "gradient": boolean;
2965
3078
  "grid": boolean;
2966
3079
  "gradientSrc": string;
3080
+ "gradientPreset": ShellGradientPreset;
2967
3081
  "shortcutsEnabled": boolean;
2968
3082
  }
2969
3083
  interface DsBadgeAttributes {
@@ -3171,6 +3285,15 @@ declare namespace LocalJSX {
3171
3285
  "ariaLabel": string | undefined;
3172
3286
  "ariaLabelledby": string | undefined;
3173
3287
  }
3288
+ interface DsShellGradientPickerAttributes {
3289
+ "value": ShellGradientPreset;
3290
+ }
3291
+ interface DsShellGradientSwatchAttributes {
3292
+ "preset": ShellGradientPreset;
3293
+ "selected": boolean;
3294
+ "inactive": boolean;
3295
+ "ariaLabel": string | undefined;
3296
+ }
3174
3297
  interface DsSkeletonAttributes {
3175
3298
  "variant": SkeletonVariant;
3176
3299
  "width": string;
@@ -3309,6 +3432,8 @@ declare namespace LocalJSX {
3309
3432
  "ds-radio-group": Omit<DsRadioGroup, keyof DsRadioGroupAttributes> & { [K in keyof DsRadioGroup & keyof DsRadioGroupAttributes]?: DsRadioGroup[K] } & { [K in keyof DsRadioGroup & keyof DsRadioGroupAttributes as `attr:${K}`]?: DsRadioGroupAttributes[K] } & { [K in keyof DsRadioGroup & keyof DsRadioGroupAttributes as `prop:${K}`]?: DsRadioGroup[K] };
3310
3433
  "ds-scrollbar": Omit<DsScrollbar, keyof DsScrollbarAttributes> & { [K in keyof DsScrollbar & keyof DsScrollbarAttributes]?: DsScrollbar[K] } & { [K in keyof DsScrollbar & keyof DsScrollbarAttributes as `attr:${K}`]?: DsScrollbarAttributes[K] } & { [K in keyof DsScrollbar & keyof DsScrollbarAttributes as `prop:${K}`]?: DsScrollbar[K] };
3311
3434
  "ds-select": Omit<DsSelect, keyof DsSelectAttributes> & { [K in keyof DsSelect & keyof DsSelectAttributes]?: DsSelect[K] } & { [K in keyof DsSelect & keyof DsSelectAttributes as `attr:${K}`]?: DsSelectAttributes[K] } & { [K in keyof DsSelect & keyof DsSelectAttributes as `prop:${K}`]?: DsSelect[K] };
3435
+ "ds-shell-gradient-picker": Omit<DsShellGradientPicker, keyof DsShellGradientPickerAttributes> & { [K in keyof DsShellGradientPicker & keyof DsShellGradientPickerAttributes]?: DsShellGradientPicker[K] } & { [K in keyof DsShellGradientPicker & keyof DsShellGradientPickerAttributes as `attr:${K}`]?: DsShellGradientPickerAttributes[K] } & { [K in keyof DsShellGradientPicker & keyof DsShellGradientPickerAttributes as `prop:${K}`]?: DsShellGradientPicker[K] };
3436
+ "ds-shell-gradient-swatch": Omit<DsShellGradientSwatch, keyof DsShellGradientSwatchAttributes> & { [K in keyof DsShellGradientSwatch & keyof DsShellGradientSwatchAttributes]?: DsShellGradientSwatch[K] } & { [K in keyof DsShellGradientSwatch & keyof DsShellGradientSwatchAttributes as `attr:${K}`]?: DsShellGradientSwatchAttributes[K] } & { [K in keyof DsShellGradientSwatch & keyof DsShellGradientSwatchAttributes as `prop:${K}`]?: DsShellGradientSwatch[K] };
3312
3437
  "ds-skeleton": Omit<DsSkeleton, keyof DsSkeletonAttributes> & { [K in keyof DsSkeleton & keyof DsSkeletonAttributes]?: DsSkeleton[K] } & { [K in keyof DsSkeleton & keyof DsSkeletonAttributes as `attr:${K}`]?: DsSkeletonAttributes[K] } & { [K in keyof DsSkeleton & keyof DsSkeletonAttributes as `prop:${K}`]?: DsSkeleton[K] };
3313
3438
  "ds-slider": Omit<DsSlider, keyof DsSliderAttributes> & { [K in keyof DsSlider & keyof DsSliderAttributes]?: DsSlider[K] } & { [K in keyof DsSlider & keyof DsSliderAttributes as `attr:${K}`]?: DsSliderAttributes[K] } & { [K in keyof DsSlider & keyof DsSliderAttributes as `prop:${K}`]?: DsSlider[K] } & OneOf<"label", DsSlider["label"], DsSliderAttributes["label"]>;
3314
3439
  "ds-surface": Omit<DsSurface, keyof DsSurfaceAttributes> & { [K in keyof DsSurface & keyof DsSurfaceAttributes]?: DsSurface[K] } & { [K in keyof DsSurface & keyof DsSurfaceAttributes as `attr:${K}`]?: DsSurfaceAttributes[K] } & { [K in keyof DsSurface & keyof DsSurfaceAttributes as `prop:${K}`]?: DsSurface[K] };
@@ -3356,6 +3481,8 @@ declare module "@stencil/core" {
3356
3481
  "ds-radio-group": LocalJSX.IntrinsicElements["ds-radio-group"] & JSXBase.HTMLAttributes<HTMLDsRadioGroupElement>;
3357
3482
  "ds-scrollbar": LocalJSX.IntrinsicElements["ds-scrollbar"] & JSXBase.HTMLAttributes<HTMLDsScrollbarElement>;
3358
3483
  "ds-select": LocalJSX.IntrinsicElements["ds-select"] & JSXBase.HTMLAttributes<HTMLDsSelectElement>;
3484
+ "ds-shell-gradient-picker": LocalJSX.IntrinsicElements["ds-shell-gradient-picker"] & JSXBase.HTMLAttributes<HTMLDsShellGradientPickerElement>;
3485
+ "ds-shell-gradient-swatch": LocalJSX.IntrinsicElements["ds-shell-gradient-swatch"] & JSXBase.HTMLAttributes<HTMLDsShellGradientSwatchElement>;
3359
3486
  "ds-skeleton": LocalJSX.IntrinsicElements["ds-skeleton"] & JSXBase.HTMLAttributes<HTMLDsSkeletonElement>;
3360
3487
  "ds-slider": LocalJSX.IntrinsicElements["ds-slider"] & JSXBase.HTMLAttributes<HTMLDsSliderElement>;
3361
3488
  "ds-surface": LocalJSX.IntrinsicElements["ds-surface"] & JSXBase.HTMLAttributes<HTMLDsSurfaceElement>;
@@ -37,6 +37,15 @@ export {
37
37
  readShellViewportDimensions,
38
38
  } from './shell-gradient';
39
39
  export type { ShellGradientLayout, ShellViewportDimensions } from './shell-gradient';
40
+ export type { ShellGradientPreset } from './shell-gradient-presets';
41
+ export {
42
+ DEFAULT_SHELL_GRADIENT_PRESET,
43
+ SHELL_GRADIENT_PRESETS,
44
+ SHELL_GRADIENT_PRESET_LABELS,
45
+ buildShellRadialGradientForPreset,
46
+ isShellGradientPreset,
47
+ shellGradientPresetStopToken,
48
+ } from './shell-gradient-presets';
40
49
  export type { ChromeTransitionDetail, ChromeTransitionSource } from './chrome-transition';
41
50
  export {
42
51
  CHROME_TRANSITION_END,
@@ -0,0 +1,35 @@
1
+ /** Built-in shell chrome wash presets — cool (blue), neutral (grey), warm (yellow). */
2
+ export type ShellGradientPreset = 'cool' | 'neutral' | 'warm';
3
+
4
+ export const SHELL_GRADIENT_PRESETS: ShellGradientPreset[] = ['cool', 'neutral', 'warm'];
5
+
6
+ /** Default wash when `gradient-preset` is omitted. */
7
+ export const DEFAULT_SHELL_GRADIENT_PRESET: ShellGradientPreset = 'neutral';
8
+
9
+ export const SHELL_GRADIENT_PRESET_LABELS: Record<ShellGradientPreset, string> = {
10
+ cool: 'Cool',
11
+ neutral: 'Neutral',
12
+ warm: 'Warm',
13
+ };
14
+
15
+ const SHELL_GRADIENT_PRESET_STOP: Record<ShellGradientPreset, string> = {
16
+ cool: 'var(--color-color-intent-blue-strong-background)',
17
+ neutral: 'var(--color-color-intent-grey-strong-background)',
18
+ warm: 'var(--color-color-intent-yellow-strong-background)',
19
+ };
20
+
21
+ const GRADIENT_GEOMETRY = '100% 100% at 0% 0%';
22
+
23
+ export function shellGradientPresetStopToken(preset: ShellGradientPreset): string {
24
+ return SHELL_GRADIENT_PRESET_STOP[preset];
25
+ }
26
+
27
+ export function isShellGradientPreset(value: string): value is ShellGradientPreset {
28
+ return (SHELL_GRADIENT_PRESETS as string[]).includes(value);
29
+ }
30
+
31
+ /** Radial wash for a preset — transparent at top-left into the intent stop. */
32
+ export function buildShellRadialGradientForPreset(preset: ShellGradientPreset): string {
33
+ const stop = shellGradientPresetStopToken(preset);
34
+ return `radial-gradient(${GRADIENT_GEOMETRY}, var(--color-background-transparent) 0%, ${stop} 100%)`;
35
+ }
@@ -1,4 +1,20 @@
1
1
  /** CSS var names consumed by `ds-panel-nav` / `ds-bar-nav` inside `ds-app-shell`. */
2
+ import type { ShellGradientPreset } from './shell-gradient-presets';
3
+ import {
4
+ DEFAULT_SHELL_GRADIENT_PRESET,
5
+ buildShellRadialGradientForPreset,
6
+ } from './shell-gradient-presets';
7
+
8
+ export type { ShellGradientPreset } from './shell-gradient-presets';
9
+ export {
10
+ DEFAULT_SHELL_GRADIENT_PRESET,
11
+ SHELL_GRADIENT_PRESETS,
12
+ SHELL_GRADIENT_PRESET_LABELS,
13
+ buildShellRadialGradientForPreset,
14
+ isShellGradientPreset,
15
+ shellGradientPresetStopToken,
16
+ } from './shell-gradient-presets';
17
+
2
18
  export const SHELL_GRADIENT_IMAGE_VAR = '--ds-shell-gradient-image';
3
19
  export const SHELL_GRADIENT_SIZE_VAR = '--ds-shell-gradient-size';
4
20
  export const SHELL_GRADIENT_POSITION_PANEL_VAR = '--ds-shell-gradient-position-panel';
@@ -15,19 +31,21 @@ export function shellChromeLayerActive(gradient: boolean, grid: boolean): boolea
15
31
  return gradient || grid;
16
32
  }
17
33
 
18
- const GRADIENT_GEOMETRY = '100% 100% at 0% 0%';
19
-
20
34
  /**
21
35
  * Shell radial wash — same for panel and bar nav.
22
- * Tokens follow `data-theme` (light/dark blue intent).
36
+ * Tokens follow `data-theme` (light/dark intent stops).
23
37
  */
24
- export function buildShellRadialGradient(): string {
25
- return `radial-gradient(${GRADIENT_GEOMETRY}, var(--color-background-transparent) 0%, var(--color-color-intent-blue-strong-background) 100%)`;
38
+ export function buildShellRadialGradient(
39
+ preset: ShellGradientPreset = DEFAULT_SHELL_GRADIENT_PRESET,
40
+ ): string {
41
+ return buildShellRadialGradientForPreset(preset);
26
42
  }
27
43
 
28
- /** Built-in radial image (optional `gradientSrc` on shell overrides). */
29
- export function shellGradientImage(): string {
30
- return buildShellRadialGradient();
44
+ /** Built-in radial image (`gradientSrc` on shell overrides). */
45
+ export function shellGradientImage(
46
+ preset: ShellGradientPreset = DEFAULT_SHELL_GRADIENT_PRESET,
47
+ ): string {
48
+ return buildShellRadialGradient(preset);
31
49
  }
32
50
 
33
51
  export interface ShellViewportDimensions {
@@ -13,13 +13,13 @@ const TOOL_SHORTCUT_KEYS: Record<string, PanelToolsToolId> = {
13
13
  n: 'activity',
14
14
  };
15
15
 
16
- /** Tool shortcut chords (⌘/Ctrl+K/A/S/M/N) toggle open/closed via `ds-panel-tools.activateTool`. */
16
+ /** Tool shortcut keys (K/A/S/M/N) toggle open/closed via `ds-panel-tools.activateTool`. */
17
17
 
18
- /** True when Cmd (macOS) or Ctrl (Windows/Linux) is held without Alt/Shift. */
19
- export function isShellShortcutModifier(
18
+ /** True when no modifier keys are held — avoids browser/app chords like ⌘N. */
19
+ export function isBareShellShortcutKey(
20
20
  e: Pick<KeyboardEvent, 'metaKey' | 'ctrlKey' | 'altKey' | 'shiftKey'>,
21
21
  ): boolean {
22
- return (e.metaKey || e.ctrlKey) && !e.altKey && !e.shiftKey;
22
+ return !e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey;
23
23
  }
24
24
 
25
25
  /** Skip shell shortcuts while typing in an editable control. */
@@ -46,11 +46,11 @@ function normalizedShortcutKey(e: Pick<KeyboardEvent, 'key' | 'code'>): string {
46
46
  return e.key.length === 1 ? e.key.toLowerCase() : e.key.toLowerCase();
47
47
  }
48
48
 
49
- /** Resolve a shell chrome shortcut, or `null` when the chord is not handled. */
49
+ /** Resolve a shell chrome shortcut, or `null` when the key is not handled. */
50
50
  export function resolveShellShortcut(
51
51
  e: Pick<KeyboardEvent, 'key' | 'code' | 'metaKey' | 'ctrlKey' | 'altKey' | 'shiftKey'>,
52
52
  ): ShellShortcutAction | null {
53
- if (!isShellShortcutModifier(e)) return null;
53
+ if (!isBareShellShortcutKey(e)) return null;
54
54
 
55
55
  const key = normalizedShortcutKey(e);
56
56
  if (key === '[') return 'toggle-panel-nav';