@aurodesignsystem-dev/auro-formkit 0.0.0-pr1574.0 → 0.0.0-pr1576.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/checkbox/demo/customize.min.js +1 -1
- package/components/checkbox/demo/getting-started.min.js +1 -1
- package/components/checkbox/demo/index.min.js +1 -1
- package/components/checkbox/dist/index.js +1 -1
- package/components/checkbox/dist/registered.js +1 -1
- package/components/combobox/demo/customize.md +40 -0
- package/components/combobox/demo/customize.min.js +256 -17
- package/components/combobox/demo/getting-started.min.js +256 -17
- package/components/combobox/demo/index.min.js +256 -17
- package/components/combobox/dist/index.js +3 -3
- package/components/combobox/dist/registered.js +3 -3
- package/components/counter/demo/customize.min.js +3 -3
- package/components/counter/demo/index.min.js +3 -3
- package/components/counter/dist/index.js +3 -3
- package/components/counter/dist/registered.js +3 -3
- package/components/datepicker/demo/customize.min.js +3 -3
- package/components/datepicker/demo/index.min.js +3 -3
- package/components/datepicker/dist/index.js +3 -3
- package/components/datepicker/dist/registered.js +3 -3
- package/components/dropdown/demo/customize.min.js +1 -1
- package/components/dropdown/demo/getting-started.min.js +1 -1
- package/components/dropdown/demo/index.min.js +1 -1
- package/components/dropdown/dist/index.js +1 -1
- package/components/dropdown/dist/registered.js +1 -1
- package/components/form/demo/customize.min.js +267 -28
- package/components/form/demo/getting-started.min.js +267 -28
- package/components/form/demo/index.min.js +267 -28
- package/components/form/demo/registerDemoDeps.min.js +267 -28
- package/components/input/demo/customize.min.js +1 -1
- package/components/input/demo/getting-started.min.js +1 -1
- package/components/input/demo/index.min.js +1 -1
- package/components/input/dist/index.js +1 -1
- package/components/input/dist/registered.js +1 -1
- package/components/menu/demo/index.min.js +253 -14
- package/components/menu/dist/auro-menu-utils.d.ts +30 -0
- package/components/menu/dist/auro-menu.d.ts +23 -0
- package/components/menu/dist/index.js +253 -14
- package/components/menu/dist/registered.js +253 -14
- package/components/radio/demo/customize.min.js +1 -1
- package/components/radio/demo/getting-started.min.js +1 -1
- package/components/radio/demo/index.min.js +1 -1
- package/components/radio/dist/index.js +1 -1
- package/components/radio/dist/registered.js +1 -1
- package/components/select/demo/customize.md +72 -0
- package/components/select/demo/customize.min.js +255 -16
- package/components/select/demo/getting-started.min.js +255 -16
- package/components/select/demo/index.min.js +255 -16
- package/components/select/dist/index.js +2 -2
- package/components/select/dist/registered.js +2 -2
- package/custom-elements.json +1617 -1513
- 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 = '
|
|
4839
|
+
var formkitVersion$1 = '202608040326';
|
|
4840
4840
|
|
|
4841
4841
|
class AuroElement extends i$2 {
|
|
4842
4842
|
static get properties() {
|
|
@@ -6938,7 +6938,7 @@ class AuroHelpText extends i$2 {
|
|
|
6938
6938
|
}
|
|
6939
6939
|
}
|
|
6940
6940
|
|
|
6941
|
-
var formkitVersion = '
|
|
6941
|
+
var formkitVersion = '202608040326';
|
|
6942
6942
|
|
|
6943
6943
|
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
6944
|
|
|
@@ -8769,6 +8769,107 @@ function isSelectableByValue(option) {
|
|
|
8769
8769
|
!option.hasAttribute('static');
|
|
8770
8770
|
}
|
|
8771
8771
|
|
|
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
|
+
|
|
8772
8873
|
/**
|
|
8773
8874
|
* Helper method to dispatch custom events.
|
|
8774
8875
|
* @param {HTMLElement} element - Element to dispatch event from.
|
|
@@ -8794,6 +8895,14 @@ function dispatchMenuEvent(element, eventName, detail = null) {
|
|
|
8794
8895
|
// See LICENSE in the project root for license information.
|
|
8795
8896
|
|
|
8796
8897
|
|
|
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
|
+
|
|
8797
8906
|
|
|
8798
8907
|
/**
|
|
8799
8908
|
* The `auro-menu` element provides users a way to select from a list of options.
|
|
@@ -8868,6 +8977,8 @@ class AuroMenu extends AuroElement$1 {
|
|
|
8868
8977
|
/**
|
|
8869
8978
|
* @private
|
|
8870
8979
|
*/
|
|
8980
|
+
menuInstanceIdCounter += 1;
|
|
8981
|
+
|
|
8871
8982
|
Object.assign(this, {
|
|
8872
8983
|
// Root-level menu (true) or a nested submenu (false)
|
|
8873
8984
|
rootMenu: true,
|
|
@@ -8877,6 +8988,21 @@ class AuroMenu extends AuroElement$1 {
|
|
|
8877
8988
|
nestingSpacer: '<span class="nestingSpacer"></span>',
|
|
8878
8989
|
// Loading indicator for slot elements
|
|
8879
8990
|
loadingSlots: null,
|
|
8991
|
+
// Unique id for this menu instance; prefixes every auto-generated option
|
|
8992
|
+
// key so keys never collide across menus in the same document.
|
|
8993
|
+
_menuInstanceId: `menu-${menuInstanceIdCounter}`,
|
|
8994
|
+
// Monotonically increasing counter for option key generation. Never
|
|
8995
|
+
// resets, so a key is never reused within this instance's lifetime.
|
|
8996
|
+
_optionKeyCounter: 0,
|
|
8997
|
+
// Key(s) of the option(s) the user has actively selected. A single string
|
|
8998
|
+
// in single-select, an array in multi-select, undefined when nothing is
|
|
8999
|
+
// user-selected. Used to disambiguate options that share a `value`.
|
|
9000
|
+
_selectedKey: undefined,
|
|
9001
|
+
// True only for the one updated() cycle following a user selection, so
|
|
9002
|
+
// reconciliation trusts `_selectedKey`. A `value` change from a consumer's
|
|
9003
|
+
// direct property assignment leaves this false, dropping the stale key so
|
|
9004
|
+
// reconciliation falls back to first-by-value (see updated()).
|
|
9005
|
+
_valueChangeFromSelection: false,
|
|
8880
9006
|
});
|
|
8881
9007
|
}
|
|
8882
9008
|
|
|
@@ -9096,6 +9222,13 @@ class AuroMenu extends AuroElement$1 {
|
|
|
9096
9222
|
return;
|
|
9097
9223
|
}
|
|
9098
9224
|
|
|
9225
|
+
// A programmatic value set carries no positional intent, so drop any
|
|
9226
|
+
// `_selectedKey` left over from a prior user click. This makes reconciliation
|
|
9227
|
+
// in updated() fall back to first-by-value (single) / value-in-DOM-order
|
|
9228
|
+
// (multi), matching the documented contract for programmatic selection even
|
|
9229
|
+
// when a stale key would still resolve to a duplicate-value option.
|
|
9230
|
+
this._selectedKey = undefined;
|
|
9231
|
+
|
|
9099
9232
|
// `value` is a String property; stringify arrays so attribute reflection and `formattedValue` parsing stay correct.
|
|
9100
9233
|
this.value = Array.isArray(value) ? JSON.stringify(value) : value;
|
|
9101
9234
|
}
|
|
@@ -9143,6 +9276,17 @@ class AuroMenu extends AuroElement$1 {
|
|
|
9143
9276
|
updated(changedProperties) {
|
|
9144
9277
|
super.updated(changedProperties);
|
|
9145
9278
|
|
|
9279
|
+
// Consume the selection-driven flag for THIS cycle up front. Clearing it
|
|
9280
|
+
// unconditionally — not only inside the `value` branch below — prevents it
|
|
9281
|
+
// from lingering `true` when a selection produces a serialized `value`
|
|
9282
|
+
// byte-identical to the current one, in which case Lit schedules no
|
|
9283
|
+
// `value`-change cycle to consume it. A lingering flag would misclassify a
|
|
9284
|
+
// later consumer's programmatic `value` set as selection-driven and keep a
|
|
9285
|
+
// stale `_selectedKey`. The reconcile path below re-sets the instance flag
|
|
9286
|
+
// after this point, so its intentional cross-cycle hand-off still works.
|
|
9287
|
+
const valueChangeFromSelection = this._valueChangeFromSelection;
|
|
9288
|
+
this._valueChangeFromSelection = false;
|
|
9289
|
+
|
|
9146
9290
|
// Single source of truth for 'auroMenu-selectedOption'. Selection handlers
|
|
9147
9291
|
// mutate optionSelected and let Lit's update cycle dispatch here; the prior
|
|
9148
9292
|
// .value comparison missed multi-select array changes and combined with the
|
|
@@ -9166,6 +9310,17 @@ class AuroMenu extends AuroElement$1 {
|
|
|
9166
9310
|
this.initItems();
|
|
9167
9311
|
}
|
|
9168
9312
|
|
|
9313
|
+
// Distinguish a selection-driven `value` change (a user click, which set
|
|
9314
|
+
// the flag in handleSelectState / _sortSelectedByDomOrder) from a
|
|
9315
|
+
// programmatic assignment by a consumer. A programmatic set carries no
|
|
9316
|
+
// positional intent, so drop any leftover `_selectedKey` and let
|
|
9317
|
+
// reconciliation fall back to first-by-value (single) / value-in-DOM-order
|
|
9318
|
+
// (multi) — the same contract selectByValue() guarantees, even when a
|
|
9319
|
+
// stale key would otherwise still resolve to a duplicate-value option.
|
|
9320
|
+
if (!valueChangeFromSelection) {
|
|
9321
|
+
this._selectedKey = undefined;
|
|
9322
|
+
}
|
|
9323
|
+
|
|
9169
9324
|
// Set when reconciliation reassigns `value` below. That reassignment schedules a
|
|
9170
9325
|
// second updated() cycle, so the `event`-attribute dispatch is deferred to that
|
|
9171
9326
|
// cycle to avoid firing option custom events twice on the same selection.
|
|
@@ -9183,7 +9338,10 @@ class AuroMenu extends AuroElement$1 {
|
|
|
9183
9338
|
// Defensive default: `formattedValue` can be undefined for unexpected value types,
|
|
9184
9339
|
// and calling `.includes` on undefined would throw during reconciliation.
|
|
9185
9340
|
const valueArray = this.formattedValue || [];
|
|
9186
|
-
|
|
9341
|
+
// Resolve by key first (the user's exact picks), then fall back to
|
|
9342
|
+
// value matching for any values not resolved by key — so pre-selection
|
|
9343
|
+
// and programmatic value sets keep working. Result is DOM-ordered.
|
|
9344
|
+
const matchingOptions = resolveSelectedOptions(this.items, valueArray, this._selectedKey);
|
|
9187
9345
|
newSelected = matchingOptions.length > 0 ? matchingOptions : undefined;
|
|
9188
9346
|
|
|
9189
9347
|
// Reconcile `value` with the selectable set. Drop only entries whose option is
|
|
@@ -9196,6 +9354,12 @@ class AuroMenu extends AuroElement$1 {
|
|
|
9196
9354
|
: [];
|
|
9197
9355
|
if (rejectedValues.length > 0) {
|
|
9198
9356
|
const reconciled = valueArray.filter((val) => !rejectedValues.includes(val));
|
|
9357
|
+
// This is an internal correction, not a consumer's programmatic set,
|
|
9358
|
+
// so preserve the selection-driven flag through the re-entrant
|
|
9359
|
+
// updated() cycle it schedules. Otherwise that cycle would treat the
|
|
9360
|
+
// reassignment as programmatic and drop `_selectedKey` mid-cascade,
|
|
9361
|
+
// flipping resolution and looping.
|
|
9362
|
+
this._valueChangeFromSelection = true;
|
|
9199
9363
|
this.value = serializeMultiSelectValue(reconciled);
|
|
9200
9364
|
valueReconciled = true;
|
|
9201
9365
|
}
|
|
@@ -9207,7 +9371,11 @@ class AuroMenu extends AuroElement$1 {
|
|
|
9207
9371
|
// `hidden` is intentionally NOT excluded: the combobox toggles
|
|
9208
9372
|
// `hidden` as its type-ahead filter, so a filtered-out option is
|
|
9209
9373
|
// still a valid programmatic selection.
|
|
9210
|
-
|
|
9374
|
+
// Prefer the option the user actually selected (tracked by
|
|
9375
|
+
// `_selectedKey`) so a click on the second of two options sharing a
|
|
9376
|
+
// `value` resolves back to that exact element instead of the first
|
|
9377
|
+
// value match. Falls back to first-by-value for programmatic sets.
|
|
9378
|
+
const matchingOption = resolveSelectedOption(this.items, this.value, this._selectedKey);
|
|
9211
9379
|
|
|
9212
9380
|
if (matchingOption) {
|
|
9213
9381
|
newSelected = matchingOption;
|
|
@@ -9435,6 +9603,14 @@ class AuroMenu extends AuroElement$1 {
|
|
|
9435
9603
|
}
|
|
9436
9604
|
});
|
|
9437
9605
|
|
|
9606
|
+
// Assign private keys once items are populated. Only the root menu assigns
|
|
9607
|
+
// keys: its `items` is a deep query that already includes nested submenu
|
|
9608
|
+
// options, so a single pass keys the entire tree. Nested menus skip this
|
|
9609
|
+
// and inherit keys from the root.
|
|
9610
|
+
if (this.rootMenu) {
|
|
9611
|
+
this._assignOptionKeys();
|
|
9612
|
+
}
|
|
9613
|
+
|
|
9438
9614
|
if (this.noCheckmark) {
|
|
9439
9615
|
this.updateItemsState(new Map([
|
|
9440
9616
|
[
|
|
@@ -9451,6 +9627,31 @@ class AuroMenu extends AuroElement$1 {
|
|
|
9451
9627
|
}));
|
|
9452
9628
|
}
|
|
9453
9629
|
|
|
9630
|
+
/**
|
|
9631
|
+
* Assigns a private, auto-generated unique key (`_optionKey`) to each menu
|
|
9632
|
+
* option that does not already have one. Keys are internal state on the
|
|
9633
|
+
* element instance — never reflected as an attribute or exposed publicly —
|
|
9634
|
+
* and let selection tracking distinguish options that share the same `value`.
|
|
9635
|
+
*
|
|
9636
|
+
* The `_optionKey === undefined` guard makes this idempotent: options keep the
|
|
9637
|
+
* key they were first assigned across re-renders and slot changes, and if a
|
|
9638
|
+
* nested menu's lifecycle runs a pass before the root, options simply wait for
|
|
9639
|
+
* the root to key them (or keep whatever key they already hold).
|
|
9640
|
+
* @private
|
|
9641
|
+
*/
|
|
9642
|
+
_assignOptionKeys() {
|
|
9643
|
+
if (!this.items) {
|
|
9644
|
+
return;
|
|
9645
|
+
}
|
|
9646
|
+
|
|
9647
|
+
this.items.forEach((option) => {
|
|
9648
|
+
if (option._optionKey === undefined) {
|
|
9649
|
+
this._optionKeyCounter += 1;
|
|
9650
|
+
option._optionKey = `${this._menuInstanceId}-${this._optionKeyCounter}`;
|
|
9651
|
+
}
|
|
9652
|
+
});
|
|
9653
|
+
}
|
|
9654
|
+
|
|
9454
9655
|
// Logic Methods
|
|
9455
9656
|
|
|
9456
9657
|
/**
|
|
@@ -9460,24 +9661,28 @@ class AuroMenu extends AuroElement$1 {
|
|
|
9460
9661
|
*/
|
|
9461
9662
|
handleSelectState(option) {
|
|
9462
9663
|
if (this.multiSelect) {
|
|
9463
|
-
const currentValue = this.formattedValue || [];
|
|
9464
9664
|
const currentSelected = this.optionSelected || [];
|
|
9465
9665
|
|
|
9466
|
-
if (!currentValue.includes(option.value)) {
|
|
9467
|
-
this.value = serializeMultiSelectValue([
|
|
9468
|
-
...currentValue,
|
|
9469
|
-
option.value
|
|
9470
|
-
]);
|
|
9471
|
-
}
|
|
9472
9666
|
if (!currentSelected.includes(option)) {
|
|
9473
9667
|
this.optionSelected = [
|
|
9474
9668
|
...currentSelected,
|
|
9475
9669
|
option
|
|
9476
9670
|
];
|
|
9477
9671
|
}
|
|
9672
|
+
|
|
9673
|
+
// Re-sort by DOM order and rebuild `_selectedKey`/`value` from the
|
|
9674
|
+
// selected set so display order stays consistent with the menu, not with
|
|
9675
|
+
// click order.
|
|
9676
|
+
this._sortSelectedByDomOrder();
|
|
9478
9677
|
} else {
|
|
9479
9678
|
this.value = option.value;
|
|
9480
9679
|
this.optionSelected = option;
|
|
9680
|
+
// Track the specific option the user selected so the value→option
|
|
9681
|
+
// reconciliation in updated() resolves back to this exact element even
|
|
9682
|
+
// when another option shares the same `value`.
|
|
9683
|
+
this._selectedKey = option._optionKey;
|
|
9684
|
+
// Mark this `value` change as selection-driven so updated() trusts the key.
|
|
9685
|
+
this._valueChangeFromSelection = true;
|
|
9481
9686
|
}
|
|
9482
9687
|
|
|
9483
9688
|
this._index = this.items.indexOf(option);
|
|
@@ -9490,18 +9695,22 @@ class AuroMenu extends AuroElement$1 {
|
|
|
9490
9695
|
*/
|
|
9491
9696
|
handleDeselectState(option) {
|
|
9492
9697
|
if (this.multiSelect) {
|
|
9493
|
-
// Remove this
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
this.optionSelected = this.optionSelected.filter((val) => val !== option);
|
|
9698
|
+
// Remove this exact element from the selection (identity, not value — two
|
|
9699
|
+
// options can share a `value`), then rebuild `value`/`_selectedKey` from
|
|
9700
|
+
// the remaining set in DOM order. An empty result collapses to undefined.
|
|
9701
|
+
this.optionSelected = this.optionSelected.filter((selected) => selected !== option);
|
|
9498
9702
|
if (this.optionSelected.length === 0) {
|
|
9499
9703
|
this.optionSelected = undefined;
|
|
9704
|
+
this._selectedKey = undefined;
|
|
9705
|
+
this.value = undefined;
|
|
9706
|
+
} else {
|
|
9707
|
+
this._sortSelectedByDomOrder();
|
|
9500
9708
|
}
|
|
9501
9709
|
} else {
|
|
9502
9710
|
// For single-select: Back to undefined when deselected
|
|
9503
9711
|
this.value = undefined;
|
|
9504
9712
|
this.optionSelected = undefined;
|
|
9713
|
+
this._selectedKey = undefined;
|
|
9505
9714
|
}
|
|
9506
9715
|
|
|
9507
9716
|
// Update the index tracking
|
|
@@ -9525,9 +9734,38 @@ class AuroMenu extends AuroElement$1 {
|
|
|
9525
9734
|
clearSelection() {
|
|
9526
9735
|
this.optionSelected = undefined;
|
|
9527
9736
|
this.value = undefined;
|
|
9737
|
+
this._selectedKey = undefined;
|
|
9528
9738
|
this._index = -1;
|
|
9529
9739
|
}
|
|
9530
9740
|
|
|
9741
|
+
/**
|
|
9742
|
+
* Re-sorts the multi-select selection into DOM order and rebuilds the derived
|
|
9743
|
+
* `_selectedKey` and `value` from `optionSelected`. Selection is always stored
|
|
9744
|
+
* and serialized in the order options appear in the menu, never in click
|
|
9745
|
+
* order — so selecting C then A yields `[A, C]`.
|
|
9746
|
+
* @private
|
|
9747
|
+
*/
|
|
9748
|
+
_sortSelectedByDomOrder() {
|
|
9749
|
+
if (!this.multiSelect || !Array.isArray(this.optionSelected) || !this.items) {
|
|
9750
|
+
return;
|
|
9751
|
+
}
|
|
9752
|
+
|
|
9753
|
+
const indexMap = new Map(this.items.map((item, index) => [
|
|
9754
|
+
item,
|
|
9755
|
+
index
|
|
9756
|
+
]));
|
|
9757
|
+
|
|
9758
|
+
// Sort any element no longer in `items` (a stale selection left over from a
|
|
9759
|
+
// dynamic rebuild that the consumer has not cleared) to the END rather than
|
|
9760
|
+
// the front, so it never displaces a live option to the head of the
|
|
9761
|
+
// serialized order. Value reconciliation drops it on the next updated() cycle.
|
|
9762
|
+
this.optionSelected.sort((optionA, optionB) => (indexMap.get(optionA) ?? this.items.length) - (indexMap.get(optionB) ?? this.items.length));
|
|
9763
|
+
this._selectedKey = this.optionSelected.map((option) => option._optionKey);
|
|
9764
|
+
this.value = serializeMultiSelectValue(this.optionSelected.map((option) => option.value));
|
|
9765
|
+
// Mark this `value` change as selection-driven so updated() trusts the keys.
|
|
9766
|
+
this._valueChangeFromSelection = true;
|
|
9767
|
+
}
|
|
9768
|
+
|
|
9531
9769
|
/**
|
|
9532
9770
|
* Resets the menu to its initial state.
|
|
9533
9771
|
* This is the only way to return value to undefined.
|
|
@@ -9537,6 +9775,7 @@ class AuroMenu extends AuroElement$1 {
|
|
|
9537
9775
|
// Reset to undefined - initial state
|
|
9538
9776
|
this.value = undefined;
|
|
9539
9777
|
this.optionSelected = undefined;
|
|
9778
|
+
this._selectedKey = undefined;
|
|
9540
9779
|
this._index = -1;
|
|
9541
9780
|
|
|
9542
9781
|
// Clear active option state so a follow-up open/navigation starts fresh
|