@aurodesignsystem-dev/auro-formkit 0.0.0-pr1540.1 → 0.0.0-pr1540.2

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 (82) hide show
  1. package/components/checkbox/demo/accessibility.md +1 -1
  2. package/components/checkbox/demo/customize.min.js +1 -1
  3. package/components/checkbox/demo/getting-started.min.js +1 -1
  4. package/components/checkbox/demo/index.min.js +1 -1
  5. package/components/checkbox/dist/index.js +1 -1
  6. package/components/checkbox/dist/registered.js +1 -1
  7. package/components/combobox/demo/accessibility.md +1 -1
  8. package/components/combobox/demo/api.md +2 -2
  9. package/components/combobox/demo/customize.md +54 -2
  10. package/components/combobox/demo/customize.min.js +421 -240
  11. package/components/combobox/demo/getting-started.min.js +421 -240
  12. package/components/combobox/demo/index.md +1 -0
  13. package/components/combobox/demo/index.min.js +421 -240
  14. package/components/combobox/demo/keyboard-behavior.md +1 -4
  15. package/components/combobox/dist/auro-combobox.d.ts +4 -1
  16. package/components/combobox/dist/index.js +334 -222
  17. package/components/combobox/dist/registered.js +334 -222
  18. package/components/counter/demo/customize.min.js +59 -222
  19. package/components/counter/demo/index.min.js +59 -222
  20. package/components/counter/dist/auro-counter.d.ts +0 -8
  21. package/components/counter/dist/index.js +59 -222
  22. package/components/counter/dist/registered.js +59 -222
  23. package/components/datepicker/demo/accessibility.md +1 -1
  24. package/components/datepicker/demo/customize.md +30 -1
  25. package/components/datepicker/demo/customize.min.js +84 -220
  26. package/components/datepicker/demo/getting-started.md +118 -2
  27. package/components/datepicker/demo/index.min.js +84 -220
  28. package/components/datepicker/dist/index.js +84 -220
  29. package/components/datepicker/dist/registered.js +84 -220
  30. package/components/dropdown/demo/customize.html +3 -0
  31. package/components/dropdown/demo/customize.min.js +55 -206
  32. package/components/dropdown/demo/getting-started.min.js +44 -205
  33. package/components/dropdown/demo/index.min.js +44 -205
  34. package/components/dropdown/dist/index.js +44 -205
  35. package/components/dropdown/dist/registered.js +44 -205
  36. package/components/form/demo/customize.min.js +670 -945
  37. package/components/form/demo/getting-started.min.js +670 -945
  38. package/components/form/demo/index.min.js +670 -945
  39. package/components/form/demo/registerDemoDeps.min.js +670 -945
  40. package/components/input/demo/accessibility.md +1 -1
  41. package/components/input/demo/customize.min.js +1 -1
  42. package/components/input/demo/getting-started.min.js +1 -1
  43. package/components/input/demo/index.min.js +1 -1
  44. package/components/input/dist/index.js +1 -1
  45. package/components/input/dist/registered.js +1 -1
  46. package/components/menu/demo/accessibility.md +9 -4
  47. package/components/menu/demo/api.md +26 -19
  48. package/components/menu/demo/css-only.md +26 -19
  49. package/components/menu/demo/customize.md +307 -47
  50. package/components/menu/demo/design.md +1 -1
  51. package/components/menu/demo/getting-started.md +144 -7
  52. package/components/menu/demo/index.min.js +214 -19
  53. package/components/menu/demo/keyboard-behavior.md +83 -4
  54. package/components/menu/demo/voiceover.md +21 -14
  55. package/components/menu/demo/why-menu.md +8 -9
  56. package/components/menu/dist/auro-menu-utils.d.ts +19 -0
  57. package/components/menu/dist/auro-menu.d.ts +4 -8
  58. package/components/menu/dist/auro-menuoption.d.ts +12 -0
  59. package/components/menu/dist/index.js +87 -18
  60. package/components/menu/dist/registered.js +87 -18
  61. package/components/radio/demo/accessibility.md +1 -1
  62. package/components/radio/demo/customize.min.js +1 -1
  63. package/components/radio/demo/getting-started.min.js +1 -1
  64. package/components/radio/demo/index.min.js +1 -1
  65. package/components/radio/dist/index.js +1 -1
  66. package/components/radio/dist/registered.js +1 -1
  67. package/components/select/demo/accessibility.md +6 -1
  68. package/components/select/demo/api.md +2 -2
  69. package/components/select/demo/customize.md +6 -3
  70. package/components/select/demo/customize.min.js +139 -227
  71. package/components/select/demo/design.md +10 -10
  72. package/components/select/demo/getting-started.md +1 -1
  73. package/components/select/demo/getting-started.min.js +139 -227
  74. package/components/select/demo/index.md +2 -2
  75. package/components/select/demo/index.min.js +139 -227
  76. package/components/select/demo/keyboard-behavior.md +53 -58
  77. package/components/select/demo/voiceover.md +28 -15
  78. package/components/select/dist/auro-select.d.ts +6 -2
  79. package/components/select/dist/index.js +52 -209
  80. package/components/select/dist/registered.js +52 -209
  81. package/custom-elements.json +1611 -1552
  82. package/package.json +2 -2
