@redvars/peacock 3.9.0 → 3.9.1

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 (83) hide show
  1. package/dist/code-highlighter.js +1 -4
  2. package/dist/code-highlighter.js.map +1 -1
  3. package/dist/custom-elements-jsdocs.json +39 -223
  4. package/dist/custom-elements.json +391 -2205
  5. package/dist/elevation.js +55 -2
  6. package/dist/elevation.js.map +1 -1
  7. package/dist/flow.js +762 -0
  8. package/dist/flow.js.map +1 -0
  9. package/dist/index.js +1 -3
  10. package/dist/index.js.map +1 -1
  11. package/dist/loader.js +2 -9
  12. package/dist/loader.js.map +1 -1
  13. package/dist/menu-item.js +144 -63
  14. package/dist/menu-item.js.map +1 -1
  15. package/dist/menu.js +161 -73
  16. package/dist/menu.js.map +1 -1
  17. package/dist/src/flow/flow.d.ts +102 -0
  18. package/dist/src/flow/index.d.ts +2 -0
  19. package/dist/src/index.d.ts +2 -4
  20. package/dist/src/menu/menu/menu.d.ts +10 -9
  21. package/dist/src/menu/menu-item/menu-item.d.ts +1 -3
  22. package/dist/src/timeline/timeline.d.ts +0 -1
  23. package/dist/sub-menu.js +28 -1
  24. package/dist/sub-menu.js.map +1 -1
  25. package/dist/timeline-item.js +22 -34
  26. package/dist/timeline-item.js.map +1 -1
  27. package/dist/timeline.js +1 -18
  28. package/dist/timeline.js.map +1 -1
  29. package/dist/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +3 -2
  31. package/readme.md +2 -2
  32. package/src/code-highlighter/code-highlighter.scss +1 -7
  33. package/src/elevation/demo/index.html +52 -0
  34. package/src/elevation/elevation.scss +52 -5
  35. package/src/elevation/elevation.ts +8 -1
  36. package/src/flow/flow.scss +195 -0
  37. package/src/flow/flow.ts +683 -0
  38. package/src/flow/index.ts +2 -0
  39. package/src/index.ts +2 -16
  40. package/src/loader.ts +2 -9
  41. package/src/menu/menu/copy-component-files.mjs +47 -0
  42. package/src/menu/menu/menu.scss +55 -17
  43. package/src/menu/menu/menu.ts +155 -84
  44. package/src/menu/menu-item/menu-item-colors.scss +3 -3
  45. package/src/menu/menu-item/menu-item.scss +118 -24
  46. package/src/menu/menu-item/menu-item.ts +61 -55
  47. package/src/menu/sub-menu/sub-menu.scss +30 -1
  48. package/src/timeline/timeline-item.scss +21 -31
  49. package/src/timeline/timeline-item.ts +2 -1
  50. package/src/timeline/timeline.scss +0 -10
  51. package/src/timeline/timeline.ts +0 -2
  52. package/dist/canvas.js +0 -385
  53. package/dist/canvas.js.map +0 -1
  54. package/dist/flow-designer-node-CGSm6cUH.js +0 -553
  55. package/dist/flow-designer-node-CGSm6cUH.js.map +0 -1
  56. package/dist/flow-designer-node.js +0 -4
  57. package/dist/flow-designer-node.js.map +0 -1
  58. package/dist/flow-designer.js +0 -1417
  59. package/dist/flow-designer.js.map +0 -1
  60. package/dist/src/canvas/canvas.d.ts +0 -92
  61. package/dist/src/canvas/index.d.ts +0 -2
  62. package/dist/src/flow-designer/commands.d.ts +0 -66
  63. package/dist/src/flow-designer/flow-designer-node.d.ts +0 -46
  64. package/dist/src/flow-designer/flow-designer.d.ts +0 -133
  65. package/dist/src/flow-designer/index.d.ts +0 -7
  66. package/dist/src/flow-designer/layout.d.ts +0 -30
  67. package/dist/src/flow-designer/types.d.ts +0 -142
  68. package/dist/src/flow-designer/validation.d.ts +0 -43
  69. package/dist/src/flow-designer/workflow-utils.d.ts +0 -40
  70. package/src/canvas/canvas.scss +0 -72
  71. package/src/canvas/canvas.ts +0 -413
  72. package/src/canvas/index.ts +0 -2
  73. package/src/flow-designer/DEMO.md +0 -239
  74. package/src/flow-designer/commands.ts +0 -278
  75. package/src/flow-designer/flow-designer-node.ts +0 -172
  76. package/src/flow-designer/flow-designer.scss +0 -457
  77. package/src/flow-designer/flow-designer.ts +0 -611
  78. package/src/flow-designer/index.ts +0 -41
  79. package/src/flow-designer/layout.ts +0 -357
  80. package/src/flow-designer/types.ts +0 -166
  81. package/src/flow-designer/validation.ts +0 -284
  82. package/src/flow-designer/workflow-utils.ts +0 -282
  83. /package/dist/test/{flow-designer.test.d.ts → elevation.test.d.ts} +0 -0
