@aurodesignsystem-dev/auro-formkit 0.0.0-pr1413.0 → 0.0.0-pr1413.2

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 (49) 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 +121 -129
  6. package/components/combobox/demo/index.min.js +121 -129
  7. package/components/combobox/demo/keyboardBehavior.md +9 -36
  8. package/components/combobox/dist/auro-combobox.d.ts +13 -0
  9. package/components/combobox/dist/comboboxKeyboardStrategy.d.ts +4 -2
  10. package/components/combobox/dist/index.js +120 -128
  11. package/components/combobox/dist/registered.js +120 -128
  12. package/components/counter/demo/api.min.js +13 -3
  13. package/components/counter/demo/index.min.js +13 -3
  14. package/components/counter/dist/index.js +13 -3
  15. package/components/counter/dist/registered.js +13 -3
  16. package/components/datepicker/demo/api.min.js +44 -21
  17. package/components/datepicker/demo/index.min.js +44 -21
  18. package/components/datepicker/dist/index.js +44 -21
  19. package/components/datepicker/dist/registered.js +44 -21
  20. package/components/dropdown/demo/api.md +29 -28
  21. package/components/dropdown/demo/api.min.js +12 -2
  22. package/components/dropdown/demo/index.min.js +12 -2
  23. package/components/dropdown/dist/auro-dropdown.d.ts +8 -0
  24. package/components/dropdown/dist/index.js +12 -2
  25. package/components/dropdown/dist/registered.js +12 -2
  26. package/components/form/demo/api.min.js +363 -264
  27. package/components/form/demo/index.min.js +363 -264
  28. package/components/input/demo/api.min.js +102 -77
  29. package/components/input/demo/index.min.js +102 -77
  30. package/components/input/dist/auro-input.d.ts +11 -0
  31. package/components/input/dist/base-input.d.ts +1 -0
  32. package/components/input/dist/index.js +32 -18
  33. package/components/input/dist/registered.js +32 -18
  34. package/components/menu/demo/api.min.js +1 -1
  35. package/components/menu/demo/index.min.js +1 -1
  36. package/components/menu/dist/index.js +1 -1
  37. package/components/menu/dist/registered.js +1 -1
  38. package/components/radio/demo/api.min.js +1 -1
  39. package/components/radio/demo/index.min.js +1 -1
  40. package/components/radio/dist/index.js +1 -1
  41. package/components/radio/dist/registered.js +1 -1
  42. package/components/select/demo/api.min.js +87 -26
  43. package/components/select/demo/index.min.js +87 -26
  44. package/components/select/demo/keyboardBehavior.md +3 -3
  45. package/components/select/dist/index.js +86 -25
  46. package/components/select/dist/registered.js +86 -25
  47. package/components/select/dist/selectKeyboardStrategy.d.ts +5 -2
  48. package/custom-elements.json +62 -4
  49. package/package.json +1 -1
@@ -1249,26 +1249,23 @@ function isClearBtnFocused(ctx, clearBtn = getClearBtn(ctx)) {
1249
1249
  if (!clearBtn) {
1250
1250
  return false;
1251
1251
  }
1252
- return Boolean(clearBtn.shadowRoot && clearBtn.shadowRoot.activeElement !== null);
1252
+ const isFocused = Boolean(clearBtn.shadowRoot && clearBtn.shadowRoot.activeElement !== null);
1253
+ return isFocused;
1253
1254
  }
1254
1255
 
