@aurodesignsystem-dev/auro-formkit 0.0.0-pr1540.0 → 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.
- package/components/checkbox/demo/accessibility.md +1 -1
- 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/accessibility.md +1 -1
- package/components/combobox/demo/api.md +2 -2
- package/components/combobox/demo/customize.md +54 -2
- package/components/combobox/demo/customize.min.js +421 -240
- package/components/combobox/demo/getting-started.min.js +421 -240
- package/components/combobox/demo/index.md +1 -0
- package/components/combobox/demo/index.min.js +421 -240
- package/components/combobox/demo/keyboard-behavior.md +1 -4
- package/components/combobox/dist/auro-combobox.d.ts +4 -1
- package/components/combobox/dist/index.js +334 -222
- package/components/combobox/dist/registered.js +334 -222
- package/components/counter/demo/customize.min.js +59 -222
- package/components/counter/demo/index.min.js +59 -222
- package/components/counter/dist/auro-counter.d.ts +0 -8
- package/components/counter/dist/index.js +59 -222
- package/components/counter/dist/registered.js +59 -222
- package/components/datepicker/demo/accessibility.md +1 -1
- package/components/datepicker/demo/customize.md +30 -1
- package/components/datepicker/demo/customize.min.js +84 -220
- package/components/datepicker/demo/getting-started.md +118 -2
- package/components/datepicker/demo/index.min.js +84 -220
- package/components/datepicker/dist/index.js +84 -220
- package/components/datepicker/dist/registered.js +84 -220
- package/components/dropdown/demo/customize.html +3 -0
- package/components/dropdown/demo/customize.min.js +55 -206
- package/components/dropdown/demo/getting-started.min.js +44 -205
- package/components/dropdown/demo/index.min.js +44 -205
- package/components/dropdown/dist/index.js +44 -205
- package/components/dropdown/dist/registered.js +44 -205
- package/components/form/demo/customize.min.js +670 -945
- package/components/form/demo/getting-started.min.js +670 -945
- package/components/form/demo/index.min.js +670 -945
- package/components/form/demo/registerDemoDeps.min.js +670 -945
- package/components/input/demo/accessibility.md +1 -1
- 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/accessibility.md +9 -4
- package/components/menu/demo/api.md +26 -19
- package/components/menu/demo/css-only.md +26 -19
- package/components/menu/demo/customize.md +307 -47
- package/components/menu/demo/design.md +1 -1
- package/components/menu/demo/getting-started.md +144 -7
- package/components/menu/demo/index.min.js +214 -19
- package/components/menu/demo/keyboard-behavior.md +83 -4
- package/components/menu/demo/voiceover.md +21 -14
- package/components/menu/demo/why-menu.md +8 -9
- package/components/menu/dist/auro-menu-utils.d.ts +19 -0
- package/components/menu/dist/auro-menu.d.ts +4 -8
- package/components/menu/dist/auro-menuoption.d.ts +12 -0
- package/components/menu/dist/index.js +87 -18
- package/components/menu/dist/registered.js +87 -18
- package/components/radio/demo/accessibility.md +1 -1
- 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/accessibility.md +6 -1
- package/components/select/demo/api.md +2 -2
- package/components/select/demo/customize.md +6 -3
- package/components/select/demo/customize.min.js +139 -227
- package/components/select/demo/design.md +10 -10
- package/components/select/demo/getting-started.md +1 -1
- package/components/select/demo/getting-started.min.js +139 -227
- package/components/select/demo/index.md +2 -2
- package/components/select/demo/index.min.js +139 -227
- package/components/select/demo/keyboard-behavior.md +53 -58
- package/components/select/demo/voiceover.md +28 -15
- package/components/select/dist/auro-select.d.ts +6 -2
- package/components/select/dist/index.js +52 -209
- package/components/select/dist/registered.js +52 -209
- package/custom-elements.json +1611 -1552
- 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
|
|
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
|
|
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
|
-
|
|
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 = '
|
|
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
|
-
|
|
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:
|
|
5983
|
-
//
|
|
5984
|
-
//
|
|
5985
|
-
//
|
|
5986
|
-
//
|
|
5987
|
-
|
|
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
|
-
|
|
5990
|
-
|
|
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 = '
|
|
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:
|
|
8880
|
+
attribute: false
|
|
9011
8881
|
},
|
|
9012
8882
|
|
|
9013
8883
|
/**
|
|
9014
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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"
|
|
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"
|
|
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"
|
|
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"
|
|
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"
|
|
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
|
<span slot="helpText">Help Text</span>
|
|
369
369
|
<auro-menu nocheckmark>
|
|
370
370
|
<auro-menuoption value="flights">
|
|
371
|
-
<auro-icon category="terminal" name="plane-diag-stroke"
|
|
371
|
+
<auro-icon category="terminal" name="plane-diag-stroke" customcolor></auro-icon> Flights
|
|
372
372
|
</auro-menuoption>
|
|
373
373
|
<auro-menuoption value="cars">
|
|
374
|
-
<auro-icon category="destination" name="car-rental-stroke"
|
|
374
|
+
<auro-icon category="destination" name="car-rental-stroke" customcolor></auro-icon> Cars
|
|
375
375
|
</auro-menuoption>
|
|
376
376
|
<auro-menuoption value="hotels">
|
|
377
|
-
<auro-icon category="destination" name="hotel-stroke"
|
|
377
|
+
<auro-icon category="destination" name="hotel-stroke" customcolor></auro-icon> Hotels
|
|
378
378
|
</auro-menuoption>
|
|
379
379
|
<auro-menuoption value="packages">
|
|
380
|
-
<auro-icon category="shop" name="gift-stroke"
|
|
380
|
+
<auro-icon category="shop" name="gift-stroke" customcolor></auro-icon> Packages
|
|
381
381
|
</auro-menuoption>
|
|
382
382
|
<auro-menuoption value="cruises">
|
|
383
|
-
<auro-icon category="in-flight" name="boarding"
|
|
383
|
+
<auro-icon category="in-flight" name="boarding" customcolor></auro-icon> Cruises
|
|
384
384
|
</auro-menuoption>
|
|
385
385
|
</auro-menu>
|
|
386
386
|
</auro-select></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>
|