@aurodesignsystem-dev/auro-formkit 0.0.0-pr1505.0 → 0.0.0-pr1506.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.min.js +120 -139
- package/components/combobox/demo/getting-started.min.js +120 -139
- package/components/combobox/demo/index.min.js +120 -139
- package/components/combobox/dist/auro-combobox.d.ts +9 -0
- package/components/combobox/dist/index.js +120 -139
- package/components/combobox/dist/registered.js +120 -139
- package/components/counter/demo/customize.min.js +2 -2
- package/components/counter/demo/index.min.js +2 -2
- package/components/counter/dist/index.js +2 -2
- package/components/counter/dist/registered.js +2 -2
- package/components/datepicker/demo/api.md +0 -2
- package/components/datepicker/demo/customize.md +33 -195
- package/components/datepicker/demo/customize.min.js +37 -43
- package/components/datepicker/demo/index.min.js +36 -35
- package/components/datepicker/dist/index.js +36 -35
- package/components/datepicker/dist/registered.js +36 -35
- package/components/datepicker/dist/src/auro-datepicker.d.ts +0 -2
- 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 +325 -230
- package/components/form/demo/getting-started.min.js +325 -230
- package/components/form/demo/index.min.js +325 -230
- package/components/form/demo/registerDemoDeps.min.js +325 -230
- package/components/input/demo/customize.md +55 -56
- package/components/input/demo/customize.min.js +32 -26
- package/components/input/demo/getting-started.min.js +32 -26
- package/components/input/demo/index.md +2 -2
- package/components/input/demo/index.min.js +32 -26
- package/components/input/dist/index.js +32 -26
- package/components/input/dist/registered.js +32 -26
- 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/api.md +1 -0
- package/components/select/demo/customize.md +71 -0
- package/components/select/demo/customize.min.js +133 -26
- package/components/select/demo/getting-started.min.js +133 -26
- package/components/select/demo/index.min.js +133 -26
- package/components/select/demo/keyboard-behavior.md +18 -0
- package/components/select/dist/auro-select.d.ts +38 -2
- package/components/select/dist/index.js +133 -26
- package/components/select/dist/registered.js +133 -26
- package/components/select/dist/selectUtils.d.ts +12 -0
- package/custom-elements.json +114 -10
- package/package.json +1 -1
|
@@ -825,6 +825,8 @@ function navigateArrow(component, direction, options = {}) {
|
|
|
825
825
|
}
|
|
826
826
|
}
|
|
827
827
|
|
|
828
|
+
/* eslint-disable no-underscore-dangle */
|
|
829
|
+
|
|
828
830
|
/**
|
|
829
831
|
* Returns the clear button element from the active input's shadow
|
|
830
832
|
* DOM, if available.
|
|
@@ -860,11 +862,9 @@ function isClearBtnFocused(ctx, clearBtn = getClearBtn(ctx)) {
|
|
|
860
862
|
* @param {Object} menu - The menu component.
|
|
861
863
|
*/
|
|
862
864
|
function reconcileMenuIndex(menu) {
|
|
863
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
864
865
|
if (menu._index < 0 && menu.optionActive && menu.items) {
|
|
865
866
|
const idx = menu.items.indexOf(menu.optionActive);
|
|
866
867
|
if (idx >= 0) {
|
|
867
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
868
868
|
menu._index = idx;
|
|
869
869
|
}
|
|
870
870
|
}
|
|
@@ -4888,7 +4888,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$3 {
|
|
|
4888
4888
|
}
|
|
4889
4889
|
};
|
|
4890
4890
|
|
|
4891
|
-
var formkitVersion$2 = '
|
|
4891
|
+
var formkitVersion$2 = '202606190840';
|
|
4892
4892
|
|
|
4893
4893
|
let AuroElement$2 = class AuroElement extends i$3 {
|
|
4894
4894
|
static get properties() {
|
|
@@ -16609,6 +16609,7 @@ class AuroInputUtilities {
|
|
|
16609
16609
|
const maskOptions = this.getMaskOptions('date', normalizedFormat);
|
|
16610
16610
|
|
|
16611
16611
|
if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
|
|
16612
|
+
console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
|
|
16612
16613
|
return undefined;
|
|
16613
16614
|
}
|
|
16614
16615
|
|
|
@@ -17419,10 +17420,6 @@ class BaseInput extends AuroElement$1 {
|
|
|
17419
17420
|
this.wrapperElement.addEventListener('click', this.handleClick);
|
|
17420
17421
|
}
|
|
17421
17422
|
|
|
17422
|
-
// add attribute for query selectors when auro-input is registered under a custom name
|
|
17423
|
-
if (this.tagName.toLowerCase() !== 'auro-input' && !this.hasAttribute('auro-input')) {
|
|
17424
|
-
this.setAttribute('auro-input', '');
|
|
17425
|
-
}
|
|
17426
17423
|
this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
|
|
17427
17424
|
|
|
17428
17425
|
// use validity message override if declared when initializing the component
|
|
@@ -17593,14 +17590,14 @@ class BaseInput extends AuroElement$1 {
|
|
|
17593
17590
|
|
|
17594
17591
|
if (formattedValue !== this.inputElement.value) {
|
|
17595
17592
|
this.skipNextProgrammaticInputEvent = true;
|
|
17596
|
-
if (this.maskInstance && this.type
|
|
17593
|
+
if (this.maskInstance && this.type !== 'date') {
|
|
17597
17594
|
// Route through the mask so its _value and el.value stay in lock-step
|
|
17598
17595
|
// (set value calls updateControl which writes el.value = displayValue).
|
|
17599
17596
|
// Writing el.value directly leaves the mask thinking displayValue is
|
|
17600
|
-
// stale; _saveSelection on the next focus/click then warns.
|
|
17601
|
-
//
|
|
17602
|
-
//
|
|
17603
|
-
//
|
|
17597
|
+
// stale; _saveSelection on the next focus/click then warns. Date is
|
|
17598
|
+
// excluded because its formattedValue can be raw ISO when the calendar
|
|
17599
|
+
// is invalid, and re-masking through mm/dd/yyyy would truncate it and
|
|
17600
|
+
// flip validity from patternMismatch to tooShort.
|
|
17604
17601
|
this.maskInstance.value = formattedValue || '';
|
|
17605
17602
|
} else if (formattedValue) {
|
|
17606
17603
|
this.inputElement.value = formattedValue;
|
|
@@ -17711,31 +17708,33 @@ class BaseInput extends AuroElement$1 {
|
|
|
17711
17708
|
* @returns {void}
|
|
17712
17709
|
*/
|
|
17713
17710
|
configureAutoFormatting() {
|
|
17714
|
-
//
|
|
17715
|
-
//
|
|
17716
|
-
//
|
|
17717
|
-
//
|
|
17711
|
+
// _configuringMask gates two things: external re-entry into this method
|
|
17712
|
+
// while setup is mid-flight (from property changes that call back here),
|
|
17713
|
+
// and the accept/complete listeners below — both need to ignore the mask
|
|
17714
|
+
// events fired by our own value-restore step.
|
|
17718
17715
|
if (this._configuringMask) return;
|
|
17719
17716
|
this._configuringMask = true;
|
|
17720
17717
|
try {
|
|
17718
|
+
// Destroy any prior mask so IMask can attach fresh under the new format.
|
|
17721
17719
|
if (this.maskInstance) {
|
|
17722
17720
|
this.maskInstance.destroy();
|
|
17723
17721
|
}
|
|
17724
17722
|
|
|
17725
|
-
// Pass new format to util
|
|
17726
17723
|
this.util.updateFormat(this.format);
|
|
17727
17724
|
|
|
17728
17725
|
const maskOptions = this.util.getMaskOptions(this.type, this.format);
|
|
17729
17726
|
|
|
17730
17727
|
if (this.inputElement && maskOptions.mask) {
|
|
17731
|
-
|
|
17732
|
-
//
|
|
17733
|
-
//
|
|
17734
|
-
//
|
|
17735
|
-
// When the format changes (e.g. locale switch) and we have a valid ISO
|
|
17736
|
-
// model value, compute the display string for the NEW format instead of
|
|
17737
|
-
// re-using the old display string, which may be invalid in the new mask.
|
|
17728
|
+
// Capture the current display so it can be re-applied after IMask
|
|
17729
|
+
// attaches. The restore at the bottom goes through maskInstance.value
|
|
17730
|
+
// (not inputElement.value directly) so the mask's internal state and
|
|
17731
|
+
// the input's displayed text stay in lock-step.
|
|
17738
17732
|
let existingValue = this.inputElement.value;
|
|
17733
|
+
|
|
17734
|
+
// Format-change case (e.g. locale switch): existingValue is the OLD
|
|
17735
|
+
// mask's display string and may not parse under the new mask. When
|
|
17736
|
+
// we have a valid date model, rebuild the display from valueObject
|
|
17737
|
+
// (the canonical source) using the new mask's format function.
|
|
17739
17738
|
if (
|
|
17740
17739
|
this.util.isFullDateFormat(this.type, this.format) &&
|
|
17741
17740
|
this.value &&
|
|
@@ -17747,15 +17746,18 @@ class BaseInput extends AuroElement$1 {
|
|
|
17747
17746
|
existingValue = maskOptions.format(this.valueObject);
|
|
17748
17747
|
}
|
|
17749
17748
|
|
|
17749
|
+
// Clear before IMask attaches so the constructor seeds an empty
|
|
17750
|
+
// internal value. Otherwise IMask reads the stale unmasked string
|
|
17751
|
+
// and emits a spurious 'accept' before the restore below runs.
|
|
17750
17752
|
this.skipNextProgrammaticInputEvent = true;
|
|
17751
17753
|
this.inputElement.value = '';
|
|
17752
17754
|
|
|
17753
17755
|
this.maskInstance = IMask(this.inputElement, maskOptions);
|
|
17754
17756
|
|
|
17757
|
+
// Mask fires 'accept' on every value change, including the restore
|
|
17758
|
+
// step below. Skip events fired during configureAutoFormatting so
|
|
17759
|
+
// we don't overwrite a value the parent just pushed.
|
|
17755
17760
|
this.maskInstance.on('accept', () => {
|
|
17756
|
-
// Suppress propagation during configureAutoFormatting's own value-restoration
|
|
17757
|
-
// (line below) — the mask emits 'accept' on every value-set, including ours,
|
|
17758
|
-
// and we don't want to overwrite a value the parent just pushed.
|
|
17759
17761
|
if (this._configuringMask) return;
|
|
17760
17762
|
this.value = this.util.toModelValue(this.maskInstance.value, this.format);
|
|
17761
17763
|
if (this.type === "date") {
|
|
@@ -17763,6 +17765,8 @@ class BaseInput extends AuroElement$1 {
|
|
|
17763
17765
|
}
|
|
17764
17766
|
});
|
|
17765
17767
|
|
|
17768
|
+
// Mask fires 'complete' on the restore step below for any value that
|
|
17769
|
+
// happens to be a complete match. Same setup-suppression as 'accept'.
|
|
17766
17770
|
this.maskInstance.on('complete', () => {
|
|
17767
17771
|
if (this._configuringMask) return;
|
|
17768
17772
|
this.value = this.util.toModelValue(this.maskInstance.value, this.format);
|
|
@@ -17771,7 +17775,9 @@ class BaseInput extends AuroElement$1 {
|
|
|
17771
17775
|
}
|
|
17772
17776
|
});
|
|
17773
17777
|
|
|
17774
|
-
//
|
|
17778
|
+
// Write existingValue through the mask (not the input directly) so
|
|
17779
|
+
// the mask reformats it under the new rules and keeps its internal
|
|
17780
|
+
// _value aligned with the input's displayed text.
|
|
17775
17781
|
if (existingValue) {
|
|
17776
17782
|
this.maskInstance.value = existingValue;
|
|
17777
17783
|
}
|
|
@@ -18477,7 +18483,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$3 {
|
|
|
18477
18483
|
}
|
|
18478
18484
|
};
|
|
18479
18485
|
|
|
18480
|
-
var formkitVersion$1 = '
|
|
18486
|
+
var formkitVersion$1 = '202606190840';
|
|
18481
18487
|
|
|
18482
18488
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
18483
18489
|
// See LICENSE in the project root for license information.
|
|
@@ -19598,7 +19604,7 @@ class AuroBibtemplate extends i$3 {
|
|
|
19598
19604
|
}
|
|
19599
19605
|
}
|
|
19600
19606
|
|
|
19601
|
-
var formkitVersion = '
|
|
19607
|
+
var formkitVersion = '202606190840';
|
|
19602
19608
|
|
|
19603
19609
|
var styleCss$3 = i$6`.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}:host{display:block;text-align:left}:host [auro-dropdown]{--ds-auro-dropdown-trigger-background-color: transparent}:host #inputInBib::part(wrapper){box-shadow:none}:host #inputInBib::part(accent-left){display:none}:host([layout*=classic]) [auro-input]{width:100%}:host([layout*=classic]) [auro-input]::part(helpText){display:none}:host([layout*=classic]) #slotHolder{display:none}`;
|
|
19604
19610
|
|
|
@@ -20585,7 +20591,7 @@ class AuroCombobox extends AuroElement {
|
|
|
20585
20591
|
if (this.menu) {
|
|
20586
20592
|
this.menu.matchWord = normalizeFilterValue(this.input.value);
|
|
20587
20593
|
}
|
|
20588
|
-
const label = getOptionLabel(this.menu.optionSelected)
|
|
20594
|
+
const label = getOptionLabel(this.menu.optionSelected);
|
|
20589
20595
|
this.updateTriggerTextDisplay(label || this.value);
|
|
20590
20596
|
}
|
|
20591
20597
|
|
|
@@ -20599,40 +20605,9 @@ class AuroCombobox extends AuroElement {
|
|
|
20599
20605
|
// in suggestion mode, do not override input value if no selection has been made and the input currently has focus
|
|
20600
20606
|
const isInputFocusedWithNoSelection = !this.menu.value && (this.input.matches(':focus-within') || (this.inputInBib && this.inputInBib.matches(':focus-within')));
|
|
20601
20607
|
|
|
20602
|
-
|
|
20603
|
-
|
|
20604
|
-
|
|
20605
|
-
// syncValuesAndStates re-enters here during typing when both inputs
|
|
20606
|
-
// already match, and a no-op flag flip would make the bib branch's
|
|
20607
|
-
// bail eat legitimate user-input events.
|
|
20608
|
-
const triggerNeedsSync = this.input.value !== nextValue;
|
|
20609
|
-
const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
|
|
20610
|
-
if (triggerNeedsSync || bibNeedsSync) {
|
|
20611
|
-
this._syncingDisplayValue = true;
|
|
20612
|
-
if (triggerNeedsSync) {
|
|
20613
|
-
this.input.value = nextValue;
|
|
20614
|
-
}
|
|
20615
|
-
if (bibNeedsSync) {
|
|
20616
|
-
this.inputInBib.value = nextValue;
|
|
20617
|
-
}
|
|
20618
|
-
const pending = [];
|
|
20619
|
-
if (triggerNeedsSync) {
|
|
20620
|
-
pending.push(this.input.updateComplete);
|
|
20621
|
-
}
|
|
20622
|
-
if (bibNeedsSync) {
|
|
20623
|
-
pending.push(this.inputInBib.updateComplete);
|
|
20624
|
-
}
|
|
20625
|
-
Promise.all(pending).then(() => {
|
|
20626
|
-
// imask reasserts otherwise, and handleBlur reverts to its stale value.
|
|
20627
|
-
if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
|
|
20628
|
-
this.input.maskInstance.updateValue();
|
|
20629
|
-
}
|
|
20630
|
-
if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
|
|
20631
|
-
this.inputInBib.maskInstance.updateValue();
|
|
20632
|
-
}
|
|
20633
|
-
this._syncingDisplayValue = false;
|
|
20634
|
-
});
|
|
20635
|
-
}
|
|
20608
|
+
const suppressed = this.persistInput || (this.behavior === 'suggestion' && isInputFocusedWithNoSelection);
|
|
20609
|
+
if (!suppressed) {
|
|
20610
|
+
this.syncInputValuesAcrossTriggerAndBib(label || this.value);
|
|
20636
20611
|
}
|
|
20637
20612
|
|
|
20638
20613
|
// update the displayValue in the trigger if displayValue slot content is present
|
|
@@ -20660,6 +20635,52 @@ class AuroCombobox extends AuroElement {
|
|
|
20660
20635
|
this.requestUpdate();
|
|
20661
20636
|
}
|
|
20662
20637
|
|
|
20638
|
+
/**
|
|
20639
|
+
* Writes nextValue to the trigger input and the bib input when their current
|
|
20640
|
+
* value differs, then re-asserts imask after Lit's update flushes.
|
|
20641
|
+
* @param {string} nextValue - The value to write to both inputs.
|
|
20642
|
+
* @returns {Promise<void> | null} Promise that resolves after the inputs flush,
|
|
20643
|
+
* or null when no sync was needed (so callers can skip post-flush work).
|
|
20644
|
+
* @private
|
|
20645
|
+
*/
|
|
20646
|
+
syncInputValuesAcrossTriggerAndBib(nextValue) {
|
|
20647
|
+
// Only set the flag when there's an actual write to suppress —
|
|
20648
|
+
// syncValuesAndStates re-enters here during typing when both inputs
|
|
20649
|
+
// already match, and a no-op flag flip would make the bib branch's
|
|
20650
|
+
// bail eat legitimate user-input events.
|
|
20651
|
+
const triggerNeedsSync = this.input.value !== nextValue;
|
|
20652
|
+
const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
|
|
20653
|
+
if (!triggerNeedsSync && !bibNeedsSync) {
|
|
20654
|
+
return null;
|
|
20655
|
+
}
|
|
20656
|
+
|
|
20657
|
+
this._syncingDisplayValue = true;
|
|
20658
|
+
if (triggerNeedsSync) {
|
|
20659
|
+
this.input.value = nextValue;
|
|
20660
|
+
}
|
|
20661
|
+
if (bibNeedsSync) {
|
|
20662
|
+
this.inputInBib.value = nextValue;
|
|
20663
|
+
}
|
|
20664
|
+
|
|
20665
|
+
const pending = [];
|
|
20666
|
+
if (triggerNeedsSync) {
|
|
20667
|
+
pending.push(this.input.updateComplete);
|
|
20668
|
+
}
|
|
20669
|
+
if (bibNeedsSync) {
|
|
20670
|
+
pending.push(this.inputInBib.updateComplete);
|
|
20671
|
+
}
|
|
20672
|
+
return Promise.all(pending).then(() => {
|
|
20673
|
+
// imask reasserts otherwise, and handleBlur reverts to its stale value.
|
|
20674
|
+
if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
|
|
20675
|
+
this.input.maskInstance.updateValue();
|
|
20676
|
+
}
|
|
20677
|
+
if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
|
|
20678
|
+
this.inputInBib.maskInstance.updateValue();
|
|
20679
|
+
}
|
|
20680
|
+
this._syncingDisplayValue = false;
|
|
20681
|
+
});
|
|
20682
|
+
}
|
|
20683
|
+
|
|
20663
20684
|
/**
|
|
20664
20685
|
* Processes hidden state of all menu options and determines if there are any available options not hidden.
|
|
20665
20686
|
* @private
|
|
@@ -20687,9 +20708,9 @@ class AuroCombobox extends AuroElement {
|
|
|
20687
20708
|
this.syncValuesAndStates();
|
|
20688
20709
|
}
|
|
20689
20710
|
|
|
20690
|
-
// Re-activate when optionActive is
|
|
20691
|
-
// been reset (e.g. by clearSelection in an async update)
|
|
20692
|
-
// makeSelection() can find the correct option.
|
|
20711
|
+
// Re-activate when optionActive is not in the current scrollable viewport,
|
|
20712
|
+
// or when _index has been reset (e.g. by clearSelection in an async update)
|
|
20713
|
+
// so that makeSelection() can find the correct option.
|
|
20693
20714
|
if (!this.availableOptions.includes(this.menu.optionActive) || this.menu._index < 0) {
|
|
20694
20715
|
this.activateFirstEnabledAvailableOption();
|
|
20695
20716
|
}
|
|
@@ -20823,28 +20844,25 @@ class AuroCombobox extends AuroElement {
|
|
|
20823
20844
|
|
|
20824
20845
|
guardTouchPassthrough(this.menu);
|
|
20825
20846
|
|
|
20826
|
-
//
|
|
20827
|
-
//
|
|
20828
|
-
//
|
|
20847
|
+
// showModal() takes focus away from the trigger. Early focus once
|
|
20848
|
+
// the dialog has painted; the shared doubleRaf below is the fallback
|
|
20849
|
+
// for when the dialog needs an extra frame and also clears the
|
|
20850
|
+
// validation guard.
|
|
20829
20851
|
requestAnimationFrame(() => {
|
|
20830
20852
|
this.setInputFocus();
|
|
20831
20853
|
});
|
|
20832
|
-
|
|
20833
|
-
doubleRaf(() => {
|
|
20834
|
-
this.setInputFocus();
|
|
20835
|
-
this._inFullscreenTransition = false;
|
|
20836
|
-
});
|
|
20837
|
-
} else {
|
|
20838
|
-
// Desktop popover-open: restore the trigger caret to end-of-text.
|
|
20839
|
-
// Clicking the trigger lands on auro-input's floating <label for="…">
|
|
20840
|
-
// overlay; Chrome resets the native input's selection to [0, 0] on
|
|
20841
|
-
// label-focus before any JS runs. setInputFocus()'s non-fullscreen
|
|
20842
|
-
// branch parks the caret at end. doubleRaf lets the dropdown layout
|
|
20843
|
-
// settle first, matching the fullscreen branch timing.
|
|
20844
|
-
doubleRaf(() => {
|
|
20845
|
-
this.setInputFocus();
|
|
20846
|
-
});
|
|
20847
20854
|
}
|
|
20855
|
+
// else (desktop popover-open): Chrome resets the trigger caret to
|
|
20856
|
+
// [0, 0] when its floating <label for="…"> overlay receives focus.
|
|
20857
|
+
// The shared doubleRaf below parks the caret back at end-of-text
|
|
20858
|
+
// after the dropdown layout settles.
|
|
20859
|
+
|
|
20860
|
+
doubleRaf(() => {
|
|
20861
|
+
this.setInputFocus();
|
|
20862
|
+
if (this._inFullscreenTransition) {
|
|
20863
|
+
this._inFullscreenTransition = false;
|
|
20864
|
+
}
|
|
20865
|
+
});
|
|
20848
20866
|
}
|
|
20849
20867
|
});
|
|
20850
20868
|
|
|
@@ -20951,9 +20969,9 @@ class AuroCombobox extends AuroElement {
|
|
|
20951
20969
|
} else {
|
|
20952
20970
|
// Safety net for the strategy-change setTimeout: a viewport-crossing
|
|
20953
20971
|
// fullscreen→floating switch can close the dialog and leave focus on
|
|
20954
|
-
// body. Every other
|
|
20955
|
-
// via the focusin → this.focus() redirect
|
|
20956
|
-
// no-op in the common case.
|
|
20972
|
+
// body. Every other call into this branch already has focus on the
|
|
20973
|
+
// input via the combobox-level focusin → this.focus() redirect, so
|
|
20974
|
+
// this is a no-op in the common case.
|
|
20957
20975
|
if (!this.input.componentHasFocus) {
|
|
20958
20976
|
this.input.focus();
|
|
20959
20977
|
}
|
|
@@ -21072,7 +21090,7 @@ class AuroCombobox extends AuroElement {
|
|
|
21072
21090
|
if (this.menu.optionSelected) {
|
|
21073
21091
|
const selected = this.menu.optionSelected;
|
|
21074
21092
|
|
|
21075
|
-
if (
|
|
21093
|
+
if (this.optionSelected !== selected) {
|
|
21076
21094
|
this.optionSelected = selected;
|
|
21077
21095
|
}
|
|
21078
21096
|
|
|
@@ -21085,7 +21103,7 @@ class AuroCombobox extends AuroElement {
|
|
|
21085
21103
|
}
|
|
21086
21104
|
|
|
21087
21105
|
// Update display
|
|
21088
|
-
this.updateTriggerTextDisplay(getOptionLabel(this.optionSelected)
|
|
21106
|
+
this.updateTriggerTextDisplay(getOptionLabel(this.optionSelected));
|
|
21089
21107
|
|
|
21090
21108
|
// Update match word for filtering
|
|
21091
21109
|
const trimmedInput = normalizeFilterValue(this.input.value);
|
|
@@ -21467,15 +21485,7 @@ class AuroCombobox extends AuroElement {
|
|
|
21467
21485
|
this.menu.value = undefined;
|
|
21468
21486
|
this.validation.reset(this);
|
|
21469
21487
|
this.touched = false;
|
|
21470
|
-
// Force validity back to the cleared state. validation.reset() calls
|
|
21471
|
-
// validate() at the end, and (post-credit-card-fix) the trigger input's
|
|
21472
|
-
// residual validity may still be copied into the combobox by the
|
|
21473
|
-
// auroInputElements loop. Explicitly clear here so reset() actually
|
|
21474
|
-
// leaves the component in a "no validity" state.
|
|
21475
21488
|
this.validity = undefined;
|
|
21476
|
-
this.errorMessage = '';
|
|
21477
|
-
this.input.validity = undefined;
|
|
21478
|
-
this.input.errorMessage = '';
|
|
21479
21489
|
}
|
|
21480
21490
|
|
|
21481
21491
|
/**
|
|
@@ -21528,52 +21538,23 @@ class AuroCombobox extends AuroElement {
|
|
|
21528
21538
|
this.input.value = this.value;
|
|
21529
21539
|
}
|
|
21530
21540
|
|
|
21531
|
-
// Sync menu.value only when an option actually matches
|
|
21541
|
+
// Sync menu.value only when an option actually matches, or when filter
|
|
21542
|
+
// mode needs setMenuValue to dispatch auroMenu-selectValueFailure (the
|
|
21543
|
+
// listener at line 1206 clears combobox.value, mirroring select's
|
|
21544
|
+
// pattern). Otherwise sync the input display for freeform values.
|
|
21532
21545
|
if (this.menu.options && this.menu.options.length > 0) {
|
|
21533
|
-
if (this.menu.options.some((opt) => opt.value === this.value)) {
|
|
21534
|
-
this.setMenuValue(this.value);
|
|
21535
|
-
} else if (this.behavior === 'filter') {
|
|
21536
|
-
// In filter mode, freeform values aren't allowed. Push the unmatched
|
|
21537
|
-
// value through setMenuValue so menu dispatches auroMenu-selectValueFailure
|
|
21538
|
-
// and the listener at line 1206 clears combobox.value (mirrors select's
|
|
21539
|
-
// pattern). Bypassing setMenuValue here would skip the failure cascade.
|
|
21546
|
+
if (this.menu.options.some((opt) => opt.value === this.value) || this.behavior === 'filter') {
|
|
21540
21547
|
this.setMenuValue(this.value);
|
|
21541
21548
|
} else {
|
|
21542
21549
|
if (this.menu.value) {
|
|
21543
21550
|
this.menu.value = undefined;
|
|
21544
21551
|
}
|
|
21545
|
-
//
|
|
21546
|
-
//
|
|
21547
|
-
//
|
|
21548
|
-
|
|
21549
|
-
|
|
21550
|
-
|
|
21551
|
-
const triggerNeedsSync = this.input.value !== nextValue;
|
|
21552
|
-
const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
|
|
21553
|
-
if (triggerNeedsSync || bibNeedsSync) {
|
|
21554
|
-
this._syncingDisplayValue = true;
|
|
21555
|
-
if (triggerNeedsSync) {
|
|
21556
|
-
this.input.value = nextValue;
|
|
21557
|
-
}
|
|
21558
|
-
if (bibNeedsSync) {
|
|
21559
|
-
this.inputInBib.value = nextValue;
|
|
21560
|
-
}
|
|
21561
|
-
const pending = [];
|
|
21562
|
-
if (triggerNeedsSync) {
|
|
21563
|
-
pending.push(this.input.updateComplete);
|
|
21564
|
-
}
|
|
21565
|
-
if (bibNeedsSync) {
|
|
21566
|
-
pending.push(this.inputInBib.updateComplete);
|
|
21567
|
-
}
|
|
21568
|
-
Promise.all(pending).then(() => {
|
|
21569
|
-
if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
|
|
21570
|
-
this.input.maskInstance.updateValue();
|
|
21571
|
-
}
|
|
21572
|
-
if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
|
|
21573
|
-
this.inputInBib.maskInstance.updateValue();
|
|
21574
|
-
}
|
|
21575
|
-
this._syncingDisplayValue = false;
|
|
21576
|
-
// handleInputValueChange bailed on the flag — refresh the filter.
|
|
21552
|
+
// Suggestion-mode freeform value: sync the trigger + bib to show it,
|
|
21553
|
+
// then refresh the filter once the inputs flush (handleInputValueChange
|
|
21554
|
+
// bailed on _syncingDisplayValue).
|
|
21555
|
+
const syncPromise = this.syncInputValuesAcrossTriggerAndBib(this.value || '');
|
|
21556
|
+
if (syncPromise) {
|
|
21557
|
+
syncPromise.then(() => {
|
|
21577
21558
|
this._programmaticFilterRefresh = true;
|
|
21578
21559
|
this.handleMenuOptions();
|
|
21579
21560
|
setTimeout(() => {
|
|
@@ -412,6 +412,15 @@ export class AuroCombobox extends AuroElement {
|
|
|
412
412
|
* @private
|
|
413
413
|
*/
|
|
414
414
|
private updateTriggerTextDisplay;
|
|
415
|
+
/**
|
|
416
|
+
* Writes nextValue to the trigger input and the bib input when their current
|
|
417
|
+
* value differs, then re-asserts imask after Lit's update flushes.
|
|
418
|
+
* @param {string} nextValue - The value to write to both inputs.
|
|
419
|
+
* @returns {Promise<void> | null} Promise that resolves after the inputs flush,
|
|
420
|
+
* or null when no sync was needed (so callers can skip post-flush work).
|
|
421
|
+
* @private
|
|
422
|
+
*/
|
|
423
|
+
private syncInputValuesAcrossTriggerAndBib;
|
|
415
424
|
_syncingDisplayValue: boolean | undefined;
|
|
416
425
|
/**
|
|
417
426
|
* Processes hidden state of all menu options and determines if there are any available options not hidden.
|