@vonage/vivid 4.12.0 → 4.13.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 (124) hide show
  1. package/custom-elements.json +2339 -288
  2. package/lib/accordion/accordion.d.ts +21 -2
  3. package/lib/accordion-item/accordion-item.d.ts +6 -2
  4. package/lib/calendar/calendar.d.ts +1 -1
  5. package/lib/date-picker/date-picker.d.ts +1 -0
  6. package/lib/file-picker/file-picker.d.ts +6 -0
  7. package/lib/menu/menu.d.ts +16 -3
  8. package/lib/menu-item/menu-item.d.ts +10 -2
  9. package/lib/option/option.d.ts +27 -7
  10. package/lib/radio/radio.d.ts +12 -2
  11. package/lib/radio/radio.form-associated.d.ts +10 -0
  12. package/lib/radio-group/radio-group.d.ts +20 -2
  13. package/lib/switch/switch.d.ts +5 -2
  14. package/lib/switch/switch.form-associated.d.ts +10 -0
  15. package/lib/tab/tab.d.ts +3 -2
  16. package/lib/tab-panel/tab-panel.d.ts +2 -2
  17. package/lib/tabs/tabs.d.ts +33 -11
  18. package/lib/text-area/text-area.d.ts +25 -3
  19. package/lib/text-area/text-field.form-associated.d.ts +10 -0
  20. package/lib/text-field/text-field.d.ts +28 -3
  21. package/lib/text-field/text-field.form-associated.d.ts +10 -0
  22. package/package.json +1 -1
  23. package/shared/date-picker/date-picker-base.d.ts +1 -0
  24. package/shared/definition.cjs +29 -72
  25. package/shared/definition.js +30 -73
  26. package/shared/definition11.cjs +1 -1
  27. package/shared/definition11.js +1 -1
  28. package/shared/definition16.cjs +1 -2
  29. package/shared/definition16.js +1 -2
  30. package/shared/definition17.cjs +3 -3
  31. package/shared/definition17.js +3 -3
  32. package/shared/definition18.cjs +6 -1
  33. package/shared/definition18.js +6 -1
  34. package/shared/definition19.cjs +17 -8
  35. package/shared/definition19.js +17 -8
  36. package/shared/definition2.cjs +154 -187
  37. package/shared/definition2.js +157 -190
  38. package/shared/definition20.cjs +3 -2
  39. package/shared/definition20.js +3 -2
  40. package/shared/definition21.cjs +1 -1
  41. package/shared/definition21.js +1 -1
  42. package/shared/definition24.cjs +1 -1
  43. package/shared/definition24.js +1 -1
  44. package/shared/definition25.cjs +24 -3
  45. package/shared/definition25.js +24 -3
  46. package/shared/definition29.cjs +358 -559
  47. package/shared/definition29.js +359 -560
  48. package/shared/definition30.cjs +2 -0
  49. package/shared/definition30.js +2 -0
  50. package/shared/definition35.cjs +223 -3
  51. package/shared/definition35.js +223 -3
  52. package/shared/definition36.cjs +149 -14
  53. package/shared/definition36.js +150 -15
  54. package/shared/definition40.cjs +226 -399
  55. package/shared/definition40.js +229 -402
  56. package/shared/definition42.cjs +3 -2
  57. package/shared/definition42.js +3 -2
  58. package/shared/definition43.cjs +1 -0
  59. package/shared/definition43.js +1 -0
  60. package/shared/definition44.cjs +1 -1
  61. package/shared/definition44.js +1 -1
  62. package/shared/definition46.cjs +1 -1
  63. package/shared/definition46.js +1 -1
  64. package/shared/definition47.cjs +8 -16
  65. package/shared/definition47.js +4 -12
  66. package/shared/definition49.cjs +64 -89
  67. package/shared/definition49.js +66 -91
  68. package/shared/definition5.cjs +1 -1
  69. package/shared/definition5.js +1 -1
  70. package/shared/definition50.cjs +1 -11
  71. package/shared/definition50.js +1 -11
  72. package/shared/definition51.cjs +5 -15
  73. package/shared/definition51.js +6 -16
  74. package/shared/definition52.cjs +284 -20
  75. package/shared/definition52.js +288 -24
  76. package/shared/definition55.cjs +160 -180
  77. package/shared/definition55.js +160 -180
  78. package/shared/definition56.cjs +3 -307
  79. package/shared/definition56.js +5 -309
  80. package/shared/definition57.cjs +34 -11
  81. package/shared/definition57.js +30 -7
  82. package/shared/definition61.cjs +1 -1
  83. package/shared/definition61.js +1 -1
  84. package/shared/definition62.cjs +17 -8
  85. package/shared/definition62.js +17 -8
  86. package/shared/definition64.cjs +18 -7
  87. package/shared/definition64.js +19 -8
  88. package/shared/form-associated.cjs +1 -1
  89. package/shared/form-associated.js +1 -1
  90. package/shared/icon.cjs +1 -1
  91. package/shared/icon.js +1 -1
  92. package/shared/index.cjs +1 -0
  93. package/shared/index.js +1 -1
  94. package/shared/key-codes.cjs +1 -94
  95. package/shared/key-codes.js +2 -89
  96. package/shared/key-codes2.cjs +87 -1
  97. package/shared/key-codes2.js +83 -2
  98. package/shared/listbox.cjs +204 -10
  99. package/shared/listbox.js +200 -6
  100. package/shared/{direction.cjs → localization.cjs} +12 -3
  101. package/shared/{direction.js → localization.js} +12 -3
  102. package/shared/numbers.cjs +0 -12
  103. package/shared/numbers.js +1 -12
  104. package/shared/presentationDate.cjs +22 -8
  105. package/shared/presentationDate.js +16 -2
  106. package/shared/radio.cjs +92 -117
  107. package/shared/radio.js +93 -118
  108. package/shared/slider.template.cjs +2 -15
  109. package/shared/slider.template.js +2 -14
  110. package/shared/strings.cjs +26 -0
  111. package/shared/strings.js +25 -1
  112. package/shared/text-field2.cjs +538 -194
  113. package/shared/text-field2.js +539 -195
  114. package/styles/core/all.css +21 -1
  115. package/styles/core/theme.css +21 -1
  116. package/styles/core/typography.css +1 -1
  117. package/styles/tokens/theme-dark.css +4 -4
  118. package/styles/tokens/theme-light.css +4 -4
  119. package/styles/tokens/vivid-2-compat.css +1 -1
  120. package/vivid.api.json +44 -0
  121. package/shared/Reflector.cjs +0 -71
  122. package/shared/Reflector.js +0 -69
  123. package/shared/listbox-option.cjs +0 -204
  124. package/shared/listbox-option.js +0 -201
