@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.
Files changed (55) hide show
  1. package/components/checkbox/demo/customize.min.js +1 -1
  2. package/components/checkbox/demo/getting-started.min.js +1 -1
  3. package/components/checkbox/demo/index.min.js +1 -1
  4. package/components/checkbox/dist/index.js +1 -1
  5. package/components/checkbox/dist/registered.js +1 -1
  6. package/components/combobox/demo/customize.min.js +120 -139
  7. package/components/combobox/demo/getting-started.min.js +120 -139
  8. package/components/combobox/demo/index.min.js +120 -139
  9. package/components/combobox/dist/auro-combobox.d.ts +9 -0
  10. package/components/combobox/dist/index.js +120 -139
  11. package/components/combobox/dist/registered.js +120 -139
  12. package/components/counter/demo/customize.min.js +2 -2
  13. package/components/counter/demo/index.min.js +2 -2
  14. package/components/counter/dist/index.js +2 -2
  15. package/components/counter/dist/registered.js +2 -2
  16. package/components/datepicker/demo/api.md +0 -2
  17. package/components/datepicker/demo/customize.md +33 -195
  18. package/components/datepicker/demo/customize.min.js +37 -43
  19. package/components/datepicker/demo/index.min.js +36 -35
  20. package/components/datepicker/dist/index.js +36 -35
  21. package/components/datepicker/dist/registered.js +36 -35
  22. package/components/datepicker/dist/src/auro-datepicker.d.ts +0 -2
  23. package/components/dropdown/demo/customize.min.js +1 -1
  24. package/components/dropdown/demo/getting-started.min.js +1 -1
  25. package/components/dropdown/demo/index.min.js +1 -1
  26. package/components/dropdown/dist/index.js +1 -1
  27. package/components/dropdown/dist/registered.js +1 -1
  28. package/components/form/demo/customize.min.js +325 -230
  29. package/components/form/demo/getting-started.min.js +325 -230
  30. package/components/form/demo/index.min.js +325 -230
  31. package/components/form/demo/registerDemoDeps.min.js +325 -230
  32. package/components/input/demo/customize.md +55 -56
  33. package/components/input/demo/customize.min.js +32 -26
  34. package/components/input/demo/getting-started.min.js +32 -26
  35. package/components/input/demo/index.md +2 -2
  36. package/components/input/demo/index.min.js +32 -26
  37. package/components/input/dist/index.js +32 -26
  38. package/components/input/dist/registered.js +32 -26
  39. package/components/radio/demo/customize.min.js +1 -1
  40. package/components/radio/demo/getting-started.min.js +1 -1
  41. package/components/radio/demo/index.min.js +1 -1
  42. package/components/radio/dist/index.js +1 -1
  43. package/components/radio/dist/registered.js +1 -1
  44. package/components/select/demo/api.md +1 -0
  45. package/components/select/demo/customize.md +71 -0
  46. package/components/select/demo/customize.min.js +133 -26
  47. package/components/select/demo/getting-started.min.js +133 -26
  48. package/components/select/demo/index.min.js +133 -26
  49. package/components/select/demo/keyboard-behavior.md +18 -0
  50. package/components/select/dist/auro-select.d.ts +38 -2
  51. package/components/select/dist/index.js +133 -26
  52. package/components/select/dist/registered.js +133 -26
  53. package/components/select/dist/selectUtils.d.ts +12 -0
  54. package/custom-elements.json +114 -10
  55. 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 = '202606171946';
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 === 'credit-card') {
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. Scoped to
17512
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
17513
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
17514
- // and flip validity from patternMismatch to tooShort.
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
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
17626
- // by _configuringMask above) could otherwise trigger handleInput
17627
- // processCreditCard configureAutoFormatting before the outer call's
17628
- // set value has finished its alignCursor pass.
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
- // Stash and clear any existing value before IMask init.
17644
- // IMask's constructor processes the current input value which requires
17645
- // selection state clearing first avoids that scenario entirely.
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
- // Restore the stashed value through IMask so it's properly masked
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 = '202606171946';
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 = '202606171946';
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) || this.menu.currentLabel;
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
- if (!this.persistInput && !(this.behavior === 'suggestion' && isInputFocusedWithNoSelection)) {
20514
- const nextValue = label || this.value;
20515
- // Only set the flag when there's an actual write to suppress —
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 no longer visible, or when _index has
20602
- // been reset (e.g. by clearSelection in an async update) so that
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
- // The dialog's showModal() steals focus from the trigger.
20738
- // A single rAF is enough for the dialog DOM to be painted and
20739
- // focusable, then doubleRaf finalizes the transition.
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 Branch 2 callsite already has focus on the input
20866
- // via the focusin → this.focus() redirect (L1448-1452), so this is a
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 (!this.optionSelected || this.optionSelected !== selected) {
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) || this.menu.value);
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; otherwise clear it.
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
- // Sync the display for programmatic freeform value changes (e.g. the
21457
- // swap-values pattern). Guard with _syncingDisplayValue so that the
21458
- // re-entrant input event from base-input.notifyValueChanged() is
21459
- // ignored by handleInputValueChange. Skip the sync when input already
21460
- // matches to avoid spurious events during the normal typing path.
21461
- const nextValue = this.value || '';
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(() => {
@@ -1099,7 +1099,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$2 {
1099
1099
  }
1100
1100
  };
1101
1101
 
1102
- var formkitVersion$1 = '202606171946';
1102
+ var formkitVersion$1 = '202606190840';
1103
1103
 
1104
1104
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1105
1105
  // See LICENSE in the project root for license information.
@@ -5445,7 +5445,7 @@ class AuroHelpText extends i$2 {
5445
5445
  }
5446
5446
  }
