@aurodesignsystem-dev/auro-formkit 0.0.0-pr1498.0 → 0.0.0-pr1499.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/checkbox/demo/customize.min.js +2 -2
- package/components/checkbox/demo/getting-started.min.js +2 -2
- package/components/checkbox/demo/index.min.js +2 -2
- package/components/checkbox/dist/index.js +2 -2
- package/components/checkbox/dist/registered.js +2 -2
- package/components/combobox/demo/customize.md +3 -7
- package/components/combobox/demo/customize.min.js +1703 -1461
- package/components/combobox/demo/getting-started.min.js +1703 -1461
- package/components/combobox/demo/index.min.js +1703 -1461
- package/components/combobox/dist/auro-combobox.d.ts +0 -5
- package/components/combobox/dist/index.js +162 -495
- package/components/combobox/dist/registered.js +162 -495
- package/components/counter/demo/customize.min.js +19 -18
- package/components/counter/demo/index.min.js +19 -18
- package/components/counter/dist/index.js +160 -5811
- package/components/counter/dist/registered.js +187 -5442
- package/components/datepicker/demo/customize.md +477 -384
- package/components/datepicker/demo/customize.min.js +99 -171
- package/components/datepicker/demo/index.md +0 -1
- package/components/datepicker/demo/index.min.js +99 -171
- package/components/datepicker/dist/index.js +99 -171
- package/components/datepicker/dist/registered.js +99 -171
- package/components/datepicker/dist/src/auro-datepicker.d.ts +2 -2
- package/components/dropdown/demo/customize.min.js +17 -16
- package/components/dropdown/demo/getting-started.min.js +17 -16
- package/components/dropdown/demo/index.min.js +17 -16
- package/components/dropdown/dist/auro-dropdown.d.ts +2 -1
- package/components/dropdown/dist/index.js +17 -16
- package/components/dropdown/dist/registered.js +17 -16
- package/components/form/demo/customize.min.js +8494 -8428
- package/components/form/demo/getting-started.min.js +8494 -8428
- package/components/form/demo/index.min.js +8494 -8428
- package/components/form/demo/registerDemoDeps.min.js +8518 -8452
- package/components/input/demo/customize.md +539 -472
- package/components/input/demo/customize.min.js +61 -136
- package/components/input/demo/getting-started.min.js +61 -136
- package/components/input/demo/index.min.js +61 -136
- package/components/input/dist/base-input.d.ts +0 -16
- package/components/input/dist/index.js +61 -136
- package/components/input/dist/registered.js +61 -136
- package/components/menu/demo/api.md +45 -41
- package/components/menu/demo/customize.md +28 -0
- package/components/menu/demo/index.min.js +1358 -783
- package/components/menu/dist/auro-menu.context.d.ts +238 -0
- package/components/menu/dist/auro-menu.d.ts +110 -95
- package/components/menu/dist/auro-menuoption.d.ts +138 -32
- package/components/menu/dist/index.js +1312 -757
- package/components/menu/dist/registered.js +1312 -769
- package/components/radio/demo/customize.min.js +2 -2
- package/components/radio/demo/getting-started.min.js +2 -2
- package/components/radio/demo/index.min.js +2 -2
- package/components/radio/dist/index.js +2 -2
- package/components/radio/dist/registered.js +2 -2
- package/components/select/demo/customize.md +3 -7
- package/components/select/demo/customize.min.js +1634 -1089
- package/components/select/demo/getting-started.min.js +1634 -1089
- package/components/select/demo/index.min.js +1634 -1089
- package/components/select/dist/index.js +31 -61
- package/components/select/dist/registered.js +31 -61
- package/custom-elements.json +1024 -378
- package/package.json +1 -1
- package/components/select/dist/selectUtils.d.ts +0 -12
|
@@ -555,7 +555,7 @@ let AuroFormValidation$1 = class AuroFormValidation {
|
|
|
555
555
|
} else if (this.runtimeUtils.elementMatch(elem, 'auro-input') && elem.errorMessage === '') {
|
|
556
556
|
const input = elem.renderRoot.querySelector('input');
|
|
557
557
|
|
|
558
|
-
if (input
|
|
558
|
+
if (input.validationMessage.length > 0) {
|
|
559
559
|
elem.errorMessage = input.validationMessage;
|
|
560
560
|
}
|
|
561
561
|
} else if (this.runtimeUtils.elementMatch(elem, 'auro-combobox') && elem.errorMessage === '') {
|
|
@@ -797,21 +797,6 @@ function isClearBtnFocused(ctx, clearBtn = getClearBtn(ctx)) {
|
|
|
797
797
|
return isFocused;
|
|
798
798
|
}
|
|
799
799
|
|
|
800
|
-
/**
|
|
801
|
-
* Reconcile the menu `_index` from `optionActive` so subsequent `makeSelection` calls find the correct option after async clearSelection has reset it.
|
|
802
|
-
* @param {Object} menu - The menu component.
|
|
803
|
-
*/
|
|
804
|
-
function reconcileMenuIndex(menu) {
|
|
805
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
806
|
-
if (menu._index < 0 && menu.optionActive && menu.items) {
|
|
807
|
-
const idx = menu.items.indexOf(menu.optionActive);
|
|
808
|
-
if (idx >= 0) {
|
|
809
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
810
|
-
menu._index = idx;
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
|
|
815
800
|
const comboboxKeyboardStrategy = {
|
|
816
801
|
ArrowDown(component, evt, ctx) {
|
|
817
802
|
// If the clear button has focus, let the browser handle ArrowDown normally.
|
|
@@ -875,7 +860,6 @@ const comboboxKeyboardStrategy = {
|
|
|
875
860
|
// block the browser's built-in "Enter activates focused button" behavior.
|
|
876
861
|
evt.stopPropagation();
|
|
877
862
|
} else if (ctx.isExpanded && component.menu.optionActive) {
|
|
878
|
-
reconcileMenuIndex(component.menu);
|
|
879
863
|
component.menu.makeSelection();
|
|
880
864
|
|
|
881
865
|
if (ctx.isModal) {
|
|
@@ -923,7 +907,6 @@ const comboboxKeyboardStrategy = {
|
|
|
923
907
|
// When the clear button is focused, Tab events do not bubble out of
|
|
924
908
|
// its shadow DOM, so this handler only fires when the clear button
|
|
925
909
|
// is NOT focused. In that case, select the active option and close.
|
|
926
|
-
reconcileMenuIndex(component.menu);
|
|
927
910
|
component.menu.makeSelection();
|
|
928
911
|
component.hideBib();
|
|
929
912
|
|
|
@@ -4806,7 +4789,7 @@ let AuroHelpText$2 = class AuroHelpText extends LitElement {
|
|
|
4806
4789
|
}
|
|
4807
4790
|
};
|
|
4808
4791
|
|
|
4809
|
-
var formkitVersion$2 = '
|
|
4792
|
+
var formkitVersion$2 = '202606101934';
|
|
4810
4793
|
|
|
4811
4794
|
let AuroElement$2 = class AuroElement extends LitElement {
|
|
4812
4795
|
static get properties() {
|
|
@@ -5664,18 +5647,27 @@ class AuroDropdown extends AuroElement$2 {
|
|
|
5664
5647
|
this.focusTrap = undefined;
|
|
5665
5648
|
}
|
|
5666
5649
|
|
|
5667
|
-
// Restore
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
this.noHideOnThisFocusLoss = this._priorNoHideOnFocusLoss;
|
|
5673
|
-
this._priorNoHideOnFocusLoss = undefined;
|
|
5650
|
+
// Restore the user-set noHideOnThisFocusLoss value, if we overrode it.
|
|
5651
|
+
if (this._noHideOverridden) {
|
|
5652
|
+
this.noHideOnThisFocusLoss = this._priorNoHide;
|
|
5653
|
+
this._noHideOverridden = false;
|
|
5654
|
+
this._priorNoHide = undefined;
|
|
5674
5655
|
}
|
|
5675
5656
|
|
|
5676
5657
|
if (this.isPopoverVisible) {
|
|
5677
5658
|
if (!this.isBibFullscreen) {
|
|
5678
5659
|
if (this.desktopModal) {
|
|
5660
|
+
// The floater's focus-loss check uses :focus-within, which does not
|
|
5661
|
+
// match the host when focus is on a slotted element projected through
|
|
5662
|
+
// multiple shadow roots. Without this override, focusing a button
|
|
5663
|
+
// inside the bib would be misread as focus leaving the dropdown and
|
|
5664
|
+
// close the bib immediately. desktopModal traps focus inside the
|
|
5665
|
+
// bib and inerts siblings, so suppressing focus-loss dismissal here
|
|
5666
|
+
// is safe — Escape and outside-click still close the bib.
|
|
5667
|
+
this._priorNoHide = this.noHideOnThisFocusLoss;
|
|
5668
|
+
this._noHideOverridden = true;
|
|
5669
|
+
this.noHideOnThisFocusLoss = true;
|
|
5670
|
+
|
|
5679
5671
|
// Desktop modal: trap focus only within the bib content.
|
|
5680
5672
|
// Can't use FocusTrap on the bib element because keydown events
|
|
5681
5673
|
// from slotted content bubble through the dropdown host (light DOM),
|
|
@@ -5748,14 +5740,6 @@ class AuroDropdown extends AuroElement$2 {
|
|
|
5748
5740
|
};
|
|
5749
5741
|
this.addEventListener('keydown', this._bibTabHandler);
|
|
5750
5742
|
|
|
5751
|
-
// Suppress AuroFloatingUI's auto-hide-on-focus-loss while the
|
|
5752
|
-
// desktopModal trap owns focus management. Without this, the very
|
|
5753
|
-
// first focus move into the bib (from the RAF below) triggers
|
|
5754
|
-
// handleFocusLoss → hideBib, tearing down the trap before the
|
|
5755
|
-
// user can press Tab.
|
|
5756
|
-
this._priorNoHideOnFocusLoss = this.noHideOnThisFocusLoss;
|
|
5757
|
-
this.noHideOnThisFocusLoss = true;
|
|
5758
|
-
|
|
5759
5743
|
// Move initial focus into the bib content, matching FocusTrap behavior
|
|
5760
5744
|
requestAnimationFrame(() => {
|
|
5761
5745
|
const focusables = getFocusableElements(this.bibContent);
|
|
@@ -10678,7 +10662,7 @@ class AuroFormValidation {
|
|
|
10678
10662
|
} else if (this.runtimeUtils.elementMatch(elem, 'auro-input') && elem.errorMessage === '') {
|
|
10679
10663
|
const input = elem.renderRoot.querySelector('input');
|
|
10680
10664
|
|
|
10681
|
-
if (input
|
|
10665
|
+
if (input.validationMessage.length > 0) {
|
|
10682
10666
|
elem.errorMessage = input.validationMessage;
|
|
10683
10667
|
}
|
|
10684
10668
|
} else if (this.runtimeUtils.elementMatch(elem, 'auro-combobox') && elem.errorMessage === '') {
|
|
@@ -16350,7 +16334,11 @@ class AuroInputUtilities {
|
|
|
16350
16334
|
return part.value;
|
|
16351
16335
|
}
|
|
16352
16336
|
})
|
|
16353
|
-
.join("")
|
|
16337
|
+
.join("")
|
|
16338
|
+
// Remove whitespace and leading/trailing special characters for IMask compatibility
|
|
16339
|
+
// for example, ko-KR's format is `YYYY. MM. DD.` which causes issues with IMask if we don't remove the trailing period.
|
|
16340
|
+
.replace(/\s/gu, '')
|
|
16341
|
+
.replace(/^[^A-Z0-9]+|[^A-Z0-9]+$/gu, '');
|
|
16354
16342
|
}
|
|
16355
16343
|
|
|
16356
16344
|
/**
|
|
@@ -16515,6 +16503,7 @@ class AuroInputUtilities {
|
|
|
16515
16503
|
const maskOptions = this.getMaskOptions('date', normalizedFormat);
|
|
16516
16504
|
|
|
16517
16505
|
if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
|
|
16506
|
+
console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
|
|
16518
16507
|
return undefined;
|
|
16519
16508
|
}
|
|
16520
16509
|
|
|
@@ -17217,7 +17206,7 @@ class BaseInput extends AuroElement$1 {
|
|
|
17217
17206
|
* @returns {Date|undefined}
|
|
17218
17207
|
*/
|
|
17219
17208
|
get valueObject() {
|
|
17220
|
-
return this._valueObject
|
|
17209
|
+
return this._valueObject;
|
|
17221
17210
|
}
|
|
17222
17211
|
|
|
17223
17212
|
/**
|
|
@@ -17225,7 +17214,7 @@ class BaseInput extends AuroElement$1 {
|
|
|
17225
17214
|
* @returns {Date|undefined}
|
|
17226
17215
|
*/
|
|
17227
17216
|
get minObject() {
|
|
17228
|
-
return this._minObject
|
|
17217
|
+
return this._minObject;
|
|
17229
17218
|
}
|
|
17230
17219
|
|
|
17231
17220
|
/**
|
|
@@ -17233,31 +17222,7 @@ class BaseInput extends AuroElement$1 {
|
|
|
17233
17222
|
* @returns {Date|undefined}
|
|
17234
17223
|
*/
|
|
17235
17224
|
get maxObject() {
|
|
17236
|
-
return this._maxObject
|
|
17237
|
-
}
|
|
17238
|
-
|
|
17239
|
-
/**
|
|
17240
|
-
* Parses a date string into a Date object when the corresponding `_*Object`
|
|
17241
|
-
* field hasn't been synced yet by `updated()`. Returns undefined when the
|
|
17242
|
-
* input type/format isn't a full date or the string is not a valid date.
|
|
17243
|
-
*
|
|
17244
|
-
* Why this exists: a parent (datepicker) can call `inputN.validate()` from
|
|
17245
|
-
* inside its own `updated()` before this input's `updated()` has run
|
|
17246
|
-
* `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
|
|
17247
|
-
* and range checks would otherwise silently no-op (flipping the result to
|
|
17248
|
-
* `valid` or `patternMismatch`).
|
|
17249
|
-
* @private
|
|
17250
|
-
* @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
|
|
17251
|
-
* @returns {Date|undefined}
|
|
17252
|
-
*/
|
|
17253
|
-
_computeDateObjectFallback(dateStr) {
|
|
17254
|
-
if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
|
|
17255
|
-
return undefined;
|
|
17256
|
-
}
|
|
17257
|
-
if (!dateFormatter.isValidDate(dateStr)) {
|
|
17258
|
-
return undefined;
|
|
17259
|
-
}
|
|
17260
|
-
return dateFormatter.stringToDateInstance(dateStr);
|
|
17225
|
+
return this._maxObject;
|
|
17261
17226
|
}
|
|
17262
17227
|
|
|
17263
17228
|
/**
|
|
@@ -17282,30 +17247,8 @@ class BaseInput extends AuroElement$1 {
|
|
|
17282
17247
|
connectedCallback() {
|
|
17283
17248
|
super.connectedCallback();
|
|
17284
17249
|
|
|
17285
|
-
// Mark for query selectors when registered under a versioned tag (e.g. inside
|
|
17286
|
-
// a datepicker/combobox). Must run before parent components call validate() on
|
|
17287
|
-
// their inner inputs — the validation framework matches via tag-or-attribute,
|
|
17288
|
-
// and parents trigger validation during their own updated() cycle, which can
|
|
17289
|
-
// precede this input's firstUpdated().
|
|
17290
|
-
if (this.tagName.toLowerCase() !== 'auro-input' && !this.hasAttribute('auro-input')) {
|
|
17291
|
-
this.setAttribute('auro-input', '');
|
|
17292
|
-
}
|
|
17293
|
-
|
|
17294
17250
|
this.locale = this.domHandler.getLocale(this);
|
|
17295
17251
|
notifyOnLangChange(this);
|
|
17296
|
-
|
|
17297
|
-
// Pre-compute lengthForType and date-object fields so a parent (e.g. datepicker)
|
|
17298
|
-
// calling our validate() synchronously during its own updated() cycle sees
|
|
17299
|
-
// populated values. Without this, range validation silently no-ops because
|
|
17300
|
-
// `max.length === lengthForType` fails when lengthForType is still undefined.
|
|
17301
|
-
// Rebuild util here (constructor seeded with en-US default) so configureDataForType's
|
|
17302
|
-
// locale-derived format lookup uses the actual locale just resolved above.
|
|
17303
|
-
this.util = new AuroInputUtilities({
|
|
17304
|
-
locale: this.locale,
|
|
17305
|
-
format: this.format
|
|
17306
|
-
});
|
|
17307
|
-
this.configureDataForType();
|
|
17308
|
-
this.syncDateValues();
|
|
17309
17252
|
}
|
|
17310
17253
|
|
|
17311
17254
|
disconnectedCallback() {
|
|
@@ -17326,8 +17269,8 @@ class BaseInput extends AuroElement$1 {
|
|
|
17326
17269
|
}
|
|
17327
17270
|
|
|
17328
17271
|
// add attribute for query selectors when auro-input is registered under a custom name
|
|
17329
|
-
if (this.tagName.toLowerCase() !== 'auro-input'
|
|
17330
|
-
this.setAttribute('auro-input',
|
|
17272
|
+
if (this.tagName.toLowerCase() !== 'auro-input') {
|
|
17273
|
+
this.setAttribute('auro-input', true);
|
|
17331
17274
|
}
|
|
17332
17275
|
this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
|
|
17333
17276
|
|
|
@@ -17375,12 +17318,6 @@ class BaseInput extends AuroElement$1 {
|
|
|
17375
17318
|
return;
|
|
17376
17319
|
}
|
|
17377
17320
|
|
|
17378
|
-
// While configureAutoFormatting is running, imask's internal updateControl
|
|
17379
|
-
// writes el.value to align display with the masked value. A synthetic input
|
|
17380
|
-
// event from that write would re-enter handleInput → processCreditCard mid-setup
|
|
17381
|
-
// and clobber a Lit value that was just pushed by the parent combobox.
|
|
17382
|
-
if (component._configuringMask) return;
|
|
17383
|
-
|
|
17384
17321
|
// If all guard clauses are passed, dispatch the event
|
|
17385
17322
|
const inputEvent = new InputEvent('input', {
|
|
17386
17323
|
bubbles: true,
|
|
@@ -17499,16 +17436,7 @@ class BaseInput extends AuroElement$1 {
|
|
|
17499
17436
|
|
|
17500
17437
|
if (formattedValue !== this.inputElement.value) {
|
|
17501
17438
|
this.skipNextProgrammaticInputEvent = true;
|
|
17502
|
-
if (
|
|
17503
|
-
// Route through the mask so its _value and el.value stay in lock-step
|
|
17504
|
-
// (set value calls updateControl which writes el.value = displayValue).
|
|
17505
|
-
// Writing el.value directly leaves the mask thinking displayValue is
|
|
17506
|
-
// stale; _saveSelection on the next focus/click then warns. Scoped to
|
|
17507
|
-
// credit-card so date's own formattedValue (raw ISO when calendar-invalid)
|
|
17508
|
-
// isn't re-masked through the mm/dd/yyyy mask, which would truncate it
|
|
17509
|
-
// and flip validity from patternMismatch to tooShort.
|
|
17510
|
-
this.maskInstance.value = formattedValue || '';
|
|
17511
|
-
} else if (formattedValue) {
|
|
17439
|
+
if (formattedValue) {
|
|
17512
17440
|
this.inputElement.value = formattedValue;
|
|
17513
17441
|
} else {
|
|
17514
17442
|
this.inputElement.value = '';
|
|
@@ -17617,73 +17545,58 @@ class BaseInput extends AuroElement$1 {
|
|
|
17617
17545
|
* @returns {void}
|
|
17618
17546
|
*/
|
|
17619
17547
|
configureAutoFormatting() {
|
|
17620
|
-
|
|
17621
|
-
|
|
17622
|
-
|
|
17623
|
-
// set value has finished its alignCursor pass.
|
|
17624
|
-
if (this._configuringMask) return;
|
|
17625
|
-
this._configuringMask = true;
|
|
17626
|
-
try {
|
|
17627
|
-
if (this.maskInstance) {
|
|
17628
|
-
this.maskInstance.destroy();
|
|
17629
|
-
}
|
|
17548
|
+
if (this.maskInstance) {
|
|
17549
|
+
this.maskInstance.destroy();
|
|
17550
|
+
}
|
|
17630
17551
|
|
|
17631
|
-
|
|
17632
|
-
|
|
17552
|
+
// Pass new format to util
|
|
17553
|
+
this.util.updateFormat(this.format);
|
|
17633
17554
|
|
|
17634
|
-
|
|
17555
|
+
const maskOptions = this.util.getMaskOptions(this.type, this.format);
|
|
17635
17556
|
|
|
17636
|
-
|
|
17557
|
+
if (this.inputElement && maskOptions.mask) {
|
|
17637
17558
|
|
|
17638
|
-
|
|
17639
|
-
|
|
17640
|
-
|
|
17641
|
-
|
|
17642
|
-
|
|
17643
|
-
|
|
17644
|
-
|
|
17645
|
-
|
|
17646
|
-
|
|
17647
|
-
|
|
17648
|
-
|
|
17649
|
-
|
|
17650
|
-
|
|
17651
|
-
|
|
17652
|
-
|
|
17653
|
-
|
|
17654
|
-
|
|
17559
|
+
// Stash and clear any existing value before IMask init.
|
|
17560
|
+
// IMask's constructor processes the current input value which requires
|
|
17561
|
+
// selection state — clearing first avoids that scenario entirely.
|
|
17562
|
+
// When the format changes (e.g. locale switch) and we have a valid ISO
|
|
17563
|
+
// model value, compute the display string for the NEW format instead of
|
|
17564
|
+
// re-using the old display string, which may be invalid in the new mask.
|
|
17565
|
+
let existingValue = this.inputElement.value;
|
|
17566
|
+
if (
|
|
17567
|
+
this.util.isFullDateFormat(this.type, this.format) &&
|
|
17568
|
+
this.value &&
|
|
17569
|
+
dateFormatter.isValidDate(this.value) &&
|
|
17570
|
+
this.valueObject instanceof Date &&
|
|
17571
|
+
!Number.isNaN(this.valueObject.getTime()) &&
|
|
17572
|
+
typeof maskOptions.format === 'function'
|
|
17573
|
+
) {
|
|
17574
|
+
existingValue = maskOptions.format(this.valueObject);
|
|
17575
|
+
}
|
|
17655
17576
|
|
|
17656
|
-
|
|
17657
|
-
|
|
17658
|
-
|
|
17659
|
-
this.maskInstance = IMask(this.inputElement, maskOptions);
|
|
17660
|
-
|
|
17661
|
-
this.maskInstance.on('accept', () => {
|
|
17662
|
-
// Suppress propagation during configureAutoFormatting's own value-restoration
|
|
17663
|
-
// (line below) — the mask emits 'accept' on every value-set, including ours,
|
|
17664
|
-
// and we don't want to overwrite a value the parent just pushed.
|
|
17665
|
-
if (this._configuringMask) return;
|
|
17666
|
-
this.value = this.util.toModelValue(this.maskInstance.value, this.format);
|
|
17667
|
-
if (this.type === "date") {
|
|
17668
|
-
this._rawMaskValue = this.maskInstance.value;
|
|
17669
|
-
}
|
|
17670
|
-
});
|
|
17577
|
+
this.skipNextProgrammaticInputEvent = true;
|
|
17578
|
+
this.inputElement.value = '';
|
|
17671
17579
|
|
|
17672
|
-
|
|
17673
|
-
if (this._configuringMask) return;
|
|
17674
|
-
this.value = this.util.toModelValue(this.maskInstance.value, this.format);
|
|
17675
|
-
if (this.type === "date") {
|
|
17676
|
-
this._rawMaskValue = this.maskInstance.value;
|
|
17677
|
-
}
|
|
17678
|
-
});
|
|
17580
|
+
this.maskInstance = IMask(this.inputElement, maskOptions);
|
|
17679
17581
|
|
|
17680
|
-
|
|
17681
|
-
|
|
17682
|
-
|
|
17582
|
+
this.maskInstance.on('accept', () => {
|
|
17583
|
+
this.value = this.util.toModelValue(this.maskInstance.value, this.format);
|
|
17584
|
+
if (this.type === "date") {
|
|
17585
|
+
this._rawMaskValue = this.maskInstance.value;
|
|
17683
17586
|
}
|
|
17587
|
+
});
|
|
17588
|
+
|
|
17589
|
+
this.maskInstance.on('complete', () => {
|
|
17590
|
+
this.value = this.util.toModelValue(this.maskInstance.value, this.format);
|
|
17591
|
+
if (this.type === "date") {
|
|
17592
|
+
this._rawMaskValue = this.maskInstance.value;
|
|
17593
|
+
}
|
|
17594
|
+
});
|
|
17595
|
+
|
|
17596
|
+
// Restore the stashed value through IMask so it's properly masked
|
|
17597
|
+
if (existingValue) {
|
|
17598
|
+
this.maskInstance.value = existingValue;
|
|
17684
17599
|
}
|
|
17685
|
-
} finally {
|
|
17686
|
-
this._configuringMask = false;
|
|
17687
17600
|
}
|
|
17688
17601
|
}
|
|
17689
17602
|
|
|
@@ -17970,10 +17883,10 @@ class BaseInput extends AuroElement$1 {
|
|
|
17970
17883
|
},
|
|
17971
17884
|
{
|
|
17972
17885
|
name: 'Diners club',
|
|
17973
|
-
regex: /^(?<num>
|
|
17886
|
+
regex: /^(?<num>36|38)\d{0}/u,
|
|
17974
17887
|
formatLength: 16,
|
|
17975
17888
|
errorMessage: CreditCardValidationMessage,
|
|
17976
|
-
cardIcon: '
|
|
17889
|
+
cardIcon: 'credit-card',
|
|
17977
17890
|
maskFormat: "0000 000000 0000"
|
|
17978
17891
|
},
|
|
17979
17892
|
{
|
|
@@ -18383,7 +18296,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
|
|
|
18383
18296
|
}
|
|
18384
18297
|
};
|
|
18385
18298
|
|
|
18386
|
-
var formkitVersion$1 = '
|
|
18299
|
+
var formkitVersion$1 = '202606101934';
|
|
18387
18300
|
|
|
18388
18301
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
18389
18302
|
// See LICENSE in the project root for license information.
|
|
@@ -18721,10 +18634,6 @@ class AuroInput extends BaseInput {
|
|
|
18721
18634
|
return i18n(this.lang, this.type);
|
|
18722
18635
|
}
|
|
18723
18636
|
|
|
18724
|
-
if (this.type === 'date') {
|
|
18725
|
-
return i18n(this.lang, this.dateFormatMap[this.format] || 'dateMMDDYYYY');
|
|
18726
|
-
}
|
|
18727
|
-
|
|
18728
18637
|
return '';
|
|
18729
18638
|
}
|
|
18730
18639
|
|
|
@@ -19508,7 +19417,7 @@ class AuroBibtemplate extends LitElement {
|
|
|
19508
19417
|
}
|
|
19509
19418
|
}
|
|
19510
19419
|
|
|
19511
|
-
var formkitVersion = '
|
|
19420
|
+
var formkitVersion = '202606101934';
|
|
19512
19421
|
|
|
19513
19422
|
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}`;
|
|
19514
19423
|
|
|
@@ -19865,25 +19774,6 @@ function normalizeFilterValue(value) {
|
|
|
19865
19774
|
return raw.trim() ? raw.trimEnd() : raw;
|
|
19866
19775
|
}
|
|
19867
19776
|
|
|
19868
|
-
/**
|
|
19869
|
-
* Returns the option's plain-text label suitable for input.value, with
|
|
19870
|
-
* HTML-indentation whitespace collapsed and the displayValue slot text
|
|
19871
|
-
* removed (the slot renders separately in the trigger).
|
|
19872
|
-
* @param {HTMLElement} option - An auro-menuoption element.
|
|
19873
|
-
* @returns {string} Normalized label.
|
|
19874
|
-
*/
|
|
19875
|
-
function getOptionLabel(option) {
|
|
19876
|
-
if (!option) {
|
|
19877
|
-
return '';
|
|
19878
|
-
}
|
|
19879
|
-
const clone = option.cloneNode(true);
|
|
19880
|
-
const displayValueEl = clone.querySelector('[slot="displayValue"]');
|
|
19881
|
-
if (displayValueEl) {
|
|
19882
|
-
displayValueEl.remove();
|
|
19883
|
-
}
|
|
19884
|
-
return (clone.textContent || '').replace(/\s+/gu, ' ').trim();
|
|
19885
|
-
}
|
|
19886
|
-
|
|
19887
19777
|
// See https://git.io/JJ6SJ for "How to document your components using JSDoc"
|
|
19888
19778
|
/**
|
|
19889
19779
|
* The `auro-combobox` element provides users with a way to select an option from a list of filtered or suggested options based on user input.
|
|
@@ -20011,19 +19901,7 @@ class AuroCombobox extends AuroElement {
|
|
|
20011
19901
|
availableOptions: {
|
|
20012
19902
|
state: true,
|
|
20013
19903
|
type: Array,
|
|
20014
|
-
reflect: false
|
|
20015
|
-
hasChanged(newVal, oldVal) {
|
|
20016
|
-
if (!oldVal && !newVal) {
|
|
20017
|
-
return false;
|
|
20018
|
-
}
|
|
20019
|
-
if (!oldVal || !newVal) {
|
|
20020
|
-
return true;
|
|
20021
|
-
}
|
|
20022
|
-
if (newVal.length !== oldVal.length) {
|
|
20023
|
-
return true;
|
|
20024
|
-
}
|
|
20025
|
-
return newVal.some((opt, idx) => opt !== oldVal[idx]);
|
|
20026
|
-
}
|
|
19904
|
+
reflect: false
|
|
20027
19905
|
},
|
|
20028
19906
|
|
|
20029
19907
|
/**
|
|
@@ -20454,15 +20332,18 @@ class AuroCombobox extends AuroElement {
|
|
|
20454
20332
|
matchString = `${matchString} ${option.getAttribute('suggest')}`.toLowerCase();
|
|
20455
20333
|
}
|
|
20456
20334
|
|
|
20457
|
-
|
|
20458
|
-
|
|
20459
|
-
|
|
20460
|
-
|
|
20461
|
-
|
|
20462
|
-
|
|
20335
|
+
// If input is empty, show all options (except static ones)
|
|
20336
|
+
if (!filterValue) {
|
|
20337
|
+
if (!option.hasAttribute('static')) {
|
|
20338
|
+
option.removeAttribute('hidden');
|
|
20339
|
+
this.availableOptions.push(option);
|
|
20340
|
+
}
|
|
20341
|
+
} else if (matchString.includes(filterValue) && !option.hasAttribute('static')) {
|
|
20342
|
+
// only count options that match the typed input value AND are not static
|
|
20463
20343
|
option.removeAttribute('hidden');
|
|
20464
20344
|
this.availableOptions.push(option);
|
|
20465
20345
|
} else if (!option.hasAttribute('persistent')) {
|
|
20346
|
+
// Hide all other non-persistent options
|
|
20466
20347
|
option.setAttribute('hidden', '');
|
|
20467
20348
|
option.removeAttribute('aria-setsize');
|
|
20468
20349
|
option.removeAttribute('aria-posinset');
|
|
@@ -20470,9 +20351,7 @@ class AuroCombobox extends AuroElement {
|
|
|
20470
20351
|
});
|
|
20471
20352
|
|
|
20472
20353
|
if (this.availableOptions.length === 0) {
|
|
20473
|
-
|
|
20474
|
-
// something. Empty input is handled by the bib being closed.
|
|
20475
|
-
if (this.noMatchOption && filterValue) {
|
|
20354
|
+
if (this.noMatchOption) {
|
|
20476
20355
|
this.noMatchOption.removeAttribute('hidden');
|
|
20477
20356
|
} else if (!this.menu.loading || this.isHiddenWhileLoading) {
|
|
20478
20357
|
this.hideBib();
|
|
@@ -20488,14 +20367,11 @@ class AuroCombobox extends AuroElement {
|
|
|
20488
20367
|
* @returns {void}
|
|
20489
20368
|
*/
|
|
20490
20369
|
syncValuesAndStates() {
|
|
20491
|
-
//
|
|
20492
|
-
// guards setMenuValue with an option-match check. Calling it unconditionally
|
|
20493
|
-
// sets free-form values on the menu, triggering clearSelection which resets
|
|
20494
|
-
// _index and breaks subsequent makeSelection calls.
|
|
20370
|
+
// Only sync matchWord, don't set menu.value here since setMenuValue should handle that
|
|
20495
20371
|
if (this.menu) {
|
|
20496
20372
|
this.menu.matchWord = normalizeFilterValue(this.input.value);
|
|
20497
20373
|
}
|
|
20498
|
-
const label =
|
|
20374
|
+
const label = this.menu.currentLabel;
|
|
20499
20375
|
this.updateTriggerTextDisplay(label || this.value);
|
|
20500
20376
|
}
|
|
20501
20377
|
|
|
@@ -20510,39 +20386,7 @@ class AuroCombobox extends AuroElement {
|
|
|
20510
20386
|
const isInputFocusedWithNoSelection = !this.menu.value && (this.input.matches(':focus-within') || (this.inputInBib && this.inputInBib.matches(':focus-within')));
|
|
20511
20387
|
|
|
20512
20388
|
if (!this.persistInput && !(this.behavior === 'suggestion' && isInputFocusedWithNoSelection)) {
|
|
20513
|
-
|
|
20514
|
-
// Only set the flag when there's an actual write to suppress —
|
|
20515
|
-
// syncValuesAndStates re-enters here during typing when both inputs
|
|
20516
|
-
// already match, and a no-op flag flip would make the bib branch's
|
|
20517
|
-
// bail eat legitimate user-input events.
|
|
20518
|
-
const triggerNeedsSync = this.input.value !== nextValue;
|
|
20519
|
-
const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
|
|
20520
|
-
if (triggerNeedsSync || bibNeedsSync) {
|
|
20521
|
-
this._syncingDisplayValue = true;
|
|
20522
|
-
if (triggerNeedsSync) {
|
|
20523
|
-
this.input.value = nextValue;
|
|
20524
|
-
}
|
|
20525
|
-
if (bibNeedsSync) {
|
|
20526
|
-
this.inputInBib.value = nextValue;
|
|
20527
|
-
}
|
|
20528
|
-
const pending = [];
|
|
20529
|
-
if (triggerNeedsSync) {
|
|
20530
|
-
pending.push(this.input.updateComplete);
|
|
20531
|
-
}
|
|
20532
|
-
if (bibNeedsSync) {
|
|
20533
|
-
pending.push(this.inputInBib.updateComplete);
|
|
20534
|
-
}
|
|
20535
|
-
Promise.all(pending).then(() => {
|
|
20536
|
-
// imask reasserts otherwise, and handleBlur reverts to its stale value.
|
|
20537
|
-
if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
|
|
20538
|
-
this.input.maskInstance.updateValue();
|
|
20539
|
-
}
|
|
20540
|
-
if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
|
|
20541
|
-
this.inputInBib.maskInstance.updateValue();
|
|
20542
|
-
}
|
|
20543
|
-
this._syncingDisplayValue = false;
|
|
20544
|
-
});
|
|
20545
|
-
}
|
|
20389
|
+
this.input.value = label || this.value;
|
|
20546
20390
|
}
|
|
20547
20391
|
|
|
20548
20392
|
// update the displayValue in the trigger if displayValue slot content is present
|
|
@@ -20556,14 +20400,6 @@ class AuroCombobox extends AuroElement {
|
|
|
20556
20400
|
const displayValueEl = this.menu.optionSelected.querySelector("[slot='displayValue']");
|
|
20557
20401
|
if (displayValueEl) {
|
|
20558
20402
|
this.input.appendChild(displayValueEl.cloneNode(true));
|
|
20559
|
-
// auro-input's hasDisplayValueContent is non-reactive; nudge it to
|
|
20560
|
-
// re-evaluate the slot and re-render so the displayValue wrapper
|
|
20561
|
-
// gets its hasContent class. Without this, the apple/icon stays
|
|
20562
|
-
// hidden when input.value is set in the same tick as the append.
|
|
20563
|
-
if (typeof this.input.checkDisplayValueSlotChange === 'function') {
|
|
20564
|
-
this.input.checkDisplayValueSlotChange();
|
|
20565
|
-
this.input.requestUpdate();
|
|
20566
|
-
}
|
|
20567
20403
|
}
|
|
20568
20404
|
}
|
|
20569
20405
|
|
|
@@ -20597,10 +20433,7 @@ class AuroCombobox extends AuroElement {
|
|
|
20597
20433
|
this.syncValuesAndStates();
|
|
20598
20434
|
}
|
|
20599
20435
|
|
|
20600
|
-
|
|
20601
|
-
// been reset (e.g. by clearSelection in an async update) so that
|
|
20602
|
-
// makeSelection() can find the correct option.
|
|
20603
|
-
if (!this.availableOptions.includes(this.menu.optionActive) || this.menu._index < 0) {
|
|
20436
|
+
if (!this.availableOptions.includes(this.menu.optionActive)) {
|
|
20604
20437
|
this.activateFirstEnabledAvailableOption();
|
|
20605
20438
|
}
|
|
20606
20439
|
}
|
|
@@ -20725,13 +20558,8 @@ class AuroCombobox extends AuroElement {
|
|
|
20725
20558
|
|
|
20726
20559
|
guardTouchPassthrough(this.menu);
|
|
20727
20560
|
|
|
20728
|
-
//
|
|
20729
|
-
//
|
|
20730
|
-
// focusable, then doubleRaf finalizes the transition.
|
|
20731
|
-
requestAnimationFrame(() => {
|
|
20732
|
-
this.setInputFocus();
|
|
20733
|
-
});
|
|
20734
|
-
|
|
20561
|
+
// Wait for the bibtemplate to fully render across
|
|
20562
|
+
// multiple Lit update cycles before moving focus into the bib
|
|
20735
20563
|
doubleRaf(() => {
|
|
20736
20564
|
this.setInputFocus();
|
|
20737
20565
|
this._inFullscreenTransition = false;
|
|
@@ -20812,42 +20640,16 @@ class AuroCombobox extends AuroElement {
|
|
|
20812
20640
|
*/
|
|
20813
20641
|
setInputFocus() {
|
|
20814
20642
|
if (this.dropdown.isBibFullscreen && this.dropdown.isPopoverVisible) {
|
|
20815
|
-
|
|
20816
|
-
// Lit's property-to-attribute sync is async (microtask), so the
|
|
20817
|
-
// native <input> inside inputInBib may still hold a stale value
|
|
20818
|
-
// when focus moves here during the fullscreen transition. Without
|
|
20819
|
-
// this, keystrokes (e.g. Backspace) operate on the wrong content.
|
|
20820
|
-
const nativeInput = this.inputInBib.inputElement;
|
|
20821
|
-
const triggerNativeInput = this.input.inputElement;
|
|
20822
|
-
if (nativeInput && triggerNativeInput && nativeInput.value !== triggerNativeInput.value) {
|
|
20823
|
-
this.inputInBib.skipNextProgrammaticInputEvent = true;
|
|
20824
|
-
nativeInput.value = triggerNativeInput.value || '';
|
|
20825
|
-
}
|
|
20826
|
-
|
|
20827
|
-
// Focus the native input directly to ensure it receives keystrokes
|
|
20828
|
-
// after the fullscreen dialog opens. The dialog's showModal() may
|
|
20829
|
-
// have moved focus to the dialog element itself; focusing the
|
|
20830
|
-
// auro-input custom element doesn't always reach the native input
|
|
20831
|
-
// when the dialog DOM isn't fully painted.
|
|
20832
|
-
if (nativeInput) {
|
|
20833
|
-
nativeInput.focus();
|
|
20834
|
-
} else {
|
|
20835
|
-
this.inputInBib.focus();
|
|
20836
|
-
}
|
|
20643
|
+
this.inputInBib.focus();
|
|
20837
20644
|
|
|
20838
20645
|
// Place cursor at end of existing text so the user can continue editing
|
|
20646
|
+
const nativeInput = this.inputInBib.inputElement;
|
|
20839
20647
|
if (nativeInput && nativeInput.value) {
|
|
20840
20648
|
const len = nativeInput.value.length;
|
|
20841
20649
|
nativeInput.setSelectionRange(len, len);
|
|
20842
20650
|
}
|
|
20843
|
-
} else
|
|
20844
|
-
const focusedEl = this.querySelector(":focus");
|
|
20651
|
+
} else {
|
|
20845
20652
|
this.input.focus();
|
|
20846
|
-
// current focus is on a menuoption, after clicking on it.
|
|
20847
|
-
if (this.persistInput && focusedEl && (focusedEl.tagName.toLowerCase() === 'auro-menuoption' || focusedEl.hasAttribute('auro-menuoption'))) {
|
|
20848
|
-
this.setClearBtnFocus();
|
|
20849
|
-
this.validate(true);
|
|
20850
|
-
}
|
|
20851
20653
|
}
|
|
20852
20654
|
}
|
|
20853
20655
|
|
|
@@ -20943,92 +20745,53 @@ class AuroCombobox extends AuroElement {
|
|
|
20943
20745
|
this.menu.setAttribute('nocheckmark', '');
|
|
20944
20746
|
}
|
|
20945
20747
|
|
|
20946
|
-
|
|
20947
|
-
|
|
20948
|
-
|
|
20949
|
-
// echo of our own setMenuValue (programmatic value sync), false means
|
|
20950
|
-
// a fresh user selection.
|
|
20951
|
-
const isEcho = this._pendingMenuValueSync === true;
|
|
20952
|
-
|
|
20953
|
-
if (this.menu.optionSelected) {
|
|
20954
|
-
const selected = this.menu.optionSelected;
|
|
20748
|
+
this.menu.addEventListener("auroMenu-deselectPrevented", () => {
|
|
20749
|
+
this.hideBib();
|
|
20750
|
+
});
|
|
20955
20751
|
|
|
20956
|
-
|
|
20957
|
-
|
|
20958
|
-
|
|
20752
|
+
// Handle menu option selection like select does
|
|
20753
|
+
this.menu.addEventListener('auroMenu-selectedOption', (event) => {
|
|
20754
|
+
// Update the optionSelected from the event details, not manually
|
|
20755
|
+
[this.optionSelected] = event.detail.options;
|
|
20959
20756
|
|
|
20960
|
-
|
|
20961
|
-
|
|
20962
|
-
if (this._pendingMenuValueSync) {
|
|
20963
|
-
this._pendingMenuValueSync = false;
|
|
20964
|
-
} else if (!this.value || this.value !== this.optionSelected.value) {
|
|
20965
|
-
this.value = this.optionSelected.value;
|
|
20966
|
-
}
|
|
20757
|
+
// Update the internal value to match the menu's value
|
|
20758
|
+
this.value = event.detail.stringValue;
|
|
20967
20759
|
|
|
20968
|
-
|
|
20969
|
-
|
|
20760
|
+
// Update display
|
|
20761
|
+
this.updateTriggerTextDisplay(event.detail.label || event.detail.value);
|
|
20970
20762
|
|
|
20971
|
-
|
|
20972
|
-
|
|
20973
|
-
|
|
20974
|
-
|
|
20975
|
-
}
|
|
20763
|
+
// Update match word for filtering
|
|
20764
|
+
const trimmedInput = normalizeFilterValue(this.input.value);
|
|
20765
|
+
if (this.menu.matchWord !== trimmedInput) {
|
|
20766
|
+
this.menu.matchWord = trimmedInput;
|
|
20976
20767
|
}
|
|
20977
20768
|
|
|
20769
|
+
// Update available options based on selection
|
|
20770
|
+
this.handleMenuOptions();
|
|
20771
|
+
|
|
20978
20772
|
// Hide dropdown on selection (except during slot changes)
|
|
20979
|
-
if (
|
|
20980
|
-
|
|
20981
|
-
|
|
20982
|
-
this.
|
|
20983
|
-
|
|
20773
|
+
if (event.detail && event.detail.source !== 'slotchange') {
|
|
20774
|
+
setTimeout(() => {
|
|
20775
|
+
// do not close while typing in suggestion mode with no value selected, to allow freeform input
|
|
20776
|
+
if (this.menu.value || this.behavior !== 'suggestion') {
|
|
20777
|
+
this.hideBib();
|
|
20778
|
+
}
|
|
20779
|
+
}, 0);
|
|
20984
20780
|
|
|
20985
20781
|
// Announce the selection after the dropdown closes so it isn't
|
|
20986
20782
|
// overridden by VoiceOver's "collapsed" announcement from aria-expanded.
|
|
20987
|
-
const selectedValue =
|
|
20783
|
+
const selectedValue = event.detail.stringValue;
|
|
20988
20784
|
const announcementDelay = 300;
|
|
20989
20785
|
setTimeout(() => {
|
|
20990
20786
|
announceToScreenReader(this._getAnnouncementRoot(), `${selectedValue}, selected`);
|
|
20991
20787
|
}, announcementDelay);
|
|
20992
20788
|
}
|
|
20993
|
-
|
|
20994
|
-
// Programmatic value syncs leave availableOptions stale because
|
|
20995
|
-
// updateTriggerTextDisplay sets input.value with _syncingDisplayValue
|
|
20996
|
-
// and handleInputValueChange bails. Refresh the filter on echo events
|
|
20997
|
-
// only — fresh user selections take the existing hideBib path.
|
|
20998
|
-
if (isEcho && this.menu.optionSelected) {
|
|
20999
|
-
this._programmaticFilterRefresh = true;
|
|
21000
|
-
this.handleMenuOptions();
|
|
21001
|
-
setTimeout(() => {
|
|
21002
|
-
this._programmaticFilterRefresh = false;
|
|
21003
|
-
}, 0);
|
|
21004
|
-
}
|
|
21005
|
-
|
|
21006
|
-
// base-input skips auto-validate when focus is inside its own shadow,
|
|
21007
|
-
// which it is after setTriggerInputFocus — re-run so prior tooShort
|
|
21008
|
-
// clears. processCreditCard reasserts errorMessage on every render.
|
|
21009
|
-
if (!isEcho && this.menu.optionSelected && this.input.validate) {
|
|
21010
|
-
this.input.updateComplete.then(() => {
|
|
21011
|
-
this.input.validate(true);
|
|
21012
|
-
if (this.input.validity === 'valid') {
|
|
21013
|
-
this.input.errorMessage = '';
|
|
21014
|
-
}
|
|
21015
|
-
});
|
|
21016
|
-
}
|
|
21017
20789
|
});
|
|
21018
20790
|
|
|
21019
20791
|
this.menu.addEventListener('auroMenu-customEventFired', () => {
|
|
21020
20792
|
this.hideBib();
|
|
21021
20793
|
});
|
|
21022
20794
|
|
|
21023
|
-
// When the menu cannot match a programmatic value to any option,
|
|
21024
|
-
// clear the combobox selection state so it doesn't reference a
|
|
21025
|
-
// stale option. Safe from re-entrancy because any resulting
|
|
21026
|
-
// input.value changes dispatch isProgrammatic events.
|
|
21027
|
-
this.menu.addEventListener('auroMenu-selectValueFailure', () => {
|
|
21028
|
-
this.value = undefined;
|
|
21029
|
-
this.optionSelected = undefined;
|
|
21030
|
-
});
|
|
21031
|
-
|
|
21032
20795
|
this.menu.addEventListener('auroMenu-activatedOption', (evt) => {
|
|
21033
20796
|
this.optionActive = evt.detail;
|
|
21034
20797
|
|
|
@@ -21129,12 +20892,11 @@ class AuroCombobox extends AuroElement {
|
|
|
21129
20892
|
// event from the trigger. The _syncingBibValue guard persists across the
|
|
21130
20893
|
// async boundary and prevents that re-entrant event from running the
|
|
21131
20894
|
// non-fullscreen path (which would call clear() → hideBib()).
|
|
20895
|
+
// When the event comes from the fullscreen bib input, sync the value to
|
|
20896
|
+
// the trigger and run filtering, but suppress the re-entrant input event
|
|
20897
|
+
// that the trigger fires (via Lit updated() → notifyValueChanged()) so
|
|
20898
|
+
// the non-fullscreen hide/clear logic doesn't close the dialog.
|
|
21132
20899
|
if (event.target === this.inputInBib) {
|
|
21133
|
-
// Mirror the trigger-branch bail below — programmatic inputInBib writes
|
|
21134
|
-
// notify back into this branch via Lit's notifyValueChanged.
|
|
21135
|
-
if (this._syncingDisplayValue) {
|
|
21136
|
-
return;
|
|
21137
|
-
}
|
|
21138
20900
|
this._syncingBibValue = true;
|
|
21139
20901
|
this.input.value = this.inputInBib.value;
|
|
21140
20902
|
this.input.updateComplete.then(() => {
|
|
@@ -21144,37 +20906,18 @@ class AuroCombobox extends AuroElement {
|
|
|
21144
20906
|
// Run filtering inline — the re-entrant event won't reach this code.
|
|
21145
20907
|
this.menu.matchWord = normalizeFilterValue(this.inputInBib.value);
|
|
21146
20908
|
this.optionActive = null;
|
|
21147
|
-
|
|
21148
|
-
// In suggestion mode, keep the combobox value in sync with the typed
|
|
21149
|
-
// text so that freeform values are captured (mirroring the non-fullscreen
|
|
21150
|
-
// path). Clear the selection when the input is emptied.
|
|
21151
|
-
if (this.behavior === 'suggestion') {
|
|
21152
|
-
this.value = this.inputInBib.value || undefined;
|
|
21153
|
-
}
|
|
21154
|
-
|
|
21155
20909
|
this.handleMenuOptions();
|
|
21156
20910
|
this.dispatchEvent(new CustomEvent('inputValue', { detail: { value: this.inputValue } }));
|
|
21157
20911
|
return;
|
|
21158
20912
|
}
|
|
21159
20913
|
|
|
21160
|
-
// Ignore re-entrant input events caused by
|
|
21161
|
-
if (this._syncingBibValue
|
|
20914
|
+
// Ignore re-entrant input events caused by the bib→trigger sync above.
|
|
20915
|
+
if (this._syncingBibValue) {
|
|
21162
20916
|
return;
|
|
21163
20917
|
}
|
|
21164
20918
|
|
|
21165
20919
|
this.inputInBib.value = this.input.value;
|
|
21166
20920
|
|
|
21167
|
-
// Also sync the native input immediately so keystrokes arriving
|
|
21168
|
-
// before Lit's async update cycle (e.g. rapid Backspaces during a
|
|
21169
|
-
// fullscreen transition) operate on the correct content.
|
|
21170
|
-
// Skip the next programmatic input event to prevent the patched setter
|
|
21171
|
-
// from re-entering handleInputValueChange via the bib path.
|
|
21172
|
-
const bibNativeInput = this.inputInBib.inputElement;
|
|
21173
|
-
if (bibNativeInput && bibNativeInput.value !== this.input.value) {
|
|
21174
|
-
this.inputInBib.skipNextProgrammaticInputEvent = true;
|
|
21175
|
-
bibNativeInput.value = this.input.value || '';
|
|
21176
|
-
}
|
|
21177
|
-
|
|
21178
20921
|
this.menu.matchWord = normalizeFilterValue(this.input.value);
|
|
21179
20922
|
this.optionActive = null;
|
|
21180
20923
|
|
|
@@ -21182,7 +20925,7 @@ class AuroCombobox extends AuroElement {
|
|
|
21182
20925
|
this.value = this.input.value;
|
|
21183
20926
|
}
|
|
21184
20927
|
|
|
21185
|
-
if (!this.input.value
|
|
20928
|
+
if (!this.input.value) {
|
|
21186
20929
|
this.clear();
|
|
21187
20930
|
}
|
|
21188
20931
|
this.handleMenuOptions();
|
|
@@ -21251,16 +20994,6 @@ class AuroCombobox extends AuroElement {
|
|
|
21251
20994
|
return;
|
|
21252
20995
|
}
|
|
21253
20996
|
|
|
21254
|
-
// Ignore dispatches from the bib (fullscreen) input. It's re-validated
|
|
21255
|
-
// inside this.validate()'s auroInputElements loop with its own
|
|
21256
|
-
// (often undefined) validity, and the event is composed/bubbles up to
|
|
21257
|
-
// this listener with `target` retargeted to the combobox. Letting it
|
|
21258
|
-
// through would overwrite the trigger input's correct validity with
|
|
21259
|
-
// the bib input's stale one (e.g. wiping `tooShort` during typing).
|
|
21260
|
-
if (this.inputInBib && evt.composedPath()[0] === this.inputInBib && this.inputInBib !== this.input) {
|
|
21261
|
-
return;
|
|
21262
|
-
}
|
|
21263
|
-
|
|
21264
20997
|
this.input.validity = evt.detail.validity;
|
|
21265
20998
|
this.input.errorMessage = evt.detail.message;
|
|
21266
20999
|
this.validity = evt.detail.validity;
|
|
@@ -21322,18 +21055,10 @@ class AuroCombobox extends AuroElement {
|
|
|
21322
21055
|
* @returns {void}
|
|
21323
21056
|
*/
|
|
21324
21057
|
setMenuValue(value) {
|
|
21325
|
-
if (!this.menu
|
|
21058
|
+
if (!this.menu) {
|
|
21326
21059
|
return;
|
|
21327
21060
|
}
|
|
21328
|
-
// One-shot flag consumed by the auroMenu-selectedOption listener so the
|
|
21329
|
-
// echo of this sync doesn't propagate back to this.value.
|
|
21330
|
-
this._pendingMenuValueSync = true;
|
|
21331
21061
|
this.menu.value = value;
|
|
21332
|
-
// Backup clear: if menu.value === menu.optionSelected.value already, the
|
|
21333
|
-
// listener won't fire and the flag would swallow the next user click.
|
|
21334
|
-
setTimeout(() => {
|
|
21335
|
-
this._pendingMenuValueSync = false;
|
|
21336
|
-
}, 0);
|
|
21337
21062
|
}
|
|
21338
21063
|
|
|
21339
21064
|
/**
|
|
@@ -21348,15 +21073,6 @@ class AuroCombobox extends AuroElement {
|
|
|
21348
21073
|
this.menu.value = undefined;
|
|
21349
21074
|
this.validation.reset(this);
|
|
21350
21075
|
this.touched = false;
|
|
21351
|
-
// Force validity back to the cleared state. validation.reset() calls
|
|
21352
|
-
// validate() at the end, and (post-credit-card-fix) the trigger input's
|
|
21353
|
-
// residual validity may still be copied into the combobox by the
|
|
21354
|
-
// auroInputElements loop. Explicitly clear here so reset() actually
|
|
21355
|
-
// leaves the component in a "no validity" state.
|
|
21356
|
-
this.validity = undefined;
|
|
21357
|
-
this.errorMessage = '';
|
|
21358
|
-
this.input.validity = undefined;
|
|
21359
|
-
this.input.errorMessage = '';
|
|
21360
21076
|
}
|
|
21361
21077
|
|
|
21362
21078
|
/**
|
|
@@ -21364,24 +21080,16 @@ class AuroCombobox extends AuroElement {
|
|
|
21364
21080
|
* @returns {void}
|
|
21365
21081
|
*/
|
|
21366
21082
|
clear() {
|
|
21367
|
-
//
|
|
21368
|
-
|
|
21369
|
-
|
|
21370
|
-
return;
|
|
21371
|
-
}
|
|
21372
|
-
this._clearing = true;
|
|
21373
|
-
try {
|
|
21374
|
-
this.optionSelected = undefined;
|
|
21375
|
-
this.value = undefined;
|
|
21083
|
+
// Clear combobox state first
|
|
21084
|
+
this.optionSelected = undefined;
|
|
21085
|
+
this.value = undefined;
|
|
21376
21086
|
|
|
21377
|
-
|
|
21378
|
-
|
|
21379
|
-
|
|
21380
|
-
|
|
21381
|
-
|
|
21382
|
-
|
|
21383
|
-
} finally {
|
|
21384
|
-
this._clearing = false;
|
|
21087
|
+
// Then clear input and menu
|
|
21088
|
+
if (this.input.value) {
|
|
21089
|
+
this.input.clear();
|
|
21090
|
+
}
|
|
21091
|
+
if (this.menu.value || this.menu.optionSelected) {
|
|
21092
|
+
this.menu.reset();
|
|
21385
21093
|
}
|
|
21386
21094
|
}
|
|
21387
21095
|
|
|
@@ -21409,63 +21117,28 @@ class AuroCombobox extends AuroElement {
|
|
|
21409
21117
|
this.input.value = this.value;
|
|
21410
21118
|
}
|
|
21411
21119
|
|
|
21412
|
-
|
|
21413
|
-
|
|
21414
|
-
|
|
21415
|
-
|
|
21416
|
-
|
|
21417
|
-
|
|
21418
|
-
|
|
21419
|
-
|
|
21420
|
-
|
|
21120
|
+
if (this.menu && this.hasValue && this.menu.options) {
|
|
21121
|
+
this.menu.options.forEach((opt) => {
|
|
21122
|
+
if (!opt.hasAttribute('static')) {
|
|
21123
|
+
opt.removeAttribute('hidden');
|
|
21124
|
+
}
|
|
21125
|
+
});
|
|
21126
|
+
}
|
|
21127
|
+
|
|
21128
|
+
if (this.behavior === 'suggestion') {
|
|
21129
|
+
if (!this.menu.options || this.menu.options.length === 0) ; else if (this.menu.options.filter((opt) => opt.value === this.value).length > 0) {
|
|
21421
21130
|
this.setMenuValue(this.value);
|
|
21422
21131
|
} else {
|
|
21423
|
-
|
|
21424
|
-
|
|
21425
|
-
|
|
21426
|
-
|
|
21427
|
-
|
|
21428
|
-
|
|
21429
|
-
|
|
21430
|
-
|
|
21431
|
-
|
|
21432
|
-
const triggerNeedsSync = this.input.value !== nextValue;
|
|
21433
|
-
const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
|
|
21434
|
-
if (triggerNeedsSync || bibNeedsSync) {
|
|
21435
|
-
this._syncingDisplayValue = true;
|
|
21436
|
-
if (triggerNeedsSync) {
|
|
21437
|
-
this.input.value = nextValue;
|
|
21438
|
-
}
|
|
21439
|
-
if (bibNeedsSync) {
|
|
21440
|
-
this.inputInBib.value = nextValue;
|
|
21441
|
-
}
|
|
21442
|
-
const pending = [];
|
|
21443
|
-
if (triggerNeedsSync) {
|
|
21444
|
-
pending.push(this.input.updateComplete);
|
|
21445
|
-
}
|
|
21446
|
-
if (bibNeedsSync) {
|
|
21447
|
-
pending.push(this.inputInBib.updateComplete);
|
|
21448
|
-
}
|
|
21449
|
-
Promise.all(pending).then(() => {
|
|
21450
|
-
if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
|
|
21451
|
-
this.input.maskInstance.updateValue();
|
|
21452
|
-
}
|
|
21453
|
-
if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
|
|
21454
|
-
this.inputInBib.maskInstance.updateValue();
|
|
21455
|
-
}
|
|
21456
|
-
this._syncingDisplayValue = false;
|
|
21457
|
-
// handleInputValueChange bailed on the flag — refresh the filter.
|
|
21458
|
-
this._programmaticFilterRefresh = true;
|
|
21459
|
-
this.handleMenuOptions();
|
|
21460
|
-
setTimeout(() => {
|
|
21461
|
-
this._programmaticFilterRefresh = false;
|
|
21462
|
-
}, 0);
|
|
21463
|
-
});
|
|
21464
|
-
}
|
|
21132
|
+
this.menu.value = undefined;
|
|
21133
|
+
// Sync the input display for freeform values that don't match any option
|
|
21134
|
+
this.input.value = this.value;
|
|
21135
|
+
}
|
|
21136
|
+
} else {
|
|
21137
|
+
// Use setMenuValue like select does instead of direct assignment
|
|
21138
|
+
this.setMenuValue(this.value);
|
|
21139
|
+
if (!this.value) {
|
|
21140
|
+
this.clear();
|
|
21465
21141
|
}
|
|
21466
|
-
}
|
|
21467
|
-
if (!this.value) {
|
|
21468
|
-
this.clear();
|
|
21469
21142
|
}
|
|
21470
21143
|
if (this.value && !this.componentHasFocus) {
|
|
21471
21144
|
// If the value got set programmatically make sure we hide the bib
|
|
@@ -21503,18 +21176,12 @@ class AuroCombobox extends AuroElement {
|
|
|
21503
21176
|
// branch from calling hideBib() when the dropdown was just opened but
|
|
21504
21177
|
// :focus-within hasn't propagated through the top-layer dialog's nested
|
|
21505
21178
|
// shadow DOM boundaries.
|
|
21506
|
-
|
|
21507
|
-
// from a programmatic filter refresh after a value swap — the user
|
|
21508
|
-
// didn't interact, so we shouldn't auto-open the bib (especially for
|
|
21509
|
-
// the no-match path where the existing condition unconditionally fires).
|
|
21510
|
-
if (this._programmaticFilterRefresh) {
|
|
21511
|
-
this._programmaticFilterRefresh = false;
|
|
21512
|
-
} else if ((this.availableOptions.length > 0 && (this.componentHasFocus || this.dropdownOpen)) || (this.menu && this.menu.loading) || (this.availableOptions.length === 0 && this.noMatchOption)) {
|
|
21179
|
+
if ((this.availableOptions.length > 0 && (this.componentHasFocus || this.dropdownOpen)) || (this.menu && this.menu.loading) || (this.availableOptions.length === 0 && this.noMatchOption)) {
|
|
21513
21180
|
this.showBib();
|
|
21514
21181
|
if (!this.availableOptions.includes(this.menu.optionActive)) {
|
|
21515
21182
|
this.activateFirstEnabledAvailableOption();
|
|
21516
21183
|
}
|
|
21517
|
-
} else
|
|
21184
|
+
} else {
|
|
21518
21185
|
this.hideBib();
|
|
21519
21186
|
}
|
|
21520
21187
|
}
|