@@ -1,14 +1,11 @@
1
- import { F as FoundationElement, D as DOM, _ as __decorate, a as attr, o as observable, h as html, r as registerFactory } from './index.js';
1
+ import { F as FoundationElement, D as DOM, o as observable, a as attr, h as html, r as registerFactory } from './index.js';
2
2
  import { a as iconRegistries } from './definition27.js';
3
- import { k as keyArrowLeft$1, a as keyArrowRight$1, g as keySpace$1, b as keyEnter$1 } from './key-codes2.js';
3
+ import { b as keyHome, a as keyEnd, d as keyArrowUp, c as keyArrowDown, e as keyArrowLeft, f as keyArrowRight, k as keySpace, g as keyEnter } from './key-codes.js';
4
4
  import { A as AffixIcon, a as affixIconTemplateFactory } from './affix.js';
5
5
  import { a as applyMixins } from './apply-mixins.js';
6
- import { S as StartEnd } from './start-end.js';
7
- import { D as Direction, g as getDirection } from './direction.js';
8
- import { i as keyArrowLeft, h as keyArrowRight, a as keySpace, k as keyEnter, g as keyHome, d as keyEnd, e as keyArrowUp, f as keyArrowDown } from './key-codes.js';
6
+ import { D as Direction, g as getDirection } from './localization.js';
9
7
  import { I as Icon } from './icon.js';
10
8
  import { b as anchored } from './anchored.js';
11
- import { i as isHTMLElement } from './dom.js';
12
9
  import { s as slotted, e as elements } from './slotted.js';
13
10
  import { w as when } from './when.js';
14
11
  import { c as classNames } from './class-names.js';
@@ -41,533 +38,11 @@ const roleForMenuItem = {
41
38
  };
42
39
 