@@ -926,7 +926,7 @@ const selectKeyboardStrategy = {
926
926
  ArrowDown(component, evt, ctx) {
927
927
  evt.preventDefault();
928
928
  if (ctx.isExpanded) {
929
- if (evt.altKey || evt.ctrlKey || evt.metaKey) {
929
+ if (evt.altKey || evt.ctrlKey) {
930
930
  // navigate to last enabled option
931
931
  selectKeyboardStrategy.End(component, evt, ctx);
932
932
  } else {
@@ -940,7 +940,7 @@ const selectKeyboardStrategy = {
940
940
  ArrowUp(component, evt, ctx) {
941
941
  evt.preventDefault();
942
942
  if (ctx.isExpanded) {
943
- if (evt.altKey || evt.ctrlKey || evt.metaKey) {
943
+ if (evt.altKey || evt.ctrlKey) {
944
944
  // navigate to first enabled option
945
945
  selectKeyboardStrategy.Home(component, evt, ctx);
946
946
  } else {
@@ -3379,12 +3379,40 @@ class AuroFloatingUI {
3379
3379
  return;
3380
3380
  }
3381
3381
 
3382
+ // Chrome-specific: during popover top-layer promotion after a click on a
3383
+ // slotted focusable, :focus-within can briefly evaluate false while the
3384
+ // active element is still structurally inside the trigger/bib. Fall back
3385
+ // to a shadow-piercing ancestry walk from the deep active element before
3386
+ // treating this as a real focus loss.
3387
+ try {
3388
+ let active = document.activeElement;
3389
+ while (active && active.shadowRoot && active.shadowRoot.activeElement) {
3390
+ active = active.shadowRoot.activeElement;
3391
+ }
3392
+ const targets = [element, element.trigger, element.bib].filter(Boolean);
3393
+ let node = active;
3394
+ while (node) {
3395
+ if (targets.includes(node)) {
3396
+ return;
3397
+ }
3398
+ node =
3399
+ node.parentElement ||
3400
+ (node.getRootNode && node.getRootNode().host) ||
3401
+ null;
3402
+ }
3403
+ } catch (e) {
3404
+ // Defensive: fall through to the existing close path if traversal fails.
3405
+ }
3406
+
3382
3407
  // if fullscreen bib is in fullscreen mode, do not close
3383
3408
  if (element.bib.hasAttribute("isfullscreen")) {
3384
3409
  return;
3385
3410
  }
3386
3411
 
3387
- this.hideBib("keydown");
3412
+ // eventType "focusloss" distinguishes a Tab/click-driven close from an
3413
+ // Escape keydown close. Consumers use this to decide whether to restore
3414
+ // focus to the trigger (Escape) or let it advance naturally (Tab).
3415
+ this.hideBib("focusloss");
3388
3416
  }
3389
3417
 
3390
3418
  setupHideHandlers() {
@@ -4054,199 +4082,6 @@ function getFocusableElements(container) {
4054
4082
  return tabIndexedUniqueElements;
4055
4083
  }
4056
4084
 
4057
- /**
4058
- * FocusTrap manages keyboard focus within a specified container element, ensuring that focus does not leave the container when tabbing.
4059
- * It is commonly used for modal dialogs or overlays to improve accessibility by trapping focus within interactive UI components.
4060
- */
4061
- class FocusTrap {
4062
- /**
4063
- * Creates a new FocusTrap instance for the given container element.
4064
- * Initializes event listeners and prepares the container for focus management.
4065
- *
4066
- * @param {HTMLElement} container The DOM element to trap focus within.
4067
- * @param {boolean} [controlTabOrder=false] If true enables manual control of the tab order by the FocusTrap.
4068
- * @throws {Error} If the provided container is not a valid HTMLElement.
4069
- */
4070
- constructor(container, controlTabOrder = false) {
4071
- if (!container || !(container instanceof HTMLElement)) {
4072
- throw new Error("FocusTrap requires a valid HTMLElement.");
4073
- }
4074
-
4075
- this.container = container;
4076
- this.tabDirection = "forward"; // or 'backward';
4077
- this.controlTabOrder = controlTabOrder;
4078
-
4079
- this._init();
4080
- }
4081
-
4082
- /**
4083
- * Initializes the focus trap by setting up event listeners and attributes on the container.
4084
- * Prepares the container for focus management, including support for shadow DOM and inert attributes.
4085
- *
4086
- * @private
4087
- */
4088
- _init() {
4089
- // Add inert attribute to prevent focusing programmatically as well (if supported)
4090
- if ("inert" in HTMLElement.prototype) {
4091
- this.container.inert = false; // Ensure the container isn't inert
4092
- this.container.setAttribute("data-focus-trap-container", true); // Mark for identification
4093
- }
4094
-
4095
- // Track tab direction
4096
- this.container.addEventListener("keydown", this._onKeydown);
4097
- }
4098
-
4099
- /**
4100
- * Gets an array of currently active (focused) elements in the document and shadow DOM.
4101
- * @returns {Array<HTMLElement>} An array of focusable elements within the container.
4102
- * @private
4103
- */
4104
- _getActiveElements() {
4105
- // Get the active element(s) in the document and shadow root
4106
- // This will include the active element in the shadow DOM if it exists
4107
- // Active element may be inside the shadow DOM depending on delegatesFocus, so we need to check both
4108
- let { activeElement } = document;
4109
- const actives = [activeElement];
4110
- while (activeElement?.shadowRoot?.activeElement) {
4111
- actives.push(activeElement.shadowRoot.activeElement);
4112
- activeElement = activeElement.shadowRoot.activeElement;
4113
- }
4114
- return actives;
4115
- }
4116
-
4117
- /**
4118
- * Gets the next focus index based on the current index and focusable elements.
4119
- * @param {number} currentIndex The current index of the focused element.
4120
- * @param {Array<HTMLElement>} focusables The array of focusable elements.
4121
- * @returns {number|null} The next focus index or null if not determined.
4122
- */
4123
- _getNextFocusIndex(currentIndex, focusables, actives) {
4124
- if (this.controlTabOrder) {
4125
- // Calculate the new index based on the current index and tab direction
4126
- let newFocusIndex =
4127
- currentIndex + (this.tabDirection === "forward" ? 1 : -1);
4128
-
4129
- // Wrap-around logic
4130
- if (newFocusIndex < 0) newFocusIndex = focusables.length - 1;
4131
- if (newFocusIndex >= focusables.length) newFocusIndex = 0;
4132
-
4133
- // Early return with the new index
4134
- return newFocusIndex;
4135
- }
4136
-
4137
- // Determine if we need to wrap
4138
- const atFirst =
4139
- actives.includes(focusables[0]) || actives.includes(this.container);
4140
- const atLast = actives.includes(focusables[focusables.length - 1]);
4141
-
4142
- // Only wrap if at the ends
4143
- if (this.tabDirection === "backward" && atFirst) {
4144
- return focusables.length - 1;
4145
- }
4146
-
4147
- if (this.tabDirection === "forward" && atLast) {
4148
- return 0;
4149
- }
4150
-
4151
- // No wrap, so don't change focus, return early
4152
- return null;
4153
- }
4154
-
4155
- /**
4156
- * Handles the Tab key press event to manage focus within the container.
4157
- * @param {KeyboardEvent} e The keyboard event triggered by the user.
4158
- * @returns {void}
4159
- */
4160
- _handleTabKey(e) {
4161
- // Update the focusable elements
4162
- const focusables = this._getFocusableElements();
4163
-
4164
- // If there are no focusable elements, exit
4165
- if (!focusables.length) return;
4166
-
4167
- // Set the tab direction based on the key pressed
4168
- this.tabDirection = e.shiftKey ? "backward" : "forward";
4169
-
4170
- // Get the active elements that are currently focused
4171
- const actives = this._getActiveElements();
4172
-
4173
- // If we're at either end of the focusable elements, wrap around to the other end
4174
- let focusIndex = focusables.findIndex((el) => actives.includes(el));
4175
-
4176
- // Fallback if we have no focused element
4177
- if (focusIndex === -1) focusIndex = 0;
4178
-
4179
- // Get the next focus index based on the current focus index, tab direction, and controlTabOrder setting
4180
- // Is null if no new focus index is determined
4181
- const newFocusIndex = this._getNextFocusIndex(
4182
- focusIndex,
4183
- focusables,
4184
- actives,
4185
- );
4186
-
4187
- // If we have a new focus index, set focus to that element
4188
- if (newFocusIndex !== null) {
4189
- e.preventDefault();
4190
- focusables[newFocusIndex].focus();
4191
- }
4192
- }
4193
-
4194
- /**
4195
- * Catches the keydown event
4196
- * @param {KeyboardEvent} e The keyboard event triggered by user interaction.
4197
- * @private
4198
- */
4199
- _onKeydown = (e) => {
4200
- // Handle tab
4201
- if (e.key === "Tab") this._handleTabKey(e);
4202
- };
4203
-
4204
- /**
4205
- * Retrieves all focusable elements within the container in DOM order, including those in shadow DOM and slots.
4206
- * Returns a unique, ordered array of elements that can receive focus.
4207
- *
4208
- * @returns {Array<HTMLElement>} An array of focusable elements within the container.
4209
- * @private
4210
- */
4211
- _getFocusableElements() {
4212
- // Use the imported utility function to get focusable elements
4213
- const elements = getFocusableElements(this.container);
4214
-
4215
- // Return the elements found
4216
- return elements;
4217
- }
4218
-
4219
- /**
4220
- * Moves focus to the first focusable element within the container.
4221
- * Useful for setting initial focus when activating the focus trap.
4222
- */
4223
- focusFirstElement() {
4224
- const focusables = this._getFocusableElements();
4225
- if (focusables.length) focusables[0].focus();
4226
- }
4227
-
4228
- /**
4229
- * Moves focus to the last focusable element within the container.
4230
- * Useful for setting focus when deactivating or cycling focus in reverse.
4231
- */
4232
- focusLastElement() {
4233
- const focusables = this._getFocusableElements();
4234
- if (focusables.length) focusables[focusables.length - 1].focus();
4235
- }
4236
-
4237
- /**
4238
- * Removes event listeners and attributes added by the focus trap.
4239
- * Call this method to clean up when the focus trap is no longer needed.
4240
- */
4241
- disconnect() {
4242
- if (this.container.hasAttribute("data-focus-trap-container")) {
4243
- this.container.removeAttribute("data-focus-trap-container");
4244
- }
4245
-
4246
- this.container.removeEventListener("keydown", this._onKeydown);
4247
- }
4248
- }
4249
-
4250
4085
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
4251
4086
  // See LICENSE in the project root for license information.
4252
4087
 
@@ -4744,7 +4579,7 @@ class AuroDropdownBib extends i$2 {
4744
4579
  classes[`shape-${this.shape}`] = true;
4745
4580
 
4746
4581
  return u$4`
4747
- <dialog class="${e$2(classes)}" part="bibContainer" role="${o(this.dialogRole)}" aria-labelledby="${o(this.dialogLabel ? 'dialogLabel' : undefined)}">
4582
+ <dialog tabindex="-1" class="${e$2(classes)}" part="bibContainer" role="${o(this.dialogRole)}" aria-labelledby="${o(this.dialogLabel ? 'dialogLabel' : undefined)}">
4748
4583
  ${this.dialogLabel ? u$4`<span id="dialogLabel" class="util_displayHiddenVisually">${this.dialogLabel}</span>` : ''}
4749
4584
  <slot></slot>
4750
4585
  <span id="srAnnouncement" class="util_displayHiddenVisually" aria-live="polite" role="status"></span>
@@ -4995,7 +4830,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$2 {
4995
4830
  }
4996
4831
  };
4997
4832
 
4998
- var formkitVersion$1 = '202607072039';
4833
+ var formkitVersion$1 = '202607102214';
4999
4834
 
5000
4835
  class AuroElement extends i$2 {
5001
4836
  static get properties() {
@@ -5749,7 +5584,10 @@ class AuroDropdown extends AuroElement {
5749
5584
  }
5750
5585
 
5751
5586
 
5752
- if (!this.isPopoverVisible) {
5587
+ // On Tab-driven close (eventType "focusloss"), let focus advance naturally
5588
+ // — restoring to the trigger would trap the user on this dropdown, forcing
5589
+ // an extra Tab to move on. Escape and outside-click still restore.
5590
+ if (!this.isPopoverVisible && eventType !== "focusloss") {
5753
5591
  // wait til the bib gets fully closed and rendered
5754
5592
  setTimeout(() => {
5755
5593
  // Skip if the bib re-opened, or if focus moved intentionally outside the dropdown (not to body).
@@ -5979,15 +5817,16 @@ class AuroDropdown extends AuroElement {
5979
5817
  }
5980
5818
  });
5981
5819
  } else {
5982
- // Normal desktop: use FocusTrap on the bib element.
5983
- // Defer focusFirstElement to the next frame because the popover
5984
- // is positioned asynchronously by Floating UI — calling focus()
5985
- // synchronously here would target elements with zero dimensions
5986
- // and the focus call would be silently ignored.
5987
- this.focusTrap = new FocusTrap(this.bibContent);
5820
+ // Normal desktop (non-modal): move initial focus into the bib but
5821
+ // don't trap Tab. Tab should exit the bib and let the floater's
5822
+ // handleFocusLoss close it, matching native <select>/<details>
5823
+ // behavior. Deferred one frame because Floating UI positions the
5824
+ // popover asynchronously a synchronous focus() would target
5825
+ // zero-dimension elements and be silently ignored.
5988
5826
  requestAnimationFrame(() => {
5989
- if (this.focusTrap) {
5990
- this.focusTrap.focusFirstElement();
5827
+ const focusables = getFocusableElements(this.bibContent);
5828
+ if (focusables.length) {
5829
+ focusables[0].focus();
5991
5830
  }
5992
5831
  });
5993
5832
  }
@@ -7034,7 +6873,7 @@ class AuroHelpText extends i$2 {
7034
6873
  }
7035
6874
  }
7036
6875
 
7037
- var formkitVersion = '202607072039';
6876
+ var formkitVersion = '202607102214';
7038
6877
 
7039
6878
  var styleCss$2 = i$5`.util_displayInline{display:inline}.util_displayInlineBlock{display:inline-block}.util_displayBlock{display:block}.util_displayFlex{display:flex}.util_displayHidden{display:none}.util_displayHiddenVisually{position:absolute;overflow:hidden;clip:rect(1px, 1px, 1px, 1px);width:1px;height:1px;padding:0;border:0}.body-default{font-size:var(--wcss-body-default-font-size, 1rem);font-weight:var(--wcss-body-default-weight, );line-height:var(--wcss-body-default-line-height, 1.5rem)}.body-default,.body-default-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-default-emphasized{font-size:var(--wcss-body-default-emphasized-font-size, 1rem);font-weight:var(--wcss-body-default-emphasized-weight, );line-height:var(--wcss-body-default-emphasized-line-height, 1.5rem)}.body-lg{font-size:var(--wcss-body-lg-font-size, 1.125rem);font-weight:var(--wcss-body-lg-weight, );line-height:var(--wcss-body-lg-line-height, 1.625rem)}.body-lg,.body-lg-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-lg-emphasized{font-size:var(--wcss-body-lg-emphasized-font-size, 1.125rem);font-weight:var(--wcss-body-lg-emphasized-weight, );line-height:var(--wcss-body-lg-emphasized-line-height, 1.625rem)}.body-sm{font-size:var(--wcss-body-sm-font-size, 0.875rem);font-weight:var(--wcss-body-sm-weight, );line-height:var(--wcss-body-sm-line-height, 1.25rem)}.body-sm,.body-sm-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-sm-emphasized{font-size:var(--wcss-body-sm-emphasized-font-size, 0.875rem);font-weight:var(--wcss-body-sm-emphasized-weight, );line-height:var(--wcss-body-sm-emphasized-line-height, 1.25rem)}.body-xs{font-size:var(--wcss-body-xs-font-size, 0.75rem);font-weight:var(--wcss-body-xs-weight, );line-height:var(--wcss-body-xs-line-height, 1rem)}.body-xs,.body-xs-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-xs-emphasized{font-size:var(--wcss-body-xs-emphasized-font-size, 0.75rem);font-weight:var(--wcss-body-xs-emphasized-weight, );line-height:var(--wcss-body-xs-emphasized-line-height, 1rem)}.body-2xs{font-size:var(--wcss-body-2xs-font-size, 0.625rem);font-weight:var(--wcss-body-2xs-weight, );line-height:var(--wcss-body-2xs-line-height, 0.875rem)}.body-2xs,.body-2xs-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-2xs-emphasized{font-size:var(--wcss-body-2xs-emphasized-font-size, 0.625rem);font-weight:var(--wcss-body-2xs-emphasized-weight, );line-height:var(--wcss-body-2xs-emphasized-line-height, 0.875rem)}.display-2xl{font-family:var(--wcss-display-2xl-family, "AS Circular"),var(--wcss-display-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-2xl-font-size, clamp(3.5rem, 6vw, 5.375rem));font-weight:var(--wcss-display-2xl-weight, 300);letter-spacing:var(--wcss-display-2xl-letter-spacing, 0);line-height:var(--wcss-display-2xl-line-height, 1.3)}.display-xl{font-family:var(--wcss-display-xl-family, "AS Circular"),var(--wcss-display-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xl-font-size, clamp(3rem, 5.3333333333vw, 4.5rem));font-weight:var(--wcss-display-xl-weight, 300);letter-spacing:var(--wcss-display-xl-letter-spacing, 0);line-height:var(--wcss-display-xl-line-height, 1.3)}.display-lg{font-family:var(--wcss-display-lg-family, "AS Circular"),var(--wcss-display-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-lg-font-size, clamp(2.75rem, 4.6666666667vw, 4rem));font-weight:var(--wcss-display-lg-weight, 300);letter-spacing:var(--wcss-display-lg-letter-spacing, 0);line-height:var(--wcss-display-lg-line-height, 1.3)}.display-md{font-family:var(--wcss-display-md-family, "AS Circular"),var(--wcss-display-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-md-font-size, clamp(2.5rem, 4vw, 3.5rem));font-weight:var(--wcss-display-md-weight, 300);letter-spacing:var(--wcss-display-md-letter-spacing, 0);line-height:var(--wcss-display-md-line-height, 1.3)}.display-sm{font-family:var(--wcss-display-sm-family, "AS Circular"),var(--wcss-display-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-sm-font-size, clamp(2rem, 3.6666666667vw, 3rem));font-weight:var(--wcss-display-sm-weight, 300);letter-spacing:var(--wcss-display-sm-letter-spacing, 0);line-height:var(--wcss-display-sm-line-height, 1.3)}.display-xs{font-family:var(--wcss-display-xs-family, "AS Circular"),var(--wcss-display-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xs-font-size, clamp(1.75rem, 3vw, 2.375rem));font-weight:var(--wcss-display-xs-weight, 300);letter-spacing:var(--wcss-display-xs-letter-spacing, 0);line-height:var(--wcss-display-xs-line-height, 1.3)}.heading-xl{font-family:var(--wcss-heading-xl-family, "AS Circular"),var(--wcss-heading-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xl-font-size, clamp(2rem, 3vw, 2.5rem));font-weight:var(--wcss-heading-xl-weight, 300);letter-spacing:var(--wcss-heading-xl-letter-spacing, 0);line-height:var(--wcss-heading-xl-line-height, 1.3)}.heading-lg{font-family:var(--wcss-heading-lg-family, "AS Circular"),var(--wcss-heading-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-lg-font-size, clamp(1.75rem, 2.6666666667vw, 2.25rem));font-weight:var(--wcss-heading-lg-weight, 300);letter-spacing:var(--wcss-heading-lg-letter-spacing, 0);line-height:var(--wcss-heading-lg-line-height, 1.3)}.heading-md{font-family:var(--wcss-heading-md-family, "AS Circular"),var(--wcss-heading-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-md-font-size, clamp(1.625rem, 2.3333333333vw, 1.75rem));font-weight:var(--wcss-heading-md-weight, 300);letter-spacing:var(--wcss-heading-md-letter-spacing, 0);line-height:var(--wcss-heading-md-line-height, 1.3)}.heading-sm{font-family:var(--wcss-heading-sm-family, "AS Circular"),var(--wcss-heading-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-sm-font-size, clamp(1.375rem, 2vw, 1.5rem));font-weight:var(--wcss-heading-sm-weight, 300);letter-spacing:var(--wcss-heading-sm-letter-spacing, 0);line-height:var(--wcss-heading-sm-line-height, 1.3)}.heading-xs{font-family:var(--wcss-heading-xs-family, "AS Circular"),var(--wcss-heading-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xs-font-size, clamp(1.25rem, 1.6666666667vw, 1.25rem));font-weight:var(--wcss-heading-xs-weight, 300);letter-spacing:var(--wcss-heading-xs-letter-spacing, 0);line-height:var(--wcss-heading-xs-line-height, 1.3)}.heading-2xs{font-family:var(--wcss-heading-2xs-family, "AS Circular"),var(--wcss-heading-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-2xs-font-size, clamp(1.125rem, 1.5vw, 1.125rem));font-weight:var(--wcss-heading-2xs-weight, 300);letter-spacing:var(--wcss-heading-2xs-letter-spacing, 0);line-height:var(--wcss-heading-2xs-line-height, 1.3)}.accent-2xl{font-family:var(--wcss-accent-2xl-family, "Good OT"),var(--wcss-accent-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xl-font-size, clamp(2rem, 3.1666666667vw, 2.375rem));font-weight:var(--wcss-accent-2xl-weight, 450);letter-spacing:var(--wcss-accent-2xl-letter-spacing, 0.05em);line-height:var(--wcss-accent-2xl-line-height, 1)}.accent-2xl,.accent-xl{text-transform:uppercase}.accent-xl{font-family:var(--wcss-accent-xl-family, "Good OT"),var(--wcss-accent-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xl-font-size, clamp(1.625rem, 2.3333333333vw, 2rem));font-weight:var(--wcss-accent-xl-weight, 450);letter-spacing:var(--wcss-accent-xl-letter-spacing, 0.05em);line-height:var(--wcss-accent-xl-line-height, 1.3)}.accent-lg{font-family:var(--wcss-accent-lg-family, "Good OT"),var(--wcss-accent-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-lg-font-size, clamp(1.5rem, 2.1666666667vw, 1.75rem));font-weight:var(--wcss-accent-lg-weight, 450);letter-spacing:var(--wcss-accent-lg-letter-spacing, 0.05em);line-height:var(--wcss-accent-lg-line-height, 1.3)}.accent-lg,.accent-md{text-transform:uppercase}.accent-md{font-family:var(--wcss-accent-md-family, "Good OT"),var(--wcss-accent-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-md-font-size, clamp(1.375rem, 1.8333333333vw, 1.5rem));font-weight:var(--wcss-accent-md-weight, 500);letter-spacing:var(--wcss-accent-md-letter-spacing, 0.05em);line-height:var(--wcss-accent-md-line-height, 1.3)}.accent-sm{font-family:var(--wcss-accent-sm-family, "Good OT"),var(--wcss-accent-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-sm-font-size, clamp(1.125rem, 1.5vw, 1.25rem));font-weight:var(--wcss-accent-sm-weight, 500);letter-spacing:var(--wcss-accent-sm-letter-spacing, 0.05em);line-height:var(--wcss-accent-sm-line-height, 1.3)}.accent-sm,.accent-xs{text-transform:uppercase}.accent-xs{font-family:var(--wcss-accent-xs-family, "Good OT"),var(--wcss-accent-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xs-font-size, clamp(1rem, 1.3333333333vw, 1rem));font-weight:var(--wcss-accent-xs-weight, 500);letter-spacing:var(--wcss-accent-xs-letter-spacing, 0.1em);line-height:var(--wcss-accent-xs-line-height, 1.3)}.accent-2xs{font-family:var(--wcss-accent-2xs-family, "Good OT"),var(--wcss-accent-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xs-font-size, clamp(0.875rem, 1.1666666667vw, 0.875rem));font-weight:var(--wcss-accent-2xs-weight, 450);letter-spacing:var(--wcss-accent-2xs-letter-spacing, 0.1em);line-height:var(--wcss-accent-2xs-line-height, 1.3);text-transform:uppercase}[auro-dropdown]{--ds-auro-dropdown-trigger-border-color: var(--ds-auro-select-border-color);--ds-auro-dropdown-trigger-background-color: var(--ds-auro-select-background-color);--ds-auro-dropdown-trigger-container-color: var(--ds-auro-select-background-color);--ds-auro-dropdown-trigger-outline-color: var(--ds-auro-select-outline-color)}:host{display:inline-block;text-align:left;vertical-align:top}:host([layout*=emphasized]) [auro-dropdown],:host([layout*=snowflake]) [auro-dropdown]{--ds-auro-select-border-color: transparent}:host([layout*=emphasized]) .mainContent,:host([layout*=snowflake]) .mainContent{text-align:center}.mainContent{position:relative;display:flex;overflow:hidden;flex:1;flex-direction:column;align-items:center;justify-content:center}.valueContainer [slot=displayValue]{display:none}.accents{display:flex;flex-direction:row;align-items:center;justify-content:center}::slotted([slot=typeIcon]){margin-right:var(--ds-size-100, 0.5rem)}.displayValue{display:block}.displayValue:not(.force){display:none}.displayValue:not(.force).hasContent:is(.withValue):not(.hasFocus){display:block}.triggerContent{display:flex;width:100%;align-items:center;justify-content:center}:host([layout*=emphasized]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem) 0 var(--ds-size-300, 1.5rem)}:host([layout*=snowflake]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem) 0 var(--ds-size-200, 1rem)}:host([layout*=snowflake]) label{padding-block:var(--ds-size-25, 0.125rem)}:host([layout*=classic]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem)}:host([layout*=classic]) .mainContent{align-items:start}:host([layout*=classic]) label{overflow:hidden;cursor:text;text-overflow:ellipsis;white-space:nowrap}:host([layout*=classic]) .value{height:auto}label{color:var(--ds-auro-select-label-text-color)}:host(:is([validity]:not([validity=valid]))) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-basic-color-status-error, #e31f26);--ds-auro-select-outline-color: var(--ds-basic-color-status-error, #e31f26);--ds-auro-dropdown-helptext-text-color: var(--ds-basic-color-texticon-default, #2a2a2a)}:host([ondark]:is([validity]:not([validity=valid]))) [auro-dropdown],:host([appearance=inverse]:is([validity]:not([validity=valid]))) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8);--ds-auro-select-outline-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8);--ds-auro-dropdown-helptext-text-color: var(--ds-basic-color-texticon-inverse, #ffffff)}#slotHolder{display:none}:host([fluid]){width:100%}:host([disabled]){pointer-events:none;user-select:none}:host([disabled]:not([ondark])) [auro-dropdown],:host([disabled]:not([appearance=inverse])) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-basic-color-border-subtle, #dddddd)}:host(:not([layout*=classic])[disabled][ondark]) [auro-dropdown],:host(:not([layout*=classic])[disabled][appearance=inverse]) [auro-dropdown]{--ds-auro-select-border-color: transparent}`;
7040
6879
 
@@ -7476,7 +7315,7 @@ class AuroSelect extends AuroElement$1 {
7476
7315
  },
7477
7316
 
7478
7317
  /**
7479
- * Value selected for the component.
7318
+ * Value selected for the component. When set programmatically or as a preset attribute, the value must match a selectable option. If it matches an option marked `disabled` or `static`, the selection is rejected: `value` is cleared to `undefined` while `optionSelected` is cleared to `undefined` in single-select or `[]` in multiSelect. `hidden` options remain selectable by value.
7480
7319
  */
7481
7320
  value: {
7482
7321
  type: String,
@@ -8296,6 +8135,10 @@ class AuroSelect extends AuroElement$1 {
8296
8135
  this._observeLabelChanges();
8297
8136
  }
8298
8137
 
8138
+ /**
8139
+ * Sets the selected value by matching it against the menu options. Options marked `disabled` or `static` are not selectable: if the value matches one, the selection is rejected and `value` is cleared to `undefined` while `optionSelected` is cleared to `undefined` in single-select or `[]` in multiSelect. `hidden` options remain selectable.
8140
+ * @param {string} value - The value to match against the menu options.
8141
+ */
8299
8142
  setMenuValue(value) {
8300
8143
  if (!this.menu) return;
8301
8144
  this.menu.selectByValue(value);
@@ -8823,6 +8666,18 @@ var tokensCss = i$5`:host{--ds-auro-menu-divider-color: var(--ds-basic-color-bor
8823
8666
  // See LICENSE in the project root for license information.
8824
8667
 
8825
8668
 
8669
+ /**
8670
+ * Serializes a multi-select value array back into the String `value` property.
8671
+ * An empty (or missing) array collapses to `undefined` so an emptied selection
8672
+ * clears `value` rather than reflecting a `"[]"` attribute.
8673
+ * @private
8674
+ * @param {Array<string>|undefined} values - The selected values.
8675
+ * @returns {string|undefined} JSON string of the values, or undefined when empty.
8676
+ */
8677
+ function serializeMultiSelectValue(values) {
8678
+ return values && values.length > 0 ? JSON.stringify(values) : undefined;
8679
+ }
8680
+
8826
8681
  /**
8827
8682
  * Validates if an option can be interacted with.
8828
8683
  * @private
@@ -8835,6 +8690,20 @@ function isOptionInteractive(option) {
8835
8690
  !option.hasAttribute('static');
8836
8691
  }
8837
8692
 
8693
+ /**
8694
+ * Validates if an option may be selected by matching a programmatic value.
8695
+ * Unlike `isOptionInteractive`, `hidden` is allowed: the combobox toggles
8696
+ * `hidden` as its type-ahead filter, so a filtered-out option is still a
8697
+ * valid programmatic selection. Only disabled and static options — which are
8698
+ * never selectable — are rejected.
8699
+ * @param {HTMLElement} option - The option to check.
8700
+ * @returns {boolean} True if option can be selected by value.
8701
+ */
8702
+ function isSelectableByValue(option) {
8703
+ return !option.hasAttribute('disabled') &&
8704
+ !option.hasAttribute('static');
8705
+ }
8706
+
8838
8707
  /**
8839
8708
  * Helper method to dispatch custom events.
8840
8709
  * @param {HTMLElement} element - Element to dispatch event from.
@@ -9004,22 +8873,26 @@ class AuroMenu extends AuroElement$1 {
9004
8873
 
9005
8874
  /**
9006
8875
  * Specifies the current active menuOption.
8876
+ * @readonly
9007
8877
  */
9008
8878
  optionActive: {
9009
8879
  type: Object,
9010
- attribute: 'optionactive'
8880
+ attribute: false
9011
8881
  },
9012
8882
 
9013
8883
  /**
9014
- * An array of currently selected menu options, type `HTMLElement` by default. In multi-select mode, `optionSelected` is an array of HTML elements.
8884
+ * The currently selected menu option(s). In single-select mode this is a single `HTMLElement` (or `undefined` when nothing is selected). In multi-select mode this is an array of `HTMLElement`s.
8885
+ * @readonly
9015
8886
  */
9016
8887
  optionSelected: {
9017
8888
  // Allow HTMLElement, HTMLElement[] arrays and undefined
9018
- type: Object
8889
+ type: Object,
8890
+ attribute: false
9019
8891
  },
9020
8892
 
9021
8893
  /**
9022
8894
  * The value of the selected option. In multi-select mode, this is a JSON stringified array of selected option values.
8895
+ * Options marked `disabled` or `static` are not selectable by value; `hidden` options remain selectable. In single-select mode, if the value matches a non-selectable option the selection is cleared (`optionSelected` becomes `undefined`) and `auroMenu-selectValueFailure` is dispatched. In multi-select mode, non-selectable entries are dropped from the value and the remaining selectable entries are selected; `auroMenu-selectValueFailure` is dispatched only when none of the entries match a selectable option.
9023
8896
  */
9024
8897
  value: {
9025
8898
  type: String,
@@ -9143,7 +9016,7 @@ class AuroMenu extends AuroElement$1 {
9143
9016
  }
9144
9017
 
9145
9018
  /**
9146
- * Selects options by value.
9019
+ * Selects options by value. Options marked `disabled` or `static` are not selectable; `hidden` options remain selectable. In single-select mode, if the value matches a non-selectable option the selection is cleared and `auroMenu-selectValueFailure` is dispatched. In multi-select mode, non-selectable entries are dropped and the remaining selectable entries are selected; `auroMenu-selectValueFailure` is dispatched only when none of the entries match a selectable option. Passing `undefined`, `null`, an empty string, or an empty array clears the selection without dispatching a failure.
9147
9020
  * @param {string|string[]|undefined|null} value - The value(s) to select.
9148
9021
  * @public
9149
9022
  */
@@ -9228,6 +9101,11 @@ class AuroMenu extends AuroElement$1 {
9228
9101
  this.initItems();
9229
9102
  }
9230
9103
 
9104
+ // Set when reconciliation reassigns `value` below. That reassignment schedules a
9105
+ // second updated() cycle, so the `event`-attribute dispatch is deferred to that
9106
+ // cycle to avoid firing option custom events twice on the same selection.
9107
+ let valueReconciled = false;
9108
+
9231
9109
  // Handle null/undefined/empty case — empty/whitespace strings clear selection
9232
9110
  // consistently with selectByValue(''), and avoid downstream `.includes('')` matches.
9233
9111
  if (this.value === undefined || this.value === null || (typeof this.value === 'string' && this.value.trim() === '')) {
@@ -9240,11 +9118,31 @@ class AuroMenu extends AuroElement$1 {
9240
9118
  // Defensive default: `formattedValue` can be undefined for unexpected value types,
9241
9119
  // and calling `.includes` on undefined would throw during reconciliation.
9242
9120
  const valueArray = this.formattedValue || [];
9243
- const matchingOptions = this.items ? this.items.filter((item) => valueArray.includes(item.value)) : [];
9121
+ const matchingOptions = this.items ? this.items.filter((item) => isSelectableByValue(item) && valueArray.includes(item.value)) : [];
9244
9122
  newSelected = matchingOptions.length > 0 ? matchingOptions : undefined;
9123
+
9124
+ // Reconcile `value` with the selectable set. Drop only entries whose option is
9125
+ // loaded but non-selectable (disabled/static) — leaving them would desync `value`
9126
+ // from `optionSelected`, and the toggle handlers rebuild `value` from `formattedValue`,
9127
+ // so the rejected entry would resurface on the next select/deselect. Entries with no
9128
+ // matching item yet are preserved so async preselection still works once options render.
9129
+ const rejectedValues = this.items
9130
+ ? this.items.filter((item) => !isSelectableByValue(item) && valueArray.includes(item.value)).map((item) => item.value)
9131
+ : [];
9132
+ if (rejectedValues.length > 0) {
9133
+ const reconciled = valueArray.filter((val) => !rejectedValues.includes(val));
9134
+ this.value = serializeMultiSelectValue(reconciled);
9135
+ valueReconciled = true;
9136
+ }
9245
9137
  } else {
9246
- // In single-select mode, this.value should be a string
9247
- const matchingOption = this.items ? this.items.find((item) => item.value === this.value) : undefined;
9138
+ // In single-select mode, this.value should be a string. Reject
9139
+ // disabled/static options so a programmatic value pointing at a
9140
+ // non-selectable option falls through to the no-match path below
9141
+ // (dispatching auroMenu-selectValueFailure) instead of pinning it.
9142
+ // `hidden` is intentionally NOT excluded: the combobox toggles
9143
+ // `hidden` as its type-ahead filter, so a filtered-out option is
9144
+ // still a valid programmatic selection.
9145
+ const matchingOption = this.items ? this.items.find((item) => isSelectableByValue(item) && item.value === this.value) : undefined;
9248
9146
 
9249
9147
  if (matchingOption) {
9250
9148
  newSelected = matchingOption;
@@ -9286,8 +9184,9 @@ class AuroMenu extends AuroElement$1 {
9286
9184
  ]
9287
9185
  ]));
9288
9186
 
9289
- // Notify of changes
9290
- if (this.optionSelected !== undefined) {
9187
+ // Notify of changes. Skip when reconciliation just reassigned `value`: the
9188
+ // follow-on update cycle re-runs this branch and fires the events exactly once.
9189
+ if (this.optionSelected !== undefined && !valueReconciled) {
9291
9190
  const selected = Array.isArray(this.optionSelected) ? this.optionSelected : [this.optionSelected];
9292
9191
  selected.forEach((opt) => {
9293
9192
  if (opt.hasAttribute('event')) {
@@ -9500,7 +9399,7 @@ class AuroMenu extends AuroElement$1 {
9500
9399
  const currentSelected = this.optionSelected || [];
9501
9400
 
9502
9401
  if (!currentValue.includes(option.value)) {
9503
- this.value = JSON.stringify([
9402
+ this.value = serializeMultiSelectValue([
9504
9403
  ...currentValue,
9505
9404
  option.value
9506
9405
  ]);
@@ -9526,15 +9425,9 @@ class AuroMenu extends AuroElement$1 {
9526
9425
  */
9527
9426
  handleDeselectState(option) {
9528
9427
  if (this.multiSelect) {
9529
- // Remove this option from array
9428
+ // Remove this option from array; an empty result collapses `value` to undefined.
9530
9429
  const newFormattedValue = (this.formattedValue || []).filter((val) => val !== option.value);
9531
-
9532
- // If array is empty after removal, set back to undefined
9533
- if (newFormattedValue && newFormattedValue.length === 0) {
9534
- this.value = undefined;
9535
- } else {
9536
- this.value = JSON.stringify(newFormattedValue);
9537
- }
9430
+ this.value = serializeMultiSelectValue(newFormattedValue);
9538
9431
 
9539
9432
  this.optionSelected = this.optionSelected.filter((val) => val !== option);
9540
9433
  if (this.optionSelected.length === 0) {
@@ -9581,6 +9474,11 @@ class AuroMenu extends AuroElement$1 {
9581
9474
  this.optionSelected = undefined;
9582
9475
  this._index = -1;
9583
9476
 
9477
+ // Clear active option state so a follow-up open/navigation starts fresh
9478
+ // rather than reusing a stale reference from before the reset.
9479
+ this.items?.forEach((item) => item.classList.remove('active'));
9480
+ this.optionActive = undefined;
9481
+
9584
9482
  // Reset UI state
9585
9483
  this.updateItemsState(new Map([
9586
9484
  [
@@ -9990,6 +9888,7 @@ let menuOptionIdCounter = 0;
9990
9888
  * The `auro-menuoption` element provides users a way to define a menu option.
9991
9889
  * @customElement auro-menuoption
9992
9890
  *
9891
+ * @attr {Boolean} static - When present, marks the option as non-interactive — it renders but is skipped during keyboard navigation and cannot be selected. Useful for section headers, informational rows inside a menu, or attaching event listeners.
9993
9892
  * @slot default - The default slot for the menu option text.
9994
9893
  *
9995
9894
  * @event auroMenuOption-mouseover - Notifies that this option has been hovered over.
@@ -10019,6 +9918,7 @@ class AuroMenuOption extends AuroElement$1 {
10019
9918
  this.noCheckmark = false;
10020
9919
  this.disabled = false;
10021
9920
  this.noMatch = false;
9921
+ this.persistent = false;
10022
9922
 
10023
9923
  /**
10024
9924
  * @private
@@ -10040,6 +9940,12 @@ class AuroMenuOption extends AuroElement$1 {
10040
9940
  type: Boolean,
10041
9941
  reflect: true
10042
9942
  },
9943
+
9944
+ /**
9945
+ * **Deprecated.** Use the `value` attribute on `auro-menu` to set the selected option when the menu renders (or call `menu.selectByValue(value)` programmatically). Support for the child-level `selected` attribute will be removed in a future major release.
9946
+ *
9947
+ * @deprecated Use the `value` attribute on `auro-menu` instead.
9948
+ */
10043
9949
  selected: {
10044
9950
  type: Boolean,
10045
9951
  reflect: true
@@ -10074,6 +9980,12 @@ class AuroMenuOption extends AuroElement$1 {
10074
9980
  reflect: true,
10075
9981
  attribute: 'nomatch'
10076
9982
  },
9983
+
9984
+ /** When true, this option is excluded from `matchWord` DOM rewriting — useful for utility rows (e.g., "Add new…") that must render identically regardless of the current filter. */
9985
+ persistent: {
9986
+ type: Boolean,
9987
+ reflect: true
9988
+ },
10077
9989
  };
10078
9990
  }
10079
9991
 
@@ -340,19 +340,19 @@
340
340
  <span slot="helpText">Help Text</span>
341
341
  <auro-menu nocheckmark>
342
342
  <auro-menuoption value="flights">
343
- <auro-icon category="terminal" name="plane-diag-stroke" customColor></auro-icon> Flights
343
+ <auro-icon category="terminal" name="plane-diag-stroke" customcolor></auro-icon> Flights
344
344
  </auro-menuoption>
345
345
  <auro-menuoption value="cars">
346
- <auro-icon category="destination" name="car-rental-stroke" customColor></auro-icon> Cars
346
+ <auro-icon category="destination" name="car-rental-stroke" customcolor></auro-icon> Cars
347
347
  </auro-menuoption>
348
348
  <auro-menuoption value="hotels">
349
- <auro-icon category="destination" name="hotel-stroke" customColor></auro-icon> Hotels
349
+ <auro-icon category="destination" name="hotel-stroke" customcolor></auro-icon> Hotels
350
350
  </auro-menuoption>
351
351
  <auro-menuoption value="packages">
352
- <auro-icon category="shop" name="gift-stroke" customColor></auro-icon> Packages
352
+ <auro-icon category="shop" name="gift-stroke" customcolor></auro-icon> Packages
353
353
  </auro-menuoption>
354
354
  <auro-menuoption value="cruises">
355
- <auro-icon category="in-flight" name="boarding" customColor></auro-icon> Cruises
355
+ <auro-icon category="in-flight" name="boarding" customcolor></auro-icon> Cruises
356
356
  </auro-menuoption>
357
357
  </auro-menu>
358
358
  </auro-select>
@@ -368,19 +368,19 @@
368
368
  &lt;span slot="helpText"&gt;Help Text&lt;/span&gt;
369
369
  &lt;auro-menu nocheckmark&gt;
370
370
  &lt;auro-menuoption value="flights"&gt;
371
- &lt;auro-icon category="terminal" name="plane-diag-stroke" customColor&gt;&lt;/auro-icon&gt; Flights
371
+ &lt;auro-icon category="terminal" name="plane-diag-stroke" customcolor&gt;&lt;/auro-icon&gt; Flights
372
372
  &lt;/auro-menuoption&gt;
373
373
  &lt;auro-menuoption value="cars"&gt;
374
- &lt;auro-icon category="destination" name="car-rental-stroke" customColor&gt;&lt;/auro-icon&gt; Cars
374
+ &lt;auro-icon category="destination" name="car-rental-stroke" customcolor&gt;&lt;/auro-icon&gt; Cars
375
375
  &lt;/auro-menuoption&gt;
376
376
  &lt;auro-menuoption value="hotels"&gt;
377
- &lt;auro-icon category="destination" name="hotel-stroke" customColor&gt;&lt;/auro-icon&gt; Hotels
377
+ &lt;auro-icon category="destination" name="hotel-stroke" customcolor&gt;&lt;/auro-icon&gt; Hotels
378
378
  &lt;/auro-menuoption&gt;
379
379
  &lt;auro-menuoption value="packages"&gt;
380
- &lt;auro-icon category="shop" name="gift-stroke" customColor&gt;&lt;/auro-icon&gt; Packages
380
+ &lt;auro-icon category="shop" name="gift-stroke" customcolor&gt;&lt;/auro-icon&gt; Packages
381
381
  &lt;/auro-menuoption&gt;
382
382
  &lt;auro-menuoption value="cruises"&gt;
383
- &lt;auro-icon category="in-flight" name="boarding" customColor&gt;&lt;/auro-icon&gt; Cruises
383
+ &lt;auro-icon category="in-flight" name="boarding" customcolor&gt;&lt;/auro-icon&gt; Cruises
384
384
  &lt;/auro-menuoption&gt;
385
385
  &lt;/auro-menu&gt;
386
386
  &lt;/auro-select&gt;</code></pre>
@@ -390,7 +390,7 @@ Ensure your `tsconfig.json` uses `"moduleResolution": "bundler"` so TypeScript c
390
390
  <auro-header level="3" id="validity">validity</auro-header>
391
391
  <p>Returns the current <code>validityState</code> of the component as a string. Possible values include <code>"valid"</code>, <code>"valueMissing"</code>, and <code>"customError"</code>.</p>
392
392
  <auro-header level="3" id="value">value</auro-header>
393
- <p>Gets or sets the selected value of the select. When set programmatically, the component will attempt to match and select the corresponding menu option.</p>
393
+ <p>Gets or sets the selected value of the select. When set programmatically, the component will attempt to match and select the corresponding menu option. If the value matches an option marked <code>disabled</code> or <code>static</code>, the selection is rejected and <code>value</code> is cleared to <code>undefined</code>. <code>hidden</code> options remain selectable by value.</p>
394
394
  </section>
395
395
  <section>
396
396
  <auro-header level="2" id="publicFunctions">Functions</auro-header>