@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
|
@@ -767,6 +767,8 @@ function navigateArrow(component, direction, options = {}) {
|
|
|
767
767
|
}
|
|
768
768
|
}
|
|
769
769
|
|
|
770
|
+
/* eslint-disable no-underscore-dangle */
|
|
771
|
+
|
|
770
772
|
/**
|
|
771
773
|
* Returns the clear button element from the active input's shadow
|
|
772
774
|
* DOM, if available.
|
|
@@ -802,11 +804,9 @@ function isClearBtnFocused(ctx, clearBtn = getClearBtn(ctx)) {
|
|
|
802
804
|
* @param {Object} menu - The menu component.
|
|
803
805
|
*/
|
|
804
806
|
function reconcileMenuIndex(menu) {
|
|
805
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
806
807
|
if (menu._index < 0 && menu.optionActive && menu.items) {
|
|
807
808
|
const idx = menu.items.indexOf(menu.optionActive);
|
|
808
809
|
if (idx >= 0) {
|
|
809
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
810
810
|
menu._index = idx;
|
|
811
811
|
}
|
|
812
812
|
}
|
|
@@ -4806,7 +4806,7 @@ let AuroHelpText$2 = class AuroHelpText extends LitElement {
|
|
|
4806
4806
|
}
|
|
4807
4807
|
};
|
|
4808
4808
|
|
|
4809
|
-
var formkitVersion$2 = '
|
|
4809
|
+
var formkitVersion$2 = '202606190840';
|
|
4810
4810
|
|
|
4811
4811
|
let AuroElement$2 = class AuroElement extends LitElement {
|
|
4812
4812
|
static get properties() {
|
|
@@ -16520,6 +16520,7 @@ class AuroInputUtilities {
|
|
|
16520
16520
|
const maskOptions = this.getMaskOptions('date', normalizedFormat);
|
|
16521
16521
|
|
|
16522
16522
|
if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
|
|
16523
|
+
console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
|
|
16523
16524
|
return undefined;
|
|
16524
16525
|
}
|
|
16525
16526
|
|
|
@@ -17330,10 +17331,6 @@ class BaseInput extends AuroElement$1 {
|
|
|
17330
17331
|
this.wrapperElement.addEventListener('click', this.handleClick);
|
|
17331
17332
|
}
|
|
17332
17333
|
|
|
17333
|
-
// add attribute for query selectors when auro-input is registered under a custom name
|
|
17334
|
-
if (this.tagName.toLowerCase() !== 'auro-input' && !this.hasAttribute('auro-input')) {
|
|
17335
|
-
this.setAttribute('auro-input', '');
|
|
17336
|
-
}
|
|
17337
17334
|
this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
|
|
17338
17335
|
|
|
17339
17336
|
// use validity message override if declared when initializing the component
|
|
@@ -17504,14 +17501,14 @@ class BaseInput extends AuroElement$1 {
|
|
|
17504
17501
|
|
|
17505
17502
|
if (formattedValue !== this.inputElement.value) {
|
|
17506
17503
|
this.skipNextProgrammaticInputEvent = true;
|
|
17507
|
-
if (this.maskInstance && this.type
|
|
17504
|
+
if (this.maskInstance && this.type !== 'date') {
|
|
17508
17505
|
// Route through the mask so its _value and el.value stay in lock-step
|
|
17509
17506
|
// (set value calls updateControl which writes el.value = displayValue).
|
|
17510
17507
|
// Writing el.value directly leaves the mask thinking displayValue is
|
|
17511
|
-
// stale; _saveSelection on the next focus/click then warns.
|
|
17512
|
-
//
|
|
17513
|
-
//
|
|
17514
|
-
//
|
|
17508
|
+
// stale; _saveSelection on the next focus/click then warns. Date is
|
|
17509
|
+
// excluded because its formattedValue can be raw ISO when the calendar
|
|
17510
|
+
// is invalid, and re-masking through mm/dd/yyyy would truncate it and
|
|
17511
|
+
// flip validity from patternMismatch to tooShort.
|
|
17515
17512
|
this.maskInstance.value = formattedValue || '';
|
|
17516
17513
|
} else if (formattedValue) {
|
|
17517
17514
|
this.inputElement.value = formattedValue;
|
|
@@ -17622,31 +17619,33 @@ class BaseInput extends AuroElement$1 {
|
|
|
17622
17619
|
* @returns {void}
|
|
17623
17620
|
*/
|
|
17624
17621
|
configureAutoFormatting() {
|
|
17625
|
-
//
|
|
17626
|
-
//
|
|
17627
|
-
//
|
|
17628
|
-
//
|
|
17622
|
+
// _configuringMask gates two things: external re-entry into this method
|
|
17623
|
+
// while setup is mid-flight (from property changes that call back here),
|
|
17624
|
+
// and the accept/complete listeners below — both need to ignore the mask
|
|
17625
|
+
// events fired by our own value-restore step.
|
|
17629
17626
|
if (this._configuringMask) return;
|
|
17630
17627
|
this._configuringMask = true;
|
|
17631
17628
|
try {
|
|
17629
|
+
// Destroy any prior mask so IMask can attach fresh under the new format.
|
|
17632
17630
|
if (this.maskInstance) {
|
|
17633
17631
|
this.maskInstance.destroy();
|
|
17634
17632
|
}
|
|
17635
17633
|
|
|
17636
|
-
// Pass new format to util
|
|
17637
17634
|
this.util.updateFormat(this.format);
|
|
17638
17635
|
|
|
17639
17636
|
const maskOptions = this.util.getMaskOptions(this.type, this.format);
|
|
17640
17637
|
|
|
17641
17638
|
if (this.inputElement && maskOptions.mask) {
|
|
17642
|
-
|
|
17643
|
-
//
|
|
17644
|
-
//
|
|
17645
|
-
//
|
|
17646
|
-
// When the format changes (e.g. locale switch) and we have a valid ISO
|
|
17647
|
-
// model value, compute the display string for the NEW format instead of
|
|
17648
|
-
// re-using the old display string, which may be invalid in the new mask.
|
|
17639
|
+
// Capture the current display so it can be re-applied after IMask
|
|
17640
|
+
// attaches. The restore at the bottom goes through maskInstance.value
|
|
17641
|
+
// (not inputElement.value directly) so the mask's internal state and
|
|
17642
|
+
// the input's displayed text stay in lock-step.
|
|
17649
17643
|
let existingValue = this.inputElement.value;
|
|
17644
|
+
|
|
17645
|
+
// Format-change case (e.g. locale switch): existingValue is the OLD
|
|
17646
|
+
// mask's display string and may not parse under the new mask. When
|
|
17647
|
+
// we have a valid date model, rebuild the display from valueObject
|
|
17648
|
+
// (the canonical source) using the new mask's format function.
|
|
17650
17649
|
if (
|
|
17651
17650
|
this.util.isFullDateFormat(this.type, this.format) &&
|
|
17652
17651
|
this.value &&
|
|
@@ -17658,15 +17657,18 @@ class BaseInput extends AuroElement$1 {
|
|
|
17658
17657
|
existingValue = maskOptions.format(this.valueObject);
|
|
17659
17658
|
}
|
|
17660
17659
|
|
|
17660
|
+
// Clear before IMask attaches so the constructor seeds an empty
|
|
17661
|
+
// internal value. Otherwise IMask reads the stale unmasked string
|
|
17662
|
+
// and emits a spurious 'accept' before the restore below runs.
|
|
17661
17663
|
this.skipNextProgrammaticInputEvent = true;
|
|
17662
17664
|
this.inputElement.value = '';
|
|
17663
17665
|
|
|
17664
17666
|
this.maskInstance = IMask(this.inputElement, maskOptions);
|
|
17665
17667
|
|
|
17668
|
+
// Mask fires 'accept' on every value change, including the restore
|
|
17669
|
+
// step below. Skip events fired during configureAutoFormatting so
|
|
17670
|
+
// we don't overwrite a value the parent just pushed.
|
|
17666
17671
|
this.maskInstance.on('accept', () => {
|
|
17667
|
-
// Suppress propagation during configureAutoFormatting's own value-restoration
|
|
17668
|
-
// (line below) — the mask emits 'accept' on every value-set, including ours,
|
|
17669
|
-
// and we don't want to overwrite a value the parent just pushed.
|
|
17670
17672
|
if (this._configuringMask) return;
|
|
17671
17673
|
this.value = this.util.toModelValue(this.maskInstance.value, this.format);
|
|
17672
17674
|
if (this.type === "date") {
|
|
@@ -17674,6 +17676,8 @@ class BaseInput extends AuroElement$1 {
|
|
|
17674
17676
|
}
|
|
17675
17677
|
});
|
|
17676
17678
|
|
|
17679
|
+
// Mask fires 'complete' on the restore step below for any value that
|
|
17680
|
+
// happens to be a complete match. Same setup-suppression as 'accept'.
|
|
17677
17681
|
this.maskInstance.on('complete', () => {
|
|
17678
17682
|
if (this._configuringMask) return;
|
|
17679
17683
|
this.value = this.util.toModelValue(this.maskInstance.value, this.format);
|
|
@@ -17682,7 +17686,9 @@ class BaseInput extends AuroElement$1 {
|
|
|
17682
17686
|
}
|
|
17683
17687
|
});
|
|
17684
17688
|
|
|
17685
|
-
//
|
|
17689
|
+
// Write existingValue through the mask (not the input directly) so
|
|
17690
|
+
// the mask reformats it under the new rules and keeps its internal
|
|
17691
|
+
// _value aligned with the input's displayed text.
|
|
17686
17692
|
if (existingValue) {
|
|
17687
17693
|
this.maskInstance.value = existingValue;
|
|
17688
17694
|
}
|
|
@@ -18388,7 +18394,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
|
|
|
18388
18394
|
}
|
|
18389
18395
|
};
|
|
18390
18396
|
|
|
18391
|
-
var formkitVersion$1 = '
|
|
18397
|
+
var formkitVersion$1 = '202606190840';
|
|
18392
18398
|
|
|
18393
18399
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
18394
18400
|
// See LICENSE in the project root for license information.
|
|
@@ -19509,7 +19515,7 @@ class AuroBibtemplate extends LitElement {
|
|
|
19509
19515
|
}
|
|
19510
19516
|
}
|
|
19511
19517
|
|
|
19512
|
-
var formkitVersion = '
|
|
19518
|
+
var formkitVersion = '202606190840';
|
|
19513
19519
|
|
|
19514
19520
|
var styleCss$1 = css`.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}`;
|
|
19515
19521
|
|
|
@@ -20496,7 +20502,7 @@ class AuroCombobox extends AuroElement {
|
|
|
20496
20502
|
if (this.menu) {
|
|
20497
20503
|
this.menu.matchWord = normalizeFilterValue(this.input.value);
|
|
20498
20504
|
}
|
|
20499
|
-
const label = getOptionLabel(this.menu.optionSelected)
|
|
20505
|
+
const label = getOptionLabel(this.menu.optionSelected);
|
|
20500
20506
|
this.updateTriggerTextDisplay(label || this.value);
|
|
20501
20507
|
}
|
|
20502
20508
|
|
|
@@ -20510,40 +20516,9 @@ class AuroCombobox extends AuroElement {
|
|
|
20510
20516
|
// in suggestion mode, do not override input value if no selection has been made and the input currently has focus
|
|
20511
20517
|
const isInputFocusedWithNoSelection = !this.menu.value && (this.input.matches(':focus-within') || (this.inputInBib && this.inputInBib.matches(':focus-within')));
|
|
20512
20518
|
|
|
20513
|
-
|
|
20514
|
-
|
|
20515
|
-
|
|
20516
|
-
// syncValuesAndStates re-enters here during typing when both inputs
|
|
20517
|
-
// already match, and a no-op flag flip would make the bib branch's
|
|
20518
|
-
// bail eat legitimate user-input events.
|
|
20519
|
-
const triggerNeedsSync = this.input.value !== nextValue;
|
|
20520
|
-
const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
|
|
20521
|
-
if (triggerNeedsSync || bibNeedsSync) {
|
|
20522
|
-
this._syncingDisplayValue = true;
|
|
20523
|
-
if (triggerNeedsSync) {
|
|
20524
|
-
this.input.value = nextValue;
|
|
20525
|
-
}
|
|
20526
|
-
if (bibNeedsSync) {
|
|
20527
|
-
this.inputInBib.value = nextValue;
|
|
20528
|
-
}
|
|
20529
|
-
const pending = [];
|
|
20530
|
-
if (triggerNeedsSync) {
|
|
20531
|
-
pending.push(this.input.updateComplete);
|
|
20532
|
-
}
|
|
20533
|
-
if (bibNeedsSync) {
|
|
20534
|
-
pending.push(this.inputInBib.updateComplete);
|
|
20535
|
-
}
|
|
20536
|
-
Promise.all(pending).then(() => {
|
|
20537
|
-
// imask reasserts otherwise, and handleBlur reverts to its stale value.
|
|
20538
|
-
if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
|
|
20539
|
-
this.input.maskInstance.updateValue();
|
|
20540
|
-
}
|
|
20541
|
-
if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
|
|
20542
|
-
this.inputInBib.maskInstance.updateValue();
|
|
20543
|
-
}
|
|
20544
|
-
this._syncingDisplayValue = false;
|
|
20545
|
-
});
|
|
20546
|
-
}
|
|
20519
|
+
const suppressed = this.persistInput || (this.behavior === 'suggestion' && isInputFocusedWithNoSelection);
|
|
20520
|
+
if (!suppressed) {
|
|
20521
|
+
this.syncInputValuesAcrossTriggerAndBib(label || this.value);
|
|
20547
20522
|
}
|
|
20548
20523
|
|
|
20549
20524
|
// update the displayValue in the trigger if displayValue slot content is present
|
|
@@ -20571,6 +20546,52 @@ class AuroCombobox extends AuroElement {
|
|
|
20571
20546
|
this.requestUpdate();
|
|
20572
20547
|
}
|
|
20573
20548
|
|
|
20549
|
+
/**
|
|
20550
|
+
* Writes nextValue to the trigger input and the bib input when their current
|
|
20551
|
+
* value differs, then re-asserts imask after Lit's update flushes.
|
|
20552
|
+
* @param {string} nextValue - The value to write to both inputs.
|
|
20553
|
+
* @returns {Promise<void> | null} Promise that resolves after the inputs flush,
|
|
20554
|
+
* or null when no sync was needed (so callers can skip post-flush work).
|
|
20555
|
+
* @private
|
|
20556
|
+
*/
|
|
20557
|
+
syncInputValuesAcrossTriggerAndBib(nextValue) {
|
|
20558
|
+
// Only set the flag when there's an actual write to suppress —
|
|
20559
|
+
// syncValuesAndStates re-enters here during typing when both inputs
|
|
20560
|
+
// already match, and a no-op flag flip would make the bib branch's
|
|
20561
|
+
// bail eat legitimate user-input events.
|
|
20562
|
+
const triggerNeedsSync = this.input.value !== nextValue;
|
|
20563
|
+
const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
|
|
20564
|
+
if (!triggerNeedsSync && !bibNeedsSync) {
|
|
20565
|
+
return null;
|
|
20566
|
+
}
|
|
20567
|
+
|
|
20568
|
+
this._syncingDisplayValue = true;
|
|
20569
|
+
if (triggerNeedsSync) {
|
|
20570
|
+
this.input.value = nextValue;
|
|
20571
|
+
}
|
|
20572
|
+
if (bibNeedsSync) {
|
|
20573
|
+
this.inputInBib.value = nextValue;
|
|
20574
|
+
}
|
|
20575
|
+
|
|
20576
|
+
const pending = [];
|
|
20577
|
+
if (triggerNeedsSync) {
|
|
20578
|
+
pending.push(this.input.updateComplete);
|
|
20579
|
+
}
|
|
20580
|
+
if (bibNeedsSync) {
|
|
20581
|
+
pending.push(this.inputInBib.updateComplete);
|
|
20582
|
+
}
|
|
20583
|
+
return Promise.all(pending).then(() => {
|
|
20584
|
+
// imask reasserts otherwise, and handleBlur reverts to its stale value.
|
|
20585
|
+
if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
|
|
20586
|
+
this.input.maskInstance.updateValue();
|
|
20587
|
+
}
|
|
20588
|
+
if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
|
|
20589
|
+
this.inputInBib.maskInstance.updateValue();
|
|
20590
|
+
}
|
|
20591
|
+
this._syncingDisplayValue = false;
|
|
20592
|
+
});
|
|
20593
|
+
}
|
|
20594
|
+
|
|
20574
20595
|
/**
|
|
20575
20596
|
* Processes hidden state of all menu options and determines if there are any available options not hidden.
|
|
20576
20597
|
* @private
|
|
@@ -20598,9 +20619,9 @@ class AuroCombobox extends AuroElement {
|
|
|
20598
20619
|
this.syncValuesAndStates();
|
|
20599
20620
|
}
|
|
20600
20621
|
|
|
20601
|
-
// Re-activate when optionActive is
|
|
20602
|
-
// been reset (e.g. by clearSelection in an async update)
|
|
20603
|
-
// makeSelection() can find the correct option.
|
|
20622
|
+
// Re-activate when optionActive is not in the current scrollable viewport,
|
|
20623
|
+
// or when _index has been reset (e.g. by clearSelection in an async update)
|
|
20624
|
+
// so that makeSelection() can find the correct option.
|
|
20604
20625
|
if (!this.availableOptions.includes(this.menu.optionActive) || this.menu._index < 0) {
|
|
20605
20626
|
this.activateFirstEnabledAvailableOption();
|
|
20606
20627
|
}
|
|
@@ -20734,28 +20755,25 @@ class AuroCombobox extends AuroElement {
|
|
|
20734
20755
|
|
|
20735
20756
|
guardTouchPassthrough(this.menu);
|
|
20736
20757
|
|
|
20737
|
-
//
|
|
20738
|
-
//
|
|
20739
|
-
//
|
|
20758
|
+
// showModal() takes focus away from the trigger. Early focus once
|
|
20759
|
+
// the dialog has painted; the shared doubleRaf below is the fallback
|
|
20760
|
+
// for when the dialog needs an extra frame and also clears the
|
|
20761
|
+
// validation guard.
|
|
20740
20762
|
requestAnimationFrame(() => {
|
|
20741
20763
|
this.setInputFocus();
|
|
20742
20764
|
});
|
|
20743
|
-
|
|
20744
|
-
doubleRaf(() => {
|
|
20745
|
-
this.setInputFocus();
|
|
20746
|
-
this._inFullscreenTransition = false;
|
|
20747
|
-
});
|
|
20748
|
-
} else {
|
|
20749
|
-
// Desktop popover-open: restore the trigger caret to end-of-text.
|
|
20750
|
-
// Clicking the trigger lands on auro-input's floating <label for="…">
|
|
20751
|
-
// overlay; Chrome resets the native input's selection to [0, 0] on
|
|
20752
|
-
// label-focus before any JS runs. setInputFocus()'s non-fullscreen
|
|
20753
|
-
// branch parks the caret at end. doubleRaf lets the dropdown layout
|
|
20754
|
-
// settle first, matching the fullscreen branch timing.
|
|
20755
|
-
doubleRaf(() => {
|
|
20756
|
-
this.setInputFocus();
|
|
20757
|
-
});
|
|
20758
20765
|
}
|
|
20766
|
+
// else (desktop popover-open): Chrome resets the trigger caret to
|
|
20767
|
+
// [0, 0] when its floating <label for="…"> overlay receives focus.
|
|
20768
|
+
// The shared doubleRaf below parks the caret back at end-of-text
|
|
20769
|
+
// after the dropdown layout settles.
|
|
20770
|
+
|
|
20771
|
+
doubleRaf(() => {
|
|
20772
|
+
this.setInputFocus();
|
|
20773
|
+
if (this._inFullscreenTransition) {
|
|
20774
|
+
this._inFullscreenTransition = false;
|
|
20775
|
+
}
|
|
20776
|
+
});
|
|
20759
20777
|
}
|
|
20760
20778
|
});
|
|
20761
20779
|
|
|
@@ -20862,9 +20880,9 @@ class AuroCombobox extends AuroElement {
|
|
|
20862
20880
|
} else {
|
|
20863
20881
|
// Safety net for the strategy-change setTimeout: a viewport-crossing
|
|
20864
20882
|
// fullscreen→floating switch can close the dialog and leave focus on
|
|
20865
|
-
// body. Every other
|
|
20866
|
-
// via the focusin → this.focus() redirect
|
|
20867
|
-
// no-op in the common case.
|
|
20883
|
+
// body. Every other call into this branch already has focus on the
|
|
20884
|
+
// input via the combobox-level focusin → this.focus() redirect, so
|
|
20885
|
+
// this is a no-op in the common case.
|
|
20868
20886
|
if (!this.input.componentHasFocus) {
|
|
20869
20887
|
this.input.focus();
|
|
20870
20888
|
}
|
|
@@ -20983,7 +21001,7 @@ class AuroCombobox extends AuroElement {
|
|
|
20983
21001
|
if (this.menu.optionSelected) {
|
|
20984
21002
|
const selected = this.menu.optionSelected;
|
|
20985
21003
|
|
|
20986
|
-
if (
|
|
21004
|
+
if (this.optionSelected !== selected) {
|
|
20987
21005
|
this.optionSelected = selected;
|
|
20988
21006
|
}
|
|
20989
21007
|
|
|
@@ -20996,7 +21014,7 @@ class AuroCombobox extends AuroElement {
|
|
|
20996
21014
|
}
|
|
20997
21015
|
|
|
20998
21016
|
// Update display
|
|
20999
|
-
this.updateTriggerTextDisplay(getOptionLabel(this.optionSelected)
|
|
21017
|
+
this.updateTriggerTextDisplay(getOptionLabel(this.optionSelected));
|
|
21000
21018
|
|
|
21001
21019
|
// Update match word for filtering
|
|
21002
21020
|
const trimmedInput = normalizeFilterValue(this.input.value);
|
|
@@ -21378,15 +21396,7 @@ class AuroCombobox extends AuroElement {
|
|
|
21378
21396
|
this.menu.value = undefined;
|
|
21379
21397
|
this.validation.reset(this);
|
|
21380
21398
|
this.touched = false;
|
|
21381
|
-
// Force validity back to the cleared state. validation.reset() calls
|
|
21382
|
-
// validate() at the end, and (post-credit-card-fix) the trigger input's
|
|
21383
|
-
// residual validity may still be copied into the combobox by the
|
|
21384
|
-
// auroInputElements loop. Explicitly clear here so reset() actually
|
|
21385
|
-
// leaves the component in a "no validity" state.
|
|
21386
21399
|
this.validity = undefined;
|
|
21387
|
-
this.errorMessage = '';
|
|
21388
|
-
this.input.validity = undefined;
|
|
21389
|
-
this.input.errorMessage = '';
|
|
21390
21400
|
}
|
|
21391
21401
|
|
|
21392
21402
|
/**
|
|
@@ -21439,52 +21449,23 @@ class AuroCombobox extends AuroElement {
|
|
|
21439
21449
|
this.input.value = this.value;
|
|
21440
21450
|
}
|
|
21441
21451
|
|
|
21442
|
-
// Sync menu.value only when an option actually matches
|
|
21452
|
+
// Sync menu.value only when an option actually matches, or when filter
|
|
21453
|
+
// mode needs setMenuValue to dispatch auroMenu-selectValueFailure (the
|
|
21454
|
+
// listener at line 1206 clears combobox.value, mirroring select's
|
|
21455
|
+
// pattern). Otherwise sync the input display for freeform values.
|
|
21443
21456
|
if (this.menu.options && this.menu.options.length > 0) {
|
|
21444
|
-
if (this.menu.options.some((opt) => opt.value === this.value)) {
|
|
21445
|
-
this.setMenuValue(this.value);
|
|
21446
|
-
} else if (this.behavior === 'filter') {
|
|
21447
|
-
// In filter mode, freeform values aren't allowed. Push the unmatched
|
|
21448
|
-
// value through setMenuValue so menu dispatches auroMenu-selectValueFailure
|
|
21449
|
-
// and the listener at line 1206 clears combobox.value (mirrors select's
|
|
21450
|
-
// pattern). Bypassing setMenuValue here would skip the failure cascade.
|
|
21457
|
+
if (this.menu.options.some((opt) => opt.value === this.value) || this.behavior === 'filter') {
|
|
21451
21458
|
this.setMenuValue(this.value);
|
|
21452
21459
|
} else {
|
|
21453
21460
|
if (this.menu.value) {
|
|
21454
21461
|
this.menu.value = undefined;
|
|
21455
21462
|
}
|
|
21456
|
-
//
|
|
21457
|
-
//
|
|
21458
|
-
//
|
|
21459
|
-
|
|
21460
|
-
|
|
21461
|
-
|
|
21462
|
-
const triggerNeedsSync = this.input.value !== nextValue;
|
|
21463
|
-
const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
|
|
21464
|
-
if (triggerNeedsSync || bibNeedsSync) {
|
|
21465
|
-
this._syncingDisplayValue = true;
|
|
21466
|
-
if (triggerNeedsSync) {
|
|
21467
|
-
this.input.value = nextValue;
|
|
21468
|
-
}
|
|
21469
|
-
if (bibNeedsSync) {
|
|
21470
|
-
this.inputInBib.value = nextValue;
|
|
21471
|
-
}
|
|
21472
|
-
const pending = [];
|
|
21473
|
-
if (triggerNeedsSync) {
|
|
21474
|
-
pending.push(this.input.updateComplete);
|
|
21475
|
-
}
|
|
21476
|
-
if (bibNeedsSync) {
|
|
21477
|
-
pending.push(this.inputInBib.updateComplete);
|
|
21478
|
-
}
|
|
21479
|
-
Promise.all(pending).then(() => {
|
|
21480
|
-
if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
|
|
21481
|
-
this.input.maskInstance.updateValue();
|
|
21482
|
-
}
|
|
21483
|
-
if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
|
|
21484
|
-
this.inputInBib.maskInstance.updateValue();
|
|
21485
|
-
}
|
|
21486
|
-
this._syncingDisplayValue = false;
|
|
21487
|
-
// handleInputValueChange bailed on the flag — refresh the filter.
|
|
21463
|
+
// Suggestion-mode freeform value: sync the trigger + bib to show it,
|
|
21464
|
+
// then refresh the filter once the inputs flush (handleInputValueChange
|
|
21465
|
+
// bailed on _syncingDisplayValue).
|
|
21466
|
+
const syncPromise = this.syncInputValuesAcrossTriggerAndBib(this.value || '');
|
|
21467
|
+
if (syncPromise) {
|
|
21468
|
+
syncPromise.then(() => {
|
|
21488
21469
|
this._programmaticFilterRefresh = true;
|
|
21489
21470
|
this.handleMenuOptions();
|
|
21490
21471
|
setTimeout(() => {
|