@aurodesignsystem-dev/auro-formkit 0.0.0-pr1400.3 → 0.0.0-pr1403.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 (42) hide show
  1. package/components/checkbox/demo/api.min.js +1 -1
  2. package/components/checkbox/demo/index.min.js +1 -1
  3. package/components/checkbox/dist/index.js +1 -1
  4. package/components/checkbox/dist/registered.js +1 -1
  5. package/components/combobox/demo/api.min.js +93 -94
  6. package/components/combobox/demo/index.min.js +93 -94
  7. package/components/combobox/dist/auro-combobox.d.ts +0 -2
  8. package/components/combobox/dist/index.js +14 -89
  9. package/components/combobox/dist/registered.js +14 -89
  10. package/components/counter/demo/api.min.js +2 -2
  11. package/components/counter/demo/index.min.js +2 -2
  12. package/components/counter/dist/index.js +2 -2
  13. package/components/counter/dist/registered.js +2 -2
  14. package/components/datepicker/demo/api.min.js +3 -3
  15. package/components/datepicker/demo/index.min.js +3 -3
  16. package/components/datepicker/dist/index.js +3 -3
  17. package/components/datepicker/dist/registered.js +3 -3
  18. package/components/dropdown/demo/api.min.js +1 -1
  19. package/components/dropdown/demo/index.min.js +1 -1
  20. package/components/dropdown/dist/index.js +1 -1
  21. package/components/dropdown/dist/registered.js +1 -1
  22. package/components/form/demo/api.min.js +104 -104
  23. package/components/form/demo/index.min.js +104 -104
  24. package/components/input/demo/api.min.js +1 -1
  25. package/components/input/demo/index.min.js +1 -1
  26. package/components/input/dist/index.js +1 -1
  27. package/components/input/dist/registered.js +1 -1
  28. package/components/menu/demo/api.min.js +79 -5
  29. package/components/menu/demo/index.min.js +79 -5
  30. package/components/menu/dist/auro-menu.context.d.ts +6 -0
  31. package/components/menu/dist/index.js +79 -5
  32. package/components/menu/dist/registered.js +79 -5
  33. package/components/radio/demo/api.min.js +1 -1
  34. package/components/radio/demo/index.min.js +1 -1
  35. package/components/radio/dist/index.js +1 -1
  36. package/components/radio/dist/registered.js +1 -1
  37. package/components/select/demo/api.min.js +82 -7
  38. package/components/select/demo/index.min.js +82 -7
  39. package/components/select/dist/index.js +3 -2
  40. package/components/select/dist/registered.js +3 -2
  41. package/custom-elements.json +14 -1
  42. package/package.json +1 -1
@@ -1687,7 +1687,7 @@ class AuroHelpText extends i$2 {
1687
1687
  }
1688
1688
  }
1689
1689
 
1690
- var formkitVersion = '202603270007';
1690
+ var formkitVersion = '202603270028';
1691
1691
 
1692
1692
  // Copyright (c) 2026 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
1693
1693
  // See LICENSE in the project root for license information.
@@ -1679,7 +1679,7 @@ class AuroHelpText extends i$2 {
1679
1679
  }
1680
1680
  }
1681
1681
 
1682
- var formkitVersion = '202603270007';
1682
+ var formkitVersion = '202603270028';
1683
1683
 
1684
1684
  // Copyright (c) 2026 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
1685
1685
  // See LICENSE in the project root for license information.
@@ -1632,7 +1632,7 @@ class AuroHelpText extends LitElement {
1632
1632
  }
1633
1633
  }
1634
1634
 
1635
- var formkitVersion = '202603270007';
1635
+ var formkitVersion = '202603270028';
1636
1636
 
1637
1637
  // Copyright (c) 2026 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
1638
1638
  // See LICENSE in the project root for license information.
@@ -1632,7 +1632,7 @@ class AuroHelpText extends LitElement {
1632
1632
  }
