@aurodesignsystem-dev/auro-formkit 0.0.0-pr1398.2 → 0.0.0-pr1398.3
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/demo/keyboardBehavior.md +0 -0
- package/components/checkbox/dist/index.js +1 -1
- package/components/checkbox/dist/registered.js +1 -1
- package/components/combobox/demo/api.min.js +129 -166
- package/components/combobox/demo/index.min.js +129 -166
- package/components/combobox/demo/keyboardBehavior.html +81 -0
- package/components/combobox/demo/keyboardBehavior.md +308 -0
- package/components/combobox/dist/index.js +87 -134
- package/components/combobox/dist/registered.js +87 -134
- package/components/counter/demo/api.min.js +157 -160
- package/components/counter/demo/index.min.js +157 -160
- package/components/counter/demo/keyboardBehavior.html +81 -0
- package/components/counter/demo/keyboardBehavior.md +127 -0
- package/components/counter/dist/auro-counter.d.ts +0 -7
- package/components/counter/dist/index.js +157 -160
- package/components/counter/dist/keyboardStrategy.d.ts +4 -0
- package/components/counter/dist/registered.js +157 -160
- package/components/datepicker/demo/api.min.js +89 -137
- package/components/datepicker/demo/index.min.js +89 -137
- package/components/datepicker/demo/keyboardBehavior.html +81 -0
- package/components/datepicker/demo/keyboardBehavior.md +24 -0
- package/components/datepicker/dist/index.js +84 -132
- package/components/datepicker/dist/registered.js +84 -132
- package/components/dropdown/demo/api.md +0 -1
- package/components/dropdown/demo/api.min.js +99 -140
- package/components/dropdown/demo/index.md +2 -2
- package/components/dropdown/demo/index.min.js +99 -140
- package/components/dropdown/demo/keyboardBehavior.html +81 -0
- package/components/dropdown/demo/keyboardBehavior.md +77 -0
- package/components/dropdown/dist/auro-dropdown.d.ts +0 -8
- package/components/dropdown/dist/auro-dropdownBib.d.ts +1 -50
- package/components/dropdown/dist/dropdownBibKeyboardStrategy.d.ts +7 -0
- package/components/dropdown/dist/index.js +83 -128
- package/components/dropdown/dist/registered.js +83 -128
- package/components/form/demo/api.min.js +466 -599
- package/components/form/demo/index.min.js +466 -599
- package/components/form/demo/keyboardBehavior.md +0 -0
- package/components/input/demo/api.min.js +1 -1
- package/components/input/demo/index.min.js +1 -1
- package/components/input/demo/keyboardBehavior.md +0 -0
- package/components/input/dist/index.js +1 -1
- package/components/input/dist/registered.js +1 -1
- package/components/menu/demo/api.min.js +42 -32
- package/components/menu/demo/index.min.js +42 -32
- package/components/menu/dist/auro-menu.d.ts +3 -11
- package/components/menu/dist/index.js +42 -32
- package/components/menu/dist/registered.js +42 -32
- 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 +132 -167
- package/components/select/demo/index.min.js +132 -167
- package/components/select/demo/keyboardBehavior.html +81 -0
- package/components/select/demo/keyboardBehavior.md +246 -0
- package/components/select/dist/index.js +90 -135
- package/components/select/dist/registered.js +90 -135
- package/custom-elements.json +61 -89
- package/package.json +2 -2
|
@@ -102,13 +102,6 @@ export class AuroCounter extends LitElement {
|
|
|
102
102
|
* @param {boolean} [force=false] - Whether to force validation.
|
|
103
103
|
*/
|
|
104
104
|
validate(force?: boolean): void;
|
|
105
|
-
/**
|
|
106
|
-
* Handles the keydown event for the counter component.
|
|
107
|
-
* @param {KeyboardEvent} event - The keyboard event object.
|
|
108
|
-
* @returns {void}
|
|
109
|
-
* @private
|
|
110
|
-
*/
|
|
111
|
-
private handleKeyDown;
|
|
112
105
|
firstUpdated(): void;
|
|
113
106
|
/**
|
|
114
107
|
* Sets an attribute that matches the default tag name if the tag name is not the default.
|
|
@@ -1184,6 +1184,57 @@ class IconUtil {
|
|
|
1184
1184
|
}
|
|
1185
1185
|
}
|
|
1186
1186
|
|
|
1187
|
+
/**
|
|
1188
|
+
* Computes display state once per keydown event.
|
|
1189
|
+
* Centralizes null-safety checks and makes the shared/modal/popover branching explicit.
|
|
1190
|
+
*
|
|
1191
|
+
* @param {HTMLElement} component - The component with a dropdown reference.
|
|
1192
|
+
* @param {Object} [options] - Optional config.
|
|
1193
|
+
* @param {HTMLElement} [options.dropdown] - Explicit dropdown reference. Falls back to component.dropdown.
|
|
1194
|
+
* @param {Function} [options.inputResolver] - Called with (component, ctx) to resolve the active input element.
|
|
1195
|
+
* @returns {{isExpanded: boolean, isModal: boolean, isPopover: boolean, activeInput: HTMLElement|null}}
|
|
1196
|
+
* isModal and isPopover reflect the display mode (fullscreen vs not) regardless of expanded state.
|
|
1197
|
+
*/
|
|
1198
|
+
function createDisplayContext$1(component, options = {}) {
|
|
1199
|
+
const dd = options.dropdown || component.dropdown;
|
|
1200
|
+
// isPopoverVisible reflects as the `open` attribute.
|
|
1201
|
+
// It reports whether the bib is open in any mode (popover or modal).
|
|
1202
|
+
const isExpanded = Boolean(dd && dd.isPopoverVisible);
|
|
1203
|
+
const isFullscreen = Boolean(dd && dd.isBibFullscreen);
|
|
1204
|
+
|
|
1205
|
+
const ctx = {
|
|
1206
|
+
isExpanded,
|
|
1207
|
+
isModal: isFullscreen,
|
|
1208
|
+
isPopover: !isFullscreen,
|
|
1209
|
+
activeInput: null,
|
|
1210
|
+
};
|
|
1211
|
+
|
|
1212
|
+
if (options.inputResolver) {
|
|
1213
|
+
const resolvedInput = options.inputResolver(component, ctx);
|
|
1214
|
+
// Guard against resolvers returning undefined or non-HTMLElement values.
|
|
1215
|
+
ctx.activeInput = resolvedInput instanceof HTMLElement ? resolvedInput : null;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
return ctx;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
/**
|
|
1222
|
+
* Wires up a keydown listener that dispatches to strategy[evt.key] or strategy.default.
|
|
1223
|
+
* Handles both sync and async handlers.
|
|
1224
|
+
* @param {HTMLElement} component - The component to attach the listener to.
|
|
1225
|
+
* @param {Object} strategy - Map of key names to handler functions.
|
|
1226
|
+
* @param {Object} [options] - Optional config passed to createDisplayContext.
|
|
1227
|
+
*/
|
|
1228
|
+
function applyKeyboardStrategy$1(component, strategy, options = {}) {
|
|
1229
|
+
component.addEventListener('keydown', async (evt) => {
|
|
1230
|
+
const handler = strategy[evt.key] || strategy.default;
|
|
1231
|
+
if (typeof handler === 'function') {
|
|
1232
|
+
const ctx = createDisplayContext$1(component, options);
|
|
1233
|
+
await handler(component, evt, ctx);
|
|
1234
|
+
}
|
|
1235
|
+
});
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1187
1238
|
var plusIcon = {"role":"img","color":"currentColor","title":"","desc":"","width":"var(--auro-size-lg, var(--ds-size-300, 1.5rem))","height":"var(--auro-size-lg, var(--ds-size-300, 1.5rem))","xmlns":"http://www.w3.org/2000/svg","xmlns_xlink":"http://www.w3.org/1999/xlink","viewBox":"0 0 24 24","path":"/icons","style":"ico_squareLarge","type":"icon","name":"plus-lg","category":"interface","svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" aria-hidden=\"true\" class=\"ico_squareLarge\" role=\"img\" style=\"min-width:var(--auro-size-lg, var(--ds-size-300, 1.5rem));height:var(--auro-size-lg, var(--ds-size-300, 1.5rem));fill:currentColor\" viewBox=\"0 0 24 24\" part=\"svg\"><title/><path d=\"M11.898 5.007 12 5a.75.75 0 0 1 .743.648l.007.102v5.5h5.5a.75.75 0 0 1 .743.648L19 12a.75.75 0 0 1-.648.743l-.102.007h-5.501l.001 5.5a.75.75 0 0 1-.648.743L12 19a.75.75 0 0 1-.743-.648l-.007-.102-.001-5.5H5.75a.75.75 0 0 1-.743-.648L5 12a.75.75 0 0 1 .648-.743l.102-.007h5.5v-5.5a.75.75 0 0 1 .648-.743L12 5z\"/></svg>"};
|
|
1188
1239
|
|
|
1189
1240
|
var minusIcon = {"role":"img","color":"currentColor","title":"","desc":"","width":"var(--auro-size-lg, var(--ds-size-300, 1.5rem))","height":"var(--auro-size-lg, var(--ds-size-300, 1.5rem))","xmlns":"http://www.w3.org/2000/svg","xmlns_xlink":"http://www.w3.org/1999/xlink","viewBox":"0 0 24 24","path":"/icons","style":"ico_squareLarge","type":"icon","name":"minus-lg","category":"interface","deprecated":true,"svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" aria-hidden=\"true\" class=\"ico_squareLarge\" data-deprecated=\"true\" role=\"img\" style=\"min-width:var(--auro-size-lg, var(--ds-size-300, 1.5rem));height:var(--auro-size-lg, var(--ds-size-300, 1.5rem));fill:currentColor\" viewBox=\"0 0 24 24\" part=\"svg\"><title/><path d=\"M5.75 12.75h12.5a.75.75 0 1 0 0-1.5H5.75a.75.75 0 1 0 0 1.5\"/></svg>"};
|
|
@@ -1420,7 +1471,30 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
|
|
|
1420
1471
|
}
|
|
1421
1472
|
};
|
|
1422
1473
|
|
|
1423
|
-
var formkitVersion$1 = '
|
|
1474
|
+
var formkitVersion$1 = '202604012043';
|
|
1475
|
+
|
|
1476
|
+
// Copyright (c) 2026 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
1477
|
+
// See LICENSE in the project root for license information.
|
|
1478
|
+
|
|
1479
|
+
const keyboardStrategy = {
|
|
1480
|
+
ArrowUp(component, _evt) {
|
|
1481
|
+
if (component.disabled) {
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
_evt.preventDefault();
|
|
1486
|
+
component.increment();
|
|
1487
|
+
},
|
|
1488
|
+
|
|
1489
|
+
ArrowDown(component, _evt) {
|
|
1490
|
+
if (component.disabled) {
|
|
1491
|
+
return;
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
_evt.preventDefault();
|
|
1495
|
+
component.decrement();
|
|
1496
|
+
}
|
|
1497
|
+
};
|
|
1424
1498
|
|
|
1425
1499
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
1426
1500
|
// See LICENSE in the project root for license information.
|
|
@@ -1494,11 +1568,10 @@ class AuroCounter extends LitElement {
|
|
|
1494
1568
|
|
|
1495
1569
|
connectedCallback() {
|
|
1496
1570
|
super.connectedCallback();
|
|
1497
|
-
this
|
|
1571
|
+
applyKeyboardStrategy$1(this, keyboardStrategy);
|
|
1498
1572
|
}
|
|
1499
1573
|
|
|
1500
1574
|
disconnectedCallback() {
|
|
1501
|
-
this.removeEventListener('keydown', this.handleKeyDown);
|
|
1502
1575
|
super.disconnectedCallback();
|
|
1503
1576
|
}
|
|
1504
1577
|
|
|
@@ -1709,29 +1782,6 @@ class AuroCounter extends LitElement {
|
|
|
1709
1782
|
this.validation.validate(this, force);
|
|
1710
1783
|
}
|
|
1711
1784
|
|
|
1712
|
-
/**
|
|
1713
|
-
* Handles the keydown event for the counter component.
|
|
1714
|
-
* @param {KeyboardEvent} event - The keyboard event object.
|
|
1715
|
-
* @returns {void}
|
|
1716
|
-
* @private
|
|
1717
|
-
*/
|
|
1718
|
-
handleKeyDown(event) {
|
|
1719
|
-
if (this.disabled) {
|
|
1720
|
-
return;
|
|
1721
|
-
}
|
|
1722
|
-
|
|
1723
|
-
switch (event.key) {
|
|
1724
|
-
case 'ArrowUp':
|
|
1725
|
-
event.preventDefault();
|
|
1726
|
-
this.increment();
|
|
1727
|
-
break;
|
|
1728
|
-
case 'ArrowDown':
|
|
1729
|
-
event.preventDefault();
|
|
1730
|
-
this.decrement();
|
|
1731
|
-
break;
|
|
1732
|
-
}
|
|
1733
|
-
}
|
|
1734
|
-
|
|
1735
1785
|
firstUpdated() {
|
|
1736
1786
|
this.initValue();
|
|
1737
1787
|
this.setTagAttribute("auro-counter");
|
|
@@ -3934,11 +3984,10 @@ class AuroFloatingUI {
|
|
|
3934
3984
|
return;
|
|
3935
3985
|
}
|
|
3936
3986
|
|
|
3937
|
-
const { activeElement } = document;
|
|
3938
3987
|
// if focus is still inside of trigger or bib, do not close
|
|
3939
3988
|
if (
|
|
3940
|
-
this.element.
|
|
3941
|
-
this.element.
|
|
3989
|
+
this.element.matches(":focus") ||
|
|
3990
|
+
this.element.matches(":focus-within")
|
|
3942
3991
|
) {
|
|
3943
3992
|
return;
|
|
3944
3993
|
}
|
|
@@ -4777,12 +4826,83 @@ let p$2 = class p{registerComponent(t,a){customElements.get(t)||customElements.d
|
|
|
4777
4826
|
|
|
4778
4827
|
var iconVersion$1 = '9.1.2';
|
|
4779
4828
|
|
|
4829
|
+
/**
|
|
4830
|
+
* Computes display state once per keydown event.
|
|
4831
|
+
* Centralizes null-safety checks and makes the shared/modal/popover branching explicit.
|
|
4832
|
+
*
|
|
4833
|
+
* @param {HTMLElement} component - The component with a dropdown reference.
|
|
4834
|
+
* @param {Object} [options] - Optional config.
|
|
4835
|
+
* @param {HTMLElement} [options.dropdown] - Explicit dropdown reference. Falls back to component.dropdown.
|
|
4836
|
+
* @param {Function} [options.inputResolver] - Called with (component, ctx) to resolve the active input element.
|
|
4837
|
+
* @returns {{isExpanded: boolean, isModal: boolean, isPopover: boolean, activeInput: HTMLElement|null}}
|
|
4838
|
+
* isModal and isPopover reflect the display mode (fullscreen vs not) regardless of expanded state.
|
|
4839
|
+
*/
|
|
4840
|
+
function createDisplayContext(component, options = {}) {
|
|
4841
|
+
const dd = options.dropdown || component.dropdown;
|
|
4842
|
+
// isPopoverVisible reflects as the `open` attribute.
|
|
4843
|
+
// It reports whether the bib is open in any mode (popover or modal).
|
|
4844
|
+
const isExpanded = Boolean(dd && dd.isPopoverVisible);
|
|
4845
|
+
const isFullscreen = Boolean(dd && dd.isBibFullscreen);
|
|
4846
|
+
|
|
4847
|
+
const ctx = {
|
|
4848
|
+
isExpanded,
|
|
4849
|
+
isModal: isFullscreen,
|
|
4850
|
+
isPopover: !isFullscreen,
|
|
4851
|
+
activeInput: null,
|
|
4852
|
+
};
|
|
4853
|
+
|
|
4854
|
+
if (options.inputResolver) {
|
|
4855
|
+
const resolvedInput = options.inputResolver(component, ctx);
|
|
4856
|
+
// Guard against resolvers returning undefined or non-HTMLElement values.
|
|
4857
|
+
ctx.activeInput = resolvedInput instanceof HTMLElement ? resolvedInput : null;
|
|
4858
|
+
}
|
|
4859
|
+
|
|
4860
|
+
return ctx;
|
|
4861
|
+
}
|
|
4862
|
+
|
|
4863
|
+
/**
|
|
4864
|
+
* Wires up a keydown listener that dispatches to strategy[evt.key] or strategy.default.
|
|
4865
|
+
* Handles both sync and async handlers.
|
|
4866
|
+
* @param {HTMLElement} component - The component to attach the listener to.
|
|
4867
|
+
* @param {Object} strategy - Map of key names to handler functions.
|
|
4868
|
+
* @param {Object} [options] - Optional config passed to createDisplayContext.
|
|
4869
|
+
*/
|
|
4870
|
+
function applyKeyboardStrategy(component, strategy, options = {}) {
|
|
4871
|
+
component.addEventListener('keydown', async (evt) => {
|
|
4872
|
+
const handler = strategy[evt.key] || strategy.default;
|
|
4873
|
+
if (typeof handler === 'function') {
|
|
4874
|
+
const ctx = createDisplayContext(component, options);
|
|
4875
|
+
await handler(component, evt, ctx);
|
|
4876
|
+
}
|
|
4877
|
+
});
|
|
4878
|
+
}
|
|
4879
|
+
|
|
4780
4880
|
var styleCss$2 = css`: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}`;
|
|
4781
4881
|
|
|
4782
4882
|
var colorCss$2 = css`.container{background-color:var(--ds-auro-dropdownbib-container-color);box-shadow:var(--ds-auro-dropdownbib-boxshadow-color);color:var(--ds-auro-dropdownbib-text-color)}`;
|
|
4783
4883
|
|
|
4784
4884
|
var tokensCss$1 = css`:host(:not([ondark])),:host(:not([appearance=inverse])){--ds-auro-dropdown-label-text-color: var(--ds-basic-color-texticon-muted, #676767);--ds-auro-dropdown-trigger-background-color: var(--ds-basic-color-surface-default, #ffffff);--ds-auro-dropdown-trigger-hover-background-color: var(--ds-basic-color-surface-default, #ffffff);--ds-auro-dropdown-trigger-container-color: var(--ds-basic-color-surface-default, #ffffff);--ds-auro-dropdown-trigger-border-color: var(--ds-basic-color-border-bold, #585e67);--ds-auro-dropdown-trigger-outline-color: transparent;--ds-auro-dropdown-trigger-text-color: var(--ds-basic-color-texticon-default, #2a2a2a);--ds-auro-dropdownbib-boxshadow-color: var(--ds-elevation-200, 0px 0px 10px rgba(0, 0, 0, 0.15));--ds-auro-dropdownbib-background-color: var(--ds-basic-color-surface-default, #ffffff);--ds-auro-dropdownbib-container-color: var(--ds-basic-color-surface-default, #ffffff);--ds-auro-dropdownbib-text-color: var(--ds-basic-color-texticon-default, #2a2a2a)}:host([ondark]),:host([appearance=inverse]){--ds-auro-dropdown-label-text-color: var(--ds-basic-color-texticon-inverse-muted, #ccd2db);--ds-auro-dropdown-trigger-background-color: var(--ds-advanced-color-shared-background-inverse, rgba(255, 255, 255, 0.15));--ds-auro-dropdown-trigger-hover-background-color: var(--ds-advanced-color-shared-background-inverse, rgba(255, 255, 255, 0.15));--ds-auro-dropdown-trigger-container-color: var(--ds-advanced-color-shared-background-inverse, rgba(255, 255, 255, 0.15));--ds-auro-dropdown-trigger-border-color: var(--ds-basic-color-border-inverse, #ffffff);--ds-auro-dropdown-trigger-outline-color: transparent;--ds-auro-dropdown-trigger-text-color: var(--ds-basic-color-texticon-inverse, #ffffff);--ds-auro-dropdownbib-boxshadow-color: var(--ds-elevation-200, 0px 0px 10px rgba(0, 0, 0, 0.15));--ds-auro-dropdownbib-background-color: var(--ds-advanced-color-shared-background-inverse, rgba(255, 255, 255, 0.15));--ds-auro-dropdownbib-container-color: var(--ds-advanced-color-shared-background-inverse, rgba(255, 255, 255, 0.15));--ds-auro-dropdownbib-text-color: var(--ds-basic-color-texticon-inverse, #ffffff)}`;
|
|
4785
4885
|
|
|
4886
|
+
/**
|
|
4887
|
+
* Creates a keyboard strategy for dialog-specific key handling.
|
|
4888
|
+
* All other keydown behavior is left to the browser's native bubbling path.
|
|
4889
|
+
* @param {HTMLElement} bib - The dropdown bib element.
|
|
4890
|
+
* @returns {Object} Keyboard handlers keyed by `event.key`.
|
|
4891
|
+
*/
|
|
4892
|
+
// eslint-disable-next-line no-unused-vars
|
|
4893
|
+
function createDropdownBibKeyboardStrategy(bib) {
|
|
4894
|
+
return {
|
|
4895
|
+
// eslint-disable-next-line no-unused-vars
|
|
4896
|
+
Enter(_dialog, event) {
|
|
4897
|
+
// Floating UI handles Enter key to open the dropdown
|
|
4898
|
+
},
|
|
4899
|
+
// eslint-disable-next-line no-unused-vars
|
|
4900
|
+
Escape(_dialog, event) {
|
|
4901
|
+
// Floating UI handles Escape key to close the dropdown
|
|
4902
|
+
}
|
|
4903
|
+
};
|
|
4904
|
+
}
|
|
4905
|
+
|
|
4786
4906
|
// Copyright (c) 2020 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
4787
4907
|
// See LICENSE in the project root for license information.
|
|
4788
4908
|
/* eslint-disable max-lines */
|
|
@@ -4907,26 +5027,11 @@ class AuroDropdownBib extends LitElement {
|
|
|
4907
5027
|
},
|
|
4908
5028
|
|
|
4909
5029
|
/**
|
|
4910
|
-
*
|
|
4911
|
-
* aria-activedescendant. The dialog keyboard bridge checks this
|
|
4912
|
-
* flag so that Enter selects the highlighted option instead of
|
|
4913
|
-
* activating the focused interactive element (e.g. the trigger
|
|
4914
|
-
* button, or the bibtemplate close button in fullscreen).
|
|
5030
|
+
* Tracks whether a menu option is currently highlighted.
|
|
4915
5031
|
* @private
|
|
4916
5032
|
*/
|
|
4917
5033
|
hasActiveDescendant: {
|
|
4918
5034
|
type: Boolean
|
|
4919
|
-
},
|
|
4920
|
-
|
|
4921
|
-
/**
|
|
4922
|
-
* When true, the keyboard bridge allows native Tab behavior
|
|
4923
|
-
* instead of intercepting it. Set this for bib consumers
|
|
4924
|
-
* (e.g. counter) whose content contains real focusable elements
|
|
4925
|
-
* that need native Tab navigation.
|
|
4926
|
-
* @private
|
|
4927
|
-
*/
|
|
4928
|
-
nativeFocusableContent: {
|
|
4929
|
-
type: Boolean
|
|
4930
5035
|
}
|
|
4931
5036
|
};
|
|
4932
5037
|
}
|
|
@@ -4996,7 +5101,7 @@ class AuroDropdownBib extends LitElement {
|
|
|
4996
5101
|
|
|
4997
5102
|
const dialog = this.shadowRoot.querySelector('dialog');
|
|
4998
5103
|
this._setupCancelHandler(dialog);
|
|
4999
|
-
|
|
5104
|
+
applyKeyboardStrategy(dialog, createDropdownBibKeyboardStrategy());
|
|
5000
5105
|
|
|
5001
5106
|
this.dispatchEvent(new CustomEvent('auro-dropdownbib-connected', {
|
|
5002
5107
|
bubbles: true,
|
|
@@ -5023,98 +5128,6 @@ class AuroDropdownBib extends LitElement {
|
|
|
5023
5128
|
});
|
|
5024
5129
|
}
|
|
5025
5130
|
|
|
5026
|
-
/**
|
|
5027
|
-
* showModal() creates a closed focus scope — keyboard events inside
|
|
5028
|
-
* the dialog's shadow DOM do NOT bubble out to the combobox/select
|
|
5029
|
-
* keydown handlers in the parent shadow DOM. This handler bridges
|
|
5030
|
-
* that gap by re-dispatching navigation keys so they cross the
|
|
5031
|
-
* shadow boundary and reach the menu navigation logic in the parent
|
|
5032
|
-
* component.
|
|
5033
|
-
*
|
|
5034
|
-
* The trade-off: intercepting these keys means native keyboard
|
|
5035
|
-
* behaviors that would normally "just work" must be manually
|
|
5036
|
-
* re-implemented here:
|
|
5037
|
-
*
|
|
5038
|
-
* - Enter on buttons: Custom elements (auro-button) don't get the
|
|
5039
|
-
* native Enter→click that <button> provides, so we call .click()
|
|
5040
|
-
* directly when Enter is pressed on a button-like element.
|
|
5041
|
-
*
|
|
5042
|
-
* - Tab: Intercepted and re-dispatched so parent components
|
|
5043
|
-
* (select/combobox) can select the active option and close the
|
|
5044
|
-
* dialog. The <dialog> provides containment and isolation
|
|
5045
|
-
* (inert background, VoiceOver focus trapping, top layer), while
|
|
5046
|
-
* the content inside is a role="listbox" navigated via
|
|
5047
|
-
* aria-activedescendant (options are not focusable). Tab keyboard
|
|
5048
|
-
* behavior follows listbox conventions (select + close) because
|
|
5049
|
-
* the dialog's native Tab trap only cycles between the close
|
|
5050
|
-
* button and browser chrome.
|
|
5051
|
-
*
|
|
5052
|
-
* - Escape: The native <dialog> fires a `cancel` event on ESC
|
|
5053
|
-
* (handled by _setupCancelHandler), so the re-dispatched Escape
|
|
5054
|
-
* is a secondary path for parent components that also listen for
|
|
5055
|
-
* Escape keydown.
|
|
5056
|
-
*
|
|
5057
|
-
* @param {HTMLDialogElement} dialog - The dialog element to attach the keyboard bridge to.
|
|
5058
|
-
* @private
|
|
5059
|
-
*/
|
|
5060
|
-
_setupKeyboardBridge(dialog) {
|
|
5061
|
-
const navKeys = new Set([
|
|
5062
|
-
'ArrowUp',
|
|
5063
|
-
'ArrowDown',
|
|
5064
|
-
'Enter',
|
|
5065
|
-
'Escape',
|
|
5066
|
-
'Tab'
|
|
5067
|
-
]);
|
|
5068
|
-
|
|
5069
|
-
dialog.addEventListener('keydown', (event) => {
|
|
5070
|
-
if (!navKeys.has(event.key)) {
|
|
5071
|
-
return;
|
|
5072
|
-
}
|
|
5073
|
-
|
|
5074
|
-
// Custom elements (auro-button) don't get the native Enter→click
|
|
5075
|
-
// behavior that <button> has. Find the button in the composed path
|
|
5076
|
-
// and click it directly — but only when no menu option is
|
|
5077
|
-
// highlighted. In fullscreen mode focus stays on the close button
|
|
5078
|
-
// while arrow keys move the active-descendant highlight through
|
|
5079
|
-
// the listbox. If the user presses Enter with an option
|
|
5080
|
-
// highlighted, the intent is to select that option, not to click
|
|
5081
|
-
// the close button. In that case we fall through and bridge the
|
|
5082
|
-
// Enter key to the parent component's keyboard strategy.
|
|
5083
|
-
if (event.key === 'Enter') {
|
|
5084
|
-
if (!this.hasActiveDescendant) {
|
|
5085
|
-
const buttonSelector = 'button, [role="button"], auro-button, [auro-button]';
|
|
5086
|
-
const btn = event.composedPath().find((el) => el.matches && el.matches(buttonSelector));
|
|
5087
|
-
if (btn) {
|
|
5088
|
-
event.preventDefault();
|
|
5089
|
-
event.stopPropagation();
|
|
5090
|
-
btn.click();
|
|
5091
|
-
return;
|
|
5092
|
-
}
|
|
5093
|
-
}
|
|
5094
|
-
}
|
|
5095
|
-
|
|
5096
|
-
// Allow native Tab when the bib contains focusable content
|
|
5097
|
-
// (e.g. counter buttons) that needs normal Tab navigation.
|
|
5098
|
-
if (event.key === 'Tab' && this.nativeFocusableContent) {
|
|
5099
|
-
return;
|
|
5100
|
-
}
|
|
5101
|
-
|
|
5102
|
-
event.preventDefault();
|
|
5103
|
-
event.stopPropagation();
|
|
5104
|
-
const newEvent = new KeyboardEvent('keydown', {
|
|
5105
|
-
key: event.key,
|
|
5106
|
-
code: event.code,
|
|
5107
|
-
shiftKey: event.shiftKey,
|
|
5108
|
-
altKey: event.altKey,
|
|
5109
|
-
ctrlKey: event.ctrlKey,
|
|
5110
|
-
metaKey: event.metaKey,
|
|
5111
|
-
bubbles: true,
|
|
5112
|
-
composed: true,
|
|
5113
|
-
cancelable: true
|
|
5114
|
-
});
|
|
5115
|
-
this.dispatchEvent(newEvent);
|
|
5116
|
-
});
|
|
5117
|
-
}
|
|
5118
5131
|
|
|
5119
5132
|
/**
|
|
5120
5133
|
* Blocks touch-driven page scroll while a fullscreen modal dialog is open.
|
|
@@ -5489,7 +5502,7 @@ class AuroHelpText extends LitElement {
|
|
|
5489
5502
|
}
|
|
5490
5503
|
}
|
|
5491
5504
|
|
|
5492
|
-
var formkitVersion = '
|
|
5505
|
+
var formkitVersion = '202604012043';
|
|
5493
5506
|
|
|
5494
5507
|
let AuroElement$1 = class AuroElement extends LitElement {
|
|
5495
5508
|
static get properties() {
|
|
@@ -5670,7 +5683,6 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5670
5683
|
this.appearance = 'default';
|
|
5671
5684
|
this.chevron = false;
|
|
5672
5685
|
this.disabled = false;
|
|
5673
|
-
this.disableFocusTrap = false;
|
|
5674
5686
|
this.error = false;
|
|
5675
5687
|
this.tabIndex = 0;
|
|
5676
5688
|
this.noToggle = false;
|
|
@@ -5768,9 +5780,8 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5768
5780
|
// showModal() fires asynchronously via Lit's update cycle, which
|
|
5769
5781
|
// falls outside the user activation window and causes iOS to
|
|
5770
5782
|
// dismiss the keyboard.
|
|
5771
|
-
if (this.
|
|
5772
|
-
|
|
5773
|
-
this.bibElement.value.open(useModal);
|
|
5783
|
+
if (this.bibElement && this.bibElement.value) {
|
|
5784
|
+
this.bibElement.value.open(this.isBibFullscreen);
|
|
5774
5785
|
}
|
|
5775
5786
|
}
|
|
5776
5787
|
|
|
@@ -5883,14 +5894,6 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5883
5894
|
reflect: true
|
|
5884
5895
|
},
|
|
5885
5896
|
|
|
5886
|
-
/**
|
|
5887
|
-
* If declared, the focus trap inside of bib will be turned off.
|
|
5888
|
-
*/
|
|
5889
|
-
disableFocusTrap: {
|
|
5890
|
-
type: Boolean,
|
|
5891
|
-
reflect: true
|
|
5892
|
-
},
|
|
5893
|
-
|
|
5894
5897
|
/**
|
|
5895
5898
|
* @private
|
|
5896
5899
|
*/
|
|
@@ -6164,7 +6167,7 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
6164
6167
|
if (this.isPopoverVisible) {
|
|
6165
6168
|
// Fullscreen: use showModal() for native accessibility (inert outside, focus trap)
|
|
6166
6169
|
// Desktop: use show() for Floating UI positioning + FocusTrap for focus management
|
|
6167
|
-
const useModal = this.isBibFullscreen
|
|
6170
|
+
const useModal = this.isBibFullscreen;
|
|
6168
6171
|
this.bibElement.value.open(useModal);
|
|
6169
6172
|
} else {
|
|
6170
6173
|
this.bibElement.value.close();
|
|
@@ -6174,7 +6177,7 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
6174
6177
|
// When fullscreen strategy changes while open, re-open dialog with correct mode
|
|
6175
6178
|
// (e.g. resizing from desktop → mobile while dropdown is open)
|
|
6176
6179
|
if (changedProperties.has('isBibFullscreen') && this.isPopoverVisible && this.bibElement.value) {
|
|
6177
|
-
const useModal = this.isBibFullscreen
|
|
6180
|
+
const useModal = this.isBibFullscreen;
|
|
6178
6181
|
this.bibElement.value.close();
|
|
6179
6182
|
this.bibElement.value.open(useModal);
|
|
6180
6183
|
}
|
|
@@ -6286,7 +6289,7 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
6286
6289
|
* @private
|
|
6287
6290
|
*/
|
|
6288
6291
|
updateFocusTrap() {
|
|
6289
|
-
if (this.isPopoverVisible
|
|
6292
|
+
if (this.isPopoverVisible) {
|
|
6290
6293
|
if (!this.isBibFullscreen) {
|
|
6291
6294
|
// Desktop: show() doesn't trap focus, so use FocusTrap
|
|
6292
6295
|
this.focusTrap = new FocusTrap(this.bibContent);
|
|
@@ -7638,11 +7641,6 @@ class AuroCounterGroup extends AuroElement {
|
|
|
7638
7641
|
|
|
7639
7642
|
// Focus close button when fullscreen dialog opens
|
|
7640
7643
|
this.dropdown.addEventListener('auroDropdown-toggled', () => {
|
|
7641
|
-
// Tell the bib's keyboard bridge to allow native Tab so focus
|
|
7642
|
-
// moves between the real focusable counter elements in the bib.
|
|
7643
|
-
if (this.dropdown.bibContent) {
|
|
7644
|
-
this.dropdown.bibContent.nativeFocusableContent = true;
|
|
7645
|
-
}
|
|
7646
7644
|
if (this.dropdown.isPopoverVisible && this.dropdown.isBibFullscreen) {
|
|
7647
7645
|
doubleRaf(() => {
|
|
7648
7646
|
this.bibtemplate.focusCloseButton();
|
|
@@ -7839,7 +7837,6 @@ class AuroCounterGroup extends AuroElement {
|
|
|
7839
7837
|
renderCounterDropdown() {
|
|
7840
7838
|
return html`
|
|
7841
7839
|
<${this.dropdownTag}
|
|
7842
|
-
noHideOnThisFocusLoss
|
|
7843
7840
|
chevron
|
|
7844
7841
|
part="dropdown"
|
|
7845
7842
|
appearance="${this.onDark ? 'inverse' : this.appearance}"
|