@aurodesignsystem-dev/auro-formkit 0.0.0-pr1576.7 → 0.0.0-pr1577.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 (51) hide show
  1. package/components/checkbox/demo/customize.min.js +1 -1
  2. package/components/checkbox/demo/getting-started.min.js +1 -1
  3. package/components/checkbox/demo/index.min.js +1 -1
  4. package/components/checkbox/dist/index.js +1 -1
  5. package/components/checkbox/dist/registered.js +1 -1
  6. package/components/combobox/demo/customize.md +0 -40
  7. package/components/combobox/demo/customize.min.js +65 -359
  8. package/components/combobox/demo/getting-started.min.js +65 -359
  9. package/components/combobox/demo/index.min.js +65 -359
  10. package/components/combobox/dist/index.js +38 -56
  11. package/components/combobox/dist/registered.js +38 -56
  12. package/components/counter/demo/customize.min.js +11 -2
  13. package/components/counter/demo/index.min.js +11 -2
  14. package/components/counter/dist/index.js +11 -2
  15. package/components/counter/dist/registered.js +11 -2
  16. package/components/datepicker/demo/customize.min.js +12 -3
  17. package/components/datepicker/demo/index.min.js +12 -3
  18. package/components/datepicker/dist/index.js +12 -3
  19. package/components/datepicker/dist/registered.js +12 -3
  20. package/components/dropdown/demo/customize.min.js +10 -1
  21. package/components/dropdown/demo/getting-started.min.js +10 -1
  22. package/components/dropdown/demo/index.min.js +10 -1
  23. package/components/dropdown/dist/index.js +10 -1
  24. package/components/dropdown/dist/registered.js +10 -1
  25. package/components/form/demo/customize.min.js +102 -369
  26. package/components/form/demo/getting-started.min.js +102 -369
  27. package/components/form/demo/index.min.js +102 -369
  28. package/components/form/demo/registerDemoDeps.min.js +102 -369
  29. package/components/input/demo/customize.min.js +1 -1
  30. package/components/input/demo/getting-started.min.js +1 -1
  31. package/components/input/demo/index.min.js +1 -1
  32. package/components/input/dist/index.js +1 -1
  33. package/components/input/dist/registered.js +1 -1
  34. package/components/menu/demo/index.min.js +27 -303
  35. package/components/menu/dist/auro-menu-utils.d.ts +0 -30
  36. package/components/menu/dist/auro-menu.d.ts +0 -23
  37. package/components/menu/dist/index.js +27 -303
  38. package/components/menu/dist/registered.js +27 -303
  39. package/components/radio/demo/customize.min.js +1 -1
  40. package/components/radio/demo/getting-started.min.js +1 -1
  41. package/components/radio/demo/index.min.js +1 -1
  42. package/components/radio/dist/index.js +1 -1
  43. package/components/radio/dist/registered.js +1 -1
  44. package/components/select/demo/customize.md +0 -72
  45. package/components/select/demo/customize.min.js +38 -305
  46. package/components/select/demo/getting-started.min.js +38 -305
  47. package/components/select/demo/index.min.js +38 -305
  48. package/components/select/dist/index.js +11 -2
  49. package/components/select/dist/registered.js +11 -2
  50. package/custom-elements.json +1511 -1614
  51. package/package.json +1 -1
@@ -4836,7 +4836,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$2 {
4836
4836
  }
4837
4837
  };
4838
4838
 
4839
- var formkitVersion$1 = '202608041729';
4839
+ var formkitVersion$1 = '202608041712';
4840
4840
 
