@aurodesignsystem-dev/auro-formkit 0.0.0-pr1474.4 → 0.0.0-pr1475.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 (83) hide show
  1. package/components/bibtemplate/dist/auro-bibtemplate.d.ts +7 -0
  2. package/components/bibtemplate/dist/index.js +9 -1
  3. package/components/bibtemplate/dist/registered.js +9 -1
  4. package/components/checkbox/demo/customize.html +2 -1
  5. package/components/checkbox/demo/customize.min.js +1 -1
  6. package/components/checkbox/demo/getting-started.min.js +1 -1
  7. package/components/checkbox/demo/index.min.js +1 -1
  8. package/components/checkbox/dist/index.js +1 -1
  9. package/components/checkbox/dist/registered.js +1 -1
  10. package/components/combobox/demo/customize.html +2 -1
  11. package/components/combobox/demo/customize.md +130 -106
  12. package/components/combobox/demo/customize.min.js +209 -16
  13. package/components/combobox/demo/getting-started.min.js +209 -16
  14. package/components/combobox/demo/index.min.js +209 -16
  15. package/components/combobox/dist/index.js +209 -16
  16. package/components/combobox/dist/registered.js +209 -16
  17. package/components/counter/demo/customize.min.js +208 -15
  18. package/components/counter/demo/index.min.js +208 -15
  19. package/components/counter/demo/keyboard-behavior.md +1 -0
  20. package/components/counter/dist/index.js +10 -2
  21. package/components/counter/dist/registered.js +10 -2
  22. package/components/datepicker/demo/accessibility.md +51 -3
  23. package/components/datepicker/demo/api.md +9 -0
  24. package/components/datepicker/demo/customize.html +2 -0
  25. package/components/datepicker/demo/customize.js +19 -0
  26. package/components/datepicker/demo/customize.md +72 -8
  27. package/components/datepicker/demo/customize.min.js +25690 -0
  28. package/components/datepicker/demo/design.md +3 -1
  29. package/components/datepicker/demo/index.js +2 -1
  30. package/components/datepicker/demo/index.md +81 -1
  31. package/components/datepicker/demo/index.min.js +1223 -101
  32. package/components/datepicker/demo/keyboard-behavior.md +201 -2
  33. package/components/datepicker/demo/voiceover.md +19 -12
  34. package/components/datepicker/dist/index.js +1155 -104
  35. package/components/datepicker/dist/registered.js +1155 -104
  36. package/components/datepicker/dist/src/auro-calendar-cell.d.ts +59 -0
  37. package/components/datepicker/dist/src/auro-calendar-month.d.ts +28 -0
  38. package/components/datepicker/dist/src/auro-calendar.d.ts +84 -0
  39. package/components/datepicker/dist/src/auro-datepicker.d.ts +80 -0
  40. package/components/datepicker/dist/src/datepickerKeyboardStrategy.d.ts +5 -3
  41. package/components/dropdown/demo/accessibility.md +11 -0
  42. package/components/dropdown/demo/api.md +1 -0
  43. package/components/dropdown/demo/customize.md +3 -0
  44. package/components/dropdown/demo/customize.min.js +198 -13
  45. package/components/dropdown/demo/getting-started.min.js +198 -13
  46. package/components/dropdown/demo/index.min.js +198 -13
  47. package/components/dropdown/demo/keyboard-behavior.md +1 -0
  48. package/components/dropdown/dist/auro-dropdown.d.ts +30 -1
  49. package/components/dropdown/dist/index.js +198 -13
  50. package/components/dropdown/dist/registered.js +198 -13
  51. package/components/form/demo/customize.html +6 -6
  52. package/components/form/demo/customize.js +0 -17
  53. package/components/form/demo/customize.md +51 -125
  54. package/components/form/demo/customize.min.js +1776 -327
  55. package/components/form/demo/getting-started.min.js +1776 -291
  56. package/components/form/demo/index.min.js +1776 -291
  57. package/components/form/demo/registerDemoDeps.min.js +1769 -139
  58. package/components/form/dist/auro-form.d.ts +5 -45
  59. package/components/form/dist/index.js +7 -152
  60. package/components/form/dist/registered.js +7 -152
  61. package/components/input/demo/customize.html +2 -1
  62. package/components/input/demo/customize.min.js +1 -1
  63. package/components/input/demo/getting-started.min.js +1 -1
  64. package/components/input/demo/index.min.js +1 -1
  65. package/components/input/dist/index.js +1 -1
  66. package/components/input/dist/registered.js +1 -1
  67. package/components/radio/demo/customize.min.js +2186 -0
  68. package/components/radio/demo/demo-support.min.js +55807 -0
  69. package/components/radio/demo/getting-started.js +1 -1
  70. package/components/radio/demo/getting-started.md +1 -1
  71. package/components/radio/demo/getting-started.min.js +2205 -0
  72. package/components/radio/demo/index.min.js +1 -1
  73. package/components/radio/dist/index.js +1 -1
  74. package/components/radio/dist/registered.js +1 -1
  75. package/components/select/demo/customize.html +2 -2
  76. package/components/select/demo/customize.min.js +208 -15
  77. package/components/select/demo/getting-started.min.js +208 -15
  78. package/components/select/demo/index.min.js +208 -15
  79. package/components/select/demo/keyboard-behavior.md +1 -0
  80. package/components/select/dist/index.js +208 -15
  81. package/components/select/dist/registered.js +208 -15
  82. package/custom-elements.json +703 -91
  83. package/package.json +2 -2