5447
5447
 
5448
- var formkitVersion = '202606171946';
5448
+ var formkitVersion = '202606190840';
5449
5449
 
5450
5450
  let AuroElement$1 = class AuroElement extends i$2 {
5451
5451
  static get properties() {
@@ -1099,7 +1099,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$2 {
1099
1099
  }
1100
1100
  };
1101
1101
 
1102
- var formkitVersion$1 = '202606171946';
1102
+ var formkitVersion$1 = '202606190840';
1103
1103
 
1104
1104
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1105
1105
  // See LICENSE in the project root for license information.
@@ -5445,7 +5445,7 @@ class AuroHelpText extends i$2 {
5445
5445
  }
5446
5446
  }
5447
5447
 
5448
- var formkitVersion = '202606171946';
5448
+ var formkitVersion = '202606190840';
5449
5449
 
5450
5450
  let AuroElement$1 = class AuroElement extends i$2 {
5451
5451
  static get properties() {
@@ -1049,7 +1049,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
1049
1049
  }
1050
1050
  };
1051
1051
 
1052
- var formkitVersion$1 = '202606171946';
1052
+ var formkitVersion$1 = '202606190840';
1053
1053
 
1054
1054
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1055
1055
  // See LICENSE in the project root for license information.
@@ -5377,7 +5377,7 @@ class AuroHelpText extends LitElement {
5377
5377
  }
5378
5378
  }
5379
5379
 
5380
- var formkitVersion = '202606171946';
5380
+ var formkitVersion = '202606190840';
5381
5381
 
5382
5382
  let AuroElement$1 = class AuroElement extends LitElement {
5383
5383
  static get properties() {
@@ -1049,7 +1049,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
1049
1049
  }
1050
1050
  };
1051
1051
 
1052
- var formkitVersion$1 = '202606171946';
1052
+ var formkitVersion$1 = '202606190840';
1053
1053
 
1054
1054
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1055
1055
  // See LICENSE in the project root for license information.
@@ -5377,7 +5377,7 @@ class AuroHelpText extends LitElement {
5377
5377
  }
5378
5378
  }
5379
5379
 
5380
- var formkitVersion = '202606171946';
5380
+ var formkitVersion = '202606190840';
5381
5381
 
5382
5382
  let AuroElement$1 = class AuroElement extends LitElement {
5383
5383
  static get properties() {
@@ -109,8 +109,6 @@ The `auro-datepicker` component provides users with a way to select a date or da
109
109
  | `fromLabel` | Defines the label content for the first input. |
110
110
  | `helpText` | Defines the content of the helpText. |
111
111
  | `label` | Defines the label content for the entire datepicker when `layout="snowflake"`. |
112
- | `optionalFromLabel` | Overrides the "(optional)" text rendered next to the first input's label when the datepicker is not `required`. |
113
- | `optionalToLabel` | Overrides the "(optional)" text rendered next to the second input's label when `range` is set and the datepicker is not `required`. |
114
112
  | `popover_YYYY_MM_DD` | Defines the content to display in the auro-calendar-cell popover for the specified date. |
115
113
  | `toLabel` | Defines the label content for the second input when the `range` attribute is used. |
116
114