@aurodesignsystem-dev/auro-formkit 0.0.0-pr1346.3 → 0.0.0-pr1346.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/checkbox/demo/api.min.js +1 -1
- package/components/checkbox/demo/index.min.js +1 -1
- package/components/checkbox/dist/index.js +1 -1
- package/components/checkbox/dist/registered.js +1 -1
- package/components/combobox/demo/api.min.js +224 -45
- package/components/combobox/demo/index.min.js +224 -45
- package/components/combobox/dist/auro-combobox.d.ts +2 -1
- package/components/combobox/dist/index.js +217 -42
- package/components/combobox/dist/registered.js +217 -42
- package/components/counter/demo/api.min.js +123 -11
- package/components/counter/demo/index.min.js +123 -11
- package/components/counter/dist/index.js +123 -11
- package/components/counter/dist/registered.js +123 -11
- package/components/datepicker/demo/api.min.js +133 -20
- package/components/datepicker/demo/index.min.js +133 -20
- package/components/datepicker/dist/index.js +133 -20
- package/components/datepicker/dist/registered.js +133 -20
- package/components/dropdown/demo/api.min.js +122 -10
- package/components/dropdown/demo/index.min.js +122 -10
- package/components/dropdown/dist/auro-dropdownBib.d.ts +18 -2
- package/components/dropdown/dist/index.js +122 -10
- package/components/dropdown/dist/registered.js +122 -10
- package/components/input/demo/api.min.js +10 -9
- package/components/input/demo/index.min.js +10 -9
- package/components/input/dist/index.js +10 -9
- package/components/input/dist/registered.js +10 -9
- package/components/menu/demo/api.min.js +7 -3
- package/components/menu/demo/index.min.js +7 -3
- package/components/menu/dist/index.js +7 -3
- package/components/menu/dist/registered.js +7 -3
- package/components/radio/demo/api.min.js +1 -1
- package/components/radio/demo/index.min.js +1 -1
- package/components/radio/dist/index.js +1 -1
- package/components/radio/dist/registered.js +1 -1
- package/components/select/demo/api.min.js +159 -17
- package/components/select/demo/index.min.js +159 -17
- package/components/select/dist/index.js +152 -14
- package/components/select/dist/registered.js +152 -14
- package/custom-elements.json +35 -10
- package/package.json +1 -1
|
@@ -1687,7 +1687,7 @@ class AuroHelpText extends i$2 {
|
|
|
1687
1687
|
}
|
|
1688
1688
|
}
|
|
1689
1689
|
|
|
1690
|
-
var formkitVersion = '
|
|
1690
|
+
var formkitVersion = '202602260152';
|
|
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 = '
|
|
1682
|
+
var formkitVersion = '202602260152';
|
|
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 = '
|
|
1635
|
+
var formkitVersion = '202602260152';
|
|
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 = '
|
|
1635
|
+
var formkitVersion = '202602260152';
|
|
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.
|
|
@@ -3950,7 +3950,7 @@ let p$4 = class p{registerComponent(t,a){customElements.get(t)||customElements.d
|
|
|
3950
3950
|
|
|
3951
3951
|
var iconVersion$3 = '9.1.2';
|
|
3952
3952
|
|
|
3953
|
-
var styleCss$2$1 = i$7`:host{position:fixed;z-index:var(--depth-tooltip, 400);display:none;isolation:isolate}:host dialog{max-width:none;max-height:none;padding:0;border:none;margin:0;outline:none;transform:translateZ(0)}:host dialog::backdrop{background:transparent}:host(:not([isfullscreen])) dialog{position:absolute;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([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}`;
|
|
3953
|
+
var styleCss$2$1 = i$7`:host{position:fixed;z-index:var(--depth-tooltip, 400);display:none;isolation:isolate}:host dialog{max-width:none;max-height:none;padding:0;border:none;margin:0;outline:none;transform:translateZ(0)}:host dialog::backdrop{background:transparent}:host(:not([isfullscreen])) dialog{position:absolute;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([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}`;
|
|
3954
3954
|
|
|
3955
3955
|
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)}`;
|
|
3956
3956
|
|
|
@@ -3958,6 +3958,8 @@ var tokensCss$1$2 = i$7`:host(:not([ondark])),:host(:not([appearance=inverse])){
|
|
|
3958
3958
|
|
|
3959
3959
|
// Copyright (c) 2020 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
3960
3960
|
// See LICENSE in the project root for license information.
|
|
3961
|
+
/* eslint-disable max-lines */
|
|
3962
|
+
// ---------------------------------------------------------------------
|
|
3961
3963
|
|
|
3962
3964
|
|
|
3963
3965
|
const DESIGN_TOKEN_BREAKPOINT_PREFIX = '--ds-grid-breakpoint-';
|
|
@@ -4133,22 +4135,63 @@ class AuroDropdownBib extends i$4 {
|
|
|
4133
4135
|
// Handle ESC key via dialog's cancel event
|
|
4134
4136
|
const dialog = this.shadowRoot.querySelector('dialog');
|
|
4135
4137
|
dialog.addEventListener('cancel', (event) => {
|
|
4136
|
-
|
|
4138
|
+
// Let parent handle closing
|
|
4139
|
+
event.preventDefault();
|
|
4137
4140
|
this.dispatchEvent(new CustomEvent('auro-bib-cancel', {
|
|
4138
4141
|
bubbles: true,
|
|
4139
4142
|
composed: true
|
|
4140
4143
|
}));
|
|
4141
4144
|
});
|
|
4142
4145
|
|
|
4143
|
-
//
|
|
4144
|
-
//
|
|
4145
|
-
//
|
|
4146
|
-
//
|
|
4147
|
-
|
|
4146
|
+
// showModal() creates a closed focus scope — keyboard events inside
|
|
4147
|
+
// the dialog's shadow DOM do NOT bubble out to the combobox/select
|
|
4148
|
+
// keydown handlers in the parent shadow DOM. This handler bridges
|
|
4149
|
+
// that gap by re-dispatching navigation keys so they cross the
|
|
4150
|
+
// shadow boundary and reach the menu navigation logic in the parent
|
|
4151
|
+
// component.
|
|
4152
|
+
//
|
|
4153
|
+
// The trade-off: intercepting these keys means native keyboard
|
|
4154
|
+
// behaviors that would normally "just work" must be manually
|
|
4155
|
+
// re-implemented here:
|
|
4156
|
+
//
|
|
4157
|
+
// - Enter on buttons: Custom elements (auro-button) don't get the
|
|
4158
|
+
// native Enter→click that <button> provides, so we call .click()
|
|
4159
|
+
// directly when Enter is pressed on a button-like element.
|
|
4160
|
+
//
|
|
4161
|
+
// - Tab: NOT intercepted — left to the browser's native focus trap
|
|
4162
|
+
// provided by showModal(), which cycles Tab between focusable
|
|
4163
|
+
// elements inside the dialog (e.g. the input and close button).
|
|
4164
|
+
// Intercepting Tab would kill the native focus trap and break
|
|
4165
|
+
// focus management inside the dialog.
|
|
4166
|
+
//
|
|
4167
|
+
// - Escape: The native <dialog> fires a `cancel` event on ESC
|
|
4168
|
+
// (handled above), so the re-dispatched Escape is a secondary
|
|
4169
|
+
// path for parent components that also listen for Escape keydown.
|
|
4170
|
+
const navKeys = new Set([
|
|
4171
|
+
'ArrowUp',
|
|
4172
|
+
'ArrowDown',
|
|
4173
|
+
'Enter',
|
|
4174
|
+
'Escape'
|
|
4175
|
+
]);
|
|
4148
4176
|
dialog.addEventListener('keydown', (event) => {
|
|
4149
4177
|
if (!navKeys.has(event.key)) {
|
|
4150
4178
|
return;
|
|
4151
4179
|
}
|
|
4180
|
+
|
|
4181
|
+
// Custom elements (auro-button) don't get the native Enter→click
|
|
4182
|
+
// behavior that <button> has. Find the button in the composed path
|
|
4183
|
+
// and click it directly.
|
|
4184
|
+
if (event.key === 'Enter') {
|
|
4185
|
+
const buttonSelector = 'button, [role="button"], auro-button, [auro-button]';
|
|
4186
|
+
const btn = event.composedPath().find((el) => el.matches && el.matches(buttonSelector));
|
|
4187
|
+
if (btn) {
|
|
4188
|
+
event.preventDefault();
|
|
4189
|
+
event.stopPropagation();
|
|
4190
|
+
btn.click();
|
|
4191
|
+
return;
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
|
|
4152
4195
|
event.preventDefault();
|
|
4153
4196
|
event.stopPropagation();
|
|
4154
4197
|
const newEvent = new KeyboardEvent('keydown', {
|
|
@@ -4172,9 +4215,55 @@ class AuroDropdownBib extends i$4 {
|
|
|
4172
4215
|
}
|
|
4173
4216
|
|
|
4174
4217
|
/**
|
|
4175
|
-
*
|
|
4176
|
-
*
|
|
4218
|
+
* Blocks touch-driven page scroll while a fullscreen modal dialog is open.
|
|
4219
|
+
*
|
|
4220
|
+
* The showModal() function places the dialog in the browser's **top layer**,
|
|
4221
|
+
* which is a separate rendering layer above the normal DOM. On mobile, the
|
|
4222
|
+
* compositor processes visual-viewport panning before top-layer touch
|
|
4223
|
+
* handling. This means the entire viewport — including the top-layer dialog
|
|
4224
|
+
* — can be panned by a touch gesture, causing the page behind the dialog to
|
|
4225
|
+
* scroll into view. To prevent this, we add a touchmove listener that cancels
|
|
4226
|
+
* the event if the touch started outside the dialog or any scrollable child within it.
|
|
4227
|
+
*
|
|
4228
|
+
* @private
|
|
4229
|
+
*/
|
|
4230
|
+
_lockTouchScroll() {
|
|
4231
|
+
const dialog = this.shadowRoot.querySelector('dialog');
|
|
4232
|
+
|
|
4233
|
+
this._touchMoveHandler = (event) => {
|
|
4234
|
+
// Walk the composed path (which crosses shadow DOM boundaries) to
|
|
4235
|
+
// check whether the touch started inside a scrollable element that
|
|
4236
|
+
// lives within the dialog. If so, allow the scroll.
|
|
4237
|
+
for (const el of event.composedPath()) {
|
|
4238
|
+
if (el === dialog) {
|
|
4239
|
+
// Reached the dialog boundary without finding a scrollable child.
|
|
4240
|
+
break;
|
|
4241
|
+
}
|
|
4242
|
+
if (el instanceof HTMLElement && el.scrollHeight > el.clientHeight) {
|
|
4243
|
+
const { overflowY } = getComputedStyle(el);
|
|
4244
|
+
if (overflowY === 'auto' || overflowY === 'scroll') {
|
|
4245
|
+
return;
|
|
4246
|
+
}
|
|
4247
|
+
}
|
|
4248
|
+
}
|
|
4249
|
+
|
|
4250
|
+
event.preventDefault();
|
|
4251
|
+
};
|
|
4252
|
+
|
|
4253
|
+
document.addEventListener('touchmove', this._touchMoveHandler, { passive: false });
|
|
4254
|
+
}
|
|
4255
|
+
|
|
4256
|
+
/**
|
|
4257
|
+
* Removes the touchmove listener added by _lockTouchScroll().
|
|
4258
|
+
* @private
|
|
4177
4259
|
*/
|
|
4260
|
+
_unlockTouchScroll() {
|
|
4261
|
+
if (this._touchMoveHandler) {
|
|
4262
|
+
document.removeEventListener('touchmove', this._touchMoveHandler);
|
|
4263
|
+
this._touchMoveHandler = undefined;
|
|
4264
|
+
}
|
|
4265
|
+
}
|
|
4266
|
+
|
|
4178
4267
|
open(modal = true) {
|
|
4179
4268
|
const dialog = this.shadowRoot.querySelector('dialog');
|
|
4180
4269
|
if (dialog && !dialog.open) {
|
|
@@ -4191,6 +4280,8 @@ class AuroDropdownBib extends i$4 {
|
|
|
4191
4280
|
|
|
4192
4281
|
documentElement.style.overflow = prevOverflow;
|
|
4193
4282
|
|
|
4283
|
+
this._lockTouchScroll();
|
|
4284
|
+
|
|
4194
4285
|
} else {
|
|
4195
4286
|
// Use setAttribute instead of dialog.show() to avoid the dialog
|
|
4196
4287
|
// focusing steps which steal focus from the trigger and cause
|
|
@@ -4206,6 +4297,7 @@ class AuroDropdownBib extends i$4 {
|
|
|
4206
4297
|
close() {
|
|
4207
4298
|
const dialog = this.shadowRoot.querySelector('dialog');
|
|
4208
4299
|
if (dialog && dialog.open) {
|
|
4300
|
+
this._unlockTouchScroll();
|
|
4209
4301
|
dialog.close();
|
|
4210
4302
|
}
|
|
4211
4303
|
}
|
|
@@ -4471,7 +4563,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$4 {
|
|
|
4471
4563
|
}
|
|
4472
4564
|
};
|
|
4473
4565
|
|
|
4474
|
-
var formkitVersion$2 = '
|
|
4566
|
+
var formkitVersion$2 = '202602260152';
|
|
4475
4567
|
|
|
4476
4568
|
let AuroElement$2 = class AuroElement extends i$4 {
|
|
4477
4569
|
static get properties() {
|
|
@@ -4744,6 +4836,18 @@ class AuroDropdown extends AuroElement$2 {
|
|
|
4744
4836
|
*/
|
|
4745
4837
|
show() {
|
|
4746
4838
|
this.floater.showBib();
|
|
4839
|
+
|
|
4840
|
+
// Open dialog synchronously so callers remain in the user gesture
|
|
4841
|
+
// chain. This is critical for mobile browsers (iOS Safari) to keep
|
|
4842
|
+
// the virtual keyboard open when transitioning from the trigger
|
|
4843
|
+
// input to an input inside the fullscreen dialog. Without this,
|
|
4844
|
+
// showModal() fires asynchronously via Lit's update cycle, which
|
|
4845
|
+
// falls outside the user activation window and causes iOS to
|
|
4846
|
+
// dismiss the keyboard.
|
|
4847
|
+
if (this.isBibFullscreen && this.bibElement && this.bibElement.value) {
|
|
4848
|
+
const useModal = !this.disableFocusTrap;
|
|
4849
|
+
this.bibElement.value.open(useModal);
|
|
4850
|
+
}
|
|
4747
4851
|
}
|
|
4748
4852
|
|
|
4749
4853
|
/**
|
|
@@ -5130,6 +5234,14 @@ class AuroDropdown extends AuroElement$2 {
|
|
|
5130
5234
|
this.bibElement.value.close();
|
|
5131
5235
|
}
|
|
5132
5236
|
}
|
|
5237
|
+
|
|
5238
|
+
// When fullscreen strategy changes while open, re-open dialog with correct mode
|
|
5239
|
+
// (e.g. resizing from desktop → mobile while dropdown is open)
|
|
5240
|
+
if (changedProperties.has('isBibFullscreen') && this.isPopoverVisible && this.bibElement.value) {
|
|
5241
|
+
const useModal = this.isBibFullscreen && !this.disableFocusTrap;
|
|
5242
|
+
this.bibElement.value.close();
|
|
5243
|
+
this.bibElement.value.open(useModal);
|
|
5244
|
+
}
|
|
5133
5245
|
}
|
|
5134
5246
|
|
|
5135
5247
|
/**
|
|
@@ -10631,6 +10743,15 @@ class BaseInput extends AuroElement$1 {
|
|
|
10631
10743
|
constructor() {
|
|
10632
10744
|
super();
|
|
10633
10745
|
|
|
10746
|
+
// Delegate focus to the native <input> inside the shadow root so that
|
|
10747
|
+
// showModal()'s dialog focusing steps reach the input element.
|
|
10748
|
+
// This keeps the mobile virtual keyboard open when the fullscreen dialog
|
|
10749
|
+
// opens, because the browser sees an input-to-input focus transfer.
|
|
10750
|
+
this.constructor.shadowRootOptions = {
|
|
10751
|
+
...AuroElement$1.shadowRootOptions,
|
|
10752
|
+
delegatesFocus: true,
|
|
10753
|
+
};
|
|
10754
|
+
|
|
10634
10755
|
this._initializeDefaults();
|
|
10635
10756
|
}
|
|
10636
10757
|
|
|
@@ -10752,14 +10873,6 @@ class BaseInput extends AuroElement$1 {
|
|
|
10752
10873
|
reflect: true
|
|
10753
10874
|
},
|
|
10754
10875
|
|
|
10755
|
-
/**
|
|
10756
|
-
* The value for the aria-controls attribute.
|
|
10757
|
-
*/
|
|
10758
|
-
a11yControls: {
|
|
10759
|
-
type: String,
|
|
10760
|
-
reflect: true
|
|
10761
|
-
},
|
|
10762
|
-
|
|
10763
10876
|
/**
|
|
10764
10877
|
* The value for the aria-activedescendant attribute.
|
|
10765
10878
|
* Points to the ID of the currently active/highlighted option in a listbox.
|
|
@@ -12179,7 +12292,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$4 {
|
|
|
12179
12292
|
}
|
|
12180
12293
|
};
|
|
12181
12294
|
|
|
12182
|
-
var formkitVersion$1 = '
|
|
12295
|
+
var formkitVersion$1 = '202602260152';
|
|
12183
12296
|
|
|
12184
12297
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
12185
12298
|
// See LICENSE in the project root for license information.
|
|
@@ -13206,7 +13319,7 @@ class AuroBibtemplate extends i$4 {
|
|
|
13206
13319
|
}
|
|
13207
13320
|
}
|
|
13208
13321
|
|
|
13209
|
-
var formkitVersion = '
|
|
13322
|
+
var formkitVersion = '202602260152';
|
|
13210
13323
|
|
|
13211
13324
|
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}`;
|
|
13212
13325
|
|
|
@@ -13624,6 +13737,7 @@ class AuroCombobox extends AuroElement {
|
|
|
13624
13737
|
this.dropdownOpen = false;
|
|
13625
13738
|
this.triggerExpandedState = false;
|
|
13626
13739
|
this._expandedTimeout = null;
|
|
13740
|
+
this._inFullscreenTransition = false;
|
|
13627
13741
|
this.errorMessage = null;
|
|
13628
13742
|
this.isHiddenWhileLoading = false;
|
|
13629
13743
|
this.largeFullscreenHeadline = false;
|
|
@@ -13644,7 +13758,7 @@ class AuroCombobox extends AuroElement {
|
|
|
13644
13758
|
|
|
13645
13759
|
/**
|
|
13646
13760
|
* Defines whether the component will be on lighter or darker backgrounds.
|
|
13647
|
-
* @property {'default' | 'inverse'}
|
|
13761
|
+
* @property {'default' | 'inverse'} appearance - The visual appearance of the component.
|
|
13648
13762
|
* @default 'default'
|
|
13649
13763
|
*/
|
|
13650
13764
|
appearance: {
|
|
@@ -14199,7 +14313,7 @@ class AuroCombobox extends AuroElement {
|
|
|
14199
14313
|
* @returns {void}
|
|
14200
14314
|
*/
|
|
14201
14315
|
showBib() {
|
|
14202
|
-
if (!this.input.value) {
|
|
14316
|
+
if (!this.input.value && !this.dropdown.isBibFullscreen) {
|
|
14203
14317
|
this.dropdown.hide();
|
|
14204
14318
|
return;
|
|
14205
14319
|
}
|
|
@@ -14268,6 +14382,18 @@ class AuroCombobox extends AuroElement {
|
|
|
14268
14382
|
|
|
14269
14383
|
// Restore trigger accessibility when closing fullscreen
|
|
14270
14384
|
this.dropdown.trigger.inert = false;
|
|
14385
|
+
|
|
14386
|
+
// Restore focus to the trigger input after closing the
|
|
14387
|
+
// fullscreen dialog. The browser's native dialog focus restoration
|
|
14388
|
+
// fails because the trigger was set to inert before showModal().
|
|
14389
|
+
// Use rAF to run after Lit's microtask update cycle calls dialog.close().
|
|
14390
|
+
if (this.dropdown.isBibFullscreen) {
|
|
14391
|
+
requestAnimationFrame(() => {
|
|
14392
|
+
if (!this.dropdown.isPopoverVisible) {
|
|
14393
|
+
this.input.focus();
|
|
14394
|
+
}
|
|
14395
|
+
});
|
|
14396
|
+
}
|
|
14271
14397
|
}
|
|
14272
14398
|
|
|
14273
14399
|
if (this.dropdownOpen) {
|
|
@@ -14277,6 +14403,19 @@ class AuroCombobox extends AuroElement {
|
|
|
14277
14403
|
this.updateBibDialogRole();
|
|
14278
14404
|
|
|
14279
14405
|
if (this.dropdown.isBibFullscreen) {
|
|
14406
|
+
// Guard against spurious validation during the focus transition
|
|
14407
|
+
// from trigger to bib input. Setting trigger.inert = true removes
|
|
14408
|
+
// focus, which fires focusout on the child auro-input before the
|
|
14409
|
+
// bib input receives focus. That focusout triggers the input's own
|
|
14410
|
+
// validate(), which dispatches a composed auroFormElement-validated
|
|
14411
|
+
// event. Because composed events are retargetted at each shadow DOM
|
|
14412
|
+
// boundary, the event appears to originate from the combobox itself
|
|
14413
|
+
// and its listener unconditionally sets this.validity — causing
|
|
14414
|
+
// premature validation. This flag suppresses all validation paths
|
|
14415
|
+
// (focusout handler, handleInputValueChange, validate(), and the
|
|
14416
|
+
// auroFormElement-validated listener) until focus settles in the bib.
|
|
14417
|
+
this._inFullscreenTransition = true;
|
|
14418
|
+
|
|
14280
14419
|
// Hide the trigger from assistive technology so VoiceOver cannot reach it
|
|
14281
14420
|
// behind the fullscreen dialog
|
|
14282
14421
|
this.dropdown.trigger.inert = true;
|
|
@@ -14308,6 +14447,7 @@ class AuroCombobox extends AuroElement {
|
|
|
14308
14447
|
requestAnimationFrame(() => {
|
|
14309
14448
|
requestAnimationFrame(() => {
|
|
14310
14449
|
this.setInputFocus();
|
|
14450
|
+
this._inFullscreenTransition = false;
|
|
14311
14451
|
});
|
|
14312
14452
|
});
|
|
14313
14453
|
} else {
|
|
@@ -14402,7 +14542,7 @@ class AuroCombobox extends AuroElement {
|
|
|
14402
14542
|
* @private
|
|
14403
14543
|
*/
|
|
14404
14544
|
updateBibDialogRole() {
|
|
14405
|
-
const bibEl = this.dropdown.bibElement
|
|
14545
|
+
const bibEl = this.dropdown.bibElement && this.dropdown.bibElement.value;
|
|
14406
14546
|
if (!bibEl) {
|
|
14407
14547
|
return;
|
|
14408
14548
|
}
|
|
@@ -14531,9 +14671,10 @@ class AuroCombobox extends AuroElement {
|
|
|
14531
14671
|
// Announce the selection after the dropdown closes so it isn't
|
|
14532
14672
|
// overridden by VoiceOver's "collapsed" announcement from aria-expanded.
|
|
14533
14673
|
const selectedValue = event.detail.stringValue;
|
|
14674
|
+
const announcementDelay = 300;
|
|
14534
14675
|
setTimeout(() => {
|
|
14535
14676
|
this.announceToScreenReader(`${selectedValue}, selected`);
|
|
14536
|
-
},
|
|
14677
|
+
}, announcementDelay);
|
|
14537
14678
|
}
|
|
14538
14679
|
});
|
|
14539
14680
|
|
|
@@ -14581,7 +14722,7 @@ class AuroCombobox extends AuroElement {
|
|
|
14581
14722
|
* Validate every time we remove focus from the combo box.
|
|
14582
14723
|
*/
|
|
14583
14724
|
this.addEventListener('focusout', () => {
|
|
14584
|
-
if (!this.componentHasFocus) {
|
|
14725
|
+
if (!this.componentHasFocus && !this._inFullscreenTransition) {
|
|
14585
14726
|
this.validate();
|
|
14586
14727
|
}
|
|
14587
14728
|
});
|
|
@@ -14632,8 +14773,11 @@ class AuroCombobox extends AuroElement {
|
|
|
14632
14773
|
}
|
|
14633
14774
|
this.handleMenuOptions();
|
|
14634
14775
|
|
|
14635
|
-
// Validate only if the value was set programmatically
|
|
14636
|
-
|
|
14776
|
+
// Validate only if the value was set programmatically (not during user
|
|
14777
|
+
// interaction). In fullscreen dialog mode, componentHasFocus returns false
|
|
14778
|
+
// because focus is inside the top-layer dialog, so also check
|
|
14779
|
+
// dropdownOpen and the fullscreen transition flag.
|
|
14780
|
+
if (!this.componentHasFocus && !this.dropdownOpen && !this._inFullscreenTransition) {
|
|
14637
14781
|
this.validate();
|
|
14638
14782
|
}
|
|
14639
14783
|
|
|
@@ -14648,6 +14792,22 @@ class AuroCombobox extends AuroElement {
|
|
|
14648
14792
|
this.hideBib();
|
|
14649
14793
|
}
|
|
14650
14794
|
|
|
14795
|
+
// iOS virtual keyboard retention: when in fullscreen mode, ensure the
|
|
14796
|
+
// dialog opens and the bib input is focused synchronously within the
|
|
14797
|
+
// input event (user gesture) chain. Without this, Lit's async update
|
|
14798
|
+
// cycle delays showModal() past the user activation window, causing
|
|
14799
|
+
// iOS Safari to dismiss the virtual keyboard when the fullscreen
|
|
14800
|
+
// dialog opens — the user then has to tap the input again to resume
|
|
14801
|
+
// typing.
|
|
14802
|
+
if (this.dropdown.isBibFullscreen && this.input.value && this.input.value.length > 0) {
|
|
14803
|
+
if (!this.dropdown.isPopoverVisible) {
|
|
14804
|
+
this.showBib();
|
|
14805
|
+
}
|
|
14806
|
+
if (this.dropdown.isPopoverVisible) {
|
|
14807
|
+
this.setInputFocus();
|
|
14808
|
+
}
|
|
14809
|
+
}
|
|
14810
|
+
|
|
14651
14811
|
this.dispatchEvent(new CustomEvent('inputValue', { detail: { value: this.inputValue } }));
|
|
14652
14812
|
}
|
|
14653
14813
|
|
|
@@ -14673,23 +14833,20 @@ class AuroCombobox extends AuroElement {
|
|
|
14673
14833
|
}
|
|
14674
14834
|
|
|
14675
14835
|
if (evt.key === 'Tab' && this.dropdown.isPopoverVisible) {
|
|
14676
|
-
|
|
14677
|
-
|
|
14678
|
-
|
|
14679
|
-
|
|
14680
|
-
|
|
14681
|
-
|
|
14682
|
-
|
|
14683
|
-
|
|
14836
|
+
// Non-fullscreen (combobox pattern per WAI-ARIA APG):
|
|
14837
|
+
// Tab accepts the focused option and closes the popup, moving focus
|
|
14838
|
+
// to the next focusable element on the page.
|
|
14839
|
+
// https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/
|
|
14840
|
+
//
|
|
14841
|
+
// Fullscreen (dialog / modal pattern): Tab navigates between
|
|
14842
|
+
// focusable elements inside the modal (e.g. the close button) via
|
|
14843
|
+
// the native focus trap provided by showModal(). The dropdown is
|
|
14844
|
+
// closed by the close button or Escape instead.
|
|
14845
|
+
if (!this.dropdown.isBibFullscreen) {
|
|
14684
14846
|
if (this.menu.optionActive && this.menu.optionActive.value) {
|
|
14685
14847
|
this.menu.value = this.menu.optionActive.value;
|
|
14686
14848
|
}
|
|
14687
|
-
|
|
14688
|
-
setTimeout(() => {
|
|
14689
|
-
if (!this.componentHasFocus) {
|
|
14690
|
-
this.hideBib();
|
|
14691
|
-
}
|
|
14692
|
-
}, 0);
|
|
14849
|
+
this.hideBib();
|
|
14693
14850
|
}
|
|
14694
14851
|
}
|
|
14695
14852
|
|
|
@@ -14720,6 +14877,14 @@ class AuroCombobox extends AuroElement {
|
|
|
14720
14877
|
});
|
|
14721
14878
|
|
|
14722
14879
|
this.addEventListener('auroFormElement-validated', (evt) => {
|
|
14880
|
+
// During the fullscreen transition, child elements (auro-input) may fire
|
|
14881
|
+
// their own validation events when the trigger becomes inert and loses
|
|
14882
|
+
// focus. Those composed events bubble up through shadow DOM boundaries
|
|
14883
|
+
// and would incorrectly set combobox validity. Ignore them.
|
|
14884
|
+
if (this._inFullscreenTransition) {
|
|
14885
|
+
return;
|
|
14886
|
+
}
|
|
14887
|
+
|
|
14723
14888
|
this.input.validity = evt.detail.validity;
|
|
14724
14889
|
this.input.errorMessage = evt.detail.message;
|
|
14725
14890
|
this.validity = evt.detail.validity;
|
|
@@ -14823,6 +14988,9 @@ class AuroCombobox extends AuroElement {
|
|
|
14823
14988
|
* @param {boolean} [force=false] - Whether to force validation.
|
|
14824
14989
|
*/
|
|
14825
14990
|
validate(force = false) {
|
|
14991
|
+
if (this._inFullscreenTransition) {
|
|
14992
|
+
return;
|
|
14993
|
+
}
|
|
14826
14994
|
this.validation.validate(this, force);
|
|
14827
14995
|
}
|
|
14828
14996
|
|
|
@@ -14876,7 +15044,13 @@ class AuroCombobox extends AuroElement {
|
|
|
14876
15044
|
}
|
|
14877
15045
|
|
|
14878
15046
|
if (changedProperties.has('availableOptions')) {
|
|
14879
|
-
|
|
15047
|
+
// dropdownOpen is set synchronously by the auroDropdown-toggled event
|
|
15048
|
+
// handler during showBib() → floater.showBib() → dispatchEventDropdownToggle(),
|
|
15049
|
+
// so it's already true by the time updated() runs. This prevents the else
|
|
15050
|
+
// branch from calling hideBib() when the dropdown was just opened but
|
|
15051
|
+
// :focus-within hasn't propagated through the top-layer dialog's nested
|
|
15052
|
+
// shadow DOM boundaries.
|
|
15053
|
+
if ((this.availableOptions.length > 0 && (this.componentHasFocus || this.dropdownOpen)) || this.menu.loading || (this.availableOptions.length === 0 && this.noMatchOption)) {
|
|
14880
15054
|
this.showBib();
|
|
14881
15055
|
} else {
|
|
14882
15056
|
this.hideBib();
|
|
@@ -15051,6 +15225,7 @@ class AuroCombobox extends AuroElement {
|
|
|
15051
15225
|
<slot @slotchange="${this.handleSlotChange}"></slot>
|
|
15052
15226
|
<${this.inputTag}
|
|
15053
15227
|
id="inputInBib"
|
|
15228
|
+
autofocus
|
|
15054
15229
|
@input="${this.handleInputValueChange}"
|
|
15055
15230
|
.a11yActivedescendant="${this.dropdownOpen && this.optionActive ? this.optionActive.id : undefined}"
|
|
15056
15231
|
.a11yControls=${`${this.dropdownId}-floater-bib`}
|
|
@@ -15389,7 +15564,11 @@ class AuroMenuOption extends AuroElement {
|
|
|
15389
15564
|
|
|
15390
15565
|
// Generate unique ID if not already set (required for aria-activedescendant)
|
|
15391
15566
|
if (!this.id) {
|
|
15392
|
-
|
|
15567
|
+
const idBase = 36;
|
|
15568
|
+
const sliceStart = 2;
|
|
15569
|
+
const sliceEnd = 8;
|
|
15570
|
+
this.id = `menuoption-${Math.random().toString(idBase).
|
|
15571
|
+
slice(sliceStart, sliceEnd)}`;
|
|
15393
15572
|
}
|
|
15394
15573
|
|
|
15395
15574
|
this.setAttribute('role', 'option');
|
|
@@ -16296,7 +16475,7 @@ class MenuService {
|
|
|
16296
16475
|
|
|
16297
16476
|
const MenuContext = n('menu-context');
|
|
16298
16477
|
|
|
16299
|
-
/* eslint-disable no-underscore-dangle
|
|
16478
|
+
/* eslint-disable no-underscore-dangle */
|
|
16300
16479
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
16301
16480
|
// See LICENSE in the project root for license information.
|
|
16302
16481
|
|
|
@@ -16317,7 +16496,7 @@ const MenuContext = n('menu-context');
|
|
|
16317
16496
|
* @slot - Slot for insertion of menu options.
|
|
16318
16497
|
*/
|
|
16319
16498
|
|
|
16320
|
-
/* eslint-disable
|
|
16499
|
+
/* eslint-disable max-lines */
|
|
16321
16500
|
|
|
16322
16501
|
class AuroMenu extends AuroElement {
|
|
16323
16502
|
|