@@ -4647,7 +4647,7 @@ function applyKeyboardStrategy(component, strategy, options = {}) {
4647
4647
  });
4648
4648
  }
4649
4649
 
4650
- var styleCss$2$1 = i$7`:host{position:fixed;z-index:var(--depth-tooltip, 400);display:none;isolation:isolate}:host dialog{width:auto;max-width:none;height:auto;max-height:none;padding:0;border:none;margin:0;outline:none;transform:translateZ(0)}:host dialog::backdrop{background:transparent}:host(:not([isfullscreen])) dialog{position:relative;inset:unset}:host(:not([isfullscreen])) .container.shape-box{border-radius:unset}:host(:not([isfullscreen])) .container[class*=shape-pill],:host(:not([isfullscreen])) .container[class*=shape-snowflake]{border-radius:30px}:host(:not([isfullscreen])) .container[class*=shape-rounded]{border-radius:16px}:host(:not([matchWidth])) .container{min-width:fit-content}:host([isfullscreen]){position:fixed;top:0;left:0}:host([isfullscreen]) .container{width:100dvw;max-width:none;height:100dvh;max-height:none;border-radius:unset;margin-top:0;box-shadow:unset;overscroll-behavior:contain}:host([isfullscreen]) .container::backdrop{background:var(--ds-color-background-primary, #fff)}:host(:popover-open){position:fixed;overflow:visible;padding:0;border:none;margin:0;background:transparent;inset:unset;outline:none}:host([data-show]){display:flex}:host([common]:not([isfullscreen])) .container,:host([rounded]:not([isfullscreen])) .container{border-radius:var(--ds-border-radius, 0.375rem)}:host([common][isfullscreen]) .container,:host([rounded][isfullscreen]) .container{border-radius:unset;box-shadow:unset}.container{display:inline-block;overflow:auto;box-sizing:border-box;border-radius:var(--ds-border-radius, 0.375rem);margin:var(--ds-size-50, 0.25rem) 0}.util_displayHiddenVisually{position:absolute;overflow:hidden;width:1px;height:1px;padding:0;border:0;margin:-1px;clip-path:inset(50%);white-space:nowrap}`;
4650
+ var styleCss$2$1 = i$7`:host{position:fixed;z-index:var(--depth-tooltip, 400);display:none;isolation:isolate}:host dialog{width:auto;max-width:none;height:auto;max-height:none;padding:0;border:none;margin:0;outline:none;transform:translateZ(0)}:host dialog::backdrop{background:transparent}:host(:not([isfullscreen])) dialog{position:relative;inset:unset}:host(:not([isfullscreen])) .container.shape-box{border-radius:unset}:host(:not([isfullscreen])) .container[class*=shape-pill],:host(:not([isfullscreen])) .container[class*=shape-snowflake]{border-radius:30px}:host(:not([isfullscreen])) .container[class*=shape-rounded]{border-radius:16px}:host([desktopmodal]:popover-open)::backdrop{background:transparent}:host(:not([matchWidth])) .container{min-width:fit-content}:host([isfullscreen]){position:fixed;top:0;left:0}:host([isfullscreen]) .container{width:100dvw;max-width:none;height:100dvh;max-height:none;border-radius:unset;margin-top:0;box-shadow:unset;overscroll-behavior:contain}:host([isfullscreen]) .container::backdrop{background:var(--ds-color-background-primary, #fff)}:host(:popover-open){position:fixed;overflow:visible;padding:0;border:none;margin:0;background:transparent;inset:unset;outline:none}:host([data-show]){display:flex}:host([common]:not([isfullscreen])) .container,:host([rounded]:not([isfullscreen])) .container{border-radius:var(--ds-border-radius, 0.375rem)}:host([common][isfullscreen]) .container,:host([rounded][isfullscreen]) .container{border-radius:unset;box-shadow:unset}.container{display:inline-block;overflow:auto;box-sizing:border-box;border-radius:var(--ds-border-radius, 0.375rem);margin:var(--ds-size-50, 0.25rem) 0}.util_displayHiddenVisually{position:absolute;overflow:hidden;width:1px;height:1px;padding:0;border:0;margin:-1px;clip-path:inset(50%);white-space:nowrap}`;
4651
4651
 
4652
4652
  var colorCss$2$1 = i$7`.container{background-color:var(--ds-auro-dropdownbib-container-color);box-shadow:var(--ds-auro-dropdownbib-boxshadow-color);color:var(--ds-auro-dropdownbib-text-color)}`;
4653
4653
 
@@ -5278,7 +5278,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$4 {
5278
5278
  }
5279
5279
  };
5280
5280
 
5281
- var formkitVersion$2 = '202605122157';
5281
+ var formkitVersion$2 = '202605182147';
5282
5282
 
