@ds-mo/ui 2.4.1 → 2.6.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 (63) 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-nav.js +1 -1
  8. package/dist/components/ds-panel-nav.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 +6 -0
  28. package/dist/types/components/Menu/Menu.d.ts +4 -0
  29. package/dist/types/components/Menu/menu-placement.d.ts +21 -0
  30. package/dist/types/components/Menu/menu-types.d.ts +11 -1
  31. package/dist/types/components/PanelNav/index.d.ts +1 -1
  32. package/dist/types/components/PanelNav/panel-nav-types.d.ts +5 -0
  33. package/dist/types/components/ShellGradientPicker/ShellGradientPicker.d.ts +10 -0
  34. package/dist/types/components/ShellGradientSwatch/ShellGradientSwatch.d.ts +14 -0
  35. package/dist/types/components/ShellGradientSwatch/shell-gradient-swatch-types.d.ts +4 -0
  36. package/dist/types/components.d.ts +127 -0
  37. package/dist/types/nav/index.d.ts +4 -0
  38. package/dist/types/nav/shell-gradient-presets.d.ts +11 -0
  39. package/dist/types/nav/shell-gradient.d.ts +7 -4
  40. package/package.json +3 -3
  41. package/src/angular/index.ts +2 -0
  42. package/src/angular/proxies.ts +69 -3
  43. package/src/react/components.ts +2 -0
  44. package/src/react/ds-menu.ts +5 -3
  45. package/src/react/ds-shell-gradient-picker.ts +27 -0
  46. package/src/react/ds-shell-gradient-swatch.ts +27 -0
  47. package/src/wc/components/AppShell/AppShell.tsx +13 -1
  48. package/src/wc/components/BarNav/bar-nav-tabs-menu-utils.ts +2 -2
  49. package/src/wc/components/Menu/Menu.tsx +27 -4
  50. package/src/wc/components/Menu/menu-placement.ts +23 -0
  51. package/src/wc/components/Menu/menu-types.ts +23 -1
  52. package/src/wc/components/PanelNav/PanelNav.tsx +3 -2
  53. package/src/wc/components/PanelNav/index.ts +1 -1
  54. package/src/wc/components/PanelNav/panel-nav-types.ts +6 -0
  55. package/src/wc/components/ShellGradientPicker/ShellGradientPicker.tsx +49 -0
  56. package/src/wc/components/ShellGradientSwatch/ShellGradientSwatch.tsx +53 -0
  57. package/src/wc/components/ShellGradientSwatch/shell-gradient-swatch-types.ts +16 -0
  58. package/src/wc/components.d.ts +130 -0
  59. package/src/wc/nav/index.ts +13 -0
  60. package/src/wc/nav/shell-gradient-presets.ts +35 -0
  61. package/src/wc/nav/shell-gradient.ts +26 -8
  62. package/dist/components/p-YzIqPOqL.js +0 -2
  63. package/dist/components/p-YzIqPOqL.js.map +0 -1
@@ -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 ''
@@ -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 ''
@@ -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>;
@@ -3372,3 +3499,6 @@ declare module "@stencil/core" {
3372
3499
  }
3373
3500
  }
3374
3501
  }
3502
+ // --- menu placement re-exports (patch-components-d-exports.mjs) ---
3503
+ export { PANEL_NAV_USER_MENU_PLACEMENT, type MenuPlacement } from "./components/Menu/menu-types";
3504
+
@@ -37,6 +37,19 @@ export {
37
37
  readShellViewportDimensions,
38
38
  } from './shell-gradient';
39
39
  export type { ShellGradientLayout, ShellViewportDimensions } from './shell-gradient';
40
+ export type { MenuPlacement } from '../components/Menu/menu-placement';
41
+ export {
42
+ PANEL_NAV_USER_MENU_PLACEMENT,
43
+ } from '../components/Menu/menu-placement';
44
+ export type { ShellGradientPreset } from './shell-gradient-presets';
45
+ export {
46
+ DEFAULT_SHELL_GRADIENT_PRESET,
47
+ SHELL_GRADIENT_PRESETS,
48
+ SHELL_GRADIENT_PRESET_LABELS,
49
+ buildShellRadialGradientForPreset,
50
+ isShellGradientPreset,
51
+ shellGradientPresetStopToken,
52
+ } from './shell-gradient-presets';
40
53
  export type { ChromeTransitionDetail, ChromeTransitionSource } from './chrome-transition';