1633
1633
  }
1634
1634
 
1635
- var formkitVersion = '202603270007';
1635
+ var formkitVersion = '202603270028';
1636
1636
 
1637
1637
  // Copyright (c) 2026 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
1638
1638
  // See LICENSE in the project root for license information.
@@ -1300,8 +1300,6 @@ function navigateArrow(component, direction, options = {}) {
1300
1300
  }
1301
1301
  }
1302
1302
 
1303
- /* eslint-disable no-underscore-dangle */
1304
-
1305
1303
  /**
1306
1304
  * Returns the clear button element from the active input's shadow
1307
1305
  * DOM, if available.
@@ -1379,32 +1377,15 @@ const comboboxKeyboardStrategy = {
1379
1377
  if (!ctx.activeInput) {
1380
1378
  return;
1381
1379
  }
1382
-
1383
- // Active option → select immediately and close the dialog.
1384
- // Flag the component so the close handler focuses the trigger's
1385
- // clear button instead of the input. Set flags before makeSelection
1386
- // because the value change triggers showBib via Lit's updated().
1387
- if (component.optionActive) {
1388
- evt.preventDefault();
1389
- component._focusClearBtnAfterClose = true;
1390
- component._clearBtnFocusPending = true;
1391
- component.menu.makeSelection();
1392
- component.hideBib();
1393
- return;
1394
- }
1395
-
1396
1380
  const clearBtn = getClearBtn(ctx);
1397
1381
  const clearBtnHasFocus = isClearBtnFocused(ctx, clearBtn);
1398
1382
 
1399
- // No active option, input has a value, clear button not focused
1400
- // move focus to the dialog's clear button.
1383
+ // Tab from input: if clear button exists and doesn't have focus, focus it
1401
1384
  if (clearBtn && !clearBtnHasFocus && ctx.activeInput.value) {
1402
-
1403
1385
  // Force clear button container visible to work around Safari not
1404
1386
  // propagating :focus-within through shadow DOM boundaries, which
1405
1387
  // causes .wrapper:not(:focus-within) to hide .notification.clear.
1406
1388
  const clearContainer = clearBtn.closest('.clear');
1407
-
1408
1389
  if (clearContainer) {
1409
1390
  clearContainer.style.display = 'flex';
1410
1391
  clearBtn.addEventListener('focusout', () => {
@@ -1427,17 +1408,18 @@ const comboboxKeyboardStrategy = {
1427
1408
  return;
1428
1409
  }
1429
1410
 
1430
- // No active option, no clear button (or already focused) → just close.
1411
+ // Tab from clear button (or no clear button / no value) →
1412
+ // select the highlighted option if any, then close
1413
+ if (component.optionActive) {
1414
+ component.menu.makeSelection();
1415
+ }
1431
1416
  component.hideBib();
1432
1417
  return;
1433
1418
  }
1434
1419
 
1435
1420
  // Non-fullscreen: select + close
1436
- if (component.optionActive) {
1437
- evt.preventDefault();
1438
- component._focusClearBtnAfterClose = true;
1439
- component._clearBtnFocusPending = true;
1440
- component.menu.makeSelection();
1421
+ if (component.menu.optionActive && component.menu.optionActive.value) {
1422
+ component.menu.value = component.menu.optionActive.value;
1441
1423
  }
1442
1424
  component.hideBib();
1443
1425
  },
@@ -5088,7 +5070,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$4 {
5088
5070
  }
5089
5071
  };
5090
5072
 
5091
- var formkitVersion$2 = '202603270007';
5073
+ var formkitVersion$2 = '202603270028';
5092
5074
 
5093
5075
  let AuroElement$2 = class AuroElement extends i$4 {
5094
5076
  static get properties() {
@@ -12852,7 +12834,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$4 {
12852
12834
  }
12853
12835
  };
12854
12836
 
12855
- var formkitVersion$1 = '202603270007';
12837
+ var formkitVersion$1 = '202603270028';
12856
12838
 
12857
12839
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12858
12840
  // See LICENSE in the project root for license information.
@@ -13891,7 +13873,7 @@ class AuroBibtemplate extends i$4 {
13891
13873
  }
13892
13874
  }
13893
13875
 
13894
- var formkitVersion = '202603270007';
13876
+ var formkitVersion = '202603270028';
13895
13877
 
13896
13878
  var styleCss$3 = i$7`.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}`;
13897
13879
 
@@ -14901,12 +14883,6 @@ class AuroCombobox extends AuroElement {
14901
14883
  * @returns {void}
14902
14884
  */