43
40
  /**
44
- * A Switch Custom HTML Element.
45
- * Implements {@link https://www.w3.org/TR/wai-aria-1.1/#menuitem | ARIA menuitem }, {@link https://www.w3.org/TR/wai-aria-1.1/#menuitemcheckbox | ARIA menuitemcheckbox}, or {@link https://www.w3.org/TR/wai-aria-1.1/#menuitemradio | ARIA menuitemradio }.
46
- *
47
- * @slot checked-indicator - The checked indicator
48
- * @slot radio-indicator - The radio indicator
49
- * @slot start - Content which can be provided before the menu item content
50
- * @slot end - Content which can be provided after the menu item content
51
- * @slot - The default slot for menu item content
52
- * @slot expand-collapse-indicator - The expand/collapse indicator
53
- * @slot submenu - Used to nest menu's within menu items
54
- * @csspart input-container - The element representing the visual checked or radio indicator
55
- * @csspart checkbox - The element wrapping the `menuitemcheckbox` indicator
56
- * @csspart radio - The element wrapping the `menuitemradio` indicator
57
- * @csspart content - The element wrapping the menu item content
58
- * @csspart expand-collapse-glyph-container - The element wrapping the expand collapse element
59
- * @csspart expand-collapse - The expand/collapse element
60
- * @csspart submenu-region - The container for the submenu, used for positioning
61
- * @fires expanded-change - Fires a custom 'expanded-change' event when the expanded state changes
62
- * @fires change - Fires a custom 'change' event when a non-submenu item with a role of `menuitemcheckbox`, `menuitemradio`, or `menuitem` is invoked
63
- *
64
- * @public
65
- */
66
- let MenuItem$1 = class MenuItem extends FoundationElement {
67
- constructor() {
68
- super(...arguments);
69
- /**
70
- * The role of the element.
71
- *
72
- * @public
73
- * @remarks
74
- * HTML Attribute: role
75
- */
76
- this.role = MenuItemRole$1.menuitem;
77
- /**
78
- * @internal
79
- */
80
- this.hasSubmenu = false;
81
- /**
82
- * Track current direction to pass to the anchored region
83
- *
84
- * @internal
85
- */
86
- this.currentDirection = Direction.ltr;
87
- this.focusSubmenuOnLoad = false;
88
- /**
89
- * @internal
90
- */
91
- this.handleMenuItemKeyDown = (e) => {
92
- if (e.defaultPrevented) {
93
- return false;
94
- }
95
- switch (e.key) {
96
- case keyEnter:
97
- case keySpace:
98
- this.invoke();
99
- return false;
100
- case keyArrowRight:
101
- //open/focus on submenu
102
- this.expandAndFocus();
103
- return false;
104
- case keyArrowLeft:
105
- //close submenu
106
- if (this.expanded) {
107
- this.expanded = false;
108
- this.focus();
109
- return false;
110
- }
111
- }
112
- return true;
113
- };
114
- /**
115
- * @internal
116
- */
117
- this.handleMenuItemClick = (e) => {
118
- if (e.defaultPrevented || this.disabled) {
119
- return false;
120
- }
121
- this.invoke();
122
- return false;
123
- };
124
- /**
125
- * @internal
126
- */
127
- this.submenuLoaded = () => {
128
- if (!this.focusSubmenuOnLoad) {
129
- return;
130
- }
131
- this.focusSubmenuOnLoad = false;
132
- if (this.hasSubmenu) {
133
- this.submenu.focus();
134
- this.setAttribute("tabindex", "-1");
135
- }
136
- };
137
- /**
138
- * @internal
139
- */
140
- this.handleMouseOver = (e) => {
141
- if (this.disabled || !this.hasSubmenu || this.expanded) {
142
- return false;
143
- }
144
- this.expanded = true;
145
- return false;
146
- };
147
- /**
148
- * @internal
149
- */
150
- this.handleMouseOut = (e) => {
151
- if (!this.expanded || this.contains(document.activeElement)) {
152
- return false;
153
- }
154
- this.expanded = false;
155
- return false;
156
- };
157
- /**
158
- * @internal
159
- */
160
- this.expandAndFocus = () => {
161
- if (!this.hasSubmenu) {
162
- return;
163
- }
164
- this.focusSubmenuOnLoad = true;
165
- this.expanded = true;
166
- };
167
- /**
168
- * @internal
169
- */
170
- this.invoke = () => {
171
- if (this.disabled) {
172
- return;
173
- }
174
- switch (this.role) {
175
- case MenuItemRole$1.menuitemcheckbox:
176
- this.checked = !this.checked;
177
- break;
178
- case MenuItemRole$1.menuitem:
179
- // update submenu
180
- this.updateSubmenu();
181
- if (this.hasSubmenu) {
182
- this.expandAndFocus();
183
- }
184
- else {
185
- this.$emit("change");
186
- }
187
- break;
188
- case MenuItemRole$1.menuitemradio:
189
- if (!this.checked) {
190
- this.checked = true;
191
- }
192
- break;
193
- }
194
- };
195
- /**
196
- * Gets the submenu element if any
197
- *
198
- * @internal
199
- */
200
- this.updateSubmenu = () => {
201
- this.submenu = this.domChildren().find((element) => {
202
- return element.getAttribute("role") === "menu";
203
- });
204
- this.hasSubmenu = this.submenu === undefined ? false : true;
205
- };
206
- }
207
- expandedChanged(oldValue) {
208
- if (this.$fastController.isConnected) {
209
- if (this.submenu === undefined) {
210
- return;
211
- }
212
- if (this.expanded === false) {
213
- this.submenu.collapseExpandedItem();
214
- }
215
- else {
216
- this.currentDirection = getDirection(this);
217
- }
218
- this.$emit("expanded-change", this, { bubbles: false });
219
- }
220
- }
221
- checkedChanged(oldValue, newValue) {
222
- if (this.$fastController.isConnected) {
223
- this.$emit("change");
224
- }
225
- }
226
- /**
227
- * @internal
228
- */
229
- connectedCallback() {
230
- super.connectedCallback();
231
- DOM.queueUpdate(() => {
232
- this.updateSubmenu();
233
- });
234
- if (!this.startColumnCount) {
235
- this.startColumnCount = 1;
236
- }
237
- this.observer = new MutationObserver(this.updateSubmenu);
238
- }
239
- /**
240
- * @internal
241
- */
242
- disconnectedCallback() {
243
- super.disconnectedCallback();
244
- this.submenu = undefined;
245
- if (this.observer !== undefined) {
246
- this.observer.disconnect();
247
- this.observer = undefined;
248
- }
249
- }
250
- /**
251
- * get an array of valid DOM children
252
- */
253
- domChildren() {
254
- return Array.from(this.children).filter(child => !child.hasAttribute("hidden"));
255
- }
256
- };
257
- __decorate([
258
- attr({ mode: "boolean" })
259
- ], MenuItem$1.prototype, "disabled", void 0);
260
- __decorate([
261
- attr({ mode: "boolean" })
262
- ], MenuItem$1.prototype, "expanded", void 0);
263
- __decorate([
264
- observable
265
- ], MenuItem$1.prototype, "startColumnCount", void 0);
266
- __decorate([
267
- attr
268
- ], MenuItem$1.prototype, "role", void 0);
269
- __decorate([
270
- attr({ mode: "boolean" })
271
- ], MenuItem$1.prototype, "checked", void 0);
272
- __decorate([
273
- observable
274
- ], MenuItem$1.prototype, "submenuRegion", void 0);
275
- __decorate([
276
- observable
277
- ], MenuItem$1.prototype, "hasSubmenu", void 0);
278
- __decorate([
279
- observable
280
- ], MenuItem$1.prototype, "currentDirection", void 0);
281
- __decorate([
282
- observable
283
- ], MenuItem$1.prototype, "submenu", void 0);
284
- applyMixins(MenuItem$1, StartEnd);
285
-
286
- /**
287
- * A Menu Custom HTML Element.
288
- * Implements the {@link https://www.w3.org/TR/wai-aria-1.1/#menu | ARIA menu }.
289
- *
290
- * @slot - The default slot for the menu items
291
- *
292
- * @public
41
+ * A test that ensures that all arguments are HTML Elements
293
42
  */