5283
5283
  let AuroElement$2 = class AuroElement extends i$4 {
5284
5284
  static get properties() {
@@ -5458,6 +5458,7 @@ class AuroDropdown extends AuroElement$2 {
5458
5458
  _intializeDefaults() {
5459
5459
  this.appearance = 'default';
5460
5460
  this.chevron = false;
5461
+ this.desktopModal = false;
5461
5462
  this.disabled = false;
5462
5463
  this.disableKeyboardHandling = false;
5463
5464
  this.error = false;
@@ -5638,6 +5639,14 @@ class AuroDropdown extends AuroElement$2 {
5638
5639
  reflect: true
5639
5640
  },
5640
5641
 
5642
+ /**
5643
+ * If declared, the dropdown will behave as a modal dialog when in a desktop viewport size.
5644
+ */
5645
+ desktopModal: {
5646
+ type: Boolean,
5647
+ reflect: true
5648
+ },
5649
+
5641
5650
  /**
5642
5651
  * If declared, the dropdown will only show by calling the API .show() public method.
5643
5652
  */
@@ -5925,6 +5934,15 @@ class AuroDropdown extends AuroElement$2 {
5925
5934
 
5926
5935
  disconnectedCallback() {
5927
5936
  super.disconnectedCallback();
5937
+ this._clearPageInert();
5938
+ if (this._bibTabHandler) {
5939
+ this.removeEventListener('keydown', this._bibTabHandler);
5940
+ this._bibTabHandler = undefined;
5941
+ }
5942
+ if (this.focusTrap) {
5943
+ this.focusTrap.disconnect();
5944
+ this.focusTrap = undefined;
5945
+ }
5928
5946
  if (this.floater) {
5929
5947
  this.floater.hideBib('disconnect');
5930
5948
  this.floater.disconnect();
@@ -5952,19 +5970,34 @@ class AuroDropdown extends AuroElement$2 {
5952
5970
  if (this.isPopoverVisible) {
5953
5971
  // Fullscreen: use showModal() for native accessibility (inert outside, focus trap)
5954
5972
  // Desktop: use show() for Floating UI positioning + FocusTrap for focus management
5955
- const useModal = this.isBibFullscreen;
5956
- this.bibElement.value.open(useModal);
5973
+ this.bibElement.value.open(this.isBibFullscreen);
5974
+ this.updateFocusTrap();
5975
+
5976
+ // Desktop modal: make siblings inert so content outside is not interactive
5977
+ if (this.desktopModal && !this.isBibFullscreen) {
5978
+ this._setPageInert();
5979
+ }
5957
5980
  } else {
5958
5981
  this.bibElement.value.close();
5982
+ this._clearPageInert();
5959
5983
  }
5960
5984
  }
5961
5985
 
5962
5986
  // When fullscreen strategy changes while open, re-open dialog with correct mode
5963
5987
  // (e.g. resizing from desktop → mobile while dropdown is open)
5964
5988
  if (changedProperties.has('isBibFullscreen') && this.isPopoverVisible && this.bibElement.value) {
5965
- const useModal = this.isBibFullscreen;
5966
5989
  this.bibElement.value.close();
5967
- this.bibElement.value.open(useModal);
5990
+ this.bibElement.value.open(this.isBibFullscreen);
5991
+
5992
+ // Re-initialize focus management for the new strategy
5993
+ this.updateFocusTrap();
5994
+
5995
+ // Toggle inert: desktop modal needs it, fullscreen showModal() handles it natively
5996
+ if (this.desktopModal && !this.isBibFullscreen) {
5997
+ this._setPageInert();
5998
+ } else {
5999
+ this._clearPageInert();
6000
+ }
5968
6001
  }
5969
6002
  }
5970
6003
 
@@ -5974,8 +6007,14 @@ class AuroDropdown extends AuroElement$2 {
5974
6007
  * @param {CustomEvent} event - The custom event that contains the dropdown toggle information.
5975
6008
  */
5976
6009
  handleDropdownToggle(event) {
5977
- this.updateFocusTrap();
5978
6010
  this.isPopoverVisible = event.detail.expanded;
6011
+
6012
+ // Tear down FocusTrap when closing. Creation happens in updated()
6013
+ // after the dialog is open so getFocusableElements can find content.
6014
+ if (!this.isPopoverVisible) {
6015
+ this.updateFocusTrap();
6016
+ }
6017
+
5979
6018
  const eventType = event.detail.eventType || "unknown";
5980
6019
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
5981
6020
  this.trigger.focus();
@@ -6074,19 +6113,164 @@ class AuroDropdown extends AuroElement$2 {
6074
6113
  * @private
6075
6114
  */
6076
6115
  updateFocusTrap() {
6116
+ // Always clean up existing handlers/traps before setting up new ones
6117
+ // to prevent duplicate listeners on repeated calls.
6118
+ if (this._bibTabHandler) {
6119
+ this.removeEventListener('keydown', this._bibTabHandler);
6120
+ this._bibTabHandler = undefined;
6121
+ }
6122
+
6123
+ if (this.focusTrap) {
6124
+ this.focusTrap.disconnect();
6125
+ this.focusTrap = undefined;
6126
+ }
6127
+
6077
6128
  if (this.isPopoverVisible) {
6078
6129
  if (!this.isBibFullscreen) {
6079
- // Desktop: show() doesn't trap focus, so use FocusTrap
6080
- this.focusTrap = new FocusTrap(this.bibContent);
6081
- this.focusTrap.focusFirstElement();
6130
+ if (this.desktopModal) {
6131
+ // Desktop modal: trap focus only within the bib content.
6132
+ // Can't use FocusTrap on the bib element because keydown events
6133
+ // from slotted content bubble through the dropdown host (light DOM),
6134
+ // not through the bib (shadow projection target). Using FocusTrap
6135
+ // on the dropdown would include the trigger in the tab cycle.
6136
+ // Instead, listen for Tab on the dropdown and manually wrap focus
6137
+ // within the bib's focusable elements.
6138
+ this._bibTabHandler = (event) => {
6139
+ if (event.key !== 'Tab') {
6140
+ return;
6141
+ }
6142
+
6143
+ // Collect focusable elements from the bib content.
6144
+ const focusables = getFocusableElements(this.bibContent);
6145
+
6146
+ // Fallback: try from slotted content directly
6147
+ if (!focusables.length) {
6148
+ const slot = this.shadowRoot.querySelector('.slotContent slot');
6149
+ const assignedNodes = slot ? slot.assignedNodes({ flatten: true }) : [];
6150
+
6151
+ for (const node of assignedNodes) {
6152
+ if (node.nodeType === Node.ELEMENT_NODE) {
6153
+ focusables.push(...getFocusableElements(node));
6154
+ }
6155
+ }
6156
+ }
6157
+
6158
+ if (!focusables.length) {
6159
+ return;
6160
+ }
6161
+
6162
+ event.preventDefault();
6163
+
6164
+ const direction = event.shiftKey ? -1 : 1; // eslint-disable-line no-magic-numbers
6165
+
6166
+ // Walk the active element chain through shadow roots
6167
+ const actives = this._getActiveElements();
6168
+
6169
+ let idx = focusables.findIndex((el) => actives.includes(el));
6170
+
6171
+ if (idx === -1) { // eslint-disable-line no-magic-numbers
6172
+ // Focus is not on a known element — move to first/last
6173
+ idx = direction === 1 ? -1 : focusables.length; // eslint-disable-line no-magic-numbers
6174
+ }
6175
+
6176
+ // Try each element in order, skipping any that can't receive focus
6177
+ // (e.g. hidden elements, elements in collapsed sections)
6178
+ for (let index = 0; index < focusables.length; index++) { // eslint-disable-line no-plusplus
6179
+ let nextIdx = idx + direction;
6180
+
6181
+ // Wrap around
6182
+ if (nextIdx < 0) {
6183
+ nextIdx = focusables.length - 1;
6184
+ } else if (nextIdx >= focusables.length) {
6185
+ nextIdx = 0;
6186
+ }
6187
+
6188
+ focusables[nextIdx].focus();
6189
+
6190
+ // Verify focus actually moved to the target
6191
+ const newActives = this._getActiveElements();
6192
+
6193
+ if (newActives.includes(focusables[nextIdx])) {
6194
+ return;
6195
+ }
6196
+
6197
+ // Focus didn't stick — skip this element and try the next
6198
+ idx = nextIdx;
6199
+ }
6200
+ };
6201
+ this.addEventListener('keydown', this._bibTabHandler);
6202
+ } else {
6203
+ // Normal desktop: use FocusTrap on the bib element
6204
+ this.focusTrap = new FocusTrap(this.bibContent);
6205
+ this.focusTrap.focusFirstElement();
6206
+ }
6082
6207
  }
6083
6208
  // Fullscreen: showModal() provides native focus trapping
6209
+ }
6210
+ }
6211
+
6212
+ /**
6213
+ * Returns the chain of active (focused) elements through shadow roots.
6214
+ * @private
6215
+ * @returns {Array<HTMLElement>}
6216
+ */
6217
+ _getActiveElements() {
6218
+ let { activeElement } = document;
6219
+ const actives = [activeElement];
6220
+
6221
+ while (activeElement?.shadowRoot?.activeElement) {
6222
+ activeElement = activeElement.shadowRoot.activeElement;
6223
+ actives.push(activeElement);
6224
+ }
6225
+
6226
+ return actives;
6227
+ }
6228
+
6229
+ /**
6230
+ * Sets `inert` on sibling elements of the dropdown's top-level host
6231
+ * so that content outside the dropdown is not interactive while the modal is open.
6232
+ * Walks up through shadow DOM boundaries to find the outermost host element
6233
+ * in the light DOM, then sets `inert` on that element's siblings.
6234
+ * @private
6235
+ */
6236
+ _setPageInert() {
6237
+ if (this._inertSiblings) {
6084
6238
  return;
6085
6239
  }
6086
6240
 
6087
- if (this.focusTrap) {
6088
- this.focusTrap.disconnect();
6089
- this.focusTrap = undefined;
6241
+ this._inertSiblings = [];
6242
+
6243
+ // Walk up through shadow DOM boundaries to find the topmost host
6244
+ // element in the light DOM. For example, if this dropdown is inside
6245
+ // auro-datepicker's shadow DOM, we walk up to the datepicker element
6246
+ // so we set inert on its siblings — not on the datepicker itself.
6247
+ let host = this;
6248
+ while (host.getRootNode() instanceof ShadowRoot) {
6249
+ host = host.getRootNode().host;
6250
+ }
6251
+
6252
+ const parent = host.parentElement;
6253
+
6254
+ if (parent) {
6255
+ for (const sibling of parent.children) {
6256
+ if (sibling !== host && !sibling.inert) {
6257
+ sibling.inert = true;
6258
+ this._inertSiblings.push(sibling);
6259
+ }
6260
+ }
6261
+ }
6262
+ }
6263
+
6264
+ /**
6265
+ * Restores `inert` state on siblings that were made inert by `_setPageInert`.
6266
+ * @private
6267
+ */
6268
+ _clearPageInert() {
6269
+ if (this._inertSiblings) {
6270
+ for (const sibling of this._inertSiblings) {
6271
+ sibling.inert = false;
6272
+ }
6273
+ this._inertSiblings = undefined;
6090
6274
  }
6091
6275
  }
6092
6276
 
@@ -6325,6 +6509,7 @@ class AuroDropdown extends AuroElement$2 {
6325
6509
  shape="${this.shape}"
6326
6510
  ?data-show="${this.isPopoverVisible}"
6327
6511
  ?isfullscreen="${this.isBibFullscreen}"
6512
+ ?desktopmodal="${this.desktopModal}"
6328
6513
  .dialogLabel="${this.bibDialogLabel}"
6329
6514
  ${n$2(this.bibElement)}
6330
6515
  >
@@ -13030,7 +13215,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$4 {
13030
13215
  }
13031
13216
  };
13032
13217
 
13033
- var formkitVersion$1 = '202605122157';
13218
+ var formkitVersion$1 = '202605182147';
13034
13219
 
13035
13220
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
13036
13221
  // See LICENSE in the project root for license information.
@@ -13984,6 +14169,14 @@ class AuroBibtemplate extends i$4 {
13984
14169
  large: {
13985
14170
  type: Boolean,
13986
14171
  reflect: true
14172
+ },
14173
+
14174
+ /**
14175
+ * If declared, the footer slot will be rendered even when not in fullscreen mode.
14176
+ */
14177
+ showFooter: {
14178
+ type: Boolean,
14179
+ reflect: true
13987
14180
  }
13988
14181
  };
13989
14182
  }
@@ -14086,7 +14279,7 @@ class AuroBibtemplate extends i$4 {
14086
14279
  <slot></slot>
14087
14280
  </div>
14088
14281
 
14089
- ${this.isFullscreen ? u$7`
14282
+ ${this.isFullscreen || this.showFooter ? u$7`
14090
14283
  <div id="footerContainer">
14091
14284
  <slot name="footer"></slot>
14092
14285
  </div>` : null}
@@ -14095,7 +14288,7 @@ class AuroBibtemplate extends i$4 {
14095
14288
  }
14096
14289
  }
14097
14290
 
14098
- var formkitVersion = '202605122157';
14291
+ var formkitVersion = '202605182147';
14099
14292
 
14100
14293
  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}`;
14101
14294
 
@@ -4647,7 +4647,7 @@ function applyKeyboardStrategy(component, strategy, options = {}) {
4647
4647
  });
4648
4648
  }
4649
4649
 
4650
- var styleCss$2$1 = i$7`:host{position:fixed;z-index:var(--depth-tooltip, 400);display:none;isolation:isolate}:host dialog{width:auto;max-width:none;height:auto;max-height:none;padding:0;border:none;margin:0;outline:none;transform:translateZ(0)}:host dialog::backdrop{background:transparent}:host(:not([isfullscreen])) dialog{position:relative;inset:unset}:host(:not([isfullscreen])) .container.shape-box{border-radius:unset}:host(:not([isfullscreen])) .container[class*=shape-pill],:host(:not([isfullscreen])) .container[class*=shape-snowflake]{border-radius:30px}:host(:not([isfullscreen])) .container[class*=shape-rounded]{border-radius:16px}:host(:not([matchWidth])) .container{min-width:fit-content}:host([isfullscreen]){position:fixed;top:0;left:0}:host([isfullscreen]) .container{width:100dvw;max-width:none;height:100dvh;max-height:none;border-radius:unset;margin-top:0;box-shadow:unset;overscroll-behavior:contain}:host([isfullscreen]) .container::backdrop{background:var(--ds-color-background-primary, #fff)}:host(:popover-open){position:fixed;overflow:visible;padding:0;border:none;margin:0;background:transparent;inset:unset;outline:none}:host([data-show]){display:flex}:host([common]:not([isfullscreen])) .container,:host([rounded]:not([isfullscreen])) .container{border-radius:var(--ds-border-radius, 0.375rem)}:host([common][isfullscreen]) .container,:host([rounded][isfullscreen]) .container{border-radius:unset;box-shadow:unset}.container{display:inline-block;overflow:auto;box-sizing:border-box;border-radius:var(--ds-border-radius, 0.375rem);margin:var(--ds-size-50, 0.25rem) 0}.util_displayHiddenVisually{position:absolute;overflow:hidden;width:1px;height:1px;padding:0;border:0;margin:-1px;clip-path:inset(50%);white-space:nowrap}`;
4650
+ var styleCss$2$1 = i$7`:host{position:fixed;z-index:var(--depth-tooltip, 400);display:none;isolation:isolate}:host dialog{width:auto;max-width:none;height:auto;max-height:none;padding:0;border:none;margin:0;outline:none;transform:translateZ(0)}:host dialog::backdrop{background:transparent}:host(:not([isfullscreen])) dialog{position:relative;inset:unset}:host(:not([isfullscreen])) .container.shape-box{border-radius:unset}:host(:not([isfullscreen])) .container[class*=shape-pill],:host(:not([isfullscreen])) .container[class*=shape-snowflake]{border-radius:30px}:host(:not([isfullscreen])) .container[class*=shape-rounded]{border-radius:16px}:host([desktopmodal]:popover-open)::backdrop{background:transparent}:host(:not([matchWidth])) .container{min-width:fit-content}:host([isfullscreen]){position:fixed;top:0;left:0}:host([isfullscreen]) .container{width:100dvw;max-width:none;height:100dvh;max-height:none;border-radius:unset;margin-top:0;box-shadow:unset;overscroll-behavior:contain}:host([isfullscreen]) .container::backdrop{background:var(--ds-color-background-primary, #fff)}:host(:popover-open){position:fixed;overflow:visible;padding:0;border:none;margin:0;background:transparent;inset:unset;outline:none}:host([data-show]){display:flex}:host([common]:not([isfullscreen])) .container,:host([rounded]:not([isfullscreen])) .container{border-radius:var(--ds-border-radius, 0.375rem)}:host([common][isfullscreen]) .container,:host([rounded][isfullscreen]) .container{border-radius:unset;box-shadow:unset}.container{display:inline-block;overflow:auto;box-sizing:border-box;border-radius:var(--ds-border-radius, 0.375rem);margin:var(--ds-size-50, 0.25rem) 0}.util_displayHiddenVisually{position:absolute;overflow:hidden;width:1px;height:1px;padding:0;border:0;margin:-1px;clip-path:inset(50%);white-space:nowrap}`;
4651
4651
 
4652
4652
  var colorCss$2$1 = i$7`.container{background-color:var(--ds-auro-dropdownbib-container-color);box-shadow:var(--ds-auro-dropdownbib-boxshadow-color);color:var(--ds-auro-dropdownbib-text-color)}`;
4653
4653
 
@@ -5278,7 +5278,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$4 {
5278
5278
  }
5279
5279
  };
5280
5280
 
5281
- var formkitVersion$2 = '202605122157';
5281
+ var formkitVersion$2 = '202605182147';
5282
5282
 
5283
5283
  let AuroElement$2 = class AuroElement extends i$4 {
5284
5284
  static get properties() {
@@ -5458,6 +5458,7 @@ class AuroDropdown extends AuroElement$2 {
5458
5458
  _intializeDefaults() {
5459
5459
  this.appearance = 'default';
5460
5460
  this.chevron = false;
5461
+ this.desktopModal = false;
5461
5462
  this.disabled = false;
5462
5463
  this.disableKeyboardHandling = false;
5463
5464
  this.error = false;
@@ -5638,6 +5639,14 @@ class AuroDropdown extends AuroElement$2 {
5638
5639
  reflect: true
5639
5640
  },
5640
5641
 
5642
+ /**
5643
+ * If declared, the dropdown will behave as a modal dialog when in a desktop viewport size.
5644
+ */
5645
+ desktopModal: {
5646
+ type: Boolean,
5647
+ reflect: true
5648
+ },
5649
+
5641
5650
  /**
5642
5651
  * If declared, the dropdown will only show by calling the API .show() public method.
5643
5652
  */
@@ -5925,6 +5934,15 @@ class AuroDropdown extends AuroElement$2 {
5925
5934
 
5926
5935
  disconnectedCallback() {
5927
5936
  super.disconnectedCallback();
5937
+ this._clearPageInert();
5938
+ if (this._bibTabHandler) {
5939
+ this.removeEventListener('keydown', this._bibTabHandler);
5940
+ this._bibTabHandler = undefined;
5941
+ }
5942
+ if (this.focusTrap) {
5943
+ this.focusTrap.disconnect();
5944
+ this.focusTrap = undefined;
5945
+ }
5928
5946
  if (this.floater) {
5929
5947
  this.floater.hideBib('disconnect');
5930
5948
  this.floater.disconnect();
@@ -5952,19 +5970,34 @@ class AuroDropdown extends AuroElement$2 {
5952
5970
  if (this.isPopoverVisible) {
5953
5971
  // Fullscreen: use showModal() for native accessibility (inert outside, focus trap)
5954
5972
  // Desktop: use show() for Floating UI positioning + FocusTrap for focus management
5955
- const useModal = this.isBibFullscreen;
5956
- this.bibElement.value.open(useModal);
5973
+ this.bibElement.value.open(this.isBibFullscreen);
5974
+ this.updateFocusTrap();
5975
+
5976
+ // Desktop modal: make siblings inert so content outside is not interactive
5977
+ if (this.desktopModal && !this.isBibFullscreen) {
5978
+ this._setPageInert();
5979
+ }
5957
5980
  } else {
5958
5981
  this.bibElement.value.close();
5982
+ this._clearPageInert();
5959
5983
  }
5960
5984
  }
5961
5985
 
5962
5986
  // When fullscreen strategy changes while open, re-open dialog with correct mode
5963
5987
  // (e.g. resizing from desktop → mobile while dropdown is open)
5964
5988
  if (changedProperties.has('isBibFullscreen') && this.isPopoverVisible && this.bibElement.value) {
5965
- const useModal = this.isBibFullscreen;
5966
5989
  this.bibElement.value.close();
5967
- this.bibElement.value.open(useModal);
5990
+ this.bibElement.value.open(this.isBibFullscreen);
5991
+
5992
+ // Re-initialize focus management for the new strategy
5993
+ this.updateFocusTrap();
5994
+
5995
+ // Toggle inert: desktop modal needs it, fullscreen showModal() handles it natively
5996
+ if (this.desktopModal && !this.isBibFullscreen) {
5997
+ this._setPageInert();
5998
+ } else {
5999
+ this._clearPageInert();
6000
+ }
5968
6001
  }
5969
6002
  }
5970
6003
 
@@ -5974,8 +6007,14 @@ class AuroDropdown extends AuroElement$2 {
5974
6007
  * @param {CustomEvent} event - The custom event that contains the dropdown toggle information.
5975
6008
  */
5976
6009
  handleDropdownToggle(event) {
5977
- this.updateFocusTrap();
5978
6010
  this.isPopoverVisible = event.detail.expanded;
6011
+
6012
+ // Tear down FocusTrap when closing. Creation happens in updated()
6013
+ // after the dialog is open so getFocusableElements can find content.
6014
+ if (!this.isPopoverVisible) {
6015
+ this.updateFocusTrap();
6016
+ }
6017
+
5979
6018
  const eventType = event.detail.eventType || "unknown";
5980
6019
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
5981
6020
  this.trigger.focus();
@@ -6074,19 +6113,164 @@ class AuroDropdown extends AuroElement$2 {
6074
6113
  * @private
6075
6114
  */
6076
6115
  updateFocusTrap() {
6116
+ // Always clean up existing handlers/traps before setting up new ones
6117
+ // to prevent duplicate listeners on repeated calls.
6118
+ if (this._bibTabHandler) {
6119
+ this.removeEventListener('keydown', this._bibTabHandler);
6120
+ this._bibTabHandler = undefined;
6121
+ }
6122
+
6123
+ if (this.focusTrap) {
6124
+ this.focusTrap.disconnect();
6125
+ this.focusTrap = undefined;
6126
+ }
6127
+
6077
6128
  if (this.isPopoverVisible) {
6078
6129
  if (!this.isBibFullscreen) {
6079
- // Desktop: show() doesn't trap focus, so use FocusTrap
6080
- this.focusTrap = new FocusTrap(this.bibContent);
6081
- this.focusTrap.focusFirstElement();
6130
+ if (this.desktopModal) {
6131
+ // Desktop modal: trap focus only within the bib content.
6132
+ // Can't use FocusTrap on the bib element because keydown events
6133
+ // from slotted content bubble through the dropdown host (light DOM),
6134
+ // not through the bib (shadow projection target). Using FocusTrap
6135
+ // on the dropdown would include the trigger in the tab cycle.
6136
+ // Instead, listen for Tab on the dropdown and manually wrap focus
6137
+ // within the bib's focusable elements.
6138
+ this._bibTabHandler = (event) => {
6139
+ if (event.key !== 'Tab') {
6140
+ return;
6141
+ }
6142
+
6143
+ // Collect focusable elements from the bib content.
6144
+ const focusables = getFocusableElements(this.bibContent);
6145
+
6146
+ // Fallback: try from slotted content directly
6147
+ if (!focusables.length) {
6148
+ const slot = this.shadowRoot.querySelector('.slotContent slot');
6149
+ const assignedNodes = slot ? slot.assignedNodes({ flatten: true }) : [];
6150
+
6151
+ for (const node of assignedNodes) {
6152
+ if (node.nodeType === Node.ELEMENT_NODE) {
6153
+ focusables.push(...getFocusableElements(node));
6154
+ }
6155
+ }
6156
+ }
6157
+
6158
+ if (!focusables.length) {
6159
+ return;
6160
+ }
6161
+
6162
+ event.preventDefault();
6163
+
6164
+ const direction = event.shiftKey ? -1 : 1; // eslint-disable-line no-magic-numbers
6165
+
6166
+ // Walk the active element chain through shadow roots
6167
+ const actives = this._getActiveElements();
6168
+
6169
+ let idx = focusables.findIndex((el) => actives.includes(el));
6170
+
6171
+ if (idx === -1) { // eslint-disable-line no-magic-numbers
6172
+ // Focus is not on a known element — move to first/last
6173
+ idx = direction === 1 ? -1 : focusables.length; // eslint-disable-line no-magic-numbers
6174
+ }
6175
+
6176
+ // Try each element in order, skipping any that can't receive focus
6177
+ // (e.g. hidden elements, elements in collapsed sections)
6178
+ for (let index = 0; index < focusables.length; index++) { // eslint-disable-line no-plusplus
6179
+ let nextIdx = idx + direction;
6180
+
6181
+ // Wrap around
6182
+ if (nextIdx < 0) {
6183
+ nextIdx = focusables.length - 1;
6184
+ } else if (nextIdx >= focusables.length) {
6185
+ nextIdx = 0;
6186
+ }
6187
+
6188
+ focusables[nextIdx].focus();
6189
+
6190
+ // Verify focus actually moved to the target
6191
+ const newActives = this._getActiveElements();
6192
+
6193
+ if (newActives.includes(focusables[nextIdx])) {
6194
+ return;
6195
+ }
6196
+
6197
+ // Focus didn't stick — skip this element and try the next
6198
+ idx = nextIdx;
6199
+ }
6200
+ };
6201
+ this.addEventListener('keydown', this._bibTabHandler);
6202
+ } else {
6203
+ // Normal desktop: use FocusTrap on the bib element
6204
+ this.focusTrap = new FocusTrap(this.bibContent);
6205
+ this.focusTrap.focusFirstElement();
6206
+ }
6082
6207
  }
6083
6208
  // Fullscreen: showModal() provides native focus trapping
6209
+ }
6210
+ }
6211
+
6212
+ /**
6213
+ * Returns the chain of active (focused) elements through shadow roots.
6214
+ * @private
6215
+ * @returns {Array<HTMLElement>}
6216
+ */
6217
+ _getActiveElements() {
6218
+ let { activeElement } = document;
6219
+ const actives = [activeElement];
6220
+
6221
+ while (activeElement?.shadowRoot?.activeElement) {
6222
+ activeElement = activeElement.shadowRoot.activeElement;
6223
+ actives.push(activeElement);
6224
+ }
6225
+
6226
+ return actives;
6227
+ }
6228
+
6229
+ /**
6230
+ * Sets `inert` on sibling elements of the dropdown's top-level host
6231
+ * so that content outside the dropdown is not interactive while the modal is open.
6232
+ * Walks up through shadow DOM boundaries to find the outermost host element
6233
+ * in the light DOM, then sets `inert` on that element's siblings.
6234
+ * @private
6235
+ */
6236
+ _setPageInert() {
6237
+ if (this._inertSiblings) {
6084
6238
  return;
6085
6239
  }
6086
6240
 
6087
- if (this.focusTrap) {
6088
- this.focusTrap.disconnect();
6089
- this.focusTrap = undefined;
6241
+ this._inertSiblings = [];
6242
+
6243
+ // Walk up through shadow DOM boundaries to find the topmost host
6244
+ // element in the light DOM. For example, if this dropdown is inside
6245
+ // auro-datepicker's shadow DOM, we walk up to the datepicker element
6246
+ // so we set inert on its siblings — not on the datepicker itself.
6247
+ let host = this;
6248
+ while (host.getRootNode() instanceof ShadowRoot) {
6249
+ host = host.getRootNode().host;
6250
+ }
6251
+
6252
+ const parent = host.parentElement;
6253
+
6254
+ if (parent) {
6255
+ for (const sibling of parent.children) {
6256
+ if (sibling !== host && !sibling.inert) {
6257
+ sibling.inert = true;
6258
+ this._inertSiblings.push(sibling);
6259
+ }
6260
+ }
6261
+ }
6262
+ }
6263
+
6264
+ /**
6265
+ * Restores `inert` state on siblings that were made inert by `_setPageInert`.
6266
+ * @private
6267
+ */
6268
+ _clearPageInert() {
6269
+ if (this._inertSiblings) {
6270
+ for (const sibling of this._inertSiblings) {
6271
+ sibling.inert = false;
6272
+ }
6273
+ this._inertSiblings = undefined;
6090
6274
  }
6091
6275
  }
6092
6276
 
@@ -6325,6 +6509,7 @@ class AuroDropdown extends AuroElement$2 {
6325
6509
  shape="${this.shape}"
6326
6510
  ?data-show="${this.isPopoverVisible}"
6327
6511
  ?isfullscreen="${this.isBibFullscreen}"
6512
+ ?desktopmodal="${this.desktopModal}"
6328
6513
  .dialogLabel="${this.bibDialogLabel}"
6329
6514
  ${n$2(this.bibElement)}
6330
6515
  >
@@ -13030,7 +13215,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$4 {
13030
13215
  }
13031
13216
  };
13032
13217
 
13033
- var formkitVersion$1 = '202605122157';
13218
+ var formkitVersion$1 = '202605182147';
13034
13219
 
13035
13220
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
13036
13221
  // See LICENSE in the project root for license information.
@@ -13984,6 +14169,14 @@ class AuroBibtemplate extends i$4 {
13984
14169
  large: {
13985
14170
  type: Boolean,
13986
14171
  reflect: true
14172
+ },
14173
+
14174
+ /**
14175
+ * If declared, the footer slot will be rendered even when not in fullscreen mode.
14176
+ */
14177
+ showFooter: {
14178
+ type: Boolean,
14179
+ reflect: true
13987
14180
  }
13988
14181
  };
13989
14182
  }
@@ -14086,7 +14279,7 @@ class AuroBibtemplate extends i$4 {
14086
14279
  <slot></slot>
14087
14280
  </div>
14088
14281
 
14089
- ${this.isFullscreen ? u$7`
14282
+ ${this.isFullscreen || this.showFooter ? u$7`
14090
14283
  <div id="footerContainer">
14091
14284
  <slot name="footer"></slot>
14092
14285
  </div>` : null}
@@ -14095,7 +14288,7 @@ class AuroBibtemplate extends i$4 {
14095
14288
  }
14096
14289
  }
14097
14290
 
14098
- var formkitVersion = '202605122157';
14291
+ var formkitVersion = '202605182147';
14099
14292
 
14100
14293
  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}`;
14101
14294