4841
4841
  class AuroElement extends i$2 {
4842
4842
  static get properties() {
@@ -5538,6 +5538,15 @@ class AuroDropdown extends AuroElement {
5538
5538
 
5539
5539
  connectedCallback() {
5540
5540
  super.connectedCallback();
5541
+ // Re-register trigger event listeners removed by floater.disconnect() in
5542
+ // disconnectedCallback(). Fires when a parent element (e.g. auro-drawer)
5543
+ // moves this element to a new DOM location. firstUpdated() won't re-run,
5544
+ // so without this the trigger click/keydown handlers are permanently gone.
5545
+ // Guard on floater.element so this is a no-op on the initial connect
5546
+ // (before firstUpdated() has called configure()).
5547
+ if (this.floater?.element) {
5548
+ this.floater.configure(this, 'auroDropdown', !this.disableKeyboardHandling);
5549
+ }
5541
5550
  }
5542
5551
 
5543
5552
  disconnectedCallback() {
@@ -6938,7 +6947,7 @@ class AuroHelpText extends i$2 {
6938
6947
  }
6939
6948
  }
6940
6949
 
6941
- var formkitVersion = '202608041729';
6950
+ var formkitVersion = '202608041712';
6942
6951
 
6943
6952
  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{max-width:100%}.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%;box-sizing:border-box;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{overflow:hidden;height:auto;text-overflow:ellipsis;white-space:nowrap}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}`;
6944
6953
 
@@ -8769,107 +8778,6 @@ function isSelectableByValue(option) {
8769
8778
  !option.hasAttribute('static');
8770
8779
  }
8771
8780
 
8772
- /* eslint-disable no-underscore-dangle */
8773
- /**
8774
- * Resolves the single selected option for a given `value`, preferring the
8775
- * option tracked by `selectedKey` (a user-initiated selection) over a
8776
- * first-by-value match. When multiple options share the same `value`, matching
8777
- * by `value` alone cannot distinguish which one the user picked; the key
8778
- * disambiguates it.
8779
- *
8780
- * The key is trusted only when it still resolves to an option whose `value`
8781
- * matches the requested `value`. If the key is stale (option removed) or the
8782
- * value was changed programmatically, resolution falls back to value matching —
8783
- * preserving backward-compatible behavior for preselection and `selectByValue`.
8784
- * @private
8785
- * @param {Array<HTMLElement>} items - The menu's flat option list.
8786
- * @param {string} value - The value to resolve.
8787
- * @param {string|undefined} selectedKey - The `_optionKey` of the user-selected option, if any.
8788
- * @returns {HTMLElement|undefined} The resolved option, or undefined when none match.
8789
- */
8790
- function resolveSelectedOption(items, value, selectedKey) {
8791
- if (!items) {
8792
- return undefined;
8793
- }
8794
-
8795
- if (selectedKey !== undefined) {
8796
- const keyed = items.find((item) => item._optionKey === selectedKey);
8797
- if (keyed && isSelectableByValue(keyed) && keyed.value === value) {
8798
- return keyed;
8799
- }
8800
- // Key exists but the option is gone or its value no longer matches — fall
8801
- // through to value-based matching.
8802
- }
8803
-
8804
- return items.find((item) => isSelectableByValue(item) && item.value === value);
8805
- }
8806
-
8807
- /**
8808
- * Resolves the selected options for a multi-select `value` array, preferring
8809
- * options tracked by `selectedKeys` (user-initiated selections) and falling
8810
- * back to value matching for any values not resolved by key. The result is
8811
- * always sorted into DOM order regardless of selection sequence.
8812
- * @private
8813
- * @param {Array<HTMLElement>} items - The menu's flat option list.
8814
- * @param {Array<string>} valueArray - The selected values.
8815
- * @param {Array<string>|undefined} selectedKeys - The `_optionKey`s of the user-selected options, if any.
8816
- * @returns {Array<HTMLElement>} The resolved options in DOM order.
8817
- */
8818
- function resolveSelectedOptions(items, valueArray, selectedKeys) {
8819
- if (!items) {
8820
- return [];
8821
- }
8822
-
8823
- const resolved = [];
8824
-
8825
- // Track how many of each value are still available to resolve. A value that
8826
- // appears N times in `valueArray` may be satisfied at most N times total across
8827
- // the key pass and the value fallback below — matching by count, not presence,
8828
- // on BOTH passes. This stops a duplicate value from being over-resolved: e.g.
8829
- // two keyed options that both carry `SEA` cannot both match a single requested
8830
- // `SEA` (which happens when `value` is set directly without clearing
8831
- // `_selectedKey`, so more keys survive than the value set now asks for).
8832
- const remaining = new Map();
8833
- valueArray.forEach((val) => remaining.set(val, (remaining.get(val) || 0) + 1));
8834
-
8835
- // Resolve by key first: trust a key only when its option is still selectable
8836
- // and there is still an unmatched occurrence of its value in the request set.
8837
- if (Array.isArray(selectedKeys)) {
8838
- selectedKeys.forEach((key) => {
8839
- const keyed = items.find((item) => item._optionKey === key);
8840
- if (keyed && isSelectableByValue(keyed) && (remaining.get(keyed.value) || 0) > 0 && !resolved.includes(keyed)) {
8841
- resolved.push(keyed);
8842
- remaining.set(keyed.value, remaining.get(keyed.value) - 1);
8843
- }
8844
- });
8845
- }
8846
-
8847
- // Fall back to value matching for the occurrences not resolved by key. Iterate
8848
- // the leftover per-value counts so a value that appears twice but was only
8849
- // resolved once by key still matches its remaining occurrence(s).
8850
- remaining.forEach((count, val) => {
8851
- for (let occurrence = 0; occurrence < count; occurrence += 1) {
8852
- const option = items.find((item) => isSelectableByValue(item) && item.value === val && !resolved.includes(item));
8853
- if (option) {
8854
- resolved.push(option);
8855
- }
8856
- }
8857
- });
8858
-
8859
- // Always return in DOM order so display is consistent regardless of the order
8860
- // keys/values were selected. Every resolved option came from `items`, so an
8861
- // O(1) index lookup mirrors `_sortSelectedByDomOrder` and avoids the O(n)
8862
- // `items.indexOf` per comparison for large combobox option sets.
8863
- const indexMap = new Map(items.map((item, index) => [
8864
- item,
8865
- index
8866
- ]));
8867
- resolved.sort((optionA, optionB) => indexMap.get(optionA) - indexMap.get(optionB));
8868
-
8869
- return resolved;
8870
- }
8871
- /* eslint-enable no-underscore-dangle */
8872
-
8873
8781
  /**
8874
8782
  * Helper method to dispatch custom events.
8875
8783
  * @param {HTMLElement} element - Element to dispatch event from.
@@ -8895,14 +8803,6 @@ function dispatchMenuEvent(element, eventName, detail = null) {
8895
8803
  // See LICENSE in the project root for license information.
8896
8804
 
8897
8805
 
8898
- /**
8899
- * Monotonically increasing counter used to give each menu instance a unique
8900
- * `_menuInstanceId` prefix. Auto-generating the id (rather than using a random
8901
- * string) keeps option keys deterministic and collision-free across menus.
8902
- * @private
8903
- */
8904
- let menuInstanceIdCounter = 0;
8905
-
8906
8806
 
8907
8807
  /**
8908
8808
  * The `auro-menu` element provides users a way to select from a list of options.
@@ -8974,8 +8874,9 @@ class AuroMenu extends AuroElement$1 {
8974
8874
 
8975
8875
  // Instance properties (non-reactive)
8976
8876
 
8977
- menuInstanceIdCounter += 1;
8978
-
8877
+ /**
8878
+ * @private
8879
+ */
8979
8880
  Object.assign(this, {
8980
8881
  // Root-level menu (true) or a nested submenu (false)
8981
8882
  rootMenu: true,
@@ -8985,21 +8886,6 @@ class AuroMenu extends AuroElement$1 {
8985
8886
  nestingSpacer: '<span class="nestingSpacer"></span>',
8986
8887
  // Loading indicator for slot elements
8987
8888
  loadingSlots: null,
8988
- // Unique id for this menu instance; prefixes every auto-generated option
8989
- // key so keys never collide across menus in the same document.
8990
- _menuInstanceId: `menu-${menuInstanceIdCounter}`,
8991
- // Monotonically increasing counter for option key generation. Never
8992
- // resets, so a key is never reused within this instance's lifetime.
8993
- _optionKeyCounter: 0,
8994
- // Key(s) of the option(s) the user has actively selected. A single string
8995
- // in single-select, an array in multi-select, undefined when nothing is
8996
- // user-selected. Used to disambiguate options that share a `value`.
8997
- _selectedKey: undefined,
8998
- // True only for the one updated() cycle following a user selection, so
8999
- // reconciliation trusts `_selectedKey`. A `value` change from a consumer's
9000
- // direct property assignment leaves this false, dropping the stale key so
9001
- // reconciliation falls back to first-by-value (see updated()).
9002
- _valueChangeFromSelection: false,
9003
8889
  });
9004
8890
  }
9005
8891
 
@@ -9219,13 +9105,6 @@ class AuroMenu extends AuroElement$1 {
9219
9105
  return;
9220
9106
  }
9221
9107
 
9222
- // A programmatic value set carries no positional intent, so drop any
9223
- // `_selectedKey` left over from a prior user click. This makes reconciliation
9224
- // in updated() fall back to first-by-value (single) / value-in-DOM-order
9225
- // (multi), matching the documented contract for programmatic selection even
9226
- // when a stale key would still resolve to a duplicate-value option.
9227
- this._selectedKey = undefined;
9228
-
9229
9108
  // `value` is a String property; stringify arrays so attribute reflection and `formattedValue` parsing stay correct.
9230
9109
  this.value = Array.isArray(value) ? JSON.stringify(value) : value;
9231
9110
  }
@@ -9273,17 +9152,6 @@ class AuroMenu extends AuroElement$1 {
9273
9152
  updated(changedProperties) {
9274
9153
  super.updated(changedProperties);
9275
9154
 
9276
- // Consume the selection-driven flag for THIS cycle up front. Clearing it
9277
- // unconditionally — not only inside the `value` branch below — prevents it
9278
- // from lingering `true` when a selection produces a serialized `value`
9279
- // byte-identical to the current one, in which case Lit schedules no
9280
- // `value`-change cycle to consume it. A lingering flag would misclassify a
9281
- // later consumer's programmatic `value` set as selection-driven and keep a
9282
- // stale `_selectedKey`. The reconcile path below re-sets the instance flag
9283
- // after this point, so its intentional cross-cycle hand-off still works.
9284
- const valueChangeFromSelection = this._valueChangeFromSelection;
9285
- this._valueChangeFromSelection = false;
9286
-
9287
9155
  // Single source of truth for 'auroMenu-selectedOption'. Selection handlers
9288
9156
  // mutate optionSelected and let Lit's update cycle dispatch here; the prior
9289
9157
  // .value comparison missed multi-select array changes and combined with the
@@ -9307,17 +9175,6 @@ class AuroMenu extends AuroElement$1 {
9307
9175
  this.initItems();
9308
9176
  }
9309
9177
 
9310
- // Distinguish a selection-driven `value` change (a user click, which set
9311
- // the flag in handleSelectState / _sortSelectedByDomOrder) from a
9312
- // programmatic assignment by a consumer. A programmatic set carries no
9313
- // positional intent, so drop any leftover `_selectedKey` and let
9314
- // reconciliation fall back to first-by-value (single) / value-in-DOM-order
9315
- // (multi) — the same contract selectByValue() guarantees, even when a
9316
- // stale key would otherwise still resolve to a duplicate-value option.
9317
- if (!valueChangeFromSelection) {
9318
- this._selectedKey = undefined;
9319
- }
9320
-
9321
9178
  // Set when reconciliation reassigns `value` below. That reassignment schedules a
9322
9179
  // second updated() cycle, so the `event`-attribute dispatch is deferred to that
9323
9180
  // cycle to avoid firing option custom events twice on the same selection.
@@ -9335,55 +9192,19 @@ class AuroMenu extends AuroElement$1 {
9335
9192
  // Defensive default: `formattedValue` can be undefined for unexpected value types,
9336
9193
  // and calling `.includes` on undefined would throw during reconciliation.
9337
9194
  const valueArray = this.formattedValue || [];
9338
- // Resolve by key first (the user's exact picks), then fall back to
9339
- // value matching for any values not resolved by key — so pre-selection
9340
- // and programmatic value sets keep working. Result is DOM-ordered.
9341
- const matchingOptions = resolveSelectedOptions(this.items, valueArray, this._selectedKey);
9195
+ const matchingOptions = this.items ? this.items.filter((item) => isSelectableByValue(item) && valueArray.includes(item.value)) : [];
9342
9196
  newSelected = matchingOptions.length > 0 ? matchingOptions : undefined;
9343
9197
 
9344
- // Reconcile `value` with the selectable set. An occurrence is dropped
9345
- // only when it is loaded but no selectable option can satisfy it —
9346
- // every loaded item sharing that value is non-selectable, or the value
9347
- // recurs more often than it has selectable options (a duplicate value
9348
- // whose extra siblings are disabled/static). This is count-based, not
9349
- // presence-based, so an enabled option is kept even when a disabled
9350
- // sibling shares its value — mirroring how `resolveSelectedOptions`
9351
- // resolves the same set. Entries with no matching item yet are
9352
- // preserved so async preselection still works, and the toggle handlers
9353
- // rebuild `value` from `formattedValue`, so a rejected entry cannot
9354
- // resurface on the next select/deselect.
9355
- const selectableByValue = new Map();
9356
- const loadedValues = new Set();
9357
- if (this.items) {
9358
- this.items.forEach((item) => {
9359
- loadedValues.add(item.value);
9360
- if (isSelectableByValue(item)) {
9361
- selectableByValue.set(item.value, (selectableByValue.get(item.value) || 0) + 1);
9362
- }
9363
- });
9364
- }
9365
-
9366
- const reconciled = valueArray.filter((val) => {
9367
- // Not loaded yet (async preselection) — keep for a later cycle.
9368
- if (!loadedValues.has(val)) {
9369
- return true;
9370
- }
9371
- // Consume one selectable option per occurrence; drop once exhausted.
9372
- const remaining = selectableByValue.get(val) || 0;
9373
- if (remaining > 0) {
9374
- selectableByValue.set(val, remaining - 1);
9375
- return true;
9376
- }
9377
- return false;
9378
- });
9379
-
9380
- if (reconciled.length !== valueArray.length) {
9381
- // This is an internal correction, not a consumer's programmatic set,
9382
- // so preserve the selection-driven flag through the re-entrant
9383
- // updated() cycle it schedules. Otherwise that cycle would treat the
9384
- // reassignment as programmatic and drop `_selectedKey` mid-cascade,
9385
- // flipping resolution and looping.
9386
- this._valueChangeFromSelection = true;
9198
+ // Reconcile `value` with the selectable set. Drop only entries whose option is
9199
+ // loaded but non-selectable (disabled/static) — leaving them would desync `value`
9200
+ // from `optionSelected`, and the toggle handlers rebuild `value` from `formattedValue`,
9201
+ // so the rejected entry would resurface on the next select/deselect. Entries with no
9202
+ // matching item yet are preserved so async preselection still works once options render.
9203
+ const rejectedValues = this.items
9204
+ ? this.items.filter((item) => !isSelectableByValue(item) && valueArray.includes(item.value)).map((item) => item.value)
9205
+ : [];
9206
+ if (rejectedValues.length > 0) {
9207
+ const reconciled = valueArray.filter((val) => !rejectedValues.includes(val));
9387
9208
  this.value = serializeMultiSelectValue(reconciled);
9388
9209
  valueReconciled = true;
9389
9210
  }
@@ -9395,11 +9216,7 @@ class AuroMenu extends AuroElement$1 {
9395
9216
  // `hidden` is intentionally NOT excluded: the combobox toggles
9396
9217
  // `hidden` as its type-ahead filter, so a filtered-out option is
9397
9218
  // still a valid programmatic selection.
9398
- // Prefer the option the user actually selected (tracked by
9399
- // `_selectedKey`) so a click on the second of two options sharing a
9400
- // `value` resolves back to that exact element instead of the first
9401
- // value match. Falls back to first-by-value for programmatic sets.
9402
- const matchingOption = resolveSelectedOption(this.items, this.value, this._selectedKey);
9219
+ const matchingOption = this.items ? this.items.find((item) => isSelectableByValue(item) && item.value === this.value) : undefined;
9403
9220
 
9404
9221
  if (matchingOption) {
9405
9222
  newSelected = matchingOption;
@@ -9627,14 +9444,6 @@ class AuroMenu extends AuroElement$1 {
9627
9444
  }
9628
9445
  });
9629
9446
 
9630
- // Assign private keys once items are populated. Only the root menu assigns
9631
- // keys: its `items` is a deep query that already includes nested submenu
9632
- // options, so a single pass keys the entire tree. Nested menus skip this
9633
- // and inherit keys from the root.
9634
- if (this.rootMenu) {
9635
- this._assignOptionKeys();
9636
- }
9637
-
9638
9447
  if (this.noCheckmark) {
9639
9448
  this.updateItemsState(new Map([
9640
9449
  [
@@ -9651,31 +9460,6 @@ class AuroMenu extends AuroElement$1 {
9651
9460
  }));
9652
9461
  }
9653
9462
 
9654
- /**
9655
- * Assigns a private, auto-generated unique key (`_optionKey`) to each menu
9656
- * option that does not already have one. Keys are internal state on the
9657
- * element instance — never reflected as an attribute or exposed publicly —
9658
- * and let selection tracking distinguish options that share the same `value`.
9659
- *
9660
- * The `_optionKey === undefined` guard makes this idempotent: options keep the
9661
- * key they were first assigned across re-renders and slot changes, and if a
9662
- * nested menu's lifecycle runs a pass before the root, options simply wait for
9663
- * the root to key them (or keep whatever key they already hold).
9664
- * @private
9665
- */
9666
- _assignOptionKeys() {
9667
- if (!this.items) {
9668
- return;
9669
- }
9670
-
9671
- this.items.forEach((option) => {
9672
- if (option._optionKey === undefined) {
9673
- this._optionKeyCounter += 1;
9674
- option._optionKey = `${this._menuInstanceId}-${this._optionKeyCounter}`;
9675
- }
9676
- });
9677
- }
9678
-
9679
9463
  // Logic Methods
9680
9464
 
9681
9465
  /**
@@ -9685,28 +9469,24 @@ class AuroMenu extends AuroElement$1 {
9685
9469
  */
9686
9470
  handleSelectState(option) {
9687
9471
  if (this.multiSelect) {
9472
+ const currentValue = this.formattedValue || [];
9688
9473
  const currentSelected = this.optionSelected || [];
9689
9474
 
9475
+ if (!currentValue.includes(option.value)) {
9476
+ this.value = serializeMultiSelectValue([
9477
+ ...currentValue,
9478
+ option.value
9479
+ ]);
9480
+ }
9690
9481
  if (!currentSelected.includes(option)) {
9691
9482
  this.optionSelected = [
9692
9483
  ...currentSelected,
9693
9484
  option
9694
9485
  ];
9695
9486
  }
9696
-
9697
- // Re-sort by DOM order and rebuild `_selectedKey`/`value` from the
9698
- // selected set so display order stays consistent with the menu, not with
9699
- // click order.
9700
- this._sortSelectedByDomOrder();
9701
9487
  } else {
9702
9488
  this.value = option.value;
9703
9489
  this.optionSelected = option;
9704
- // Track the specific option the user selected so the value→option
9705
- // reconciliation in updated() resolves back to this exact element even
9706
- // when another option shares the same `value`.
9707
- this._selectedKey = option._optionKey;
9708
- // Mark this `value` change as selection-driven so updated() trusts the key.
9709
- this._valueChangeFromSelection = true;
9710
9490
  }
9711
9491
 
9712
9492
  this._index = this.items.indexOf(option);
@@ -9719,22 +9499,18 @@ class AuroMenu extends AuroElement$1 {
9719
9499
  */
9720
9500
  handleDeselectState(option) {
9721
9501
  if (this.multiSelect) {
9722
- // Remove this exact element from the selection (identity, not value — two
9723
- // options can share a `value`), then rebuild `value`/`_selectedKey` from
9724
- // the remaining set in DOM order. An empty result collapses to undefined.
9725
- this.optionSelected = this.optionSelected.filter((selected) => selected !== option);
9502
+ // Remove this option from array; an empty result collapses `value` to undefined.
9503
+ const newFormattedValue = (this.formattedValue || []).filter((val) => val !== option.value);
9504
+ this.value = serializeMultiSelectValue(newFormattedValue);
9505
+
9506
+ this.optionSelected = this.optionSelected.filter((val) => val !== option);
9726
9507
  if (this.optionSelected.length === 0) {
9727
9508
  this.optionSelected = undefined;
9728
- this._selectedKey = undefined;
9729
- this.value = undefined;
9730
- } else {
9731
- this._sortSelectedByDomOrder();
9732
9509
  }
9733
9510
  } else {
9734
9511
  // For single-select: Back to undefined when deselected
9735
9512
  this.value = undefined;
9736
9513
  this.optionSelected = undefined;
9737
- this._selectedKey = undefined;
9738
9514
  }
9739
9515
 
9740
9516
  // Update the index tracking
@@ -9758,38 +9534,9 @@ class AuroMenu extends AuroElement$1 {
9758
9534
  clearSelection() {
9759
9535
  this.optionSelected = undefined;
9760
9536
  this.value = undefined;
9761
- this._selectedKey = undefined;
9762
9537
  this._index = -1;
9763
9538
  }
9764
9539
 
9765
- /**
9766
- * Re-sorts the multi-select selection into DOM order and rebuilds the derived
9767
- * `_selectedKey` and `value` from `optionSelected`. Selection is always stored
9768
- * and serialized in the order options appear in the menu, never in click
9769
- * order — so selecting C then A yields `[A, C]`.
9770
- * @private
9771
- */
9772
- _sortSelectedByDomOrder() {
9773
- if (!this.multiSelect || !Array.isArray(this.optionSelected) || !this.items) {
9774
- return;
9775
- }
9776
-
9777
- const indexMap = new Map(this.items.map((item, index) => [
9778
- item,
9779
- index
9780
- ]));
9781
-
9782
- // Sort any element no longer in `items` (a stale selection left over from a
9783
- // dynamic rebuild that the consumer has not cleared) to the END rather than
9784
- // the front, so it never displaces a live option to the head of the
9785
- // serialized order. Value reconciliation drops it on the next updated() cycle.
9786
- this.optionSelected.sort((optionA, optionB) => (indexMap.get(optionA) ?? this.items.length) - (indexMap.get(optionB) ?? this.items.length));
9787
- this._selectedKey = this.optionSelected.map((option) => option._optionKey);
9788
- this.value = serializeMultiSelectValue(this.optionSelected.map((option) => option.value));
9789
- // Mark this `value` change as selection-driven so updated() trusts the keys.
9790
- this._valueChangeFromSelection = true;
9791
- }
9792
-
9793
9540
  /**
9794
9541
  * Resets the menu to its initial state.
9795
9542
  * This is the only way to return value to undefined.
@@ -9799,7 +9546,6 @@ class AuroMenu extends AuroElement$1 {
9799
9546
  // Reset to undefined - initial state
9800
9547
  this.value = undefined;
9801
9548
  this.optionSelected = undefined;
9802
- this._selectedKey = undefined;
9803
9549
  this._index = -1;
9804
9550
 
9805
9551
  // Clear active option state so a follow-up open/navigation starts fresh
@@ -9861,19 +9607,6 @@ class AuroMenu extends AuroElement$1 {
9861
9607
  this.initItems();
9862
9608
  }
9863
9609
 
9864
- // Recover `_index` from the highlighted option when it has been reset to -1.
9865
- // In multi-select, deselecting the last remaining option collapses the value
9866
- // to undefined, and the updated() reconciliation resets `_index = -1` even
9867
- // though `optionActive` still points at the highlighted option. Without this,
9868
- // reading `items[-1]` returns undefined and the re-select no-ops until the
9869
- // highlight is moved away and back. Mirrors auro-combobox's reconcileMenuIndex.
9870
- if (this._index < 0 && this.optionActive && this.items) {
9871
- const activeIndex = this.items.indexOf(this.optionActive);
9872
- if (activeIndex >= 0) {
9873
- this._index = activeIndex;
9874
- }
9875
- }
9876
-
9877
9610
  // Get currently selected menu option based on index
9878
9611
  const option = this.items ? this.items[this._index] : undefined;
9879
9612