294
- let Menu$1 = class Menu extends FoundationElement {
295
- constructor() {
296
- super(...arguments);
297
- this.expandedItem = null;
298
- /**
299
- * The index of the focusable element in the items array
300
- * defaults to -1
301
- */
302
- this.focusIndex = -1;
303
- /**
304
- * @internal
305
- */
306
- this.isNestedMenu = () => {
307
- return (this.parentElement !== null &&
308
- isHTMLElement(this.parentElement) &&
309
- this.parentElement.getAttribute("role") === "menuitem");
310
- };
311
- /**
312
- * if focus is moving out of the menu, reset to a stable initial state
313
- * @internal
314
- */
315
- this.handleFocusOut = (e) => {
316
- if (!this.contains(e.relatedTarget) && this.menuItems !== undefined) {
317
- this.collapseExpandedItem();
318
- // find our first focusable element
319
- const focusIndex = this.menuItems.findIndex(this.isFocusableElement);
320
- // set the current focus index's tabindex to -1
321
- this.menuItems[this.focusIndex].setAttribute("tabindex", "-1");
322
- // set the first focusable element tabindex to 0
323
- this.menuItems[focusIndex].setAttribute("tabindex", "0");
324
- // set the focus index
325
- this.focusIndex = focusIndex;
326
- }
327
- };
328
- this.handleItemFocus = (e) => {
329
- const targetItem = e.target;
330
- if (this.menuItems !== undefined &&
331
- targetItem !== this.menuItems[this.focusIndex]) {
332
- this.menuItems[this.focusIndex].setAttribute("tabindex", "-1");
333
- this.focusIndex = this.menuItems.indexOf(targetItem);
334
- targetItem.setAttribute("tabindex", "0");
335
- }
336
- };
337
- this.handleExpandedChanged = (e) => {
338
- if (e.defaultPrevented ||
339
- e.target === null ||
340
- this.menuItems === undefined ||
341
- this.menuItems.indexOf(e.target) < 0) {
342
- return;
343
- }
344
- e.preventDefault();
345
- const changedItem = e.target;
346
- // closing an expanded item without opening another
347
- if (this.expandedItem !== null &&
348
- changedItem === this.expandedItem &&
349
- changedItem.expanded === false) {
350
- this.expandedItem = null;
351
- return;
352
- }
353
- if (changedItem.expanded) {
354
- if (this.expandedItem !== null && this.expandedItem !== changedItem) {
355
- this.expandedItem.expanded = false;
356
- }
357
- this.menuItems[this.focusIndex].setAttribute("tabindex", "-1");
358
- this.expandedItem = changedItem;
359
- this.focusIndex = this.menuItems.indexOf(changedItem);
360
- changedItem.setAttribute("tabindex", "0");
361
- }
362
- };
363
- this.removeItemListeners = () => {
364
- if (this.menuItems !== undefined) {
365
- this.menuItems.forEach((item) => {
366
- item.removeEventListener("expanded-change", this.handleExpandedChanged);
367
- item.removeEventListener("focus", this.handleItemFocus);
368
- });
369
- }
370
- };
371
- this.setItems = () => {
372
- const newItems = this.domChildren();
373
- this.removeItemListeners();
374
- this.menuItems = newItems;
375
- const menuItems = this.menuItems.filter(this.isMenuItemElement);
376
- // if our focus index is not -1 we have items
377
- if (menuItems.length) {
378
- this.focusIndex = 0;
379
- }
380
- function elementIndent(el) {
381
- const role = el.getAttribute("role");
382
- const startSlot = el.querySelector("[slot=start]");
383
- if (role !== MenuItemRole$1.menuitem && startSlot === null) {
384
- return 1;
385
- }
386
- else if (role === MenuItemRole$1.menuitem && startSlot !== null) {
387
- return 1;
388
- }
389
- else if (role !== MenuItemRole$1.menuitem && startSlot !== null) {
390
- return 2;
391
- }
392
- else {
393
- return 0;
394
- }
395
- }
396
- const indent = menuItems.reduce((accum, current) => {
397
- const elementValue = elementIndent(current);
398
- return accum > elementValue ? accum : elementValue;
399
- }, 0);
400
- menuItems.forEach((item, index) => {
401
- item.setAttribute("tabindex", index === 0 ? "0" : "-1");
402
- item.addEventListener("expanded-change", this.handleExpandedChanged);
403
- item.addEventListener("focus", this.handleItemFocus);
404
- if (item instanceof MenuItem$1 || "startColumnCount" in item) {
405
- item.startColumnCount = indent;
406
- }
407
- });
408
- };
409
- /**
410
- * handle change from child element
411
- */
412
- this.changeHandler = (e) => {
413
- if (this.menuItems === undefined) {
414
- return;
415
- }
416
- const changedMenuItem = e.target;
417
- const changeItemIndex = this.menuItems.indexOf(changedMenuItem);
418
- if (changeItemIndex === -1) {
419
- return;
420
- }
421
- if (changedMenuItem.role === "menuitemradio" &&
422
- changedMenuItem.checked === true) {
423
- for (let i = changeItemIndex - 1; i >= 0; --i) {
424
- const item = this.menuItems[i];
425
- const role = item.getAttribute("role");
426
- if (role === MenuItemRole$1.menuitemradio) {
427
- item.checked = false;
428
- }
429
- if (role === "separator") {
430
- break;
431
- }
432
- }
433
- const maxIndex = this.menuItems.length - 1;
434
- for (let i = changeItemIndex + 1; i <= maxIndex; ++i) {
435
- const item = this.menuItems[i];
436
- const role = item.getAttribute("role");
437
- if (role === MenuItemRole$1.menuitemradio) {
438
- item.checked = false;
439
- }
440
- if (role === "separator") {
441
- break;
442
- }
443
- }
444
- }
445
- };
446
- /**
447
- * check if the item is a menu item
448
- */
449
- this.isMenuItemElement = (el) => {
450
- return (isHTMLElement(el) &&
451
- Menu.focusableElementRoles.hasOwnProperty(el.getAttribute("role")));
452
- };
453
- /**
454
- * check if the item is focusable
455
- */
456
- this.isFocusableElement = (el) => {
457
- return this.isMenuItemElement(el);
458
- };
459
- }
460
- itemsChanged(oldValue, newValue) {
461
- // only update children after the component is connected and
462
- // the setItems has run on connectedCallback
463
- // (menuItems is undefined until then)
464
- if (this.$fastController.isConnected && this.menuItems !== undefined) {
465
- this.setItems();
466
- }
467
- }
468
- /**
469
- * @internal
470
- */
471
- connectedCallback() {
472
- super.connectedCallback();
473
- DOM.queueUpdate(() => {
474
- // wait until children have had a chance to
475
- // connect before setting/checking their props/attributes
476
- this.setItems();
477
- });
478
- this.addEventListener("change", this.changeHandler);
479
- }
480
- /**
481
- * @internal
482
- */
483
- disconnectedCallback() {
484
- super.disconnectedCallback();
485
- this.removeItemListeners();
486
- this.menuItems = undefined;
487
- this.removeEventListener("change", this.changeHandler);
488
- }
489
- /**
490
- * Focuses the first item in the menu.
491
- *
492
- * @public
493
- */
494
- focus() {
495
- this.setFocus(0, 1);
496
- }
497
- /**
498
- * Collapses any expanded menu items.
499
- *
500
- * @public
501
- */
502
- collapseExpandedItem() {
503
- if (this.expandedItem !== null) {
504
- this.expandedItem.expanded = false;
505
- this.expandedItem = null;
506
- }
507
- }
508
- /**
509
- * @internal
510
- */
511
- handleMenuKeyDown(e) {
512
- if (e.defaultPrevented || this.menuItems === undefined) {
513
- return;
514
- }
515
- switch (e.key) {
516
- case keyArrowDown:
517
- // go forward one index
518
- this.setFocus(this.focusIndex + 1, 1);
519
- return;
520
- case keyArrowUp:
521
- // go back one index
522
- this.setFocus(this.focusIndex - 1, -1);
523
- return;
524
- case keyEnd:
525
- // set focus on last item
526
- this.setFocus(this.menuItems.length - 1, -1);
527
- return;
528
- case keyHome:
529
- // set focus on first item
530
- this.setFocus(0, 1);
531
- return;
532
- default:
533
- // if we are not handling the event, do not prevent default
534
- return true;
535
- }
536
- }
537
- /**
538
- * get an array of valid DOM children
539
- */
540
- domChildren() {
541
- return Array.from(this.children).filter(child => !child.hasAttribute("hidden"));
542
- }
543
- setFocus(focusIndex, adjustment) {
544
- if (this.menuItems === undefined) {
545
- return;
546
- }
547
- while (focusIndex >= 0 && focusIndex < this.menuItems.length) {
548
- const child = this.menuItems[focusIndex];
549
- if (this.isFocusableElement(child)) {
550
- // change the previous index to -1
551
- if (this.focusIndex > -1 &&
552
- this.menuItems.length >= this.focusIndex - 1) {
553
- this.menuItems[this.focusIndex].setAttribute("tabindex", "-1");
554
- }
555
- // update the focus index
556
- this.focusIndex = focusIndex;
557
- // update the tabindex of next focusable element
558
- child.setAttribute("tabindex", "0");
559
- // focus the element
560
- child.focus();
561
- break;
562
- }
563
- focusIndex += adjustment;
564
- }
565
- }
566
- };
567
- Menu$1.focusableElementRoles = roleForMenuItem;
568
- __decorate([
569
- observable
570
- ], Menu$1.prototype, "items", void 0);
43
+ function isHTMLElement(...args) {
44
+ return args.every((arg) => arg instanceof HTMLElement);
45
+ }
571
46
 