41
54
  export {
42
55
  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 {
@@ -1,2 +0,0 @@
1
- import{p as e,H as s,c as i,h as t,a as n,t as o}from"./index.js";import{T as r}from"./p-BRju0sEC.js";import{r as a}from"./p-CYJ-de0u.js";import{r as d}from"./p-C1cBr-Ri.js";function u(e){const{anchorRect:s,popupWidth:i,popupHeight:t,side:n,align:o,sideOffsetPx:r,alignOffsetPx:a,viewportPadPx:d,viewportWidth:u,viewportHeight:c}=e;let h=0;let l=0;switch(n){case"top":l=s.top-t-r;h=o==="start"?s.left+a:o==="end"?s.right-i+a:s.left+s.width/2-i/2+a;break;case"bottom":l=s.bottom+r;h=o==="start"?s.left+a:o==="end"?s.right-i+a:s.left+s.width/2-i/2+a;break;case"left":h=s.left-i-r;l=o==="start"?s.top+a:o==="end"?s.bottom-t+a:s.top+s.height/2-t/2+a;break;case"right":h=s.right+r;l=o==="start"?s.top+a:o==="end"?s.bottom-t+a:s.top+s.height/2-t/2+a;break}return{x:Math.min(Math.max(h,d),u-i-d),y:Math.min(Math.max(l,d),c-t-d)}}const c=()=>`.sc-ds-menu-h{--ds-focus-ring-width:var(--dimension-stroke-width-025, 2px);--ds-focus-ring-offset:var(--dimension-space-025, 2px);--ds-focus-ring-color:var(--color-interaction-focus)}.ds-focus-ring.sc-ds-menu:focus-visible{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:var(--ds-focus-ring-offset)}.ds-focus-ring.ds-focus-ring--visible.sc-ds-menu{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:var(--ds-focus-ring-offset)}.ds-focus-ring-inset.sc-ds-menu:focus-visible{outline:none}.ds-focus-ring-inset.sc-ds-menu:focus-visible::after{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:calc(-1 * var(--ds-focus-ring-width))}.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-menu{outline:none}.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-menu::after{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:calc(-1 * var(--ds-focus-ring-width))}.menu-popup.sc-ds-menu{box-sizing:border-box;display:flex;flex-direction:column;min-width:var(--dimension-menu-width-xs);max-width:var(--dimension-panel-width-lg);overflow:hidden;background-color:var(--color-background-primary);border-radius:var(--dimension-radius-075);box-shadow:var(--effect-shadow-elevated-floating);animation:menuFadeIn var(--effect-motion-short-2) forwards;backface-visibility:hidden;will-change:transform}.menu-popup.sc-ds-menu::after{content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;box-shadow:var(--effect-highlight-elevated-floating)}.menu-popup--closing.sc-ds-menu{animation:menuFadeOut var(--effect-motion-short-3) forwards}@keyframes menuFadeIn{from{opacity:0;transform:inherit scale(0.97)}to{opacity:1}}@keyframes menuFadeOut{from{opacity:1}to{opacity:0}}.menu-section.sc-ds-menu{display:flex;flex-direction:column;gap:var(--dimension-space-050);padding:var(--dimension-space-050)}.menu-section--divided.sc-ds-menu{border-bottom:var(--dimension-stroke-width-015) solid var(--color-border-tertiary)}.section-header.sc-ds-menu{display:flex;align-items:center;height:var(--dimension-size-400);padding:var(--dimension-space-050) var(--dimension-space-075);-webkit-user-select:none;user-select:none}.section-label.sc-ds-menu{color:var(--color-foreground-secondary)}.menu-item.sc-ds-menu{display:flex;align-items:center;gap:var(--dimension-space-050);position:relative;width:100%;min-height:var(--dimension-size-400);padding:var(--dimension-space-075);box-sizing:border-box;border:none;border-radius:var(--dimension-radius-025);background:transparent;cursor:pointer;-webkit-user-select:none;user-select:none;text-align:left;color:inherit;--_hover-bg:var(--color-interaction-hover);--_pressed-bg:var(--color-interaction-pressed);--_selected-bg:var(--color-interaction-active)}.menu-item.sc-ds-menu:has(.menu-item__subtext){align-items:flex-start}.menu-item.sc-ds-menu::after{content:'';position:absolute;inset:0;border-radius:inherit;background:transparent;pointer-events:none;transition:none}.menu-item--selected.sc-ds-menu::after{background:var(--_selected-bg);transition:none}.menu-item.sc-ds-menu:hover:not(:disabled):not(.menu-item--selected)::after{background:var(--_hover-bg);transition:none}.menu-item.sc-ds-menu:active:not(:disabled)::after{background:var(--_pressed-bg);transition:none}.menu-item--inactive.sc-ds-menu{opacity:0.5;cursor:not-allowed;pointer-events:none}.menu-item--destructive.sc-ds-menu .menu-item__label.sc-ds-menu{color:var(--color-foreground-bold-negative) !important}.menu-item__content.sc-ds-menu{position:relative;z-index:1;display:flex;flex:1;flex-direction:column;gap:var(--dimension-space-025);min-width:0}.menu-item__label.sc-ds-menu{color:var(--color-foreground-secondary)}.menu-item.sc-ds-menu:has(.menu-item__subtext) .menu-item__label.sc-ds-menu,.menu-item--selected.sc-ds-menu .menu-item__label.sc-ds-menu{color:var(--color-foreground-primary)}.menu-item__subtext.sc-ds-menu{color:var(--color-foreground-secondary);line-height:1.4}.menu-item__toggle.sc-ds-menu{position:relative;z-index:1;flex-shrink:0;width:calc(var(--dimension-size-400) + var(--dimension-size-050));height:var(--dimension-size-250);border-radius:var(--dimension-radius-125);background-color:var(--color-background-translucent);transition:background-color var(--effect-motion-short-2)}.menu-item__toggle--on.sc-ds-menu{background-color:var(--color-background-medium-brand)}.menu-item__toggle-thumb.sc-ds-menu{position:absolute;top:var(--dimension-space-025);left:var(--dimension-space-025);width:var(--dimension-size-200);height:var(--dimension-size-200);border-radius:50%;background-color:var(--color-foreground-on-bold-background-primary);transition:transform var(--effect-motion-short-2)}.menu-item__toggle--on.sc-ds-menu .menu-item__toggle-thumb.sc-ds-menu{transform:translateX(var(--dimension-offset-200, 16px))}`;const h=8;const l=e(class e extends s{constructor(e){super();if(e!==false){this.__registerHost()}this.dsClose=i(this,"dsClose");this.dsSelect=i(this,"dsSelect");this.open=false;this.items=[];this.sections=[];this.side="bottom";this.align="start";this.sideOffset=r.space050;this.alignOffset=0;this.initialFocusVisible=false;this.shouldRender=false;this.closing=false;this.pos={x:0,y:0};this.focusedIndex=0;this.positionReady=false;this.focusRingVisible=false;this.clickOutsideHandler=null;this.scrollResizeHandler=null;this.closeTimer=null;this.itemEls=[];this.positionRetryRaf=null;this.listenersReady=false}componentDidLoad(){if(this.open)this.onOpenChange(true)}disconnectedCallback(){this.cancelPositionRetry();this.teardownListeners()}onOpenChange(e){if(e){this.teardownListeners();this.shouldRender=true;this.closing=false;this.positionReady=false;this.listenersReady=false;this.focusRingVisible=this.initialFocusVisible;this.listenersReady=true;this.setupListeners();this.schedulePositionUpdate((()=>{this.focusInitialItem()}))}else if(this.shouldRender){this.cancelPositionRetry();this.closing=true;this.teardownListeners();this.listenersReady=false;this.closeTimer=setTimeout((()=>{this.shouldRender=false;this.closing=false;this.closeTimer=null}),this.closeAnimationMs)}}onAnchorChange(){if(this.open)this.schedulePositionUpdate()}onPositionPropsChange(){if(this.open)this.schedulePositionUpdate()}get viewportPadPx(){return a(r.space050,r.space050)}get sideOffsetPx(){return a(this.sideOffset,r.space050)}get alignOffsetPx(){return a(this.alignOffset,0)}get popupFallbackWidthPx(){return a(r.menuWidthXs,r.menuWidthXs)}get popupFallbackHeightPx(){return a(r.menuFallbackHeight,r.menuFallbackHeight)}get closeAnimationMs(){return d(r.motionShort3,r.animationDurationShort3)}get resolvedAnchor(){if(this.anchor)return this.anchor;if(this.anchorId)return document.getElementById(this.anchorId);return null}get activeSections(){if(this.sections.length>0)return this.sections;if(this.items.length>0)return[{items:this.items}];return[]}get flatItems(){return this.activeSections.flatMap((e=>e.items))}cancelPositionRetry(){if(this.positionRetryRaf!==null){cancelAnimationFrame(this.positionRetryRaf);this.positionRetryRaf=null}}schedulePositionUpdate(e){if(!this.open)return;this.cancelPositionRetry();this.positionReady=false;let s=h;const i=()=>{this.positionRetryRaf=null;if(!this.open)return;if(this.calculatePosition()){this.positionReady=true;e?.();return}if(s>0){s-=1;this.positionRetryRaf=requestAnimationFrame(i)}};this.positionRetryRaf=requestAnimationFrame(i)}calculatePosition(){const e=this.resolvedAnchor;if(!e)return false;const s=this.el.querySelector(".menu-popup");if(!s)return false;this.pos=u({anchorRect:e.getBoundingClientRect(),popupWidth:s.offsetWidth||this.popupFallbackWidthPx,popupHeight:s.offsetHeight||this.popupFallbackHeightPx,side:this.side,align:this.align,sideOffsetPx:this.sideOffsetPx,alignOffsetPx:this.alignOffsetPx,viewportPadPx:this.viewportPadPx,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight});return true}focusInitialItem(){const e=this.flatItems;const s=e.findIndex((e=>e.isSelected&&!e.isInactive));const i=e.findIndex((e=>!e.isInactive));this.focusedIndex=s>=0?s:i>=0?i:0;requestAnimationFrame((()=>{const e=this.el.querySelectorAll(".menu-item");e[this.focusedIndex]?.focus()}))}setupListeners(){this.clickOutsideHandler=e=>{const s=e.target;const i=this.el.querySelector(".menu-popup");const t=this.resolvedAnchor;if(i?.contains(s)||t?.contains(s))return;this.close()};this.scrollResizeHandler=()=>{if(this.shouldRender&&!this.closing)this.calculatePosition()};document.addEventListener("mousedown",this.clickOutsideHandler,true);window.addEventListener("scroll",this.scrollResizeHandler,true);window.addEventListener("resize",this.scrollResizeHandler)}teardownListeners(){if(this.clickOutsideHandler){document.removeEventListener("mousedown",this.clickOutsideHandler,true);this.clickOutsideHandler=null}if(this.scrollResizeHandler){window.removeEventListener("scroll",this.scrollResizeHandler,true);window.removeEventListener("resize",this.scrollResizeHandler);this.scrollResizeHandler=null}if(this.closeTimer){clearTimeout(this.closeTimer);this.closeTimer=null}}close(){this.resolvedAnchor?.focus();this.dsClose.emit();this.open=false;this.onOpenChange(false)}handleKeyDown(e){if(!this.shouldRender||this.closing)return;const s=this.flatItems;const i=s.map(((e,s)=>({it:e,i:s}))).filter((({it:e})=>!e.isInactive)).map((({i:e})=>e));if(!i.length)return;const t=i.indexOf(this.focusedIndex);const n=t<0?0:t;switch(e.key){case"ArrowDown":e.preventDefault();e.stopPropagation();this.focusRingVisible=true;this.focusedIndex=i[(n+1)%i.length];this.focusItem(this.focusedIndex);break;case"ArrowUp":e.preventDefault();e.stopPropagation();this.focusRingVisible=true;this.focusedIndex=i[(n-1+i.length)%i.length];this.focusItem(this.focusedIndex);break;case"Home":e.preventDefault();e.stopPropagation();this.focusRingVisible=true;this.focusedIndex=i[0];this.focusItem(this.focusedIndex);break;case"End":e.preventDefault();e.stopPropagation();this.focusRingVisible=true;this.focusedIndex=i[i.length-1];this.focusItem(this.focusedIndex);break;case"Escape":e.preventDefault();this.close();break;case"Tab":e.preventDefault();this.close();break}}focusItem(e){const s=this.el.querySelectorAll(".menu-item");s[e]?.focus()}handleItemClick(e){if(e.isInactive)return;this.dsSelect.emit(e);this.close()}render(){if(!this.shouldRender)return t(n,{style:{display:"contents"}});const e=this.activeSections;let s=0;const i={position:"fixed",left:"0",top:"0",transform:`translate(${Math.round(this.pos.x)}px, ${Math.round(this.pos.y)}px)`,zIndex:"9998",visibility:this.positionReady?"visible":"hidden"};if(this.menuWidth)i["width"]=this.menuWidth;if(this.minWidth)i["min-width"]=this.minWidth;return t(n,{style:{display:"contents"}},t("div",{class:{"menu-popup":true,"menu-popup--closing":this.closing},style:i,role:"menu","aria-label":"Menu","aria-orientation":"vertical"},e.map(((i,n)=>t("div",{key:n,class:{"menu-section":true,"menu-section--divided":n<e.length-1},role:i.header?"group":undefined,"aria-label":i.header},i.header&&t("div",{class:"section-header","aria-hidden":"true"},t("span",{class:"text-body-small-emphasis section-label"},i.header)),i.items.map((e=>{const i=s++;const n=this.focusedIndex===i;return t("button",{key:i,type:"button",class:{"menu-item":true,"ds-focus-ring-inset":true,"ds-focus-ring--visible":n&&this.focusRingVisible,"menu-item--selected":!!e.isSelected,"menu-item--inactive":!!e.isInactive,"menu-item--destructive":!!e.isDestructive,"menu-item--focused":n},role:"menuitem","aria-current":e.isSelected?"true":undefined,disabled:e.isInactive,tabIndex:n?0:-1,onMouseDown:()=>{this.focusRingVisible=false},onClick:()=>this.handleItemClick(e),onFocus:()=>{this.focusedIndex=i}},t("div",{class:"menu-item__content"},t("span",{class:e.isSelected?"text-body-medium-emphasis menu-item__label":"text-body-medium menu-item__label"},e.label),e.subtext&&t("span",{class:"text-body-small menu-item__subtext"},e.subtext)),e.showToggle&&t("div",{class:{"menu-item__toggle":true,"menu-item__toggle--on":!!e.toggleValue},"aria-hidden":"true"},t("div",{class:"menu-item__toggle-thumb"})))})))))))}get el(){return this}static get watchers(){return{open:[{onOpenChange:0}],anchor:[{onAnchorChange:0}],anchorId:[{onAnchorChange:0}],side:[{onPositionPropsChange:0}],align:[{onPositionPropsChange:0}],sideOffset:[{onPositionPropsChange:0}],alignOffset:[{onPositionPropsChange:0}]}}static get style(){return c()}},[2,"ds-menu",{open:[1028],items:[16],sections:[16],side:[1],align:[1],sideOffset:[8,"side-offset"],alignOffset:[8,"align-offset"],menuWidth:[1,"menu-width"],minWidth:[1,"min-width"],anchor:[16],anchorId:[1,"anchor-id"],initialFocusVisible:[4,"initial-focus-visible"],shouldRender:[32],closing:[32],pos:[32],focusedIndex:[32],positionReady:[32],focusRingVisible:[32]},[[0,"keydown","handleKeyDown"]],{open:[{onOpenChange:0}],anchor:[{onAnchorChange:0}],anchorId:[{onAnchorChange:0}],side:[{onPositionPropsChange:0}],align:[{onPositionPropsChange:0}],sideOffset:[{onPositionPropsChange:0}],alignOffset:[{onPositionPropsChange:0}]}]);function m(){if(typeof customElements==="undefined"){return}const e=["ds-menu"];e.forEach((e=>{switch(e){case"ds-menu":if(!customElements.get(o(e))){customElements.define(o(e),l)}break}}))}m();export{l as M,m as d};
2
- //# sourceMappingURL=p-YzIqPOqL.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["computeMenuPosition","input","anchorRect","a","popupWidth","pw","popupHeight","ph","side","align","sideOffsetPx","alignOffsetPx","viewportPadPx","vpPad","viewportWidth","viewportHeight","x","y","top","left","right","width","bottom","height","Math","min","max","menuCss","POSITION_RETRY_BUDGET","Menu","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","open","items","sections","sideOffset","TOKEN_DEFAULTS","space050","alignOffset","initialFocusVisible","shouldRender","closing","pos","focusedIndex","positionReady","focusRingVisible","clickOutsideHandler","scrollResizeHandler","closeTimer","itemEls","positionRetryRaf","listenersReady","componentDidLoad","onOpenChange","disconnectedCallback","cancelPositionRetry","teardownListeners","isOpen","setupListeners","schedulePositionUpdate","focusInitialItem","setTimeout","closeAnimationMs","onAnchorChange","onPositionPropsChange","resolveCssLengthPx","popupFallbackWidthPx","menuWidthXs","popupFallbackHeightPx","menuFallbackHeight","resolveCssTimeMs","motionShort3","animationDurationShort3","resolvedAnchor","anchor","anchorId","document","getElementById","activeSections","length","flatItems","flatMap","s","cancelAnimationFrame","onReady","remaining","attempt","calculatePosition","requestAnimationFrame","anchorEl","popup","el","querySelector","getBoundingClientRect","offsetWidth","offsetHeight","window","innerWidth","innerHeight","flat","selectedIdx","findIndex","it","isSelected","isInactive","firstEnabledIdx","btns","querySelectorAll","focus","e","t","target","contains","close","addEventListener","removeEventListener","clearTimeout","dsClose","emit","handleKeyDown","enabled","map","i","filter","cur","indexOf","safe","key","preventDefault","stopPropagation","focusItem","idx","handleItemClick","item","dsSelect","render","h","Host","style","display","flatIdx","popupStyle","position","transform","round","zIndex","visibility","menuWidth","minWidth","class","role","section","si","header","undefined","isFocused","type","isDestructive","disabled","tabIndex","onMouseDown","onClick","onFocus","label","subtext","showToggle","toggleValue"],"sources":["src/wc/components/Menu/menu-position.ts","src/wc/components/Menu/Menu.css?tag=ds-menu&encapsulation=scoped","src/wc/components/Menu/Menu.tsx"],"sourcesContent":["export type MenuSide = 'top' | 'right' | 'bottom' | 'left';\nexport type MenuAlign = 'start' | 'center' | 'end';\n\nexport interface MenuPositionInput {\n anchorRect: Pick<DOMRectReadOnly, 'top' | 'left' | 'right' | 'bottom' | 'width' | 'height'>;\n popupWidth: number;\n popupHeight: number;\n side: MenuSide;\n align: MenuAlign;\n sideOffsetPx: number;\n alignOffsetPx: number;\n viewportPadPx: number;\n viewportWidth: number;\n viewportHeight: number;\n}\n\n/** Pure layout math for ds-menu — anchor rect + placement props → viewport-fixed x/y. */\nexport function computeMenuPosition(input: MenuPositionInput): { x: number; y: number } {\n const {\n anchorRect: a,\n popupWidth: pw,\n popupHeight: ph,\n side,\n align,\n sideOffsetPx,\n alignOffsetPx,\n viewportPadPx: vpPad,\n viewportWidth,\n viewportHeight,\n } = input;\n\n let x = 0;\n let y = 0;\n\n switch (side) {\n case 'top':\n y = a.top - ph - sideOffsetPx;\n x =\n align === 'start'\n ? a.left + alignOffsetPx\n : align === 'end'\n ? a.right - pw + alignOffsetPx\n : a.left + a.width / 2 - pw / 2 + alignOffsetPx;\n break;\n case 'bottom':\n y = a.bottom + sideOffsetPx;\n x =\n align === 'start'\n ? a.left + alignOffsetPx\n : align === 'end'\n ? a.right - pw + alignOffsetPx\n : a.left + a.width / 2 - pw / 2 + alignOffsetPx;\n break;\n case 'left':\n x = a.left - pw - sideOffsetPx;\n y =\n align === 'start'\n ? a.top + alignOffsetPx\n : align === 'end'\n ? a.bottom - ph + alignOffsetPx\n : a.top + a.height / 2 - ph / 2 + alignOffsetPx;\n break;\n case 'right':\n x = a.right + sideOffsetPx;\n y =\n align === 'start'\n ? a.top + alignOffsetPx\n : align === 'end'\n ? a.bottom - ph + alignOffsetPx\n : a.top + a.height / 2 - ph / 2 + alignOffsetPx;\n break;\n }\n\n return {\n x: Math.min(Math.max(x, vpPad), viewportWidth - pw - vpPad),\n y: Math.min(Math.max(y, vpPad), viewportHeight - ph - vpPad),\n };\n}\n","@import '../../utils/focus-ring.css';\n\n/* ── Popup shell ─────────────────────────────────────────────────────────── */\n\n.menu-popup {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n min-width: var(--dimension-menu-width-xs);\n max-width: var(--dimension-panel-width-lg);\n overflow: hidden;\n background-color: var(--color-background-primary);\n border-radius: var(--dimension-radius-075);\n /* Split elevation: shadow on shell, inset highlight on ::after (combined token clips with overflow:hidden). */\n box-shadow: var(--effect-shadow-elevated-floating);\n animation: menuFadeIn var(--effect-motion-short-2) forwards;\n backface-visibility: hidden;\n will-change: transform;\n}\n\n.menu-popup::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n pointer-events: none;\n box-shadow: var(--effect-highlight-elevated-floating);\n}\n\n.menu-popup--closing {\n animation: menuFadeOut var(--effect-motion-short-3) forwards;\n}\n\n@keyframes menuFadeIn {\n from { opacity: 0; transform: inherit scale(0.97); }\n to { opacity: 1; }\n}\n\n@keyframes menuFadeOut {\n from { opacity: 1; }\n to { opacity: 0; }\n}\n\n/* ── Sections ────────────────────────────────────────────────────────────── */\n\n.menu-section {\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-050);\n padding: var(--dimension-space-050);\n}\n\n.menu-section--divided {\n border-bottom: var(--dimension-stroke-width-015) solid var(--color-border-tertiary);\n}\n\n.section-header {\n display: flex;\n align-items: center;\n height: var(--dimension-size-400);\n padding: var(--dimension-space-050) var(--dimension-space-075);\n -webkit-user-select: none;\n user-select: none;\n}\n\n.section-label {\n color: var(--color-foreground-secondary);\n}\n\n/* ── Items ───────────────────────────────────────────────────────────────── */\n\n.menu-item {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-050);\n position: relative;\n width: 100%;\n min-height: var(--dimension-size-400);\n padding: var(--dimension-space-075);\n box-sizing: border-box;\n border: none;\n border-radius: var(--dimension-radius-025);\n background: transparent;\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n text-align: left;\n color: inherit;\n --_hover-bg: var(--color-interaction-hover);\n --_pressed-bg: var(--color-interaction-pressed);\n --_selected-bg: var(--color-interaction-active);\n}\n\n.menu-item:has(.menu-item__subtext) {\n align-items: flex-start;\n}\n\n/* Interaction layer — same ::after pattern as tabs / BarNav trigger */\n.menu-item::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: transparent;\n pointer-events: none;\n transition: none;\n}\n\n.menu-item--selected::after {\n background: var(--_selected-bg);\n transition: none;\n}\n\n.menu-item:hover:not(:disabled):not(.menu-item--selected)::after {\n background: var(--_hover-bg);\n transition: none;\n}\n\n.menu-item:active:not(:disabled)::after {\n background: var(--_pressed-bg);\n transition: none;\n}\n\n.menu-item--inactive {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n.menu-item--destructive .menu-item__label {\n color: var(--color-foreground-bold-negative) !important;\n}\n\n.menu-item__content {\n position: relative;\n z-index: 1;\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: var(--dimension-space-025);\n min-width: 0;\n}\n\n.menu-item__label {\n color: var(--color-foreground-secondary);\n}\n\n.menu-item:has(.menu-item__subtext) .menu-item__label,\n.menu-item--selected .menu-item__label {\n color: var(--color-foreground-primary);\n}\n\n.menu-item__subtext {\n color: var(--color-foreground-secondary);\n line-height: 1.4;\n}\n\n/* ── Toggle suffix ───────────────────────────────────────────────────────── */\n\n.menu-item__toggle {\n position: relative;\n z-index: 1;\n flex-shrink: 0;\n width: calc(var(--dimension-size-400) + var(--dimension-size-050));\n height: var(--dimension-size-250);\n border-radius: var(--dimension-radius-125);\n background-color: var(--color-background-translucent);\n transition: background-color var(--effect-motion-short-2);\n}\n\n.menu-item__toggle--on {\n background-color: var(--color-background-medium-brand);\n}\n\n.menu-item__toggle-thumb {\n position: absolute;\n top: var(--dimension-space-025);\n left: var(--dimension-space-025);\n width: var(--dimension-size-200);\n height: var(--dimension-size-200);\n border-radius: 50%;\n background-color: var(--color-foreground-on-bold-background-primary);\n transition: transform var(--effect-motion-short-2);\n}\n\n.menu-item__toggle--on .menu-item__toggle-thumb {\n transform: translateX(var(--dimension-offset-200, 16px));\n}\n","import { Component, Prop, State, Event, EventEmitter, Element, Watch, Listen, h, Host } from '@stencil/core';\nimport { resolveCssLengthPx, resolveCssTimeMs, TOKEN_DEFAULTS } from '../../utils';\nimport { computeMenuPosition, type MenuAlign, type MenuSide } from './menu-position';\nimport type { MenuItemData, MenuSection } from './menu-types';\n\n/** rAF retries while the popup mounts or the anchor resolves. */\nconst POSITION_RETRY_BUDGET = 8;\n\n@Component({\n tag: 'ds-menu',\n styleUrl: 'Menu.css',\n scoped: true,\n})\nexport class Menu {\n @Element() el!: HTMLElement;\n\n @Prop({ mutable: true }) open: boolean = false;\n @Prop() items: MenuItemData[] = [];\n @Prop() sections: MenuSection[] = [];\n @Prop() side: MenuSide = 'bottom';\n @Prop() align: MenuAlign = 'start';\n /** Gap between anchor and menu — number (px) or TokoMo length (`var(--dimension-space-050)`, etc.). */\n @Prop() sideOffset: number | string = TOKEN_DEFAULTS.space050;\n /** Cross-axis offset — number (px) or TokoMo length. */\n @Prop() alignOffset: number | string = 0;\n @Prop() menuWidth: string | undefined;\n @Prop() minWidth: string | undefined;\n /** External trigger element to position against. Set via JS: menuEl.anchor = buttonEl */\n @Prop() anchor: HTMLElement | undefined;\n /** ID of the external trigger element for positioning */\n @Prop() anchorId: string | undefined;\n /** Show a visible ring on the initially focused menu item. Use only when the opener was keyboard-driven. */\n @Prop() initialFocusVisible: boolean = false;\n\n @State() private shouldRender: boolean = false;\n @State() private closing: boolean = false;\n @State() private pos: { x: number; y: number } = { x: 0, y: 0 };\n @State() private focusedIndex: number = 0;\n @State() private positionReady: boolean = false;\n @State() private focusRingVisible: boolean = false;\n\n @Event() dsClose!: EventEmitter<void>;\n @Event() dsSelect!: EventEmitter<MenuItemData>;\n\n private clickOutsideHandler: ((e: MouseEvent) => void) | null = null;\n private scrollResizeHandler: (() => void) | null = null;\n private closeTimer: ReturnType<typeof setTimeout> | null = null;\n private itemEls: HTMLElement[] = [];\n private positionRetryRaf: number | null = null;\n private listenersReady = false;\n\n componentDidLoad() {\n if (this.open) this.onOpenChange(true);\n }\n\n disconnectedCallback() {\n this.cancelPositionRetry();\n this.teardownListeners();\n }\n\n @Watch('open')\n onOpenChange(isOpen: boolean) {\n if (isOpen) {\n this.teardownListeners();\n this.shouldRender = true;\n this.closing = false;\n this.positionReady = false;\n this.listenersReady = false;\n this.focusRingVisible = this.initialFocusVisible;\n this.listenersReady = true;\n this.setupListeners();\n this.schedulePositionUpdate(() => {\n this.focusInitialItem();\n });\n } else if (this.shouldRender) {\n this.cancelPositionRetry();\n this.closing = true;\n this.teardownListeners();\n this.listenersReady = false;\n this.closeTimer = setTimeout(() => {\n this.shouldRender = false;\n this.closing = false;\n this.closeTimer = null;\n }, this.closeAnimationMs);\n }\n }\n\n @Watch('anchor')\n @Watch('anchorId')\n onAnchorChange() {\n if (this.open) this.schedulePositionUpdate();\n }\n\n @Watch('side')\n @Watch('align')\n @Watch('sideOffset')\n @Watch('alignOffset')\n onPositionPropsChange() {\n if (this.open) this.schedulePositionUpdate();\n }\n\n private get viewportPadPx(): number {\n return resolveCssLengthPx(TOKEN_DEFAULTS.space050, TOKEN_DEFAULTS.space050);\n }\n\n private get sideOffsetPx(): number {\n return resolveCssLengthPx(this.sideOffset, TOKEN_DEFAULTS.space050);\n }\n\n private get alignOffsetPx(): number {\n return resolveCssLengthPx(this.alignOffset, 0);\n }\n\n private get popupFallbackWidthPx(): number {\n return resolveCssLengthPx(TOKEN_DEFAULTS.menuWidthXs, TOKEN_DEFAULTS.menuWidthXs);\n }\n\n private get popupFallbackHeightPx(): number {\n return resolveCssLengthPx(TOKEN_DEFAULTS.menuFallbackHeight, TOKEN_DEFAULTS.menuFallbackHeight);\n }\n\n private get closeAnimationMs(): number {\n return resolveCssTimeMs(TOKEN_DEFAULTS.motionShort3, TOKEN_DEFAULTS.animationDurationShort3);\n }\n\n private get resolvedAnchor(): HTMLElement | null {\n if (this.anchor) return this.anchor;\n if (this.anchorId) return document.getElementById(this.anchorId);\n return null;\n }\n\n private get activeSections(): MenuSection[] {\n if (this.sections.length > 0) return this.sections;\n if (this.items.length > 0) return [{ items: this.items }];\n return [];\n }\n\n private get flatItems(): MenuItemData[] {\n return this.activeSections.flatMap(s => s.items);\n }\n\n private cancelPositionRetry() {\n if (this.positionRetryRaf !== null) {\n cancelAnimationFrame(this.positionRetryRaf);\n this.positionRetryRaf = null;\n }\n }\n\n /** Retry until anchor + popup exist — do not reveal at 0,0 on a failed first pass. */\n private schedulePositionUpdate(onReady?: () => void) {\n if (!this.open) return;\n\n this.cancelPositionRetry();\n this.positionReady = false;\n\n let remaining = POSITION_RETRY_BUDGET;\n\n const attempt = () => {\n this.positionRetryRaf = null;\n if (!this.open) return;\n\n if (this.calculatePosition()) {\n this.positionReady = true;\n onReady?.();\n return;\n }\n\n if (remaining > 0) {\n remaining -= 1;\n this.positionRetryRaf = requestAnimationFrame(attempt);\n }\n };\n\n this.positionRetryRaf = requestAnimationFrame(attempt);\n }\n\n /** @returns `true` when anchor and popup were found and `pos` was updated. */\n private calculatePosition(): boolean {\n const anchorEl = this.resolvedAnchor;\n if (!anchorEl) return false;\n const popup = this.el.querySelector('.menu-popup') as HTMLElement | null;\n if (!popup) return false;\n\n this.pos = computeMenuPosition({\n anchorRect: anchorEl.getBoundingClientRect(),\n popupWidth: popup.offsetWidth || this.popupFallbackWidthPx,\n popupHeight: popup.offsetHeight || this.popupFallbackHeightPx,\n side: this.side,\n align: this.align,\n sideOffsetPx: this.sideOffsetPx,\n alignOffsetPx: this.alignOffsetPx,\n viewportPadPx: this.viewportPadPx,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n });\n return true;\n }\n\n /** Focus the selected item when present, otherwise the first enabled item. */\n private focusInitialItem() {\n const flat = this.flatItems;\n const selectedIdx = flat.findIndex(it => it.isSelected && !it.isInactive);\n const firstEnabledIdx = flat.findIndex(it => !it.isInactive);\n this.focusedIndex = selectedIdx >= 0\n ? selectedIdx\n : (firstEnabledIdx >= 0 ? firstEnabledIdx : 0);\n\n requestAnimationFrame(() => {\n const btns = this.el.querySelectorAll<HTMLElement>('.menu-item');\n btns[this.focusedIndex]?.focus();\n });\n }\n\n private setupListeners() {\n this.clickOutsideHandler = (e: MouseEvent) => {\n const t = e.target as Node;\n const popup = this.el.querySelector('.menu-popup');\n const anchorEl = this.resolvedAnchor;\n if (popup?.contains(t) || anchorEl?.contains(t)) return;\n this.close();\n };\n\n this.scrollResizeHandler = () => {\n if (this.shouldRender && !this.closing) this.calculatePosition();\n };\n\n document.addEventListener('mousedown', this.clickOutsideHandler, true);\n window.addEventListener('scroll', this.scrollResizeHandler, true);\n window.addEventListener('resize', this.scrollResizeHandler);\n }\n\n private teardownListeners() {\n if (this.clickOutsideHandler) {\n document.removeEventListener('mousedown', this.clickOutsideHandler, true);\n this.clickOutsideHandler = null;\n }\n if (this.scrollResizeHandler) {\n window.removeEventListener('scroll', this.scrollResizeHandler, true);\n window.removeEventListener('resize', this.scrollResizeHandler);\n this.scrollResizeHandler = null;\n }\n if (this.closeTimer) {\n clearTimeout(this.closeTimer);\n this.closeTimer = null;\n }\n }\n\n private close() {\n this.resolvedAnchor?.focus();\n this.dsClose.emit();\n this.open = false;\n this.onOpenChange(false);\n }\n\n @Listen('keydown')\n handleKeyDown(e: KeyboardEvent) {\n if (!this.shouldRender || this.closing) return;\n const flat = this.flatItems;\n const enabled = flat.map((it, i) => ({ it, i })).filter(({ it }) => !it.isInactive).map(({ i }) => i);\n if (!enabled.length) return;\n\n const cur = enabled.indexOf(this.focusedIndex);\n const safe = cur < 0 ? 0 : cur;\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault(); e.stopPropagation();\n this.focusRingVisible = true;\n this.focusedIndex = enabled[(safe + 1) % enabled.length];\n this.focusItem(this.focusedIndex);\n break;\n case 'ArrowUp':\n e.preventDefault(); e.stopPropagation();\n this.focusRingVisible = true;\n this.focusedIndex = enabled[(safe - 1 + enabled.length) % enabled.length];\n this.focusItem(this.focusedIndex);\n break;\n case 'Home':\n e.preventDefault(); e.stopPropagation();\n this.focusRingVisible = true;\n this.focusedIndex = enabled[0];\n this.focusItem(this.focusedIndex);\n break;\n case 'End':\n e.preventDefault(); e.stopPropagation();\n this.focusRingVisible = true;\n this.focusedIndex = enabled[enabled.length - 1];\n this.focusItem(this.focusedIndex);\n break;\n case 'Escape':\n e.preventDefault();\n this.close();\n break;\n case 'Tab':\n e.preventDefault();\n this.close();\n break;\n }\n }\n\n private focusItem(idx: number) {\n const btns = this.el.querySelectorAll<HTMLElement>('.menu-item');\n btns[idx]?.focus();\n }\n\n private handleItemClick(item: MenuItemData) {\n if (item.isInactive) return;\n this.dsSelect.emit(item);\n this.close();\n }\n\n render() {\n if (!this.shouldRender) return <Host style={{ display: 'contents' }} />;\n\n const sections = this.activeSections;\n let flatIdx = 0;\n\n const popupStyle: Record<string, string> = {\n position: 'fixed',\n left: '0',\n top: '0',\n transform: `translate(${Math.round(this.pos.x)}px, ${Math.round(this.pos.y)}px)`,\n zIndex: '9998',\n visibility: this.positionReady ? 'visible' : 'hidden',\n };\n\n if (this.menuWidth) popupStyle['width'] = this.menuWidth;\n if (this.minWidth) popupStyle['min-width'] = this.minWidth;\n\n return (\n <Host style={{ display: 'contents' }}>\n <div\n class={{ 'menu-popup': true, 'menu-popup--closing': this.closing }}\n style={popupStyle}\n role=\"menu\"\n aria-label=\"Menu\"\n aria-orientation=\"vertical\"\n >\n {sections.map((section, si) => (\n <div\n key={si}\n class={{ 'menu-section': true, 'menu-section--divided': si < sections.length - 1 }}\n role={section.header ? 'group' : undefined}\n aria-label={section.header}\n >\n {section.header && (\n <div class=\"section-header\" aria-hidden=\"true\">\n <span class=\"text-body-small-emphasis section-label\">{section.header}</span>\n </div>\n )}\n {section.items.map(item => {\n const idx = flatIdx++;\n const isFocused = this.focusedIndex === idx;\n return (\n <button\n key={idx}\n type=\"button\"\n class={{\n 'menu-item': true,\n 'ds-focus-ring-inset': true,\n 'ds-focus-ring--visible': isFocused && this.focusRingVisible,\n 'menu-item--selected': !!item.isSelected,\n 'menu-item--inactive': !!item.isInactive,\n 'menu-item--destructive': !!item.isDestructive,\n 'menu-item--focused': isFocused,\n }}\n role=\"menuitem\"\n aria-current={item.isSelected ? 'true' : undefined}\n disabled={item.isInactive}\n tabIndex={isFocused ? 0 : -1}\n onMouseDown={() => { this.focusRingVisible = false; }}\n onClick={() => this.handleItemClick(item)}\n onFocus={() => { this.focusedIndex = idx; }}\n >\n <div class=\"menu-item__content\">\n <span class={item.isSelected ? 'text-body-medium-emphasis menu-item__label' : 'text-body-medium menu-item__label'}>\n {item.label}\n </span>\n {item.subtext && (\n <span class=\"text-body-small menu-item__subtext\">{item.subtext}</span>\n )}\n </div>\n {item.showToggle && (\n <div class={{ 'menu-item__toggle': true, 'menu-item__toggle--on': !!item.toggleValue }} aria-hidden=\"true\">\n <div class=\"menu-item__toggle-thumb\" />\n </div>\n )}\n </button>\n );\n })}\n </div>\n ))}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"8KAiBM,SAAUA,EAAoBC,GAClC,MACEC,WAAYC,EACZC,WAAYC,EACZC,YAAaC,EAAEC,KACfA,EAAIC,MACJA,EAAKC,aACLA,EAAYC,cACZA,EACAC,cAAeC,EAAKC,cACpBA,EAAaC,eACbA,GACEd,EAEJ,IAAIe,EAAI,EACR,IAAIC,EAAI,EAER,OAAQT,GACN,IAAK,MACHS,EAAId,EAAEe,IAAMX,EAAKG,EACjBM,EACEP,IAAU,QACNN,EAAEgB,KAAOR,EACTF,IAAU,MACRN,EAAEiB,MAAQf,EAAKM,EACfR,EAAEgB,KAAOhB,EAAEkB,MAAQ,EAAIhB,EAAK,EAAIM,EACxC,MACF,IAAK,SACHM,EAAId,EAAEmB,OAASZ,EACfM,EACEP,IAAU,QACNN,EAAEgB,KAAOR,EACTF,IAAU,MACRN,EAAEiB,MAAQf,EAAKM,EACfR,EAAEgB,KAAOhB,EAAEkB,MAAQ,EAAIhB,EAAK,EAAIM,EACxC,MACF,IAAK,OACHK,EAAIb,EAAEgB,KAAOd,EAAKK,EAClBO,EACER,IAAU,QACNN,EAAEe,IAAMP,EACRF,IAAU,MACRN,EAAEmB,OAASf,EAAKI,EAChBR,EAAEe,IAAMf,EAAEoB,OAAS,EAAIhB,EAAK,EAAII,EACxC,MACF,IAAK,QACHK,EAAIb,EAAEiB,MAAQV,EACdO,EACER,IAAU,QACNN,EAAEe,IAAMP,EACRF,IAAU,MACRN,EAAEmB,OAASf,EAAKI,EAChBR,EAAEe,IAAMf,EAAEoB,OAAS,EAAIhB,EAAK,EAAII,EACxC,MAGJ,MAAO,CACLK,EAAGQ,KAAKC,IAAID,KAAKE,IAAIV,EAAGH,GAAQC,EAAgBT,EAAKQ,GACrDI,EAAGO,KAAKC,IAAID,KAAKE,IAAIT,EAAGJ,GAAQE,EAAiBR,EAAKM,GAE1D,CC7EA,MAAMc,EAAU,IAAM,8vJCMtB,MAAMC,EAAwB,E,MAOjBC,EAAIC,EAAA,MAAAD,UAAAE,EALjB,WAAAC,CAAAC,G,4GAQ2BC,KAAAC,KAAgB,MACjCD,KAAAE,MAAwB,GACxBF,KAAAG,SAA0B,GAC1BH,KAAA1B,KAAiB,SACjB0B,KAAAzB,MAAmB,QAEnByB,KAAAI,WAA8BC,EAAeC,SAE7CN,KAAAO,YAA+B,EAQ/BP,KAAAQ,oBAA+B,MAEtBR,KAAAS,aAAwB,MACxBT,KAAAU,QAAmB,MACnBV,KAAAW,IAAgC,CAAE7B,EAAG,EAAGC,EAAG,GAC3CiB,KAAAY,aAAuB,EACvBZ,KAAAa,cAAyB,MACzBb,KAAAc,iBAA4B,MAKrCd,KAAAe,oBAAwD,KACxDf,KAAAgB,oBAA2C,KAC3ChB,KAAAiB,WAAmD,KACnDjB,KAAAkB,QAAyB,GACzBlB,KAAAmB,iBAAkC,KAClCnB,KAAAoB,eAAiB,KA2V1B,CAzVC,gBAAAC,GACE,GAAIrB,KAAKC,KAAMD,KAAKsB,aAAa,K,CAGnC,oBAAAC,GACEvB,KAAKwB,sBACLxB,KAAKyB,mB,CAIP,YAAAH,CAAaI,GACX,GAAIA,EAAQ,CACV1B,KAAKyB,oBACLzB,KAAKS,aAAe,KACpBT,KAAKU,QAAU,MACfV,KAAKa,cAAgB,MACrBb,KAAKoB,eAAiB,MACtBpB,KAAKc,iBAAmBd,KAAKQ,oBAC7BR,KAAKoB,eAAiB,KACtBpB,KAAK2B,iBACL3B,KAAK4B,wBAAuB,KAC1B5B,KAAK6B,kBAAkB,G,MAEpB,GAAI7B,KAAKS,aAAc,CAC5BT,KAAKwB,sBACLxB,KAAKU,QAAU,KACfV,KAAKyB,oBACLzB,KAAKoB,eAAiB,MACtBpB,KAAKiB,WAAaa,YAAW,KAC3B9B,KAAKS,aAAe,MACpBT,KAAKU,QAAU,MACfV,KAAKiB,WAAa,IAAI,GACrBjB,KAAK+B,iB,EAMZ,cAAAC,GACE,GAAIhC,KAAKC,KAAMD,KAAK4B,wB,CAOtB,qBAAAK,GACE,GAAIjC,KAAKC,KAAMD,KAAK4B,wB,CAGtB,iBAAYlD,GACV,OAAOwD,EAAmB7B,EAAeC,SAAUD,EAAeC,S,CAGpE,gBAAY9B,GACV,OAAO0D,EAAmBlC,KAAKI,WAAYC,EAAeC,S,CAG5D,iBAAY7B,GACV,OAAOyD,EAAmBlC,KAAKO,YAAa,E,CAG9C,wBAAY4B,GACV,OAAOD,EAAmB7B,EAAe+B,YAAa/B,EAAe+B,Y,CAGvE,yBAAYC,GACV,OAAOH,EAAmB7B,EAAeiC,mBAAoBjC,EAAeiC,mB,CAG9E,oBAAYP,GACV,OAAOQ,EAAiBlC,EAAemC,aAAcnC,EAAeoC,wB,CAGtE,kBAAYC,GACV,GAAI1C,KAAK2C,OAAQ,OAAO3C,KAAK2C,OAC7B,GAAI3C,KAAK4C,SAAU,OAAOC,SAASC,eAAe9C,KAAK4C,UACvD,OAAO,I,CAGT,kBAAYG,GACV,GAAI/C,KAAKG,SAAS6C,OAAS,EAAG,OAAOhD,KAAKG,SAC1C,GAAIH,KAAKE,MAAM8C,OAAS,EAAG,MAAO,CAAC,CAAE9C,MAAOF,KAAKE,QACjD,MAAO,E,CAGT,aAAY+C,GACV,OAAOjD,KAAK+C,eAAeG,SAAQC,GAAKA,EAAEjD,O,CAGpC,mBAAAsB,GACN,GAAIxB,KAAKmB,mBAAqB,KAAM,CAClCiC,qBAAqBpD,KAAKmB,kBAC1BnB,KAAKmB,iBAAmB,I,EAKpB,sBAAAS,CAAuByB,GAC7B,IAAKrD,KAAKC,KAAM,OAEhBD,KAAKwB,sBACLxB,KAAKa,cAAgB,MAErB,IAAIyC,EAAY5D,EAEhB,MAAM6D,EAAU,KACdvD,KAAKmB,iBAAmB,KACxB,IAAKnB,KAAKC,KAAM,OAEhB,GAAID,KAAKwD,oBAAqB,CAC5BxD,KAAKa,cAAgB,KACrBwC,MACA,M,CAGF,GAAIC,EAAY,EAAG,CACjBA,GAAa,EACbtD,KAAKmB,iBAAmBsC,sBAAsBF,E,GAIlDvD,KAAKmB,iBAAmBsC,sBAAsBF,E,CAIxC,iBAAAC,GACN,MAAME,EAAW1D,KAAK0C,eACtB,IAAKgB,EAAU,OAAO,MACtB,MAAMC,EAAQ3D,KAAK4D,GAAGC,cAAc,eACpC,IAAKF,EAAO,OAAO,MAEnB3D,KAAKW,IAAM7C,EAAoB,CAC7BE,WAAY0F,EAASI,wBACrB5F,WAAYyF,EAAMI,aAAe/D,KAAKmC,qBACtC/D,YAAauF,EAAMK,cAAgBhE,KAAKqC,sBACxC/D,KAAM0B,KAAK1B,KACXC,MAAOyB,KAAKzB,MACZC,aAAcwB,KAAKxB,aACnBC,cAAeuB,KAAKvB,cACpBC,cAAesB,KAAKtB,cACpBE,cAAeqF,OAAOC,WACtBrF,eAAgBoF,OAAOE,cAEzB,OAAO,I,CAID,gBAAAtC,GACN,MAAMuC,EAAOpE,KAAKiD,UAClB,MAAMoB,EAAcD,EAAKE,WAAUC,GAAMA,EAAGC,aAAeD,EAAGE,aAC9D,MAAMC,EAAkBN,EAAKE,WAAUC,IAAOA,EAAGE,aACjDzE,KAAKY,aAAeyD,GAAe,EAC/BA,EACCK,GAAmB,EAAIA,EAAkB,EAE9CjB,uBAAsB,KACpB,MAAMkB,EAAO3E,KAAK4D,GAAGgB,iBAA8B,cACnDD,EAAK3E,KAAKY,eAAeiE,OAAO,G,CAI5B,cAAAlD,GACN3B,KAAKe,oBAAuB+D,IAC1B,MAAMC,EAAID,EAAEE,OACZ,MAAMrB,EAAQ3D,KAAK4D,GAAGC,cAAc,eACpC,MAAMH,EAAW1D,KAAK0C,eACtB,GAAIiB,GAAOsB,SAASF,IAAMrB,GAAUuB,SAASF,GAAI,OACjD/E,KAAKkF,OAAO,EAGdlF,KAAKgB,oBAAsB,KACzB,GAAIhB,KAAKS,eAAiBT,KAAKU,QAASV,KAAKwD,mBAAmB,EAGlEX,SAASsC,iBAAiB,YAAanF,KAAKe,oBAAqB,MACjEkD,OAAOkB,iBAAiB,SAAUnF,KAAKgB,oBAAqB,MAC5DiD,OAAOkB,iBAAiB,SAAUnF,KAAKgB,oB,CAGjC,iBAAAS,GACN,GAAIzB,KAAKe,oBAAqB,CAC5B8B,SAASuC,oBAAoB,YAAapF,KAAKe,oBAAqB,MACpEf,KAAKe,oBAAsB,I,CAE7B,GAAIf,KAAKgB,oBAAqB,CAC5BiD,OAAOmB,oBAAoB,SAAUpF,KAAKgB,oBAAqB,MAC/DiD,OAAOmB,oBAAoB,SAAUpF,KAAKgB,qBAC1ChB,KAAKgB,oBAAsB,I,CAE7B,GAAIhB,KAAKiB,WAAY,CACnBoE,aAAarF,KAAKiB,YAClBjB,KAAKiB,WAAa,I,EAId,KAAAiE,GACNlF,KAAK0C,gBAAgBmC,QACrB7E,KAAKsF,QAAQC,OACbvF,KAAKC,KAAO,MACZD,KAAKsB,aAAa,M,CAIpB,aAAAkE,CAAcV,GACZ,IAAK9E,KAAKS,cAAgBT,KAAKU,QAAS,OACxC,MAAM0D,EAAOpE,KAAKiD,UAClB,MAAMwC,EAAUrB,EAAKsB,KAAI,CAACnB,EAAIoB,KAAC,CAAQpB,KAAIoB,QAAMC,QAAO,EAAGrB,SAAUA,EAAGE,aAAYiB,KAAI,EAAGC,OAAQA,IACnG,IAAKF,EAAQzC,OAAQ,OAErB,MAAM6C,EAAMJ,EAAQK,QAAQ9F,KAAKY,cACjC,MAAMmF,EAAOF,EAAM,EAAI,EAAIA,EAE3B,OAAQf,EAAEkB,KACR,IAAK,YACHlB,EAAEmB,iBAAkBnB,EAAEoB,kBACtBlG,KAAKc,iBAAmB,KACxBd,KAAKY,aAAe6E,GAASM,EAAO,GAAKN,EAAQzC,QACjDhD,KAAKmG,UAAUnG,KAAKY,cACpB,MACF,IAAK,UACHkE,EAAEmB,iBAAkBnB,EAAEoB,kBACtBlG,KAAKc,iBAAmB,KACxBd,KAAKY,aAAe6E,GAASM,EAAO,EAAIN,EAAQzC,QAAUyC,EAAQzC,QAClEhD,KAAKmG,UAAUnG,KAAKY,cACpB,MACF,IAAK,OACHkE,EAAEmB,iBAAkBnB,EAAEoB,kBACtBlG,KAAKc,iBAAmB,KACxBd,KAAKY,aAAe6E,EAAQ,GAC5BzF,KAAKmG,UAAUnG,KAAKY,cACpB,MACF,IAAK,MACHkE,EAAEmB,iBAAkBnB,EAAEoB,kBACtBlG,KAAKc,iBAAmB,KACxBd,KAAKY,aAAe6E,EAAQA,EAAQzC,OAAS,GAC7ChD,KAAKmG,UAAUnG,KAAKY,cACpB,MACF,IAAK,SACHkE,EAAEmB,iBACFjG,KAAKkF,QACL,MACF,IAAK,MACHJ,EAAEmB,iBACFjG,KAAKkF,QACL,M,CAIE,SAAAiB,CAAUC,GAChB,MAAMzB,EAAO3E,KAAK4D,GAAGgB,iBAA8B,cACnDD,EAAKyB,IAAMvB,O,CAGL,eAAAwB,CAAgBC,GACtB,GAAIA,EAAK7B,WAAY,OACrBzE,KAAKuG,SAAShB,KAAKe,GACnBtG,KAAKkF,O,CAGP,MAAAsB,GACE,IAAKxG,KAAKS,aAAc,OAAOgG,EAACC,EAAI,CAACC,MAAO,CAAEC,QAAS,cAEvD,MAAMzG,EAAWH,KAAK+C,eACtB,IAAI8D,EAAU,EAEd,MAAMC,EAAqC,CACzCC,SAAU,QACV9H,KAAM,IACND,IAAK,IACLgI,UAAW,aAAa1H,KAAK2H,MAAMjH,KAAKW,IAAI7B,SAASQ,KAAK2H,MAAMjH,KAAKW,IAAI5B,QACzEmI,OAAQ,OACRC,WAAYnH,KAAKa,cAAgB,UAAY,UAG/C,GAAIb,KAAKoH,UAAWN,EAAW,SAAW9G,KAAKoH,UAC/C,GAAIpH,KAAKqH,SAAUP,EAAW,aAAe9G,KAAKqH,SAElD,OACEZ,EAACC,EAAI,CAACC,MAAO,CAAEC,QAAS,aACtBH,EAAA,OACEa,MAAO,CAAE,aAAc,KAAM,sBAAuBtH,KAAKU,SACzDiG,MAAOG,EACPS,KAAK,OAAM,aACA,OAAM,mBACA,YAEhBpH,EAASuF,KAAI,CAAC8B,EAASC,IACtBhB,EAAA,OACET,IAAKyB,EACLH,MAAO,CAAE,eAAgB,KAAM,wBAAyBG,EAAKtH,EAAS6C,OAAS,GAC/EuE,KAAMC,EAAQE,OAAS,QAAUC,UAAS,aAC9BH,EAAQE,QAEnBF,EAAQE,QACPjB,EAAA,OAAKa,MAAM,iBAAgB,cAAa,QACtCb,EAAA,QAAMa,MAAM,0CAA0CE,EAAQE,SAGjEF,EAAQtH,MAAMwF,KAAIY,IACjB,MAAMF,EAAMS,IACZ,MAAMe,EAAY5H,KAAKY,eAAiBwF,EACxC,OACEK,EAAA,UACET,IAAKI,EACLyB,KAAK,SACLP,MAAO,CACL,YAAa,KACb,sBAAuB,KACvB,yBAA0BM,GAAa5H,KAAKc,iBAC5C,wBAAyBwF,EAAK9B,WAC9B,wBAAyB8B,EAAK7B,WAC9B,2BAA4B6B,EAAKwB,cACjC,qBAAsBF,GAExBL,KAAK,WAAU,eACDjB,EAAK9B,WAAa,OAASmD,UACzCI,SAAUzB,EAAK7B,WACfuD,SAAUJ,EAAY,GAAI,EAC1BK,YAAa,KAAQjI,KAAKc,iBAAmB,KAAK,EAClDoH,QAAS,IAAMlI,KAAKqG,gBAAgBC,GACpC6B,QAAS,KAAQnI,KAAKY,aAAewF,CAAG,GAExCK,EAAA,OAAKa,MAAM,sBACTb,EAAA,QAAMa,MAAOhB,EAAK9B,WAAa,6CAA+C,qCAC3E8B,EAAK8B,OAEP9B,EAAK+B,SACJ5B,EAAA,QAAMa,MAAM,sCAAsChB,EAAK+B,UAG1D/B,EAAKgC,YACJ7B,EAAA,OAAKa,MAAO,CAAE,oBAAqB,KAAM,0BAA2BhB,EAAKiC,aAAa,cAAc,QAClG9B,EAAA,OAAKa,MAAM,6BAGR,Q","ignoreList":[]}