14903
14885
  showBib() {
14904
- // Suppress reopening the bib when a Tab selection is in progress —
14905
- // the value change from makeSelection triggers availableOptions update
14906
- // which calls showBib from updated(), but the bib should stay closed.
14907
- if (this._clearBtnFocusPending) {
14908
- return;
14909
- }
14910
14886
  if (!this.input.value && !this.dropdown.isBibFullscreen) {
14911
14887
  this.dropdown.hide();
14912
14888
  return;
@@ -14963,6 +14939,7 @@ class AuroCombobox extends AuroElement {
14963
14939
  if (!this.dropdownOpen && this.input) {
14964
14940
  this.input.setActiveDescendant(null);
14965
14941
  this.optionActive = null;
14942
+ this.menu.menuService.clearHighlight();
14966
14943
 
14967
14944
  // Remove the highlighted state from all menu options so re-opening
14968
14945
  // the dropdown doesn't show a stale highlight.
@@ -14977,38 +14954,7 @@ class AuroCombobox extends AuroElement {
14977
14954
  // during fullscreen open to prevent touch pass-through.
14978
14955
  this.menu.style.pointerEvents = '';
14979
14956
 
14980
- const shouldFocusClearBtn = this._focusClearBtnAfterClose;
14981
- this._focusClearBtnAfterClose = false;
14982
-
14983
- if (shouldFocusClearBtn) {
14984
- // Set a guard so duplicate toggle events don't call
14985
- // restoreTriggerAfterClose and steal focus from the clear button.
14986
- this._clearBtnFocusPending = true;
14987
-
14988
- restoreTriggerAfterClose(this.dropdown, this.input);
14989
-
14990
- if (this.input.componentHasFocus) {
14991
- // Desktop: input already has focus, redirect to clear button
14992
- // after restoreTriggerAfterClose's rAF settles.
14993
- requestAnimationFrame(() => {
14994
- this.setClearBtnFocus();
14995
- this._clearBtnFocusPending = false;
14996
- });
14997
- } else {
14998
- // Fullscreen: input will receive focus after dialog.close().
14999
- // Listen for that focus event then redirect to clear button.
15000
- const onFocus = () => {
15001
- this.input.removeEventListener('focusin', onFocus);
15002
- requestAnimationFrame(() => {
15003
- this.setClearBtnFocus();
15004
- this._clearBtnFocusPending = false;
15005
- });
15006
- };
15007
- this.input.addEventListener('focusin', onFocus);
15008
- }
15009
- } else if (!this._clearBtnFocusPending) {
15010
- restoreTriggerAfterClose(this.dropdown, this.input);
15011
- }
14957
+ restoreTriggerAfterClose(this.dropdown, this.input);
15012
14958
  }
15013
14959
 
15014
14960
  if (this.dropdownOpen) {
@@ -15099,28 +15045,7 @@ class AuroCombobox extends AuroElement {
15099
15045
  setClearBtnFocus() {
15100
15046
  const clearBtn = this.input.shadowRoot.querySelector('.clearBtn');
15101
15047
  if (clearBtn) {
15102
- // Force the clear button container visible — without :focus-within
15103
- // the CSS rule `.wrapper:not(:focus-within) .notification.clear`
15104
- // hides the container with display:none, preventing focus.
15105
- const clearContainer = clearBtn.closest('.clear');
15106
-
15107
- if (clearContainer) {
15108
- clearContainer.style.display = 'flex';
15109
- clearBtn.addEventListener('focusout', () => {
15110
- requestAnimationFrame(() => {
15111
- clearContainer.style.display = '';
15112
- });
15113
- }, { once: true });
15114
- }
15115
-
15116
- // Focus the native button inside auro-button so the browser
15117
- // treats it as a real focusable element.
15118
- const nativeBtn = clearBtn.shadowRoot && clearBtn.shadowRoot.querySelector('button');
15119
- if (nativeBtn) {
15120
- nativeBtn.focus();
15121
- } else {
15122
- clearBtn.focus();
15123
- }
15048
+ clearBtn.focus();
15124
15049
  }
15125
15050
  }
15126
15051
 
@@ -16483,7 +16408,7 @@ class MenuService {
16483
16408
  * @returns {AuroMenuOption|null}
16484
16409
  */
16485
16410
  get highlightedOption() {
16486
- return this._menuOptions[this.highlightedIndex] || null;
16411
+ return this._highlightedOption;
16487
16412
  }
16488
16413
 
16489
16414
  /**
@@ -16571,6 +16496,7 @@ class MenuService {
16571
16496
  this.selectAllMatchingOptions = undefined;
16572
16497
 
16573
16498
  this.highlightedIndex = -1;
16499
+ this._highlightedOption = null;
16574
16500
 
16575
16501
  this._menuOptions = [];
16576
16502
  this._subscribers = [];
@@ -16621,6 +16547,7 @@ class MenuService {
16621
16547
  this._pendingValue = null;
16622
16548
  this._pendingRetryScheduled = false;
16623
16549
  this._pendingRetryCount = 0;
16550
+ this._highlightedOption = null;
16624
16551
  }
16625
16552
 
16626
16553
  /**
@@ -16678,8 +16605,12 @@ class MenuService {
16678
16605
  */
16679
16606
  moveHighlightedOption(direction) {
16680
16607
 
16681
- // Get the active options
16682
- const activeOptions = this._menuOptions.filter(option => option.isActive);
16608
+ // Build a flattened list of all active options from the full menu subtree in
16609
+ // DOM order so that nested <auro-menu> options participate in traversal.
16610
+ // querySelectorAll walks the entire light-DOM subtree and is not limited to
16611
+ // direct children, which is what caused nested options to be unreachable.
16612
+ const allOptions = Array.from(this.host.querySelectorAll('auro-menuoption, [auro-menuoption]'));
16613
+ const activeOptions = allOptions.filter(option => option.isActive);
16683
16614
 
16684
16615
  // Get the currently active option
16685
16616
  const currentActiveOption = activeOptions[activeOptions.indexOf(this.highlightedOption)];
@@ -16709,15 +16640,39 @@ class MenuService {
16709
16640
 
16710
16641
  if (!option) return;
16711
16642
 
16712
- // Get the index of the option to highlight
16643
+ // If the previously highlighted option belongs to a nested menu's own
16644
+ // MenuService (i.e. not in this._menuOptions), notify() won't reach it —
16645
+ // subscribers are per-service. Deactivate it directly so it loses its
16646
+ // highlighted CSS class before we move on.
16647
+ const prevOption = this._highlightedOption;
16648
+ if (prevOption && !this._menuOptions.includes(prevOption)) {
16649
+ prevOption.active = false;
16650
+ prevOption.updateActiveClasses();
16651
+ }
16652
+
16653
+ // Track by direct reference so nested options (not in _menuOptions) are
16654
+ // correctly remembered for the next navigation call.
16655
+ this._highlightedOption = option;
16656
+
16657
+ // highlightedIndex reflects position within the registered _menuOptions array.
16658
+ // For options that live in a nested menu's own MenuService this will be -1,
16659
+ // which is acceptable — the index is informational only.
16713
16660
  const index = this._menuOptions.indexOf(option);
16714
16661
 
16715
16662
  // Update highlighted index
16716
16663
  this.highlightedIndex = index;
16717
16664
 
16718
- // Notify subscribers of highlight change
16665
+ // Notify root-level subscribers of the highlight change. This correctly
16666
+ // activates/deactivates options that subscribed to THIS service.
16719
16667
  this.notify({ type: 'highlightChange', option, index: this.highlightedIndex });
16720
16668
 
16669
+ // If the new option is nested (not in this._menuOptions), notify() won't
16670
+ // reach it either. Activate it directly so it gains the highlighted class.
16671
+ if (!this._menuOptions.includes(option)) {
16672
+ option.active = true;
16673
+ option.updateActiveClasses();
16674
+ }
16675
+
16721
16676
  // Dispatch the change event
16722
16677
  this.dispatchChangeEvent('auroMenu-activatedOption', option);
16723
16678
  }
@@ -16731,6 +16686,20 @@ class MenuService {
16731
16686
  this.setHighlightedOption(option);
16732
16687
  }
16733
16688
 
16689
+ /**
16690
+ * Clears the highlighted option and removes its active CSS class.
16691
+ * Call this when the dropdown closes so the next open starts from a clean state.
16692
+ */
16693
+ clearHighlight() {
16694
+ const prev = this._highlightedOption;
16695
+ if (prev) {
16696
+ prev.active = false;
16697
+ prev.updateActiveClasses();
16698
+ }
16699
+ this._highlightedOption = null;
16700
+ this.highlightedIndex = -1;
16701
+ }
16702
+
16734
16703
  /**
16735
16704
  * Selects the currently highlighted option.
16736
16705
  */
@@ -16879,6 +16848,26 @@ class MenuService {
16879
16848
  return;
16880
16849
  }
16881
16850
 
16851
+ // Before treating this as a hard miss, scan the full DOM subtree for
16852
+ // nested menuoptions whose keys match. Nested options register with
16853
+ // their own MenuService instance (context isolation), so they never
16854
+ // appear in this._menuOptions.
16855
+ const allOptions = Array.from(this.host.querySelectorAll('auro-menuoption, [auro-menuoption]'));
16856
+ const nestedMatches = allOptions.filter(option =>
16857
+ !this._menuOptions.includes(option) &&
16858
+ option.isActive &&
16859
+ validatedValues.includes(option.key)
16860
+ );
16861
+
16862
+ if (nestedMatches.length) {
16863
+ this.clearPendingValue();
16864
+ const selected = this.multiSelect ? nestedMatches : [nestedMatches[nestedMatches.length - 1]];
16865
+ if (this.optionsArraysMatch(selected, this.selectedOptions)) return;
16866
+ this.selectedOptions = selected;
16867
+ this.stageUpdate();
16868
+ return;
16869
+ }
16870
+
16882
16871
  this.clearPendingValue();
16883
16872
 
16884
16873
  if (this.selectedOptions.length > 0) {
@@ -17005,6 +16994,16 @@ class MenuService {
17005
16994
  selectedOptions: this.selectedOptions,
17006
16995
  ...meta
17007
16996
  });
16997
+
16998
+ // Options subscribed to a nested menu's own service never receive the
16999
+ // notify() broadcast above. Sync their selected state directly so the
17000
+ // DOM attribute stays accurate and dual-selection cannot occur.
17001
+ const allOptions = Array.from(this.host.querySelectorAll('auro-menuoption, [auro-menuoption]'));
17002
+ allOptions.forEach(option => {
17003
+ if (!this._menuOptions.includes(option)) {
17004
+ option.setInternalSelected(this.selectedOptions.includes(option));
17005
+ }
17006
+ });
17008
17007
  }
17009
17008
 
17010
17009
  /**