572
47
  const styles = ":host(:focus-visible){outline:none}:host([disabled]){pointer-events:none}.base{--_appearance-color-text: var(--_connotation-color-firm);--_appearance-color-fill: transparent;--_appearance-color-outline: transparent}.base:where(.hover,:hover):where(:not(.disabled,:disabled,.readonly)){--_appearance-color-text: var(--_connotation-color-firm);--_appearance-color-fill: var(--_connotation-color-faint);--_appearance-color-outline: transparent}.base:where(.disabled,:disabled){--_appearance-color-text: var(--vvd-color-neutral-300);--_appearance-color-fill: transparent;--_appearance-color-outline: transparent}.base:where(.active,:active):where(:not(.disabled,:disabled)){--_appearance-color-text: var(--_connotation-color-firm);--_appearance-color-fill: var(--_connotation-color-soft);--_appearance-color-outline: transparent}.base:where(.selected):where(:not(.disabled,:disabled)){--_appearance-color-text: var(--_connotation-color-firm);--_appearance-color-fill: var(--_connotation-color-soft);--_appearance-color-outline: transparent}.base:where(.selected):where(.hover,:hover):where(:not(.disabled,:disabled,.readonly)){--_appearance-color-text: var(--_connotation-color-firm);--_appearance-color-fill: var(--_connotation-color-dim);--_appearance-color-outline: transparent}.base.connotation-cta{--_connotation-color-primary: var(--vvd-menu-item-cta-primary, var(--vvd-color-cta-500));--_connotation-color-primary-text: var(--vvd-menu-item-cta-primary-text, var(--vvd-color-canvas));--_connotation-color-primary-increment: var(--vvd-menu-item-cta-primary-increment, var(--vvd-color-cta-600));--_connotation-color-firm: var(--vvd-menu-item-cta-firm, var(--vvd-color-cta-600));--_connotation-color-faint: var(--vvd-menu-item-cta-faint, var(--vvd-color-cta-50));--_connotation-color-soft: var(--vvd-menu-item-cta-soft, var(--vvd-color-cta-100));--_connotation-color-pale: var(--vvd-menu-item-cta-pale, var(--vvd-color-cta-300));--_connotation-color-dim: var(--vvd-menu-item-cta-dim, var(--vvd-color-cta-200))}.base:not(.connotation-cta){--_connotation-color-primary: var(--vvd-menu-item-accent-primary, var(--vvd-color-canvas-text));--_connotation-color-primary-text: var(--vvd-menu-item-accent-primary-text, var(--vvd-color-canvas));--_connotation-color-primary-increment: var(--vvd-menu-item-accent-primary-increment, var(--vvd-color-neutral-800));--_connotation-color-firm: var(--vvd-menu-item-accent-firm, var(--vvd-color-canvas-text));--_connotation-color-faint: var(--vvd-menu-item-accent-faint, var(--vvd-color-neutral-50));--_connotation-color-soft: var(--vvd-menu-item-accent-soft, var(--vvd-color-neutral-100));--_connotation-color-pale: var(--vvd-menu-item-accent-pale, var(--vvd-color-neutral-300));--_connotation-color-dim: var(--vvd-menu-item-accent-dim, var(--vvd-color-neutral-200))}.base{display:flex;box-sizing:border-box;align-items:center;background-color:var(--_appearance-color-fill);box-shadow:inset 0 0 0 1px var(--_appearance-color-outline);inline-size:100%}.base:not(.two-lines){gap:12px;min-block-size:calc(1px*(40 + 4*clamp(-1,var(--vvd-size-density, 0),2)));padding-block:8px;padding-inline:12px}.base.two-lines{padding:12px;gap:16px;min-block-size:calc(1px*(40 + 4*clamp(-1,var(--vvd-size-density, 0),2)) + 1px*(24 + 4*clamp(-1,var(--vvd-size-density, 0),2)))}@supports (user-select: none){.base{user-select:none}}.base:not(.disabled){cursor:pointer}:host(:not([role=presentation]):focus-visible) .base{box-shadow:inset 0 0 0 3px var(--focus-stroke-gap-color, currentColor);outline:2px solid var(--focus-stroke-color, var(--vvd-color-canvas-text));outline-offset:calc(-2px - var(--focus-inset, 0px));--focus-stroke-gap-color: transparent}.icon{flex-shrink:0;font-size:calc(1px*(40 + 4*clamp(-1,var(--vvd-size-density, 0),2))/2);line-height:1}.action,.decorative{display:flex;place-content:center}.action{color:var(--_appearance-color-text)}.base.trailing .action,.base.has-meta .action{order:2}:host(:not([check-appearance],[aria-checked=true],[disabled])) .action{color:var(--vvd-color-neutral-500)}.base:not(.disabled) .decorative{color:var(--vvd-color-neutral-600)}.base.disabled .decorative{color:var(--vvd-color-neutral-200)}.base.has-meta .decorative{order:1}.chevron{order:3}.text{display:flex;overflow:hidden;flex-direction:column;gap:4px;margin-inline-end:auto}.text-primary,.text-secondary{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical;font:var(--vvd-typography-base)}.text-primary{font:var(--vvd-typography-base);-webkit-line-clamp:var(--text-primary-line-clamp, 1)}.base:not(.disabled) .text-primary{color:var(--vvd-color-canvas-text)}.base.disabled .text-primary{color:var(--_appearance-color-text)}.base.two-lines .text-primary{font:var(--vvd-typography-base-bold)}.text-secondary{color:var(--vvd-color-neutral-800);font:var(--vvd-typography-base-condensed);-webkit-line-clamp:var(--text-secondary-line-clamp, 1)}.base.two-lines .text-secondary{color:var(--vvd-color-neutral-600)}.base.disabled .text-secondary{color:var(--_appearance-color-text)}.base.selected:not(.disabled) .text-secondary{color:var(--vvd-color-neutral-800)}";