1255
1256
  const comboboxKeyboardStrategy = {
1256
- async Enter(component, evt, ctx) {
1257
- // If the clear button has focus, let the browser activate it normally.
1258
- // stopPropagation prevents parent containers (e.g., forms) from treating
1259
- // Enter as a submit, but we must NOT call preventDefault — that would
1260
- // block the browser's built-in "Enter activates focused button" behavior.
1257
+ Enter(component, evt, ctx) {
1261
1258
  if (isClearBtnFocused(ctx)) {
1259
+ // If the clear button has focus, let the browser activate it normally.
1260
+ // stopPropagation prevents parent containers (e.g., forms) from treating
1261
+ // Enter as a submit, but we must NOT call preventDefault — that would
1262
+ // block the browser's built-in "Enter activates focused button" behavior.
1262
1263
  evt.stopPropagation();
1263
- return;
1264
- }
1265
-
1266
- if (ctx.isExpanded && component.optionActive) {
1264
+ } else if (ctx.isExpanded && component.menu.optionActive) {
1267
1265
  component.menu.makeSelection();
1268
- await component.updateComplete;
1266
+ component.setClearBtnFocus();
1269
1267
  evt.preventDefault();
1270
1268
  evt.stopPropagation();
1271
- component.setClearBtnFocus();
1272
1269
  } else {
1273
1270
  // Prevent the keypress from bubbling to parent containers (e.g., forms)
1274
1271
  // which could interpret Enter as a submit or trigger other unintended behavior.
@@ -1280,71 +1277,28 @@ const comboboxKeyboardStrategy = {
1280
1277
  }
1281
1278
  },
1282
1279
 
1283
- Tab(component, evt, ctx) {
1284
- if (!ctx.isExpanded) {
1285
- return;
1280
+ Tab(component, _evt, ctx) {
1281
+ if (ctx.isExpanded && !isClearBtnFocused(ctx)) {
1282
+ // ClearBtn will not bubble up tab key events when it's focused, so need to manage it here when focused
1283
+ component.menu.makeSelection();
1284
+ component.hideBib();
1286
1285
  }
1286
+ },
1287
1287
 
1288
- // Shift+Tab moves the highlight to the first non-disabled option
1289
- // without making a selection or closing the bib.
1290
- if (evt.shiftKey) {
1288
+ Home(component, evt, ctx) {
1289
+ if (ctx.isExpanded) {
1291
1290
  evt.preventDefault();
1292
- const firstActive = component.menu.menuService.menuOptions.find((option) => option.isActive);
1293
- if (firstActive) {
1294
- component.menu.updateActiveOption(firstActive);
1295
- }
1296
- return;
1297
- }
1298
-
1299
- if (ctx.isModal) {
1300
- if (!ctx.activeInput) {
1301
- return;
1302
- }
1303
- const clearBtn = getClearBtn(ctx);
1304
- const clearBtnHasFocus = isClearBtnFocused(ctx, clearBtn);
1305
-
1306
- // Tab from input: if clear button exists and doesn't have focus, focus it
1307
- if (clearBtn && !clearBtnHasFocus && ctx.activeInput.value) {
1308
- // Force clear button container visible to work around Safari not
1309
- // propagating :focus-within through shadow DOM boundaries, which
1310
- // causes .wrapper:not(:focus-within) to hide .notification.clear.
1311
- const clearContainer = clearBtn.closest('.clear');
1312
- if (clearContainer) {
1313
- clearContainer.style.display = 'flex';
1314
- clearBtn.addEventListener('focusout', () => {
1315
- // Delay cleanup so :focus-within settles when focus moves
1316
- // to a sibling (e.g., Shift+Tab back to the input).
1317
- requestAnimationFrame(() => {
1318
- clearContainer.style.display = '';
1319
- });
1320
- }, { once: true });
1321
- }
1322
-
1323
- // Focus the native button inside auro-button so the browser
1324
- // treats it as a real focusable element inside the dialog.
1325
- const nativeBtn = clearBtn.shadowRoot && clearBtn.shadowRoot.querySelector('button');
1326
- if (nativeBtn) {
1327
- nativeBtn.focus();
1328
- } else {
1329
- clearBtn.focus();
1330
- }
1331
- return;
1332
- }
1333
-
1334
- // Tab from clear button (or no clear button / no value) →
1335
- // select the highlighted option if any, then close
1336
- if (component.optionActive) {
1337
- component.menu.makeSelection();
1338
- }
1339
- component.hideBib();
1340
- return;
1291
+ evt.stopPropagation();
1292
+ component.activateFirstEnabledAvailableOption();
1341
1293
  }
1294
+ },
1342
1295
 
1343
- // Non-fullscreen: select + close
1344
- if (component.menu.optionActive && component.menu.optionActive.value) {
1345
- component.menu.value = component.menu.optionActive.value;
1296
+ End(component, evt, ctx) {
1297
+ if (ctx.isExpanded) {
1298
+ evt.preventDefault();
1299
+ evt.stopPropagation();
1300
+ component.activateLastEnabledAvailableOption();
1346
1301
  }
1347
- component.hideBib();
1348
1302
  },
1349
1303
 
1350
1304
  ArrowUp(component, evt, ctx) {
@@ -1353,14 +1307,15 @@ const comboboxKeyboardStrategy = {
1353
1307
  return;
1354
1308
  }
1355
1309
 
1310
+ // option display and navigation are prevented if there are no available options
1356
1311
  if (component.availableOptions.length > 0) {
1357
- component.showBib();
1358
- }
1359
- // Read live visibility — ctx.isExpanded was computed before showBib() above,
1360
- // so it wouldn't reflect the state change.
1361
- if (component.dropdown.isPopoverVisible) {
1362
- evt.preventDefault();
1363
- navigateArrow(component, 'up');
1312
+ // navigate if bib is open otherwise open it
1313
+ if (component.dropdown.isPopoverVisible) {
1314
+ evt.preventDefault();
1315
+ navigateArrow(component, 'up');
1316
+ } else {
1317
+ component.showBib();
1318
+ }
1364
1319
  }
1365
1320
  },
1366
1321
 
@@ -1370,16 +1325,17 @@ const comboboxKeyboardStrategy = {
1370
1325
  return;
1371
1326
  }
1372
1327
 
1328
+ // option display and navigation are prevented if there are no available options
1373
1329
  if (component.availableOptions.length > 0) {
1374
- component.showBib();
1375
- }
1376
- // Read live visibility — ctx.isExpanded was computed before showBib() above,
1377
- // so it wouldn't reflect the state change.
1378
- if (component.dropdown.isPopoverVisible) {
1379
- evt.preventDefault();
1380
- navigateArrow(component, 'down');
1330
+ // navigate if bib is open otherwise open it
1331
+ if (component.dropdown.isPopoverVisible) {
1332
+ evt.preventDefault();
1333
+ navigateArrow(component, 'down');
1334
+ } else {
1335
+ component.showBib();
1336
+ }
1381
1337
  }
1382
- },
1338
+ }
1383
1339
  };
1384
1340
 
1385
1341
  /**
@@ -4983,7 +4939,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$4 {
4983
4939
  }
4984
4940
  };
4985
4941
 
4986
- var formkitVersion$2 = '202604021941';
4942
+ var formkitVersion$2 = '202604031554';
4987
4943
 
4988
4944
  let AuroElement$2 = class AuroElement extends i$4 {
4989
4945
  static get properties() {
@@ -5164,6 +5120,7 @@ class AuroDropdown extends AuroElement$2 {
5164
5120
  this.appearance = 'default';
5165
5121
  this.chevron = false;
5166
5122
  this.disabled = false;
5123
+ this.disableKeyboardHandling = false;
5167
5124
  this.error = false;
5168
5125
  this.tabIndex = 0;
5169
5126
  this.noToggle = false;
@@ -5375,6 +5332,14 @@ class AuroDropdown extends AuroElement$2 {
5375
5332
  reflect: true
5376
5333
  },
5377
5334
 
5335
+ /**
5336
+ * If declared, the dropdown will not handle keyboard events and will require the consumer to manage this behavior.
5337
+ */
5338
+ disableKeyboardHandling: {
5339
+ type: Boolean,
5340
+ reflect: true
5341
+ },
5342
+
5378
5343
  /**
5379
5344
  * @private
5380
5345
  */
@@ -5680,7 +5645,7 @@ class AuroDropdown extends AuroElement$2 {
5680
5645
 
5681
5646
  firstUpdated() {
5682
5647
  // Configure the floater to, this will generate the ID for the bib
5683
- this.floater.configure(this, 'auroDropdown');
5648
+ this.floater.configure(this, 'auroDropdown', !this.disableKeyboardHandling);
5684
5649
 
5685
5650
  // Prevent `contain: layout` on the dropdown host. Layout containment
5686
5651
  // creates a containing block for position:fixed descendants (the bib),
@@ -5988,6 +5953,7 @@ class AuroDropdown extends AuroElement$2 {
5988
5953
  aria-expanded="${o(this.a11yRole === 'button' || this.triggerContentFocusable ? undefined : this.isPopoverVisible)}"
5989
5954
  aria-controls="${o(this.a11yRole === 'button' || this.triggerContentFocusable ? undefined : this.dropdownId)}"
5990
5955
  aria-labelledby="${o(this.triggerContentFocusable ? undefined : 'triggerLabel')}"
5956
+ aria-disabled="${o(this.disabled ? 'true' : undefined)}"
5991
5957
  @focusin="${this.handleFocusin}"
5992
5958
  @blur="${this.handleFocusOut}">
5993
5959
  <div class="triggerContentWrapper" id="triggerLabel">
@@ -11714,6 +11680,12 @@ class BaseInput extends AuroElement$1 {
11714
11680
  this.wrapperElement = this.shadowRoot.querySelector('.wrapper');
11715
11681
  this.inputElement = this.renderRoot.querySelector('input');
11716
11682
  this.labelElement = this.shadowRoot.querySelector('label');
11683
+ this.clearBtn = this.clearButtonRef.value;
11684
+
11685
+ // This must get moved into inputKeyboardStrategy when implemented
11686
+ this.clearBtn.addEventListener('keydown', (evt) => {
11687
+ evt.stopPropagation();
11688
+ });
11717
11689
 
11718
11690
  this.patchInputEvent(this.inputElement);
11719
11691
 
@@ -12737,7 +12709,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$4 {
12737
12709
  }
12738
12710
  };
12739
12711
 
12740
- var formkitVersion$1 = '202604021941';
12712
+ var formkitVersion$1 = '202604031554';
12741
12713
 
12742
12714
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12743
12715
  // See LICENSE in the project root for license information.
@@ -12794,6 +12766,11 @@ class AuroInput extends BaseInput {
12794
12766
  * @private
12795
12767
  */
12796
12768
  this.iconTag = versioning.generateTag('auro-formkit-input-icon', iconVersion$2, _$2);
12769
+
12770
+ /**
12771
+ * @private
12772
+ */
12773
+ this.clearButtonRef = e$1();
12797
12774
  }
12798
12775
 
12799
12776
  static get styles() {
@@ -12811,6 +12788,19 @@ class AuroInput extends BaseInput {
12811
12788
  ];
12812
12789
  }
12813
12790
 
12791
+ /**
12792
+ * Returns classmap configuration for the clear button visibility.
12793
+ * The button is hidden when the input has no value, is read-only, or is disabled.
12794
+ * @private
12795
+ * @returns {Record<string, boolean>} - Classmap object controlling clear button display state.
12796
+ */
12797
+ get clearBtnClassMap() {
12798
+ return {
12799
+ 'util_displayHidden': !this.hasValue || this.readyOnly || this.disabled
12800
+ };
12801
+ }
12802
+
12803
+
12814
12804
  /**
12815
12805
  * Determines if the HTML input element should be visually hidden.
12816
12806
  * Returns true when display value content exists without focus and has a value,
@@ -13130,10 +13120,11 @@ class AuroInput extends BaseInput {
13130
13120
  <${this.buttonTag}
13131
13121
  @click="${this.handleClickClear}"
13132
13122
  appearance="${this.onDark ? 'inverse' : this.appearance}"
13133
- class="notificationBtn clearBtn"
13123
+ class="notificationBtn clearBtn ${e$3(this.clearBtnClassMap)}"
13134
13124
  shape="circle"
13135
13125
  size="sm"
13136
- variant="ghost">
13126
+ variant="ghost"
13127
+ ${n$2(this.clearButtonRef)}>
13137
13128
  <span><slot name="ariaLabel.clear">Clear Input</slot></span>
13138
13129
  <${this.iconTag}
13139
13130
  aria-hidden="true"
@@ -13278,11 +13269,7 @@ class AuroInput extends BaseInput {
13278
13269
  <div part="accent-right" class="accents right">
13279
13270
  ${this.renderValidationErrorIconHtml()}
13280
13271
  ${this.hasValue && this.type === 'password' ? this.renderHtmlNotificationPassword() : undefined}
13281
- ${this.hasValue ? u$7`
13282
- ${!this.disabled && !this.readonly ? u$7`
13283
- ${this.renderHtmlActionClear()}
13284
- ` : undefined}
13285
- ` : undefined}
13272
+ ${this.renderHtmlActionClear()}
13286
13273
  </div>
13287
13274
  </div>
13288
13275
  <div class="helpTextWrapper leftIndent rightIndent" part="inputHelpText">
@@ -13314,11 +13301,7 @@ class AuroInput extends BaseInput {
13314
13301
  ${this.layout.includes('right') || this.layout === "emphasized" ? u$7`
13315
13302
  ${this.renderValidationErrorIconHtml()}
13316
13303
  ` : undefined}
13317
- ${this.hasValue ? u$7`
13318
- ${!this.disabled && !this.readonly ? u$7`
13319
- ${this.renderHtmlActionClear()}
13320
- ` : undefined}
13321
- ` : undefined}
13304
+ ${this.renderHtmlActionClear()}
13322
13305
  </div>
13323
13306
  </div>
13324
13307
  <div class="${e$3(this.helpTextClasses)}" part="inputHelpText">
@@ -13346,11 +13329,7 @@ class AuroInput extends BaseInput {
13346
13329
  </div>
13347
13330
  <div class="accents right">
13348
13331
  ${this.renderValidationErrorIconHtml()}
13349
- ${this.hasValue ? u$7`
13350
- ${!this.disabled && !this.readonly ? u$7`
13351
- ${this.renderHtmlActionClear()}
13352
- ` : undefined}
13353
- ` : undefined}
13332
+ ${this.renderHtmlActionClear()}
13354
13333
  </div>
13355
13334
  </div>
13356
13335
  <div class="helpTextWrapper leftIndent rightIndent" part="inputHelpText">
@@ -13776,7 +13755,7 @@ class AuroBibtemplate extends i$4 {
13776
13755
  }
13777
13756
  }
13778
13757
 
13779
- var formkitVersion = '202604021941';
13758
+ var formkitVersion = '202604031554';
13780
13759
 
13781
13760
  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}`;
13782
13761
 
@@ -14255,6 +14234,7 @@ class AuroCombobox extends AuroElement {
14255
14234
 
14256
14235
  /**
14257
14236
  * Array of available options to display in the dropdown.
14237
+ * This array contains all non-hidden options (e.g., hidden by filtering on input value).
14258
14238
  * @private
14259
14239
  */
14260
14240
  availableOptions: {
@@ -14632,12 +14612,40 @@ class AuroCombobox extends AuroElement {
14632
14612
  AuroLibraryRuntimeUtils$4.prototype.registerComponent(name, AuroCombobox);
14633
14613
  }
14634
14614
 
14615
+ /**
14616
+ * Mark the first available (non-hidden), enabled option as `active`.
14617
+ * @private
14618
+ * @returns {void}
14619
+ */
14620
+ activateFirstEnabledAvailableOption() {
14621
+ const firstEnabledOptionIndex = this.availableOptions.findIndex((opt) => !opt.disabled);
14622
+ this.updateActiveOption(firstEnabledOptionIndex);
14623
+ }
14624
+
14625
+ /**
14626
+ * Mark the last available (non-hidden), enabled option as `active`.
14627
+ * @private
14628
+ * @returns {void}
14629
+ */
14630
+ activateLastEnabledAvailableOption() {
14631
+ let lastEnabledOptionIndex = -1;
14632
+
14633
+ // Work backwards through the available options array to find the last enabled option
14634
+ for (let index = this.availableOptions.length - 1; index >= 0; index -= 1) {
14635
+ if (!this.availableOptions[index].disabled) {
14636
+ lastEnabledOptionIndex = index;
14637
+ break;
14638
+ }
14639
+ }
14640
+
14641
+ this.updateActiveOption(lastEnabledOptionIndex);
14642
+ }
14643
+
14635
14644
  /**
14636
14645
  * Updates the filter for the available options based on the input value.
14637
14646
  * @private
14638
14647
  */
14639
14648
  updateFilter() {
14640
-
14641
14649
  // Reset available options if noFilter is set to false after being true.
14642
14650
  if (this.noFilter) {
14643
14651
  this.availableOptions = [...this.options];
@@ -14756,6 +14764,10 @@ class AuroCombobox extends AuroElement {
14756
14764
  if (this.value && this.input.value && !this.menu.value) {
14757
14765
  this.syncValuesAndStates();
14758
14766
  }
14767
+
14768
+ if (!this.availableOptions.includes(this.menu.optionActive)) {
14769
+ this.activateFirstEnabledAvailableOption();
14770
+ }
14759
14771
  }
14760
14772
 
14761
14773
  /**
@@ -14829,9 +14841,6 @@ class AuroCombobox extends AuroElement {
14829
14841
  if (this.dropdownOpen) {
14830
14842
  const expandedDelay = 150;
14831
14843
  this._expandedTimeout = setTimeout(() => {
14832
- if (!this.value) {
14833
- this.updateActiveOption(0);
14834
- }
14835
14844
  this.triggerExpandedState = true;
14836
14845
  }, expandedDelay);
14837
14846
  } else {
@@ -14841,16 +14850,6 @@ class AuroCombobox extends AuroElement {
14841
14850
  // Clear aria-activedescendant when dropdown closes
14842
14851
  if (!this.dropdownOpen && this.input) {
14843
14852
  this.input.setActiveDescendant(null);
14844
- this.optionActive = null;
14845
-
14846
- // Remove the highlighted state from all menu options so re-opening
14847
- // the dropdown doesn't show a stale highlight.
14848
- if (this.options) {
14849
- this.options.forEach((opt) => {
14850
- opt.active = false;
14851
- opt.classList.remove('active');
14852
- });
14853
- }
14854
14853
 
14855
14854
  // Restore pointer events on the menu in case they were disabled
14856
14855
  // during fullscreen open to prevent touch pass-through.
@@ -14891,13 +14890,6 @@ class AuroCombobox extends AuroElement {
14891
14890
  this.setInputFocus();
14892
14891
  this._inFullscreenTransition = false;
14893
14892
  });
14894
- } else {
14895
- // wait a frame in case the bib gets hidden immediately after showing because there is no value
14896
- setTimeout(() => {
14897
- if (this.componentHasFocus) {
14898
- this.setInputFocus();
14899
- }
14900
- }, 0);
14901
14893
  }
14902
14894
  }
14903
14895
  });
@@ -16279,7 +16271,7 @@ class AuroMenuOption extends AuroElement {
16279
16271
  });
16280
16272
 
16281
16273
  return u$7`
16282
- <div class="${classes}">
16274
+ <div class="${classes}" aria-disabled="${this.disabled ? 'true' : 'false'}">
16283
16275
  ${this.selected && !this.noCheckmark
16284
16276
  ? this.generateIconHtml(checkmarkIcon.svg)
16285
16277
  : undefined}
@@ -3,7 +3,7 @@
3
3
  <div class="mainContent">
4
4
  <div class="scrollWrapper">
5
5
  <auro-header level="2" id="tabBehavior">Tab Behavior</auro-header>
6
- <p>The component trigger contains an <code>&lt;auro-input&gt;</code> which has two focusable elements:</p>
6
+ <p>The component trigger contains an <code>&lt;auro-input&gt;</code> which has two elements:</p>
7
7
  <ol>
8
8
  <li><strong>Input</strong></li>
9
9
  <li><strong>Clear button:</strong> only shown when the input has a value.</li>
@@ -11,7 +11,7 @@
11
11
  <p>Each focusable element <em>(when shown)</em> participates in the browser window's default <code>tabindex</code> sequence.</p>
12
12
  <p>When the component is <code>disabled</code> it is removed from the <code>tabindex</code> sequence. VoiceOver's virtual cursor <em>(swipe navigation)</em> can still encounter the component, but standard keyboard <code>Tab</code> navigation skips it.</p>
13
13
  <p>On <strong>large viewport devices</strong> (e.g., desktop browser, tablet) there is no focusable content inside the component bib.</p>
14
- <p>On <strong>small viewport devices</strong> (e.g., phone) the bib opens a modal dialog with a focusable <strong>input</strong> and <strong>clear button</strong> which may be tabbed through naturally.</p>
14
+ <p>On <strong>small viewport devices</strong> (e.g., phone) the bib opens a modal dialog with a focusable <strong>input</strong> and <strong>clear button</strong> which can receive <strong>Click</strong> and <strong>Tap</strong> events.</p>
15
15
  <auro-header level="2" id="keyEvents">Key Events</auro-header>
16
16
  <!-- AURO-GENERATED-CONTENT:START (FILE:src=./../docs/partials/keyEvents.md) -->
17
17
  <!-- The below content is automatically added from ./../docs/partials/keyEvents.md -->
@@ -166,8 +166,8 @@
166
166
  </td>
167
167
  </tr>
168
168
  <tr>
169
- <td rowspan="6">Enter</td>
170
- <td rowspan="6">-</td>
169
+ <td rowspan="4">Enter</td>
170
+ <td rowspan="4">-</td>
171
171
  <td>Collapsed, list options have been populated</td>
172
172
  <td>
173
173
  Trigger input, <strong>NOT</strong> the input clear button
@@ -186,7 +186,7 @@
186
186
  </td>
187
187
  </tr>
188
188
  <tr>
189
- <td rowspan="2">Expanded, large viewport device</td>
189
+ <td>Expanded, large viewport device</td>
190
190
  <td>
191
191
  Trigger input element, <strong>NOT</strong> the trigger input clear button
192
192
  </td>
@@ -195,15 +195,7 @@
195
195
  </td>
196
196
  </tr>
197
197
  <tr>
198
- <td>
199
- Trigger input close button, <strong>NOT</strong> the trigger input
200
- </td>
201
- <td>
202
- The input value is cleared and <strong>focus</strong> is moved to the trigger input element.
203
- </td>
204
- </tr>
205
- <tr>
206
- <td rowspan="2">Expanded, small viewport device</td>
198
+ <td>Expanded, small viewport device</td>
207
199
  <td>
208
200
  Dialog input element, <strong>NOT</strong> the dialog input clear button
209
201
  </td>
@@ -211,14 +203,6 @@
211
203
  The current <code>focused</code> option is selected, closes the bib and <strong>focus</strong> is returned to the trigger input element.
212
204
  </td>
213
205
  </tr>
214
- <tr>
215
- <td>
216
- Dialog input clear button, <strong>NOT</strong> the dialog input element
217
- </td>
218
- <td>
219
- The <strong>input</strong> value is cleared, <strong>focus</strong> moves to the dialog input element.
220
- </td>
221
- </tr>
222
206
  <tr>
223
207
  <td>Escape</td>
224
208
  <td>-</td>
@@ -248,9 +232,9 @@
248
232
  </td>
249
233
  </tr>
250
234
  <tr>
251
- <td rowspan="3">Tab</td>
252
- <td rowspan="2">-</td>
253
- <td rowspan="2">Expanded</td>
235
+ <td rowspan="2">Tab</td>
236
+ <td>-</td>
237
+ <td>Expanded</td>
254
238
  <td>
255
239
  Input element, <strong>NOT</strong> the input clear button
256
240
  <div class="note">
@@ -261,17 +245,6 @@
261
245
  The current <code>focused</code> option is selected, the bib is closed and <strong>focus</strong> is moved to the <strong>clear button</strong> in the component trigger.
262
246
  </td>
263
247
  </tr>
264
- <tr>
265
- <td>
266
- Input clear button, <strong>NOT</strong> the input element
267
- <div class="note">
268
- <strong>Note:</strong> Includes both trigger and bib content input clear buttons.
269
- </div>
270
- </td>
271
- <td>
272
- <span style="background-color: pink; color: red;">&nbsp;What do we do here?&nbsp;&nbsp;</span>
273
- </td>
274
- </tr>
275
248
  <tr>
276
249
  <td>Shift</td>
277
250
  <td>Expanded</td>
@@ -42,6 +42,7 @@ export class AuroCombobox extends AuroElement {
42
42
  };
43
43
  /**
44
44
  * Array of available options to display in the dropdown.
45
+ * This array contains all non-hidden options (e.g., hidden by filtering on input value).
45
46
  * @private
46
47
  */
47
48
  availableOptions: {
@@ -381,6 +382,18 @@ export class AuroCombobox extends AuroElement {
381
382
  * @returns {boolean} - Returns true if the element is valid, false otherwise.
382
383
  */
383
384
  isValid(): boolean;
385
+ /**
386
+ * Mark the first available (non-hidden), enabled option as `active`.
387
+ * @private
388
+ * @returns {void}
389
+ */
390
+ private activateFirstEnabledAvailableOption;
391
+ /**
392
+ * Mark the last available (non-hidden), enabled option as `active`.
393
+ * @private
394
+ * @returns {void}
395
+ */
396
+ private activateLastEnabledAvailableOption;
384
397
  /**
385
398
  * Updates the filter for the available options based on the input value.
386
399
  * @private
@@ -1,6 +1,8 @@
1
1
  export namespace comboboxKeyboardStrategy {
2
- function Enter(component: any, evt: any, ctx: any): Promise<void>;
3
- function Tab(component: any, evt: any, ctx: any): void;
2
+ function Enter(component: any, evt: any, ctx: any): void;
3
+ function Tab(component: any, _evt: any, ctx: any): void;
4
+ function Home(component: any, evt: any, ctx: any): void;
5
+ function End(component: any, evt: any, ctx: any): void;
4
6
  function ArrowUp(component: any, evt: any, ctx: any): void;
5
7
  function ArrowDown(component: any, evt: any, ctx: any): void;
6
8
  }