package/src/loader.ts CHANGED
@@ -389,15 +389,8 @@ const loaderConfig: LoaderConfig = {
389
389
  'wc-calendar-month-view': {
390
390
  importPath: `${distDirectory}/calendar-month-view.js`,
391
391
  },
392
- 'wc-canvas': {
393
- importPath: `${distDirectory}/canvas.js`,
394
- },
395
- 'wc-flow-designer': {
396
- importPath: `${distDirectory}/flow-designer.js`,
397
- dependencies: ['wc-flow-designer-node'],
398
- },
399
- 'wc-flow-designer-node': {
400
- importPath: `${distDirectory}/flow-designer-node.js`,
392
+ 'wc-flow': {
393
+ importPath: `${distDirectory}/flow.js`,
401
394
  },
402
395
  'wc-chart-doughnut': {
403
396
  importPath: `${distDirectory}/chart-doughnut.js`,
@@ -0,0 +1,47 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ const sourceDir = '../components/dist';
5
+ const destDir = './public/assets/peacock';
6
+
7
+ /**
8
+ * Clears the destination directory
9
+ */
10
+ function clearDirectory(directory) {
11
+ if (fs.existsSync(directory)) {
12
+ // recursive: true deletes subdirectories
13
+ // force: true ignores errors if the path doesn't exist
14
+ fs.rmSync(directory, { recursive: true, force: true });
15
+ console.log(`Cleared directory: ${directory}`);
16
+ }
17
+ }
18
+
19
+ function copyFolderRecursiveSync(source, destination) {
20
+ if (!fs.existsSync(destination)) {
21
+ fs.mkdirSync(destination, { recursive: true });
22
+ }
23
+
24
+ const files = fs.readdirSync(source);
25
+
26
+ files.forEach(file => {
27
+ const srcPath = path.join(source, file);
28
+ const destPath = path.join(destination, file);
29
+ const stat = fs.statSync(srcPath);
30
+
31
+ if (stat.isDirectory()) {
32
+ copyFolderRecursiveSync(srcPath, destPath);
33
+ } else {
34
+ fs.copyFileSync(srcPath, destPath);
35
+ }
36
+ });
37
+
38
+ console.log(`Copied: ${source} -> ${destination}`);
39
+ }
40
+
41
+ // --- Execution ---
42
+
43
+ // 1. Clean the destination
44
+ clearDirectory(destDir);
45
+
46
+ // 2. Perform the copy
47
+ copyFolderRecursiveSync(sourceDir, destDir);
@@ -53,18 +53,66 @@
53
53
  z-index: 1;
54
54
  width: 100%;
55
55
 
56
- ::slotted(:first-child) {
57
- --menu-item-container-shape-start-start: var(--shape-corner-medium);
58
- --menu-item-container-shape-start-end: var(--shape-corner-medium);
56
+ ::slotted([data-position-after-divider]) {
57
+ --menu-item-backdrop-container-shape-start-start: var(
58
+ --shape-corner-small
59
+ );
60
+ --menu-item-backdrop-container-shape-start-end: var(--shape-corner-small);
61
+ --sub-menu-item-backdrop-container-shape-start-start: var(
62
+ --shape-corner-small
63
+ );
64
+ --sub-menu-item-backdrop-container-shape-start-end: var(
65
+ --shape-corner-small
66
+ );
67
+
68
+ --menu-item-backdrop-elevation-level-block-start: 1;
59
69
  }
60
- ::slotted(:last-child) {
61
- --menu-item-container-shape-end-start: var(--shape-corner-medium);
62
- --menu-item-container-shape-end-end: var(--shape-corner-medium);
70
+
71
+ ::slotted([data-position-first]) {
72
+ --menu-item-backdrop-container-shape-start-start: var(
73
+ --shape-corner-large
74
+ );
75
+ --menu-item-backdrop-container-shape-start-end: var(--shape-corner-large);
76
+ --sub-menu-item-backdrop-container-shape-start-start: var(
77
+ --shape-corner-large
78
+ );
79
+ --sub-menu-item-backdrop-container-shape-start-end: var(
80
+ --shape-corner-large
81
+ );
82
+
83
+ --menu-item-backdrop-elevation-level-block-start: 1;
84
+ }
85
+
86
+ ::slotted([data-position-before-divider]) {
87
+ --menu-item-backdrop-elevation-level-block-end: 1;
88
+ --menu-item-backdrop-container-shape-end-start: var(--shape-corner-small);
89
+
90
+ --menu-item-backdrop-container-shape-end-end: var(--shape-corner-small);
91
+ --sub-menu-item-backdrop-container-shape-end-start: var(
92
+ --shape-corner-small
93
+ );
94
+ --sub-menu-item-backdrop-container-shape-end-end: var(
95
+ --shape-corner-small
96
+ );
97
+ }
98
+
99
+ ::slotted([data-position-last]) {
100
+ --menu-item-backdrop-elevation-level-block-end: 1;
101
+ --menu-item-backdrop-container-shape-end-start: var(--shape-corner-large);
102
+
103
+ --menu-item-backdrop-container-shape-end-end: var(--shape-corner-large);
104
+ --sub-menu-item-backdrop-container-shape-end-start: var(
105
+ --shape-corner-large
106
+ );
107
+ --sub-menu-item-backdrop-container-shape-end-end: var(
108
+ --shape-corner-large
109
+ );
63
110
  }
64
111
 
65
112
  ::slotted(wc-divider) {
66
- --divider-spacing: var(--spacing-100);
113
+ --divider-spacing: 1px;
67
114
  padding-inline: var(--spacing-050);
115
+ --divider-color: transparent;
68
116
  }
69
117
  }
70
118
 
@@ -73,8 +121,6 @@
73
121
  position: absolute;
74
122
  inset: 0;
75
123
 
76
- border: 1px solid var(--color-red);
77
-
78
124
  border-start-start-radius: var(--_container-shape-start-start);
79
125
  border-start-end-radius: var(--_container-shape-start-end);
80
126
  border-end-start-radius: var(--_container-shape-end-start);
@@ -95,12 +141,4 @@
95
141
  --_container-shape-start-end: var(--shape-corner-large);
96
142
  --_container-shape-end-start: var(--shape-corner-large);
97
143
  --_container-shape-end-end: var(--shape-corner-large);
98
-
99
- &.variant-standard {
100
- --menu-item-container-color: var(--color-surface-container);
101
- }
102
-
103
- &.variant-vibrant {
104
- --menu-item-container-color: var(--color-tertiary-container);
105
- }
106
144
  }
@@ -1,18 +1,18 @@
1
- import { LitElement, html } from 'lit';
2
- import { property, query, state } from 'lit/decorators.js';
3
- import { classMap } from 'lit/directives/class-map.js';
4
- import type { Placement } from '@floating-ui/dom';
5
- import styles from './menu.scss';
6
- import { FloatingController } from '../../__internal/controllers/floating-controller.js';
7
- import { MenuItem } from '../menu-item/menu-item.js';
8
- import IndividualComponent from '@/IndividualComponent.js';
1
+ import { html, LitElement } from "lit";
2
+ import { property, query, state } from "lit/decorators.js";
3
+ import { classMap } from "lit/directives/class-map.js";
4
+ import type { Placement } from "@floating-ui/dom";
5
+ import styles from "./menu.scss";
6
+ import { FloatingController } from "../../__internal/controllers/floating-controller.js";
7
+ import { MenuItem } from "../menu-item/menu-item.js";
8
+ import IndividualComponent from "@/IndividualComponent.js";
9
9
 
10
10
  type CloseReason =
11
- | { kind: 'click-selection' }
12
- | { kind: 'keydown'; key: string }
13
- | { kind: 'outside-click' }
14
- | { kind: 'focusout' }
15
- | { kind: 'programmatic' };
11
+ | { kind: "click-selection" }
12
+ | { kind: "keydown"; key: string }
13
+ | { kind: "outside-click" }
14
+ | { kind: "focusout" }
15
+ | { kind: "programmatic" };
16
16
 
17
17
  /**
18
18
  * @label Menu
@@ -36,54 +36,62 @@ export class Menu extends LitElement {
36
36
  static Item = MenuItem;
37
37
 
38
38
  /** Whether the menu is currently visible. */
39
- @property({ type: Boolean, reflect: true }) open = false;
39
+ @property({ type: Boolean, reflect: true })
40
+ open = false;
40
41
 
41
42
  /** Visual variant of the menu. `"vibrant"` applies stronger color emphasis. */
42
- @property({ type: String, reflect: true }) variant: 'standard' | 'vibrant' =
43
- 'standard';
43
+ @property({ type: String, reflect: true })
44
+ variant: "standard" | "vibrant" = "standard";
44
45
 
45
46
  /** ID of the anchor element the menu is positioned relative to. */
46
- @property({ type: String }) anchor = '';
47
+ @property({ type: String })
48
+ anchor = "";
47
49
 
48
50
  /** When true, renders the menu in a static preview state (always visible, no animation). */
49
- @property({ type: Boolean, reflect: true }) preview = false;
51
+ @property({ type: Boolean, reflect: true })
52
+ preview = false;
50
53
 
51
54
  /** When true, the menu will not close when a click occurs outside it. */
52
- @property({ type: Boolean, attribute: 'stay-open-on-outside-click' })
55
+ @property({ type: Boolean, attribute: "stay-open-on-outside-click" })
53
56
  stayOpenOnOutsideClick = false;
54
57
 
55
58
  /** When true, the menu will not close when focus leaves it. */
56
- @property({ type: Boolean, attribute: 'stay-open-on-focusout' })
59
+ @property({ type: Boolean, attribute: "stay-open-on-focusout" })
57
60
  stayOpenOnFocusout = false;
58
61
 
59
62
  /** Set to true when this menu is being used as a submenu inside another menu. */
60
- @property({ type: Boolean, attribute: 'is-submenu' }) isSubmenu = false;
63
+ @property({ type: Boolean, attribute: "is-submenu" })
64
+ isSubmenu = false;
61
65
 
62
66
  /** Floating UI placement of the menu relative to its anchor. */
63
- @property({ type: String }) placement: Placement = 'bottom-start';
67
+ @property({ type: String })
68
+ placement: Placement = "bottom-start";
64
69
 
65
70
  /** Distance in pixels between the menu and its anchor element. */
66
- @property({ type: Number }) offset = 6;
71
+ @property({ type: Number })
72
+ offset = 6;
67
73
 
68
74
  /** Index of the currently focused/active item within the enabled items list. */
69
- @state() private activeIndex = -1;
75
+ @state()
76
+ private activeIndex = -1;
70
77
 
71
- @query('.menu') private readonly menuListElement!: HTMLElement;
78
+ @query(".menu")
79
+ private readonly menuListElement!: HTMLElement;
72
80
 
73
81
  /** Direct reference to the anchor element; takes precedence over the `anchor` ID property. */
74
82
  anchorElement: HTMLElement | null = null;
75
83
 
76
84
  /** Controller managing floating-UI positioning. */
77
85
  private readonly _floatingController = new FloatingController(this, {
78
- trigger: 'manual',
86
+ trigger: "manual",
79
87
  closeOnClickOutside: false,
80
- strategy: 'fixed',
81
- onOpenChange: isOpen => {
88
+ strategy: "fixed",
89
+ onOpenChange: (isOpen) => {
82
90
  if (isOpen || !this.open) {
83
91
  return;
84
92
  }
85
93
 
86
- this.close({ kind: 'outside-click' });
94
+ this.close({ kind: "outside-click" });
87
95
  },
88
96
  });
89
97
 
@@ -91,27 +99,27 @@ export class Menu extends LitElement {
91
99
  private _lastFocusedElement: HTMLElement | null = null;
92
100
 
93
101
  /** Reason that triggered the most recent close, included in the `closed` event detail. */
94
- private _closeReason: CloseReason = { kind: 'programmatic' };
102
+ private _closeReason: CloseReason = { kind: "programmatic" };
95
103
 
96
104
  connectedCallback() {
97
105
  // eslint-disable-next-line wc/guard-super-call
98
106
  super.connectedCallback();
99
- this.setAttribute('role', 'menu');
107
+ this.setAttribute("role", "menu");
100
108
 
101
- this.addEventListener('keydown', this._onKeyDown);
102
- this.addEventListener('click', this._onClick);
109
+ this.addEventListener("keydown", this._onKeyDown);
110
+ this.addEventListener("click", this._onClick);
103
111
  this._syncAnchorAria();
104
112
  }
105
113
 
106
114
  disconnectedCallback() {
107
- this.removeEventListener('keydown', this._onKeyDown);
108
- this.removeEventListener('click', this._onClick);
115
+ this.removeEventListener("keydown", this._onKeyDown);
116
+ this.removeEventListener("click", this._onClick);
109
117
  this._floatingController.close();
110
118
  super.disconnectedCallback();
111
119
  }
112
120
 
113
121
  get items(): MenuItem[] {
114
- const slot = this.shadowRoot?.querySelector('slot');
122
+ const slot = this.shadowRoot?.querySelector("slot");
115
123
  const elements = slot?.assignedElements({ flatten: true }) ?? [];
116
124
  const items: MenuItem[] = [];
117
125
 
@@ -134,11 +142,11 @@ export class Menu extends LitElement {
134
142
  return;
135
143
  }
136
144
 
137
- this._closeReason = { kind: 'programmatic' };
145
+ this._closeReason = { kind: "programmatic" };
138
146
  this.open = true;
139
147
  }
140
148
 
141
- close(reason: CloseReason = { kind: 'programmatic' }) {
149
+ close(reason: CloseReason = { kind: "programmatic" }) {
142
150
  if (!this.open) {
143
151
  return;
144
152
  }
@@ -162,7 +170,7 @@ export class Menu extends LitElement {
162
170
  }
163
171
 
164
172
  const root = this.getRootNode() as Document | ShadowRoot;
165
- if ('getElementById' in root) {
173
+ if ("getElementById" in root) {
166
174
  return root.getElementById(this.anchor);
167
175
  }
168
176
 
@@ -179,13 +187,13 @@ export class Menu extends LitElement {
179
187
  this.id = `wc-menu-${Math.random().toString(36).slice(2, 9)}`;
180
188
  }
181
189
 
182
- anchorEl.setAttribute('aria-haspopup', 'menu');
183
- anchorEl.setAttribute('aria-controls', this.id);
184
- anchorEl.setAttribute('aria-expanded', String(this.open));
190
+ anchorEl.setAttribute("aria-haspopup", "menu");
191
+ anchorEl.setAttribute("aria-controls", this.id);
192
+ anchorEl.setAttribute("aria-expanded", String(this.open));
185
193
  }
186
194
 
187
195
  private _enabledItems() {
188
- return this.items.filter(item => !item.disabled);
196
+ return this.items.filter((item) => !item.disabled);
189
197
  }
190
198
 
191
199
  private _syncRovingTabIndex() {
@@ -250,7 +258,7 @@ export class Menu extends LitElement {
250
258
 
251
259
  private _isEventFromThisMenu(event: Event) {
252
260
  const path = event.composedPath();
253
- const sourceMenu = path.find(target => target instanceof Menu);
261
+ const sourceMenu = path.find((target) => target instanceof Menu);
254
262
 
255
263
  return sourceMenu === this;
256
264
  }
@@ -265,7 +273,7 @@ export class Menu extends LitElement {
265
273
 
266
274
  for (const target of path) {
267
275
  if (target instanceof MenuItem) {
268
- const ownedItem = ownedItems.find(item => item === target);
276
+ const ownedItem = ownedItems.find((item) => item === target);
269
277
  if (ownedItem) {
270
278
  return ownedItem;
271
279
  }
@@ -288,7 +296,7 @@ export class Menu extends LitElement {
288
296
 
289
297
  private _dispatchItemActivate(item: MenuItem) {
290
298
  this.dispatchEvent(
291
- new CustomEvent('menu-item-activate', {
299
+ new CustomEvent("menu-item-activate", {
292
300
  bubbles: true,
293
301
  composed: true,
294
302
  detail: { item },
@@ -312,7 +320,7 @@ export class Menu extends LitElement {
312
320
  return;
313
321
  }
314
322
 
315
- this.close({ kind: 'click-selection' });
323
+ this.close({ kind: "click-selection" });
316
324
  };
317
325
 
318
326
  private _onKeyDown = (event: KeyboardEvent) => {
@@ -330,33 +338,33 @@ export class Menu extends LitElement {
330
338
  }
331
339
 
332
340
  switch (event.key) {
333
- case 'ArrowDown':
341
+ case "ArrowDown":
334
342
  event.preventDefault();
335
343
  this._setActiveByOffset(1);
336
344
  break;
337
- case 'ArrowUp':
345
+ case "ArrowUp":
338
346
  event.preventDefault();
339
347
  this._setActiveByOffset(-1);
340
348
  break;
341
- case 'Home':
349
+ case "Home":
342
350
  event.preventDefault();
343
351
  this._setBoundaryActive(0);
344
352
  break;
345
- case 'End': {
353
+ case "End": {
346
354
  event.preventDefault();
347
355
  const last = Math.max(this._enabledItems().length - 1, 0);
348
356
  this._setBoundaryActive(last);
349
357
  break;
350
358
  }
351
- case 'Escape':
359
+ case "Escape":
352
360
  event.preventDefault();
353
- this.close({ kind: 'keydown', key: 'Escape' });
361
+ this.close({ kind: "keydown", key: "Escape" });
354
362
  break;
355
- case 'Tab':
356
- this.close({ kind: 'keydown', key: 'Tab' });
363
+ case "Tab":
364
+ this.close({ kind: "keydown", key: "Tab" });
357
365
  break;
358
- case 'Enter':
359
- case ' ': {
366
+ case "Enter":
367
+ case " ": {
360
368
  event.preventDefault();
361
369
  const activeItem = this._getActiveItem() ?? this._getFirstEnabledItem();
362
370
  if (!activeItem) {
@@ -374,8 +382,68 @@ export class Menu extends LitElement {
374
382
 
375
383
  private _onSlotChange = () => {
376
384
  this._syncRovingTabIndex();
385
+ this._syncItemPositions();
377
386
  };
378
387
 
388
+ private _syncItemPositions() {
389
+ const slot = this.shadowRoot?.querySelector("slot");
390
+ const elements = slot?.assignedElements({ flatten: true }) ?? [];
391
+
392
+ for (const el of elements) {
393
+ if (el instanceof HTMLElement) {
394
+ el.removeAttribute("data-position-first");
395
+ el.removeAttribute("data-position-last");
396
+ el.removeAttribute("data-position-after-divider");
397
+ el.removeAttribute("data-position-before-divider");
398
+ }
399
+ }
400
+
401
+ const items = elements.filter(
402
+ (el) => el.tagName.toLowerCase() !== "wc-divider"
403
+ );
404
+
405
+ if (items.length === 0) {
406
+ return;
407
+ }
408
+
409
+ const firstItem = items[0];
410
+ if (firstItem instanceof HTMLElement) {
411
+ firstItem.setAttribute("data-position-first", "");
412
+ }
413
+
414
+ const lastItem = items[items.length - 1];
415
+ if (lastItem instanceof HTMLElement) {
416
+ lastItem.setAttribute("data-position-last", "");
417
+ }
418
+
419
+ for (let i = 0; i < elements.length; i++) {
420
+ const el = elements[i];
421
+ if (el.tagName.toLowerCase() === "wc-divider") {
422
+ let prevItem: Element | null = null;
423
+ for (let j = i - 1; j >= 0; j--) {
424
+ if (elements[j].tagName.toLowerCase() !== "wc-divider") {
425
+ prevItem = elements[j];
426
+ break;
427
+ }
428
+ }
429
+ if (prevItem instanceof HTMLElement) {
430
+ prevItem.setAttribute("data-position-before-divider", "");
431
+ }
432
+
433
+ let nextItem: Element | null = null;
434
+ for (let j = i + 1; j < elements.length; j++) {
435
+ if (elements[j].tagName.toLowerCase() !== "wc-divider") {
436
+ nextItem = elements[j];
437
+ break;
438
+ }
439
+ }
440
+ if (nextItem instanceof HTMLElement) {
441
+ nextItem.setAttribute("data-position-after-divider", "");
442
+ }
443
+ }
444
+ }
445
+ }
446
+
379
447
  private _applyPositioning() {
380
448
  if (!this.open || !this.menuListElement) {
381
449
  return;
@@ -389,7 +457,7 @@ export class Menu extends LitElement {
389
457
  this._floatingController.setOptions({
390
458
  placement: this.placement,
391
459
  offset: this.offset,
392
- strategy: 'fixed',
460
+ strategy: "fixed",
393
461
  closeOnClickOutside: !this.stayOpenOnOutsideClick,
394
462
  });
395
463
  this._floatingController.setElements(anchorEl, this.menuListElement);
@@ -397,16 +465,17 @@ export class Menu extends LitElement {
397
465
  }
398
466
 
399
467
  protected override updated(changedProperties: Map<string, unknown>) {
400
- if (changedProperties.has('anchor') || changedProperties.has('open')) {
468
+ if (changedProperties.has("anchor") || changedProperties.has("open")) {
401
469
  this._syncAnchorAria();
402
470
  }
403
471
 
404
- if (changedProperties.has('open')) {
472
+ if (changedProperties.has("open")) {
405
473
  if (this.open) {
406
474
  this._lastFocusedElement = document.activeElement as HTMLElement | null;
407
475
  this._syncRovingTabIndex();
476
+ this._syncItemPositions();
408
477
  this.dispatchEvent(
409
- new CustomEvent('opened', {
478
+ new CustomEvent("opened", {
410
479
  bubbles: true,
411
480
  composed: true,
412
481
  }),
@@ -418,7 +487,7 @@ export class Menu extends LitElement {
418
487
 
419
488
  const reason = this._closeReason;
420
489
  this.dispatchEvent(
421
- new CustomEvent('close-menu', {
490
+ new CustomEvent("close-menu", {
422
491
  bubbles: true,
423
492
  composed: true,
424
493
  detail: {
@@ -428,15 +497,15 @@ export class Menu extends LitElement {
428
497
  }),
429
498
  );
430
499
  this.dispatchEvent(
431
- new CustomEvent('closed', {
500
+ new CustomEvent("closed", {
432
501
  bubbles: true,
433
502
  composed: true,
434
503
  detail: { reason },
435
504
  }),
436
505
  );
437
506
 
438
- const shouldRestoreFocus =
439
- reason.kind !== 'keydown' || reason.key !== 'Tab';
507
+ const shouldRestoreFocus = reason.kind !== "keydown" ||
508
+ reason.key !== "Tab";
440
509
 
441
510
  if (!this.isSubmenu && shouldRestoreFocus) {
442
511
  this._lastFocusedElement?.focus();
@@ -445,10 +514,10 @@ export class Menu extends LitElement {
445
514
  }
446
515
 
447
516
  if (
448
- (changedProperties.has('open') ||
449
- changedProperties.has('anchor') ||
450
- changedProperties.has('placement') ||
451
- changedProperties.has('offset')) &&
517
+ (changedProperties.has("open") ||
518
+ changedProperties.has("anchor") ||
519
+ changedProperties.has("placement") ||
520
+ changedProperties.has("offset")) &&
452
521
  this.open
453
522
  ) {
454
523
  this._applyPositioning();
@@ -456,21 +525,23 @@ export class Menu extends LitElement {
456
525
  }
457
526
 
458
527
  render() {
459
- return html`<div
460
- class=${classMap({
461
- menu: true,
462
- open: !this.preview && this.open,
463
- closed: !this.preview && !this.open,
464
- preview: this.preview,
465
- [`variant-${this.variant}`]: true,
466
- })}
467
- aria-hidden=${String(!this.open)}
468
- >
469
- <div class="background"></div>
470
-
471
- <div class="menu-content">
472
- <slot @slotchange=${this._onSlotChange}></slot>
528
+ return html`
529
+ <div
530
+ class="${classMap({
531
+ menu: true,
532
+ open: !this.preview && this.open,
533
+ closed: !this.preview && !this.open,
534
+ preview: this.preview,
535
+ [`variant-${this.variant}`]: true,
536
+ })}"
537
+ aria-hidden="${String(!this.open)}"
538
+ >
539
+ <div class="background"></div>
540
+
541
+ <div class="menu-content">
542
+ <slot @slotchange="${this._onSlotChange}"></slot>
543
+ </div>
473
544
  </div>
474
- </div>`;
545
+ `;
475
546
  }
476
547
  }
@@ -1,12 +1,12 @@
1
- @use "../../../scss/mixin";
1
+ @use '../../../scss/mixin';
2
2
 
3
- :host-context([variant=standard]) {
3
+ :host-context([variant='standard']) {
4
4
  --menu-item-label-color: var(--color-on-surface-variant);
5
5
  --menu-item-label-selected-color: var(--color-on-tertiary-container);
6
6
  --menu-item-container-selected-color: var(--color-tertiary-container);
7
7
  }
8
8
 
9
- :host-context([variant=vibrant]) {
9
+ :host-context([variant='vibrant']) {
10
10
  --menu-item-label-color: var(--color-on-tertiary-container);
11
11
  --menu-item-label-selected-color: var(--color-on-tertiary);
12
12
  --menu-item-container-selected-color: var(--color-tertiary);