@aurodesignsystem-dev/auro-formkit 0.0.0-pr1576.8 → 0.0.0-pr1577.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/combobox/demo/customize.md +0 -40
- package/components/combobox/demo/customize.min.js +62 -365
- package/components/combobox/demo/getting-started.min.js +62 -365
- package/components/combobox/demo/index.min.js +62 -365
- package/components/combobox/dist/index.js +35 -53
- package/components/combobox/dist/registered.js +35 -53
- package/components/counter/demo/customize.min.js +9 -0
- package/components/counter/demo/index.min.js +9 -0
- package/components/counter/dist/index.js +9 -0
- package/components/counter/dist/registered.js +9 -0
- package/components/datepicker/demo/customize.min.js +9 -0
- package/components/datepicker/demo/index.min.js +9 -0
- package/components/datepicker/dist/index.js +9 -0
- package/components/datepicker/dist/registered.js +9 -0
- package/components/dropdown/demo/customize.min.js +9 -0
- package/components/dropdown/demo/getting-started.min.js +9 -0
- package/components/dropdown/demo/index.min.js +9 -0
- package/components/dropdown/dist/index.js +9 -0
- package/components/dropdown/dist/registered.js +9 -0
- package/components/form/demo/customize.min.js +89 -365
- package/components/form/demo/getting-started.min.js +89 -365
- package/components/form/demo/index.min.js +89 -365
- package/components/form/demo/registerDemoDeps.min.js +89 -365
- package/components/menu/demo/customize.md +0 -50
- package/components/menu/demo/index.min.js +27 -312
- package/components/menu/dist/auro-menu-utils.d.ts +0 -30
- package/components/menu/dist/auro-menu.d.ts +0 -23
- package/components/menu/dist/index.js +27 -312
- package/components/menu/dist/registered.js +27 -312
- package/components/select/demo/customize.md +0 -72
- package/components/select/demo/customize.min.js +36 -312
- package/components/select/demo/getting-started.min.js +36 -312
- package/components/select/demo/index.min.js +36 -312
- package/components/select/dist/index.js +9 -0
- package/components/select/dist/registered.js +9 -0
- package/custom-elements.json +1510 -1613
- package/package.json +1 -1
|
@@ -33204,6 +33204,15 @@ let AuroDropdown$3 = class AuroDropdown extends AuroElement$2$2 {
|
|
|
33204
33204
|
|
|
33205
33205
|
connectedCallback() {
|
|
33206
33206
|
super.connectedCallback();
|
|
33207
|
+
// Re-register trigger event listeners removed by floater.disconnect() in
|
|
33208
|
+
// disconnectedCallback(). Fires when a parent element (e.g. auro-drawer)
|
|
33209
|
+
// moves this element to a new DOM location. firstUpdated() won't re-run,
|
|
33210
|
+
// so without this the trigger click/keydown handlers are permanently gone.
|
|
33211
|
+
// Guard on floater.element so this is a no-op on the initial connect
|
|
33212
|
+
// (before firstUpdated() has called configure()).
|
|
33213
|
+
if (this.floater?.element) {
|
|
33214
|
+
this.floater.configure(this, 'auroDropdown', !this.disableKeyboardHandling);
|
|
33215
|
+
}
|
|
33207
33216
|
}
|
|
33208
33217
|
|
|
33209
33218
|
disconnectedCallback() {
|
|
@@ -56021,6 +56030,15 @@ let AuroDropdown$2 = class AuroDropdown extends AuroElement$1$2 {
|
|
|
56021
56030
|
|
|
56022
56031
|
connectedCallback() {
|
|
56023
56032
|
super.connectedCallback();
|
|
56033
|
+
// Re-register trigger event listeners removed by floater.disconnect() in
|
|
56034
|
+
// disconnectedCallback(). Fires when a parent element (e.g. auro-drawer)
|
|
56035
|
+
// moves this element to a new DOM location. firstUpdated() won't re-run,
|
|
56036
|
+
// so without this the trigger click/keydown handlers are permanently gone.
|
|
56037
|
+
// Guard on floater.element so this is a no-op on the initial connect
|
|
56038
|
+
// (before firstUpdated() has called configure()).
|
|
56039
|
+
if (this.floater?.element) {
|
|
56040
|
+
this.floater.configure(this, 'auroDropdown', !this.disableKeyboardHandling);
|
|
56041
|
+
}
|
|
56024
56042
|
}
|
|
56025
56043
|
|
|
56026
56044
|
disconnectedCallback() {
|
|
@@ -67159,6 +67177,15 @@ let AuroDropdown$1 = class AuroDropdown extends AuroElement$2$1 {
|
|
|
67159
67177
|
|
|
67160
67178
|
connectedCallback() {
|
|
67161
67179
|
super.connectedCallback();
|
|
67180
|
+
// Re-register trigger event listeners removed by floater.disconnect() in
|
|
67181
|
+
// disconnectedCallback(). Fires when a parent element (e.g. auro-drawer)
|
|
67182
|
+
// moves this element to a new DOM location. firstUpdated() won't re-run,
|
|
67183
|
+
// so without this the trigger click/keydown handlers are permanently gone.
|
|
67184
|
+
// Guard on floater.element so this is a no-op on the initial connect
|
|
67185
|
+
// (before firstUpdated() has called configure()).
|
|
67186
|
+
if (this.floater?.element) {
|
|
67187
|
+
this.floater.configure(this, 'auroDropdown', !this.disableKeyboardHandling);
|
|
67188
|
+
}
|
|
67162
67189
|
}
|
|
67163
67190
|
|
|
67164
67191
|
disconnectedCallback() {
|
|
@@ -83101,17 +83128,7 @@ class AuroCombobox extends AuroElement$3 {
|
|
|
83101
83128
|
return;
|
|
83102
83129
|
}
|
|
83103
83130
|
|
|
83104
|
-
|
|
83105
|
-
// the selected option's LABEL, which is not its machine value. When an
|
|
83106
|
-
// option's label differs from its value (and especially when several
|
|
83107
|
-
// options share a value but render distinct labels — AB#1602086), writing
|
|
83108
|
-
// the label back into this.value clobbers the machine value the selection
|
|
83109
|
-
// listener just set (this.value = optionSelected.value), collapsing the
|
|
83110
|
-
// selection. _syncingBibValue still tracks (that mirrors user-typed text
|
|
83111
|
-
// from the fullscreen bib, where value should follow the input).
|
|
83112
|
-
if (!this._syncingDisplayValue) {
|
|
83113
|
-
this.value = this.input.value;
|
|
83114
|
-
}
|
|
83131
|
+
this.value = this.input.value;
|
|
83115
83132
|
|
|
83116
83133
|
// Ignore re-entrant input events caused by programmatic value sets.
|
|
83117
83134
|
if (this._syncingBibValue || this._syncingDisplayValue) {
|
|
@@ -83375,50 +83392,33 @@ class AuroCombobox extends AuroElement$3 {
|
|
|
83375
83392
|
}
|
|
83376
83393
|
|
|
83377
83394
|
if (this.input.value !== this.value) {
|
|
83378
|
-
//
|
|
83379
|
-
//
|
|
83380
|
-
//
|
|
83381
|
-
//
|
|
83382
|
-
//
|
|
83383
|
-
|
|
83384
|
-
|
|
83385
|
-
|
|
83386
|
-
// So only treat the divergence as a stale menu when the selected option
|
|
83387
|
-
// does NOT match the new value.
|
|
83388
|
-
const menuSelectionMatchesValue =
|
|
83389
|
-
this.menu.optionSelected &&
|
|
83390
|
-
!Array.isArray(this.menu.optionSelected) &&
|
|
83391
|
-
this.menu.optionSelected.value === this.value;
|
|
83392
|
-
|
|
83393
|
-
if (!menuSelectionMatchesValue) {
|
|
83394
|
-
// Clear menu.value AND menu.optionSelected together. Clearing only
|
|
83395
|
-
// menu.value leaves the previously-selected option element pinned
|
|
83396
|
-
// as menu.optionSelected; a later auroMenu-selectedOption event
|
|
83397
|
-
// would then write its stale .value back into combobox.value
|
|
83398
|
-
// (e.g. Tab-after-Backspace re-selecting the prior option).
|
|
83399
|
-
if (this.menu.value || this.menu.optionSelected) {
|
|
83400
|
-
this.menu.clearSelection();
|
|
83401
|
-
}
|
|
83395
|
+
// Clear menu.value AND menu.optionSelected together. Clearing only
|
|
83396
|
+
// menu.value leaves the previously-selected option element pinned
|
|
83397
|
+
// as menu.optionSelected; a later auroMenu-selectedOption event
|
|
83398
|
+
// would then write its stale .value back into combobox.value
|
|
83399
|
+
// (e.g. Tab-after-Backspace re-selecting the prior option).
|
|
83400
|
+
if (this.menu.value || this.menu.optionSelected) {
|
|
83401
|
+
this.menu.clearSelection();
|
|
83402
|
+
}
|
|
83402
83403
|
|
|
83403
|
-
|
|
83404
|
-
|
|
83405
|
-
|
|
83404
|
+
if (!this.persistInput) {
|
|
83405
|
+
this.syncInputValuesAcrossTriggerAndBib(this.value || '');
|
|
83406
|
+
}
|
|
83406
83407
|
|
|
83407
|
-
|
|
83408
|
-
|
|
83409
|
-
|
|
83410
|
-
|
|
83411
|
-
|
|
83412
|
-
|
|
83413
|
-
|
|
83414
|
-
|
|
83415
|
-
|
|
83416
|
-
|
|
83417
|
-
|
|
83418
|
-
|
|
83419
|
-
|
|
83420
|
-
|
|
83421
|
-
}
|
|
83408
|
+
// Programmatic value with no matching option: updateFilter will close
|
|
83409
|
+
// the bib silently (see line 648 — no noMatchOption + 0 results
|
|
83410
|
+
// hides). Announce so screen-reader users hear the request was
|
|
83411
|
+
// dropped. Gated on `input.value !== this.value` so this never fires
|
|
83412
|
+
// for user typing — that path always reconciles input.value to
|
|
83413
|
+
// this.value before updated() runs.
|
|
83414
|
+
if (
|
|
83415
|
+
this.value &&
|
|
83416
|
+
this.menu &&
|
|
83417
|
+
this.menu.options &&
|
|
83418
|
+
this.menu.options.length > 0 &&
|
|
83419
|
+
!this.menu.options.some((opt) => opt.value === this.value)
|
|
83420
|
+
) {
|
|
83421
|
+
announceToScreenReader$1(this._getAnnouncementRoot(), `No matching option for ${this.value}`);
|
|
83422
83422
|
}
|
|
83423
83423
|
}
|
|
83424
83424
|
|
|
@@ -83938,116 +83938,6 @@ function isSelectableByValue(option) {
|
|
|
83938
83938
|
!option.hasAttribute('static');
|
|
83939
83939
|
}
|
|
83940
83940
|
|
|
83941
|
-
/* eslint-disable no-underscore-dangle */
|
|
83942
|
-
/**
|
|
83943
|
-
* Resolves the single selected option for a given `value`, preferring the
|
|
83944
|
-
* option tracked by `selectedKey` (a user-initiated selection) over a
|
|
83945
|
-
* first-by-value match. When multiple options share the same `value`, matching
|
|
83946
|
-
* by `value` alone cannot distinguish which one the user picked; the key
|
|
83947
|
-
* disambiguates it.
|
|
83948
|
-
*
|
|
83949
|
-
* The key is trusted only when it still resolves to an option whose `value`
|
|
83950
|
-
* matches the requested `value`. If the key is stale (option removed) or the
|
|
83951
|
-
* value was changed programmatically, resolution falls back to value matching —
|
|
83952
|
-
* preserving backward-compatible behavior for preselection and `selectByValue`.
|
|
83953
|
-
* @private
|
|
83954
|
-
* @param {Array<HTMLElement>} items - The menu's flat option list.
|
|
83955
|
-
* @param {string} value - The value to resolve.
|
|
83956
|
-
* @param {string|undefined} selectedKey - The `_optionKey` of the user-selected option, if any.
|
|
83957
|
-
* @returns {HTMLElement|undefined} The resolved option, or undefined when none match.
|
|
83958
|
-
*/
|
|
83959
|
-
function resolveSelectedOption(items, value, selectedKey) {
|
|
83960
|
-
if (!items) {
|
|
83961
|
-
return undefined;
|
|
83962
|
-
}
|
|
83963
|
-
|
|
83964
|
-
if (selectedKey !== undefined) {
|
|
83965
|
-
const keyed = items.find((item) => item._optionKey === selectedKey);
|
|
83966
|
-
if (keyed && isSelectableByValue(keyed) && keyed.value === value) {
|
|
83967
|
-
return keyed;
|
|
83968
|
-
}
|
|
83969
|
-
// Key exists but the option is gone or its value no longer matches — fall
|
|
83970
|
-
// through to value-based matching.
|
|
83971
|
-
}
|
|
83972
|
-
|
|
83973
|
-
return items.find((item) => isSelectableByValue(item) && item.value === value);
|
|
83974
|
-
}
|
|
83975
|
-
|
|
83976
|
-
/**
|
|
83977
|
-
* Resolves the selected options for a multi-select `value` array, preferring
|
|
83978
|
-
* options tracked by `selectedKeys` (user-initiated selections) and falling
|
|
83979
|
-
* back to value matching for any values not resolved by key. The result is
|
|
83980
|
-
* always sorted into DOM order regardless of selection sequence.
|
|
83981
|
-
* @private
|
|
83982
|
-
* @param {Array<HTMLElement>} items - The menu's flat option list.
|
|
83983
|
-
* @param {Array<string>} valueArray - The selected values.
|
|
83984
|
-
* @param {Array<string>|undefined} selectedKeys - The `_optionKey`s of the user-selected options, if any.
|
|
83985
|
-
* @returns {Array<HTMLElement>} The resolved options in DOM order.
|
|
83986
|
-
*/
|
|
83987
|
-
function resolveSelectedOptions(items, valueArray, selectedKeys) {
|
|
83988
|
-
if (!items) {
|
|
83989
|
-
return [];
|
|
83990
|
-
}
|
|
83991
|
-
|
|
83992
|
-
const resolved = [];
|
|
83993
|
-
// Mirror `resolved` as a Set for O(1) membership checks below, matching the
|
|
83994
|
-
// indexMap optimization used for the sort rather than scanning `resolved`
|
|
83995
|
-
// on every candidate.
|
|
83996
|
-
const resolvedSet = new Set();
|
|
83997
|
-
|
|
83998
|
-
// Track how many of each value are still available to resolve. A value that
|
|
83999
|
-
// appears N times in `valueArray` may be satisfied at most N times total across
|
|
84000
|
-
// the key pass and the value fallback below — matching by count, not presence,
|
|
84001
|
-
// on BOTH passes. This stops a duplicate value from being over-resolved: e.g.
|
|
84002
|
-
// two keyed options that both carry `SEA` cannot both match a single requested
|
|
84003
|
-
// `SEA` (which happens when `value` is set directly without clearing
|
|
84004
|
-
// `_selectedKey`, so more keys survive than the value set now asks for).
|
|
84005
|
-
const remaining = new Map();
|
|
84006
|
-
valueArray.forEach((val) => remaining.set(val, (remaining.get(val) || 0) + 1));
|
|
84007
|
-
|
|
84008
|
-
// Resolve by key first: trust a key only when its option is still selectable
|
|
84009
|
-
// and there is still an unmatched occurrence of its value in the request set.
|
|
84010
|
-
if (Array.isArray(selectedKeys)) {
|
|
84011
|
-
selectedKeys.forEach((key) => {
|
|
84012
|
-
const keyed = items.find((item) => item._optionKey === key);
|
|
84013
|
-
if (keyed && isSelectableByValue(keyed) && (remaining.get(keyed.value) || 0) > 0 && !resolvedSet.has(keyed)) {
|
|
84014
|
-
resolved.push(keyed);
|
|
84015
|
-
resolvedSet.add(keyed);
|
|
84016
|
-
remaining.set(keyed.value, remaining.get(keyed.value) - 1);
|
|
84017
|
-
}
|
|
84018
|
-
});
|
|
84019
|
-
}
|
|
84020
|
-
|
|
84021
|
-
// Fall back to value matching for the occurrences not resolved by key. Iterate
|
|
84022
|
-
// the leftover per-value counts so a value that appears twice but was only
|
|
84023
|
-
// resolved once by key still matches its remaining occurrence(s).
|
|
84024
|
-
remaining.forEach((count, val) => {
|
|
84025
|
-
for (let occurrence = 0; occurrence < count; occurrence += 1) {
|
|
84026
|
-
const option = items.find((item) => isSelectableByValue(item) && item.value === val && !resolvedSet.has(item));
|
|
84027
|
-
if (option) {
|
|
84028
|
-
resolved.push(option);
|
|
84029
|
-
resolvedSet.add(option);
|
|
84030
|
-
}
|
|
84031
|
-
}
|
|
84032
|
-
});
|
|
84033
|
-
|
|
84034
|
-
// Always return in DOM order so display is consistent regardless of the order
|
|
84035
|
-
// keys/values were selected. Every resolved option came from `items`, so an
|
|
84036
|
-
// O(1) index lookup mirrors `_sortSelectedByDomOrder` and avoids the O(n)
|
|
84037
|
-
// `items.indexOf` per comparison for large combobox option sets. Any element
|
|
84038
|
-
// not in `items` (a stale snapshot from a future caller) sorts to the END via
|
|
84039
|
-
// `?? items.length`, matching `_sortSelectedByDomOrder` and avoiding NaN
|
|
84040
|
-
// comparisons.
|
|
84041
|
-
const indexMap = new Map(items.map((item, index) => [
|
|
84042
|
-
item,
|
|
84043
|
-
index
|
|
84044
|
-
]));
|
|
84045
|
-
resolved.sort((optionA, optionB) => (indexMap.get(optionA) ?? items.length) - (indexMap.get(optionB) ?? items.length));
|
|
84046
|
-
|
|
84047
|
-
return resolved;
|
|
84048
|
-
}
|
|
84049
|
-
/* eslint-enable no-underscore-dangle */
|
|
84050
|
-
|
|
84051
83941
|
/**
|
|
84052
83942
|
* Helper method to dispatch custom events.
|
|
84053
83943
|
* @param {HTMLElement} element - Element to dispatch event from.
|
|
@@ -84073,14 +83963,6 @@ function dispatchMenuEvent(element, eventName, detail = null) {
|
|
|
84073
83963
|
// See LICENSE in the project root for license information.
|
|
84074
83964
|
|
|
84075
83965
|
|
|
84076
|
-
/**
|
|
84077
|
-
* Monotonically increasing counter used to give each menu instance a unique
|
|
84078
|
-
* `_menuInstanceId` prefix. Auto-generating the id (rather than using a random
|
|
84079
|
-
* string) keeps option keys deterministic and collision-free across menus.
|
|
84080
|
-
* @private
|
|
84081
|
-
*/
|
|
84082
|
-
let menuInstanceIdCounter = 0;
|
|
84083
|
-
|
|
84084
83966
|
|
|
84085
83967
|
/**
|
|
84086
83968
|
* The `auro-menu` element provides users a way to select from a list of options.
|
|
@@ -84152,8 +84034,9 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84152
84034
|
|
|
84153
84035
|
// Instance properties (non-reactive)
|
|
84154
84036
|
|
|
84155
|
-
|
|
84156
|
-
|
|
84037
|
+
/**
|
|
84038
|
+
* @private
|
|
84039
|
+
*/
|
|
84157
84040
|
Object.assign(this, {
|
|
84158
84041
|
// Root-level menu (true) or a nested submenu (false)
|
|
84159
84042
|
rootMenu: true,
|
|
@@ -84163,21 +84046,6 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84163
84046
|
nestingSpacer: '<span class="nestingSpacer"></span>',
|
|
84164
84047
|
// Loading indicator for slot elements
|
|
84165
84048
|
loadingSlots: null,
|
|
84166
|
-
// Unique id for this menu instance; prefixes every auto-generated option
|
|
84167
|
-
// key so keys never collide across menus in the same document.
|
|
84168
|
-
_menuInstanceId: `menu-${menuInstanceIdCounter}`,
|
|
84169
|
-
// Monotonically increasing counter for option key generation. Never
|
|
84170
|
-
// resets, so a key is never reused within this instance's lifetime.
|
|
84171
|
-
_optionKeyCounter: 0,
|
|
84172
|
-
// Key(s) of the option(s) the user has actively selected. A single string
|
|
84173
|
-
// in single-select, an array in multi-select, undefined when nothing is
|
|
84174
|
-
// user-selected. Used to disambiguate options that share a `value`.
|
|
84175
|
-
_selectedKey: undefined,
|
|
84176
|
-
// True only for the one updated() cycle following a user selection, so
|
|
84177
|
-
// reconciliation trusts `_selectedKey`. A `value` change from a consumer's
|
|
84178
|
-
// direct property assignment leaves this false, dropping the stale key so
|
|
84179
|
-
// reconciliation falls back to first-by-value (see updated()).
|
|
84180
|
-
_valueChangeFromSelection: false,
|
|
84181
84049
|
});
|
|
84182
84050
|
}
|
|
84183
84051
|
|
|
@@ -84397,13 +84265,6 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84397
84265
|
return;
|
|
84398
84266
|
}
|
|
84399
84267
|
|
|
84400
|
-
// A programmatic value set carries no positional intent, so drop any
|
|
84401
|
-
// `_selectedKey` left over from a prior user click. This makes reconciliation
|
|
84402
|
-
// in updated() fall back to first-by-value (single) / value-in-DOM-order
|
|
84403
|
-
// (multi), matching the documented contract for programmatic selection even
|
|
84404
|
-
// when a stale key would still resolve to a duplicate-value option.
|
|
84405
|
-
this._selectedKey = undefined;
|
|
84406
|
-
|
|
84407
84268
|
// `value` is a String property; stringify arrays so attribute reflection and `formattedValue` parsing stay correct.
|
|
84408
84269
|
this.value = Array.isArray(value) ? JSON.stringify(value) : value;
|
|
84409
84270
|
}
|
|
@@ -84451,17 +84312,6 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84451
84312
|
updated(changedProperties) {
|
|
84452
84313
|
super.updated(changedProperties);
|
|
84453
84314
|
|
|
84454
|
-
// Consume the selection-driven flag for THIS cycle up front. Clearing it
|
|
84455
|
-
// unconditionally — not only inside the `value` branch below — prevents it
|
|
84456
|
-
// from lingering `true` when a selection produces a serialized `value`
|
|
84457
|
-
// byte-identical to the current one, in which case Lit schedules no
|
|
84458
|
-
// `value`-change cycle to consume it. A lingering flag would misclassify a
|
|
84459
|
-
// later consumer's programmatic `value` set as selection-driven and keep a
|
|
84460
|
-
// stale `_selectedKey`. The reconcile path below re-sets the instance flag
|
|
84461
|
-
// after this point, so its intentional cross-cycle hand-off still works.
|
|
84462
|
-
const valueChangeFromSelection = this._valueChangeFromSelection;
|
|
84463
|
-
this._valueChangeFromSelection = false;
|
|
84464
|
-
|
|
84465
84315
|
// Single source of truth for 'auroMenu-selectedOption'. Selection handlers
|
|
84466
84316
|
// mutate optionSelected and let Lit's update cycle dispatch here; the prior
|
|
84467
84317
|
// .value comparison missed multi-select array changes and combined with the
|
|
@@ -84485,17 +84335,6 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84485
84335
|
this.initItems();
|
|
84486
84336
|
}
|
|
84487
84337
|
|
|
84488
|
-
// Distinguish a selection-driven `value` change (a user click, which set
|
|
84489
|
-
// the flag in handleSelectState / _sortSelectedByDomOrder) from a
|
|
84490
|
-
// programmatic assignment by a consumer. A programmatic set carries no
|
|
84491
|
-
// positional intent, so drop any leftover `_selectedKey` and let
|
|
84492
|
-
// reconciliation fall back to first-by-value (single) / value-in-DOM-order
|
|
84493
|
-
// (multi) — the same contract selectByValue() guarantees, even when a
|
|
84494
|
-
// stale key would otherwise still resolve to a duplicate-value option.
|
|
84495
|
-
if (!valueChangeFromSelection) {
|
|
84496
|
-
this._selectedKey = undefined;
|
|
84497
|
-
}
|
|
84498
|
-
|
|
84499
84338
|
// Set when reconciliation reassigns `value` below. That reassignment schedules a
|
|
84500
84339
|
// second updated() cycle, so the `event`-attribute dispatch is deferred to that
|
|
84501
84340
|
// cycle to avoid firing option custom events twice on the same selection.
|
|
@@ -84513,55 +84352,19 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84513
84352
|
// Defensive default: `formattedValue` can be undefined for unexpected value types,
|
|
84514
84353
|
// and calling `.includes` on undefined would throw during reconciliation.
|
|
84515
84354
|
const valueArray = this.formattedValue || [];
|
|
84516
|
-
|
|
84517
|
-
// value matching for any values not resolved by key — so pre-selection
|
|
84518
|
-
// and programmatic value sets keep working. Result is DOM-ordered.
|
|
84519
|
-
const matchingOptions = resolveSelectedOptions(this.items, valueArray, this._selectedKey);
|
|
84355
|
+
const matchingOptions = this.items ? this.items.filter((item) => isSelectableByValue(item) && valueArray.includes(item.value)) : [];
|
|
84520
84356
|
newSelected = matchingOptions.length > 0 ? matchingOptions : undefined;
|
|
84521
84357
|
|
|
84522
|
-
// Reconcile `value` with the selectable set.
|
|
84523
|
-
//
|
|
84524
|
-
//
|
|
84525
|
-
//
|
|
84526
|
-
//
|
|
84527
|
-
|
|
84528
|
-
|
|
84529
|
-
|
|
84530
|
-
|
|
84531
|
-
|
|
84532
|
-
// resurface on the next select/deselect.
|
|
84533
|
-
const selectableByValue = new Map();
|
|
84534
|
-
const loadedValues = new Set();
|
|
84535
|
-
if (this.items) {
|
|
84536
|
-
this.items.forEach((item) => {
|
|
84537
|
-
loadedValues.add(item.value);
|
|
84538
|
-
if (isSelectableByValue(item)) {
|
|
84539
|
-
selectableByValue.set(item.value, (selectableByValue.get(item.value) || 0) + 1);
|
|
84540
|
-
}
|
|
84541
|
-
});
|
|
84542
|
-
}
|
|
84543
|
-
|
|
84544
|
-
const reconciled = valueArray.filter((val) => {
|
|
84545
|
-
// Not loaded yet (async preselection) — keep for a later cycle.
|
|
84546
|
-
if (!loadedValues.has(val)) {
|
|
84547
|
-
return true;
|
|
84548
|
-
}
|
|
84549
|
-
// Consume one selectable option per occurrence; drop once exhausted.
|
|
84550
|
-
const remaining = selectableByValue.get(val) || 0;
|
|
84551
|
-
if (remaining > 0) {
|
|
84552
|
-
selectableByValue.set(val, remaining - 1);
|
|
84553
|
-
return true;
|
|
84554
|
-
}
|
|
84555
|
-
return false;
|
|
84556
|
-
});
|
|
84557
|
-
|
|
84558
|
-
if (reconciled.length !== valueArray.length) {
|
|
84559
|
-
// This is an internal correction, not a consumer's programmatic set,
|
|
84560
|
-
// so preserve the selection-driven flag through the re-entrant
|
|
84561
|
-
// updated() cycle it schedules. Otherwise that cycle would treat the
|
|
84562
|
-
// reassignment as programmatic and drop `_selectedKey` mid-cascade,
|
|
84563
|
-
// flipping resolution and looping.
|
|
84564
|
-
this._valueChangeFromSelection = true;
|
|
84358
|
+
// Reconcile `value` with the selectable set. Drop only entries whose option is
|
|
84359
|
+
// loaded but non-selectable (disabled/static) — leaving them would desync `value`
|
|
84360
|
+
// from `optionSelected`, and the toggle handlers rebuild `value` from `formattedValue`,
|
|
84361
|
+
// so the rejected entry would resurface on the next select/deselect. Entries with no
|
|
84362
|
+
// matching item yet are preserved so async preselection still works once options render.
|
|
84363
|
+
const rejectedValues = this.items
|
|
84364
|
+
? this.items.filter((item) => !isSelectableByValue(item) && valueArray.includes(item.value)).map((item) => item.value)
|
|
84365
|
+
: [];
|
|
84366
|
+
if (rejectedValues.length > 0) {
|
|
84367
|
+
const reconciled = valueArray.filter((val) => !rejectedValues.includes(val));
|
|
84565
84368
|
this.value = serializeMultiSelectValue(reconciled);
|
|
84566
84369
|
valueReconciled = true;
|
|
84567
84370
|
}
|
|
@@ -84573,11 +84376,7 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84573
84376
|
// `hidden` is intentionally NOT excluded: the combobox toggles
|
|
84574
84377
|
// `hidden` as its type-ahead filter, so a filtered-out option is
|
|
84575
84378
|
// still a valid programmatic selection.
|
|
84576
|
-
|
|
84577
|
-
// `_selectedKey`) so a click on the second of two options sharing a
|
|
84578
|
-
// `value` resolves back to that exact element instead of the first
|
|
84579
|
-
// value match. Falls back to first-by-value for programmatic sets.
|
|
84580
|
-
const matchingOption = resolveSelectedOption(this.items, this.value, this._selectedKey);
|
|
84379
|
+
const matchingOption = this.items ? this.items.find((item) => isSelectableByValue(item) && item.value === this.value) : undefined;
|
|
84581
84380
|
|
|
84582
84381
|
if (matchingOption) {
|
|
84583
84382
|
newSelected = matchingOption;
|
|
@@ -84805,14 +84604,6 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84805
84604
|
}
|
|
84806
84605
|
});
|
|
84807
84606
|
|
|
84808
|
-
// Assign private keys once items are populated. Only the root menu assigns
|
|
84809
|
-
// keys: its `items` is a deep query that already includes nested submenu
|
|
84810
|
-
// options, so a single pass keys the entire tree. Nested menus skip this
|
|
84811
|
-
// and inherit keys from the root.
|
|
84812
|
-
if (this.rootMenu) {
|
|
84813
|
-
this._assignOptionKeys();
|
|
84814
|
-
}
|
|
84815
|
-
|
|
84816
84607
|
if (this.noCheckmark) {
|
|
84817
84608
|
this.updateItemsState(new Map([
|
|
84818
84609
|
[
|
|
@@ -84829,31 +84620,6 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84829
84620
|
}));
|
|
84830
84621
|
}
|
|
84831
84622
|
|
|
84832
|
-
/**
|
|
84833
|
-
* Assigns a private, auto-generated unique key (`_optionKey`) to each menu
|
|
84834
|
-
* option that does not already have one. Keys are internal state on the
|
|
84835
|
-
* element instance — never reflected as an attribute or exposed publicly —
|
|
84836
|
-
* and let selection tracking distinguish options that share the same `value`.
|
|
84837
|
-
*
|
|
84838
|
-
* The `_optionKey === undefined` guard makes this idempotent: options keep the
|
|
84839
|
-
* key they were first assigned across re-renders and slot changes, and if a
|
|
84840
|
-
* nested menu's lifecycle runs a pass before the root, options simply wait for
|
|
84841
|
-
* the root to key them (or keep whatever key they already hold).
|
|
84842
|
-
* @private
|
|
84843
|
-
*/
|
|
84844
|
-
_assignOptionKeys() {
|
|
84845
|
-
if (!this.items) {
|
|
84846
|
-
return;
|
|
84847
|
-
}
|
|
84848
|
-
|
|
84849
|
-
this.items.forEach((option) => {
|
|
84850
|
-
if (option._optionKey === undefined) {
|
|
84851
|
-
this._optionKeyCounter += 1;
|
|
84852
|
-
option._optionKey = `${this._menuInstanceId}-${this._optionKeyCounter}`;
|
|
84853
|
-
}
|
|
84854
|
-
});
|
|
84855
|
-
}
|
|
84856
|
-
|
|
84857
84623
|
// Logic Methods
|
|
84858
84624
|
|
|
84859
84625
|
/**
|
|
@@ -84863,28 +84629,24 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84863
84629
|
*/
|
|
84864
84630
|
handleSelectState(option) {
|
|
84865
84631
|
if (this.multiSelect) {
|
|
84632
|
+
const currentValue = this.formattedValue || [];
|
|
84866
84633
|
const currentSelected = this.optionSelected || [];
|
|
84867
84634
|
|
|
84635
|
+
if (!currentValue.includes(option.value)) {
|
|
84636
|
+
this.value = serializeMultiSelectValue([
|
|
84637
|
+
...currentValue,
|
|
84638
|
+
option.value
|
|
84639
|
+
]);
|
|
84640
|
+
}
|
|
84868
84641
|
if (!currentSelected.includes(option)) {
|
|
84869
84642
|
this.optionSelected = [
|
|
84870
84643
|
...currentSelected,
|
|
84871
84644
|
option
|
|
84872
84645
|
];
|
|
84873
84646
|
}
|
|
84874
|
-
|
|
84875
|
-
// Re-sort by DOM order and rebuild `_selectedKey`/`value` from the
|
|
84876
|
-
// selected set so display order stays consistent with the menu, not with
|
|
84877
|
-
// click order.
|
|
84878
|
-
this._sortSelectedByDomOrder();
|
|
84879
84647
|
} else {
|
|
84880
84648
|
this.value = option.value;
|
|
84881
84649
|
this.optionSelected = option;
|
|
84882
|
-
// Track the specific option the user selected so the value→option
|
|
84883
|
-
// reconciliation in updated() resolves back to this exact element even
|
|
84884
|
-
// when another option shares the same `value`.
|
|
84885
|
-
this._selectedKey = option._optionKey;
|
|
84886
|
-
// Mark this `value` change as selection-driven so updated() trusts the key.
|
|
84887
|
-
this._valueChangeFromSelection = true;
|
|
84888
84650
|
}
|
|
84889
84651
|
|
|
84890
84652
|
this._index = this.items.indexOf(option);
|
|
@@ -84897,22 +84659,18 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84897
84659
|
*/
|
|
84898
84660
|
handleDeselectState(option) {
|
|
84899
84661
|
if (this.multiSelect) {
|
|
84900
|
-
// Remove this
|
|
84901
|
-
|
|
84902
|
-
|
|
84903
|
-
|
|
84662
|
+
// Remove this option from array; an empty result collapses `value` to undefined.
|
|
84663
|
+
const newFormattedValue = (this.formattedValue || []).filter((val) => val !== option.value);
|
|
84664
|
+
this.value = serializeMultiSelectValue(newFormattedValue);
|
|
84665
|
+
|
|
84666
|
+
this.optionSelected = this.optionSelected.filter((val) => val !== option);
|
|
84904
84667
|
if (this.optionSelected.length === 0) {
|
|
84905
84668
|
this.optionSelected = undefined;
|
|
84906
|
-
this._selectedKey = undefined;
|
|
84907
|
-
this.value = undefined;
|
|
84908
|
-
} else {
|
|
84909
|
-
this._sortSelectedByDomOrder();
|
|
84910
84669
|
}
|
|
84911
84670
|
} else {
|
|
84912
84671
|
// For single-select: Back to undefined when deselected
|
|
84913
84672
|
this.value = undefined;
|
|
84914
84673
|
this.optionSelected = undefined;
|
|
84915
|
-
this._selectedKey = undefined;
|
|
84916
84674
|
}
|
|
84917
84675
|
|
|
84918
84676
|
// Update the index tracking
|
|
@@ -84936,38 +84694,9 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84936
84694
|
clearSelection() {
|
|
84937
84695
|
this.optionSelected = undefined;
|
|
84938
84696
|
this.value = undefined;
|
|
84939
|
-
this._selectedKey = undefined;
|
|
84940
84697
|
this._index = -1;
|
|
84941
84698
|
}
|
|
84942
84699
|
|
|
84943
|
-
/**
|
|
84944
|
-
* Re-sorts the multi-select selection into DOM order and rebuilds the derived
|
|
84945
|
-
* `_selectedKey` and `value` from `optionSelected`. Selection is always stored
|
|
84946
|
-
* and serialized in the order options appear in the menu, never in click
|
|
84947
|
-
* order — so selecting C then A yields `[A, C]`.
|
|
84948
|
-
* @private
|
|
84949
|
-
*/
|
|
84950
|
-
_sortSelectedByDomOrder() {
|
|
84951
|
-
if (!this.multiSelect || !Array.isArray(this.optionSelected) || !this.items) {
|
|
84952
|
-
return;
|
|
84953
|
-
}
|
|
84954
|
-
|
|
84955
|
-
const indexMap = new Map(this.items.map((item, index) => [
|
|
84956
|
-
item,
|
|
84957
|
-
index
|
|
84958
|
-
]));
|
|
84959
|
-
|
|
84960
|
-
// Sort any element no longer in `items` (a stale selection left over from a
|
|
84961
|
-
// dynamic rebuild that the consumer has not cleared) to the END rather than
|
|
84962
|
-
// the front, so it never displaces a live option to the head of the
|
|
84963
|
-
// serialized order. Value reconciliation drops it on the next updated() cycle.
|
|
84964
|
-
this.optionSelected.sort((optionA, optionB) => (indexMap.get(optionA) ?? this.items.length) - (indexMap.get(optionB) ?? this.items.length));
|
|
84965
|
-
this._selectedKey = this.optionSelected.map((option) => option._optionKey);
|
|
84966
|
-
this.value = serializeMultiSelectValue(this.optionSelected.map((option) => option.value));
|
|
84967
|
-
// Mark this `value` change as selection-driven so updated() trusts the keys.
|
|
84968
|
-
this._valueChangeFromSelection = true;
|
|
84969
|
-
}
|
|
84970
|
-
|
|
84971
84700
|
/**
|
|
84972
84701
|
* Resets the menu to its initial state.
|
|
84973
84702
|
* This is the only way to return value to undefined.
|
|
@@ -84977,7 +84706,6 @@ class AuroMenu extends AuroElement$2 {
|
|
|
84977
84706
|
// Reset to undefined - initial state
|
|
84978
84707
|
this.value = undefined;
|
|
84979
84708
|
this.optionSelected = undefined;
|
|
84980
|
-
this._selectedKey = undefined;
|
|
84981
84709
|
this._index = -1;
|
|
84982
84710
|
|
|
84983
84711
|
// Clear active option state so a follow-up open/navigation starts fresh
|
|
@@ -85039,19 +84767,6 @@ class AuroMenu extends AuroElement$2 {
|
|
|
85039
84767
|
this.initItems();
|
|
85040
84768
|
}
|
|
85041
84769
|
|
|
85042
|
-
// Recover `_index` from the highlighted option when it has been reset to -1.
|
|
85043
|
-
// In multi-select, deselecting the last remaining option collapses the value
|
|
85044
|
-
// to undefined, and the updated() reconciliation resets `_index = -1` even
|
|
85045
|
-
// though `optionActive` still points at the highlighted option. Without this,
|
|
85046
|
-
// reading `items[-1]` returns undefined and the re-select no-ops until the
|
|
85047
|
-
// highlight is moved away and back. Mirrors auro-combobox's reconcileMenuIndex.
|
|
85048
|
-
if (this._index < 0 && this.optionActive && this.items) {
|
|
85049
|
-
const activeIndex = this.items.indexOf(this.optionActive);
|
|
85050
|
-
if (activeIndex >= 0) {
|
|
85051
|
-
this._index = activeIndex;
|
|
85052
|
-
}
|
|
85053
|
-
}
|
|
85054
|
-
|
|
85055
84770
|
// Get currently selected menu option based on index
|
|
85056
84771
|
const option = this.items ? this.items[this._index] : undefined;
|
|
85057
84772
|
|
|
@@ -91184,6 +90899,15 @@ class AuroDropdown extends AuroElement {
|
|
|
91184
90899
|
|
|
91185
90900
|
connectedCallback() {
|
|
91186
90901
|
super.connectedCallback();
|
|
90902
|
+
// Re-register trigger event listeners removed by floater.disconnect() in
|
|
90903
|
+
// disconnectedCallback(). Fires when a parent element (e.g. auro-drawer)
|
|
90904
|
+
// moves this element to a new DOM location. firstUpdated() won't re-run,
|
|
90905
|
+
// so without this the trigger click/keydown handlers are permanently gone.
|
|
90906
|
+
// Guard on floater.element so this is a no-op on the initial connect
|
|
90907
|
+
// (before firstUpdated() has called configure()).
|
|
90908
|
+
if (this.floater?.element) {
|
|
90909
|
+
this.floater.configure(this, 'auroDropdown', !this.disableKeyboardHandling);
|
|
90910
|
+
}
|
|
91187
90911
|
}
|
|
91188
90912
|
|
|
91189
90913
|
disconnectedCallback() {
|