573
48
 
@@ -589,10 +64,88 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
589
64
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
590
65
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
591
66
  var _Menu_instances, triggerBehaviour_get, setupAnchor_fn, updateAnchor_fn, cleanupAnchor_fn, _onAnchorClick;
592
- let Menu = class extends Menu$1 {
67
+ let Menu = class extends FoundationElement {
593
68
  constructor() {
594
- super();
69
+ super(...arguments);
595
70
  __privateAdd(this, _Menu_instances);
71
+ this.expandedItem = null;
72
+ /**
73
+ * The index of the focusable element in the items array
74
+ * defaults to -1
75
+ */
76
+ this.focusIndex = -1;
77
+ /**
78
+ * if focus is moving out of the menu, reset to a stable initial state
79
+ * @internal
80
+ */
81
+ this.handleFocusOut = (e) => {
82
+ if (!this.contains(e.relatedTarget) && this.menuItems !== void 0 && this.menuItems.length) {
83
+ this.collapseExpandedItem();
84
+ const focusIndex = this.menuItems.findIndex(
85
+ this.isFocusableElement
86
+ );
87
+ this.menuItems[this.focusIndex].setAttribute("tabindex", "-1");
88
+ this.menuItems[focusIndex].setAttribute("tabindex", "0");
89
+ this.focusIndex = focusIndex;
90
+ }
91
+ };
92
+ this.handleItemFocus = (e) => {
93
+ const targetItem = e.target;
94
+ if (this.menuItems !== void 0 && targetItem !== this.menuItems[this.focusIndex]) {
95
+ this.menuItems[this.focusIndex].setAttribute("tabindex", "-1");
96
+ this.focusIndex = this.menuItems.indexOf(targetItem);
97
+ targetItem.setAttribute("tabindex", "0");
98
+ }
99
+ };
100
+ this.handleExpandedChanged = (e) => {
101
+ const changedItem = e.target;
102
+ if (this.expandedItem !== null && changedItem === this.expandedItem && changedItem.expanded === false) {
103
+ this.expandedItem = null;
104
+ }
105
+ if (changedItem.expanded) {
106
+ this.expandedItem = changedItem;
107
+ }
108
+ };
109
+ this.removeItemListeners = () => {
110
+ if (this.menuItems !== void 0) {
111
+ this.menuItems.forEach((item) => {
112
+ item.removeEventListener("expanded-change", this.handleExpandedChanged);
113
+ item.removeEventListener(
114
+ "focus",
115
+ this.handleItemFocus
116
+ );
117
+ });
118
+ }
119
+ };
120
+ this.setItems = () => {
121
+ const newItems = this.domChildren();
122
+ this.removeItemListeners();
123
+ this.menuItems = newItems;
124
+ const menuItems = this.menuItems.filter(this.isMenuItemElement);
125
+ if (menuItems.length) {
126
+ this.focusIndex = 0;
127
+ }
128
+ menuItems.forEach((item, index) => {
129
+ item.setAttribute("tabindex", index === 0 ? "0" : "-1");
130
+ item.addEventListener("expanded-change", this.handleExpandedChanged);
131
+ item.addEventListener("focus", this.handleItemFocus);
132
+ });
133
+ };
134
+ /**
135
+ * check if the item is a menu item
136
+ */
137
+ this.isMenuItemElement = (el) => {
138
+ return isHTMLElement(el) && Object.prototype.hasOwnProperty.call(
139
+ Menu.focusableElementRoles,
140
+ el.getAttribute("role")
141
+ );
142
+ };
143
+ /**
144
+ * check if the item is focusable
145
+ */
146
+ this.isFocusableElement = (el) => {
147
+ return this.isMenuItemElement(el);
148
+ };
596
149
  this.ariaLabel = null;
597
150
  this.placement = "bottom";
598
151
  this.autoDismiss = false;
@@ -615,24 +168,112 @@ let Menu = class extends Menu$1 {
615
168
  this.open = false;
616
169
  }
617
170
  };
618
- const handleFocusOut = this.handleFocusOut;
619
- this.handleFocusOut = (e) => {
620
- const privates2 = this;
621
- const isSafeToCallSuper = privates2.menuItems.some(
622
- privates2.isFocusableElement
623
- );
624
- if (!isSafeToCallSuper) {
171
+ }
172
+ /**
173
+ * @internal
174
+ */
175
+ itemsChanged() {
176
+ if (this.$fastController.isConnected && this.menuItems !== void 0) {
177
+ this.setItems();
178
+ }
179
+ }
180
+ /**
181
+ * @internal
182
+ */
183
+ connectedCallback() {
184
+ super.connectedCallback();
185
+ DOM.queueUpdate(() => {
186
+ this.setItems();
187
+ });
188
+ }
189
+ /**
190
+ * @internal
191
+ */
192
+ disconnectedCallback() {
193
+ super.disconnectedCallback();
194
+ this.removeItemListeners();
195
+ this.menuItems = void 0;
196
+ }
197
+ /**
198
+ * Moves focus into the menu. If there is a child with the `autofocus` attribute, it will be focused.
199
+ * Otherwise, the first focusable child will be focused.
200
+ *
201
+ * @public
202
+ */
203
+ focus() {
204
+ const autoFocusElement = this.querySelector(
205
+ '[autofocus]:not([slot="anchor"])'
206
+ );
207
+ if (autoFocusElement instanceof HTMLElement) {
208
+ autoFocusElement.focus();
209
+ } else {
210
+ this.setFocus(0, 1);
211
+ }
212
+ }
213
+ /**
214
+ * Collapses any expanded Menu Items.
215
+ *
216
+ * @public
217
+ */
218
+ collapseExpandedItem() {
219
+ if (this.expandedItem !== null) {
220
+ this.expandedItem.expanded = false;
221
+ this.expandedItem = null;
222
+ }
223
+ }
224
+ /**
225
+ * @internal
226
+ */
227
+ handleMenuKeyDown(e) {
228
+ if (e.defaultPrevented || this.menuItems === void 0) {
229
+ return;
230
+ }
231
+ switch (e.key) {
232
+ case keyArrowDown:
233
+ this.setFocus(this.focusIndex + 1, 1);
625
234
  return;
235
+ case keyArrowUp:
236
+ this.setFocus(this.focusIndex - 1, -1);
237
+ return;
238
+ case keyEnd:
239
+ this.setFocus(this.menuItems.length - 1, -1);
240
+ return;
241
+ case keyHome:
242
+ this.setFocus(0, 1);
243
+ return;
244
+ default:
245
+ return true;
246
+ }
247
+ }
248
+ /**
249
+ * get an array of valid DOM children
250
+ */
251
+ domChildren() {
252
+ return Array.from(this.children).filter((child) => !child.hasAttribute("hidden")).filter((child) => !child.hasAttribute("slot"));
253
+ }
254
+ setFocus(focusIndex, adjustment) {
255
+ if (this.menuItems === void 0) {
256
+ return;
257
+ }
258
+ while (focusIndex >= 0 && focusIndex < this.menuItems.length) {
259
+ const child = this.menuItems[focusIndex];
260
+ if (this.isFocusableElement(child)) {
261
+ if (this.focusIndex > -1 && this.menuItems.length >= this.focusIndex - 1) {
262
+ this.menuItems[this.focusIndex].setAttribute("tabindex", "-1");
263
+ }
264
+ this.focusIndex = focusIndex;
265
+ child.setAttribute("tabindex", "0");
266
+ child.focus();
267
+ break;
626
268
  }
627
- handleFocusOut(e);
628
- };
629
- const privates = this;
630
- const domChildren = privates.domChildren;
631
- privates.domChildren = () => {
632
- return domChildren.call(this).filter((child) => !child.hasAttribute("slot"));
633
- };
269
+ focusIndex += adjustment;
270
+ }
634
271
  }
635
272
  openChanged(_, newValue) {
273
+ if (newValue) {
274
+ this._popupEl?.show();
275
+ this.focus();
276
+ }
636
277
  newValue ? this.$emit("open", void 0, { bubbles: false }) : this.$emit("close", void 0, { bubbles: false });
637
278
  if (this._anchorEl) {
638
279
  __privateMethod(this, _Menu_instances, updateAnchor_fn).call(this, this._anchorEl);
@@ -653,6 +294,34 @@ let Menu = class extends Menu$1 {
653
294
  if (__privateGet(this, _Menu_instances, triggerBehaviour_get) === "auto" && clickedOnNonCheckboxMenuItem) {
654
295
  this.open = false;
655
296
  }
297
+ const changedMenuItem = e.target;
298
+ const changeItemIndex = this.menuItems.indexOf(changedMenuItem);
299
+ if (changeItemIndex === -1) {
300
+ return;
301
+ }
302
+ if (changedMenuItem.role === "menuitemradio" && changedMenuItem.checked) {
303
+ for (let i = changeItemIndex - 1; i >= 0; --i) {
304
+ const item = this.menuItems[i];
305
+ const role = item.getAttribute("role");
306
+ if (role === MenuItemRole.menuitemradio) {
307
+ item.checked = false;
308
+ }
309
+ if (role === "separator") {
310
+ break;
311
+ }
312
+ }
313
+ const maxIndex = this.menuItems.length - 1;
314
+ for (let i = changeItemIndex + 1; i <= maxIndex; ++i) {
315
+ const item = this.menuItems[i];
316
+ const role = item.getAttribute("role");
317
+ if (role === MenuItemRole.menuitemradio) {
318
+ item.checked = false;
319
+ }
320
+ if (role === "separator") {
321
+ break;
322
+ }
323
+ }
324
+ }
656
325
  return true;
657
326
  }
658
327
  };
@@ -676,6 +345,10 @@ cleanupAnchor_fn = function(a) {
676
345
  a.removeAttribute("aria-expanded");
677
346
  };
678
347
  _onAnchorClick = new WeakMap();
348
+ Menu.focusableElementRoles = roleForMenuItem;
349
+ __decorateClass$1([
350
+ observable
351
+ ], Menu.prototype, "items", 2);
679
352
  __decorateClass$1([
680
353
  attr({ attribute: "aria-label" })
681
354
  ], Menu.prototype, "ariaLabel", 2);
@@ -722,43 +395,146 @@ var CheckAppearance = /* @__PURE__ */ ((CheckAppearance2) => {
722
395
  CheckAppearance2["TickOnly"] = "tick-only";
723
396
  return CheckAppearance2;
724
397
  })(CheckAppearance || {});
725
- class MenuItem extends MenuItem$1 {
398
+ class MenuItem extends FoundationElement {
726
399
  constructor() {
727
400
  super();
401
+ // eslint-disable-next-line @nrwl/nx/workspace/no-attribute-default-value
402
+ this.role = MenuItemRole.menuitem;
403
+ this.hasSubmenu = false;
404
+ this.currentDirection = Direction.ltr;
405
+ /**
406
+ * @internal
407
+ */
408
+ this.handleMenuItemClick = (e) => {
409
+ if (e.defaultPrevented || this.disabled) {
410
+ return false;
411
+ }
412
+ this.invoke();
413
+ return false;
414
+ };
415
+ /**
416
+ * @internal
417
+ */
418
+ this.handleMouseOver = (_) => {
419
+ if (this.disabled || !this.hasSubmenu || this.expanded) {
420
+ return false;
421
+ }
422
+ this.expanded = true;
423
+ return false;
424
+ };
425
+ /**
426
+ * @internal
427
+ */
428
+ this.handleMouseOut = (_) => {
429
+ if (!this.expanded || this.contains(document.activeElement)) {
430
+ return false;
431
+ }
432
+ this.expanded = false;
433
+ return false;
434
+ };
435
+ this.invoke = () => {
436
+ if (this.disabled) {
437
+ return;
438
+ }
439
+ switch (this.role) {
440
+ case MenuItemRole.menuitemcheckbox:
441
+ this.checked = !this.checked;
442
+ break;
443
+ case MenuItemRole.menuitem:
444
+ this.updateSubmenu();
445
+ if (this.hasSubmenu) {
446
+ this.expanded = true;
447
+ } else {
448
+ this.$emit("change");
449
+ }
450
+ break;
451
+ case MenuItemRole.menuitemradio:
452
+ if (!this.checked) {
453
+ this.checked = true;
454
+ }
455
+ break;
456
+ }
457
+ };
728
458
  this.checkTrailing = false;
729
459
  this.#submenuArray = [];
730
- this.#handleMenuItemKeyDown = (e) => {
460
+ /**
461
+ * @internal
462
+ */
463
+ this.handleMenuItemKeyDown = (e) => {
731
464
  if (e.defaultPrevented) {
732
465
  return false;
733
466
  }
734
467
  switch (e.key) {
735
- case keyEnter$1:
736
- case keySpace$1:
468
+ case keyEnter:
469
+ case keySpace:
737
470
  this.invoke();
738
471
  if (!this.disabled) {
739
472
  this.#emitSyntheticClick();
740
473
  }
741
474
  return false;
742
- case keyArrowRight$1:
743
- this.expandAndFocus();
475
+ case keyArrowRight:
744
476
  if (this.hasSubmenu) {
477
+ this.expanded = true;
745
478
  this.#emitSyntheticClick();
746
479
  }
747
480
  return false;
748
- case keyArrowLeft$1:
481
+ case keyArrowLeft:
749
482
  if (this.expanded) {
483
+ this.#emitSyntheticClick();
750
484
  this.expanded = false;
751
485
  this.focus();
752
- this.#emitSyntheticClick();
753
486
  return false;
754
487
  }
755
488
  }
756
489
  return true;
757
490
  };
758
491
  this.#syntheticClickEvents = /* @__PURE__ */ new WeakSet();
759
- this.updateSubmenu = () => this.#updateSubmenu();
760
492
  this.addEventListener("expanded-change", this.#expandedChange);
761
- this.handleMenuItemKeyDown = this.#handleMenuItemKeyDown;
493
+ }
494
+ /**
495
+ * @internal
496
+ */
497
+ expandedChanged() {
498
+ if (this.$fastController.isConnected) {
499
+ if (this.submenu === void 0) {
500
+ return;
501
+ }
502
+ if (this.expanded === false) {
503
+ this.submenu.collapseExpandedItem();
504
+ } else {
505
+ this.currentDirection = getDirection(this);
506
+ }
507
+ this.$emit("expanded-change", this, { bubbles: false });
508
+ }
509
+ }
510
+ /**
511
+ * @internal
512
+ */
513
+ checkedChanged() {
514
+ if (this.$fastController.isConnected) {
515
+ this.$emit("change");
516
+ }
517
+ }
518
+ /**
519
+ * @internal
520
+ */
521
+ connectedCallback() {
522
+ super.connectedCallback();
523
+ DOM.queueUpdate(() => {
524
+ this.updateSubmenu();
525
+ });
526
+ this.observer = new MutationObserver(this.updateSubmenu);
527
+ }
528
+ /**
529
+ * @internal
530
+ */
531
+ disconnectedCallback() {
532
+ super.disconnectedCallback();
533
+ this.submenu = void 0;
534
+ if (this.observer !== void 0) {
535
+ this.observer.disconnect();
536
+ this.observer = void 0;
537
+ }
762
538
  }
763
539
  #submenuArray;
764
540
  /**
@@ -769,7 +545,7 @@ class MenuItem extends MenuItem$1 {
769
545
  slottedSubmenuChanged(_oldValue, newValue) {
770
546
  this.#submenuArray = newValue;
771
547
  }
772
- #updateSubmenu() {
548
+ updateSubmenu() {
773
549
  for (const submenu of this.#submenuArray) {
774
550
  this.submenu = submenu;
775
551
  this.submenu.anchor = this;
@@ -786,7 +562,6 @@ class MenuItem extends MenuItem$1 {
786
562
  this.submenu.open = this.expanded;
787
563
  }
788
564
  }
789
- #handleMenuItemKeyDown;
790
565
  #syntheticClickEvents;
791
566
  /**
792
567
  * @internal
@@ -803,6 +578,30 @@ class MenuItem extends MenuItem$1 {
803
578
  this.dispatchEvent(mouseEvent);
804
579
  }
805
580
  }
581
+ __decorateClass([
582
+ attr({ mode: "boolean" })
583
+ ], MenuItem.prototype, "disabled");
584
+ __decorateClass([
585
+ attr({ mode: "boolean" })
586
+ ], MenuItem.prototype, "expanded");
587
+ __decorateClass([
588
+ attr
589
+ ], MenuItem.prototype, "role");
590
+ __decorateClass([
591
+ attr({ mode: "boolean" })
592
+ ], MenuItem.prototype, "checked");
593
+ __decorateClass([
594
+ observable
595
+ ], MenuItem.prototype, "submenuRegion");
596
+ __decorateClass([
597
+ observable
598
+ ], MenuItem.prototype, "hasSubmenu");
599
+ __decorateClass([
600
+ observable
601
+ ], MenuItem.prototype, "currentDirection");
602
+ __decorateClass([
603
+ observable
604
+ ], MenuItem.prototype, "submenu");
806
605
  __decorateClass([
807
606
  attr
808
607
  ], MenuItem.prototype, "text");