@aurodesignsystem-dev/auro-formkit 0.0.0-pr1492.4 → 0.0.0-pr1493.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.
- package/components/bibtemplate/dist/auro-bibtemplate.d.ts +7 -0
- package/components/bibtemplate/dist/index.js +9 -1
- package/components/bibtemplate/dist/registered.js +9 -1
- package/components/checkbox/demo/css-only.html +57 -0
- package/components/checkbox/demo/css-only.md +146 -0
- package/components/checkbox/demo/customize.min.js +2 -2
- package/components/checkbox/demo/getting-started.min.js +2 -2
- package/components/checkbox/demo/index.min.js +2 -2
- package/components/checkbox/demo/pages.json +1 -1
- package/components/checkbox/demo/styles.min.css +1 -1
- package/components/checkbox/demo/why-checkbox.html +57 -0
- package/components/checkbox/demo/why-checkbox.md +86 -0
- package/components/checkbox/dist/index.js +2 -2
- package/components/checkbox/dist/registered.js +2 -2
- package/components/combobox/demo/css-only.html +57 -0
- package/components/combobox/demo/css-only.md +209 -0
- package/components/combobox/demo/customize.md +7 -3
- package/components/combobox/demo/customize.min.js +1846 -1804
- package/components/combobox/demo/getting-started.min.js +1846 -1804
- package/components/combobox/demo/index.min.js +1846 -1804
- package/components/combobox/demo/pages.json +1 -1
- package/components/combobox/demo/styles.min.css +1 -1
- package/components/combobox/demo/why-combobox.html +57 -0
- package/components/combobox/demo/why-combobox.md +113 -0
- package/components/combobox/dist/auro-combobox.d.ts +5 -0
- package/components/combobox/dist/index.js +796 -179
- package/components/combobox/dist/registered.js +796 -179
- package/components/counter/demo/css-only.html +57 -0
- package/components/counter/demo/css-only.md +184 -0
- package/components/counter/demo/customize.min.js +276 -16
- package/components/counter/demo/index.min.js +276 -16
- package/components/counter/demo/keyboard-behavior.md +1 -0
- package/components/counter/demo/pages.json +1 -1
- package/components/counter/demo/styles.min.css +1 -1
- package/components/counter/demo/why-counter.html +57 -0
- package/components/counter/demo/why-counter.md +108 -0
- package/components/counter/dist/index.js +5457 -193
- package/components/counter/dist/registered.js +5457 -193
- package/components/datepicker/demo/accessibility.md +54 -3
- package/components/datepicker/demo/api.md +65 -55
- package/components/datepicker/demo/css-only.html +57 -0
- package/components/datepicker/demo/css-only.md +151 -0
- package/components/datepicker/demo/customize.html +2 -0
- package/components/datepicker/demo/customize.js +19 -0
- package/components/datepicker/demo/customize.md +474 -298
- package/components/datepicker/demo/customize.min.js +36243 -0
- package/components/datepicker/demo/design.md +5 -3
- package/components/datepicker/demo/getting-started.md +6 -6
- package/components/datepicker/demo/index.js +5 -1
- package/components/datepicker/demo/index.md +113 -16
- package/components/datepicker/demo/index.min.js +2736 -398
- package/components/datepicker/demo/keyboard-behavior.md +201 -2
- package/components/datepicker/demo/pages.json +1 -1
- package/components/datepicker/demo/styles.min.css +1 -1
- package/components/datepicker/demo/voiceover.md +21 -12
- package/components/datepicker/demo/why-datepicker.html +57 -0
- package/components/datepicker/demo/why-datepicker.md +133 -0
- package/components/datepicker/dist/index.js +2650 -399
- package/components/datepicker/dist/registered.js +2650 -399
- package/components/datepicker/dist/src/auro-calendar-cell.d.ts +116 -14
- package/components/datepicker/dist/src/auro-calendar-month.d.ts +54 -1
- package/components/datepicker/dist/src/auro-calendar.d.ts +264 -0
- package/components/datepicker/dist/src/auro-datepicker.d.ts +189 -53
- package/components/datepicker/dist/src/datepickerKeyboardStrategy.d.ts +5 -3
- package/components/datepicker/dist/src/utilities.d.ts +0 -14
- package/components/dropdown/demo/accessibility.md +11 -0
- package/components/dropdown/demo/api.md +1 -0
- package/components/dropdown/demo/css-only.html +57 -0
- package/components/dropdown/demo/css-only.md +219 -0
- package/components/dropdown/demo/customize.md +3 -0
- package/components/dropdown/demo/customize.min.js +265 -13
- package/components/dropdown/demo/getting-started.min.js +265 -13
- package/components/dropdown/demo/index.min.js +265 -13
- package/components/dropdown/demo/keyboard-behavior.md +1 -0
- package/components/dropdown/demo/pages.json +1 -1
- package/components/dropdown/demo/styles.min.css +1 -1
- package/components/dropdown/demo/why-dropdown.html +57 -0
- package/components/dropdown/demo/why-dropdown.md +97 -0
- package/components/dropdown/dist/auro-dropdown.d.ts +36 -1
- package/components/dropdown/dist/index.js +265 -13
- package/components/dropdown/dist/registered.js +265 -13
- package/components/form/demo/css-only.html +57 -0
- package/components/form/demo/css-only.md +156 -0
- package/components/form/demo/customize.min.js +11085 -8074
- package/components/form/demo/getting-started.min.js +11085 -8074
- package/components/form/demo/index.min.js +11085 -8074
- package/components/form/demo/pages.json +1 -1
- package/components/form/demo/registerDemoDeps.min.js +11084 -8073
- package/components/form/demo/styles.min.css +1 -1
- package/components/form/demo/why-form.html +57 -0
- package/components/form/demo/why-form.md +101 -0
- package/components/input/demo/css-only.html +57 -0
- package/components/input/demo/css-only.md +199 -0
- package/components/input/demo/customize.md +625 -636
- package/components/input/demo/customize.min.js +150 -75
- package/components/input/demo/getting-started.md +16 -6
- package/components/input/demo/getting-started.min.js +150 -75
- package/components/input/demo/index.min.js +150 -75
- package/components/input/demo/pages.json +1 -1
- package/components/input/demo/styles.min.css +1 -1
- package/components/input/demo/why-input.html +57 -0
- package/components/input/demo/why-input.md +121 -0
- package/components/input/dist/auro-input-util.d.ts +1 -1
- package/components/input/dist/base-input.d.ts +16 -0
- package/components/input/dist/index.js +150 -75
- package/components/input/dist/registered.js +150 -75
- package/components/input/dist/utilities.d.ts +1 -2
- package/components/menu/demo/api.md +41 -45
- package/components/menu/demo/css-only.html +57 -0
- package/components/menu/demo/css-only.md +166 -0
- package/components/menu/demo/customize.md +0 -28
- package/components/menu/demo/index.min.js +779 -1354
- package/components/menu/demo/pages.json +1 -1
- package/components/menu/demo/styles.min.css +1 -1
- package/components/menu/demo/why-menu.html +57 -0
- package/components/menu/demo/why-menu.md +104 -0
- package/components/menu/dist/auro-menu.d.ts +95 -110
- package/components/menu/dist/auro-menuoption.d.ts +32 -138
- package/components/menu/dist/index.js +753 -1308
- package/components/menu/dist/registered.js +765 -1308
- package/components/radio/demo/css-only.html +57 -0
- package/components/radio/demo/css-only.md +151 -0
- package/components/radio/demo/customize.min.js +1764 -0
- package/components/radio/demo/demo-support.min.js +55807 -0
- package/components/radio/demo/getting-started.js +1 -1
- package/components/radio/demo/getting-started.md +1 -1
- package/components/radio/demo/getting-started.min.js +1783 -0
- package/components/radio/demo/index.min.js +2 -2
- package/components/radio/demo/pages.json +1 -1
- package/components/radio/demo/styles.min.css +1 -1
- package/components/radio/demo/why-radio.html +57 -0
- package/components/radio/demo/why-radio.md +92 -0
- package/components/radio/dist/index.js +2 -2
- package/components/radio/dist/registered.js +2 -2
- package/components/select/demo/api.md +1 -0
- package/components/select/demo/css-only.html +57 -0
- package/components/select/demo/css-only.md +203 -0
- package/components/select/demo/customize.md +78 -3
- package/components/select/demo/customize.min.js +1341 -1533
- package/components/select/demo/getting-started.min.js +1341 -1533
- package/components/select/demo/index.min.js +1341 -1533
- package/components/select/demo/keyboard-behavior.md +19 -0
- package/components/select/demo/pages.json +1 -1
- package/components/select/demo/styles.min.css +1 -1
- package/components/select/demo/why-select.html +57 -0
- package/components/select/demo/why-select.md +128 -0
- package/components/select/dist/auro-select.d.ts +38 -2
- package/components/select/dist/index.js +435 -52
- package/components/select/dist/registered.js +435 -52
- package/components/select/dist/selectUtils.d.ts +12 -0
- package/custom-elements.json +3051 -2553
- package/package.json +8 -8
- package/components/menu/dist/auro-menu.context.d.ts +0 -238
|
@@ -623,7 +623,7 @@ class AuroFormValidation {
|
|
|
623
623
|
} else if (this.runtimeUtils.elementMatch(elem, 'auro-input') && elem.errorMessage === '') {
|
|
624
624
|
const input = elem.renderRoot.querySelector('input');
|
|
625
625
|
|
|
626
|
-
if (input.validationMessage.length > 0) {
|
|
626
|
+
if (input && input.validationMessage.length > 0) {
|
|
627
627
|
elem.errorMessage = input.validationMessage;
|
|
628
628
|
}
|
|
629
629
|
} else if (this.runtimeUtils.elementMatch(elem, 'auro-combobox') && elem.errorMessage === '') {
|
|
@@ -835,6 +835,21 @@ function navigateArrow(component, direction, options = {}) {
|
|
|
835
835
|
}
|
|
836
836
|
}
|
|
837
837
|
|
|
838
|
+
/**
|
|
839
|
+
* Returns the enabled (non-disabled) options for a menu, safely.
|
|
840
|
+
*
|
|
841
|
+
* Auro-menu's `options` getter returns `undefined` when the menu has no items
|
|
842
|
+
* (initItems sets `items` to undefined for empty menus). Callers that reach for
|
|
843
|
+
* `.find()` / `[...spread]` would otherwise crash; this helper normalizes the
|
|
844
|
+
* empty case to `[]` so array methods are always safe.
|
|
845
|
+
*
|
|
846
|
+
* @param {HTMLElement | null | undefined} menu - The auro-menu element.
|
|
847
|
+
* @returns {Array<HTMLElement>} Non-disabled options, empty array when none.
|
|
848
|
+
*/
|
|
849
|
+
function getEnabledOptions(menu) {
|
|
850
|
+
return (menu?.options || []).filter((option) => !option.disabled);
|
|
851
|
+
}
|
|
852
|
+
|
|
838
853
|
/* eslint-disable new-cap */
|
|
839
854
|
|
|
840
855
|
const selectKeyboardStrategy = {
|
|
@@ -867,6 +882,14 @@ const selectKeyboardStrategy = {
|
|
|
867
882
|
},
|
|
868
883
|
|
|
869
884
|
Escape(component, evt, ctx) {
|
|
885
|
+
// Always clear the type-ahead buffer — Escape is a universal cancel.
|
|
886
|
+
// Safe to call when the buffer is empty.
|
|
887
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
888
|
+
if (typeof component._clearTypeaheadBuffer === 'function') {
|
|
889
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
890
|
+
component._clearTypeaheadBuffer();
|
|
891
|
+
}
|
|
892
|
+
|
|
870
893
|
if (!ctx.isExpanded) {
|
|
871
894
|
return;
|
|
872
895
|
}
|
|
@@ -883,7 +906,8 @@ const selectKeyboardStrategy = {
|
|
|
883
906
|
}
|
|
884
907
|
evt.preventDefault();
|
|
885
908
|
evt.stopPropagation();
|
|
886
|
-
|
|
909
|
+
// `pop()` is safe here: getEnabledOptions returns a fresh filtered array.
|
|
910
|
+
const lastOption = getEnabledOptions(component.menu).pop();
|
|
887
911
|
if (lastOption) {
|
|
888
912
|
component.menu.updateActiveOption(lastOption);
|
|
889
913
|
}
|
|
@@ -905,7 +929,7 @@ const selectKeyboardStrategy = {
|
|
|
905
929
|
}
|
|
906
930
|
evt.preventDefault();
|
|
907
931
|
evt.stopPropagation();
|
|
908
|
-
const firstOption = component.menu
|
|
932
|
+
const [firstOption] = getEnabledOptions(component.menu);
|
|
909
933
|
if (firstOption) {
|
|
910
934
|
component.menu.updateActiveOption(firstOption);
|
|
911
935
|
}
|
|
@@ -925,16 +949,25 @@ const selectKeyboardStrategy = {
|
|
|
925
949
|
},
|
|
926
950
|
|
|
927
951
|
default(component, evt, ctx) {
|
|
928
|
-
|
|
952
|
+
// Space resolves to either typeahead-buffer extension or bib toggle
|
|
953
|
+
// depending on whether a type-ahead buffer is active. Mirrors native
|
|
954
|
+
// <select> and the WAI-ARIA APG Listbox guidance: mid-typeahead space
|
|
955
|
+
// is a search character (e.g. "San Francisco"); otherwise it toggles.
|
|
929
956
|
if (evt.key === ' ') {
|
|
930
957
|
evt.preventDefault();
|
|
931
958
|
evt.stopPropagation();
|
|
959
|
+
if (component.typeaheadBuffer && component.typeaheadBuffer.length > 0) {
|
|
960
|
+
component.updateActiveOptionBasedOnKey(evt.key);
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
932
963
|
if (ctx.isExpanded) {
|
|
933
964
|
component.dropdown.hide();
|
|
934
|
-
|
|
965
|
+
} else {
|
|
966
|
+
component.dropdown.show();
|
|
935
967
|
}
|
|
936
|
-
|
|
968
|
+
return;
|
|
937
969
|
}
|
|
970
|
+
component.updateActiveOptionBasedOnKey(evt.key);
|
|
938
971
|
},
|
|
939
972
|
};
|
|
940
973
|
|
|
@@ -4215,7 +4248,7 @@ function applyKeyboardStrategy(component, strategy, options = {}) {
|
|
|
4215
4248
|
});
|
|
4216
4249
|
}
|
|
4217
4250
|
|
|
4218
|
-
var styleCss$2$1 = 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}`;
|
|
4251
|
+
var styleCss$2$1 = 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([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}`;
|
|
4219
4252
|
|
|
4220
4253
|
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)}`;
|
|
4221
4254
|
|
|
@@ -4846,7 +4879,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
|
|
|
4846
4879
|
}
|
|
4847
4880
|
};
|
|
4848
4881
|
|
|
4849
|
-
var formkitVersion$1 = '
|
|
4882
|
+
var formkitVersion$1 = '202606181613';
|
|
4850
4883
|
|
|
4851
4884
|
class AuroElement extends LitElement {
|
|
4852
4885
|
static get properties() {
|
|
@@ -5026,6 +5059,7 @@ class AuroDropdown extends AuroElement {
|
|
|
5026
5059
|
_intializeDefaults() {
|
|
5027
5060
|
this.appearance = 'default';
|
|
5028
5061
|
this.chevron = false;
|
|
5062
|
+
this.desktopModal = false;
|
|
5029
5063
|
this.disabled = false;
|
|
5030
5064
|
this.disableKeyboardHandling = false;
|
|
5031
5065
|
this.error = false;
|
|
@@ -5206,6 +5240,14 @@ class AuroDropdown extends AuroElement {
|
|
|
5206
5240
|
reflect: true
|
|
5207
5241
|
},
|
|
5208
5242
|
|
|
5243
|
+
/**
|
|
5244
|
+
* If declared, the dropdown will behave as a modal dialog when in a desktop viewport size.
|
|
5245
|
+
*/
|
|
5246
|
+
desktopModal: {
|
|
5247
|
+
type: Boolean,
|
|
5248
|
+
reflect: true
|
|
5249
|
+
},
|
|
5250
|
+
|
|
5209
5251
|
/**
|
|
5210
5252
|
* If declared, the dropdown will only show by calling the API .show() public method.
|
|
5211
5253
|
*/
|
|
@@ -5493,6 +5535,15 @@ class AuroDropdown extends AuroElement {
|
|
|
5493
5535
|
|
|
5494
5536
|
disconnectedCallback() {
|
|
5495
5537
|
super.disconnectedCallback();
|
|
5538
|
+
this._clearPageInert();
|
|
5539
|
+
if (this._bibTabHandler) {
|
|
5540
|
+
this.removeEventListener('keydown', this._bibTabHandler);
|
|
5541
|
+
this._bibTabHandler = undefined;
|
|
5542
|
+
}
|
|
5543
|
+
if (this.focusTrap) {
|
|
5544
|
+
this.focusTrap.disconnect();
|
|
5545
|
+
this.focusTrap = undefined;
|
|
5546
|
+
}
|
|
5496
5547
|
if (this.floater) {
|
|
5497
5548
|
this.floater.hideBib('disconnect');
|
|
5498
5549
|
this.floater.disconnect();
|
|
@@ -5520,19 +5571,45 @@ class AuroDropdown extends AuroElement {
|
|
|
5520
5571
|
if (this.isPopoverVisible) {
|
|
5521
5572
|
// Fullscreen: use showModal() for native accessibility (inert outside, focus trap)
|
|
5522
5573
|
// Desktop: use show() for Floating UI positioning + FocusTrap for focus management
|
|
5523
|
-
|
|
5524
|
-
this.
|
|
5574
|
+
this.bibElement.value.open(this.isBibFullscreen);
|
|
5575
|
+
this.updateFocusTrap();
|
|
5576
|
+
|
|
5577
|
+
// Desktop modal: make siblings inert so content outside is not interactive
|
|
5578
|
+
if (this.desktopModal && !this.isBibFullscreen) {
|
|
5579
|
+
this._setPageInert();
|
|
5580
|
+
}
|
|
5525
5581
|
} else {
|
|
5526
5582
|
this.bibElement.value.close();
|
|
5583
|
+
this._clearPageInert();
|
|
5527
5584
|
}
|
|
5528
5585
|
}
|
|
5529
5586
|
|
|
5530
5587
|
// When fullscreen strategy changes while open, re-open dialog with correct mode
|
|
5531
5588
|
// (e.g. resizing from desktop → mobile while dropdown is open)
|
|
5532
5589
|
if (changedProperties.has('isBibFullscreen') && this.isPopoverVisible && this.bibElement.value) {
|
|
5533
|
-
const useModal = this.isBibFullscreen;
|
|
5534
5590
|
this.bibElement.value.close();
|
|
5535
|
-
this.bibElement.value.open(
|
|
5591
|
+
this.bibElement.value.open(this.isBibFullscreen);
|
|
5592
|
+
|
|
5593
|
+
// Re-initialize focus management for the new strategy
|
|
5594
|
+
this.updateFocusTrap();
|
|
5595
|
+
|
|
5596
|
+
// Toggle inert: desktop modal needs it, fullscreen showModal() handles it natively
|
|
5597
|
+
if (this.desktopModal && !this.isBibFullscreen) {
|
|
5598
|
+
this._setPageInert();
|
|
5599
|
+
} else {
|
|
5600
|
+
this._clearPageInert();
|
|
5601
|
+
}
|
|
5602
|
+
}
|
|
5603
|
+
|
|
5604
|
+
// Handle desktopModal toggled while the dropdown is already open.
|
|
5605
|
+
// Re-initialize focus trapping and page inert state to match the new mode.
|
|
5606
|
+
if (changedProperties.has('desktopModal') && this.isPopoverVisible && !this.isBibFullscreen) {
|
|
5607
|
+
this.updateFocusTrap();
|
|
5608
|
+
if (this.desktopModal) {
|
|
5609
|
+
this._setPageInert();
|
|
5610
|
+
} else {
|
|
5611
|
+
this._clearPageInert();
|
|
5612
|
+
}
|
|
5536
5613
|
}
|
|
5537
5614
|
}
|
|
5538
5615
|
|
|
@@ -5542,8 +5619,14 @@ class AuroDropdown extends AuroElement {
|
|
|
5542
5619
|
* @param {CustomEvent} event - The custom event that contains the dropdown toggle information.
|
|
5543
5620
|
*/
|
|
5544
5621
|
handleDropdownToggle(event) {
|
|
5545
|
-
this.updateFocusTrap();
|
|
5546
5622
|
this.isPopoverVisible = event.detail.expanded;
|
|
5623
|
+
|
|
5624
|
+
// Tear down FocusTrap when closing. Creation happens in updated()
|
|
5625
|
+
// after the dialog is open so getFocusableElements can find content.
|
|
5626
|
+
if (!this.isPopoverVisible) {
|
|
5627
|
+
this.updateFocusTrap();
|
|
5628
|
+
}
|
|
5629
|
+
|
|
5547
5630
|
const eventType = event.detail.eventType || "unknown";
|
|
5548
5631
|
if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
|
|
5549
5632
|
this.trigger.focus();
|
|
@@ -5642,19 +5725,220 @@ class AuroDropdown extends AuroElement {
|
|
|
5642
5725
|
* @private
|
|
5643
5726
|
*/
|
|
5644
5727
|
updateFocusTrap() {
|
|
5728
|
+
// Always clean up existing handlers/traps before setting up new ones
|
|
5729
|
+
// to prevent duplicate listeners on repeated calls.
|
|
5730
|
+
if (this._bibTabHandler) {
|
|
5731
|
+
this.removeEventListener('keydown', this._bibTabHandler);
|
|
5732
|
+
this._bibTabHandler = undefined;
|
|
5733
|
+
}
|
|
5734
|
+
|
|
5735
|
+
if (this.focusTrap) {
|
|
5736
|
+
this.focusTrap.disconnect();
|
|
5737
|
+
this.focusTrap = undefined;
|
|
5738
|
+
}
|
|
5739
|
+
|
|
5740
|
+
// Restore the user-set noHideOnThisFocusLoss value, if we overrode it.
|
|
5741
|
+
if (this._noHideOverridden) {
|
|
5742
|
+
this.noHideOnThisFocusLoss = this._priorNoHide;
|
|
5743
|
+
this._noHideOverridden = false;
|
|
5744
|
+
this._priorNoHide = undefined;
|
|
5745
|
+
}
|
|
5746
|
+
|
|
5645
5747
|
if (this.isPopoverVisible) {
|
|
5646
5748
|
if (!this.isBibFullscreen) {
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5749
|
+
if (this.desktopModal) {
|
|
5750
|
+
// The floater's focus-loss check uses :focus-within, which does not
|
|
5751
|
+
// match the host when focus is on a slotted element projected through
|
|
5752
|
+
// multiple shadow roots. Without this override, focusing a button
|
|
5753
|
+
// inside the bib would be misread as focus leaving the dropdown and
|
|
5754
|
+
// close the bib immediately. desktopModal traps focus inside the
|
|
5755
|
+
// bib and inerts siblings, so suppressing focus-loss dismissal here
|
|
5756
|
+
// is safe — Escape and outside-click still close the bib.
|
|
5757
|
+
this._priorNoHide = this.noHideOnThisFocusLoss;
|
|
5758
|
+
this._noHideOverridden = true;
|
|
5759
|
+
this.noHideOnThisFocusLoss = true;
|
|
5760
|
+
|
|
5761
|
+
// Desktop modal: trap focus only within the bib content.
|
|
5762
|
+
// Can't use FocusTrap on the bib element because keydown events
|
|
5763
|
+
// from slotted content bubble through the dropdown host (light DOM),
|
|
5764
|
+
// not through the bib (shadow projection target). Using FocusTrap
|
|
5765
|
+
// on the dropdown would include the trigger in the tab cycle.
|
|
5766
|
+
// Instead, listen for Tab on the dropdown and manually wrap focus
|
|
5767
|
+
// within the bib's focusable elements.
|
|
5768
|
+
this._bibTabHandler = (event) => {
|
|
5769
|
+
if (event.key !== 'Tab') {
|
|
5770
|
+
return;
|
|
5771
|
+
}
|
|
5772
|
+
|
|
5773
|
+
// Collect focusable elements from the bib content.
|
|
5774
|
+
const focusables = getFocusableElements(this.bibContent);
|
|
5775
|
+
|
|
5776
|
+
// Fallback: try from slotted content directly
|
|
5777
|
+
if (!focusables.length) {
|
|
5778
|
+
const slot = this.shadowRoot.querySelector('.slotContent slot');
|
|
5779
|
+
const assignedNodes = slot.assignedNodes({ flatten: true });
|
|
5780
|
+
|
|
5781
|
+
for (const node of assignedNodes) {
|
|
5782
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
5783
|
+
focusables.push(...getFocusableElements(node));
|
|
5784
|
+
}
|
|
5785
|
+
}
|
|
5786
|
+
}
|
|
5787
|
+
|
|
5788
|
+
if (!focusables.length) {
|
|
5789
|
+
return;
|
|
5790
|
+
}
|
|
5791
|
+
|
|
5792
|
+
event.preventDefault();
|
|
5793
|
+
|
|
5794
|
+
const direction = event.shiftKey ? -1 : 1; // eslint-disable-line no-magic-numbers
|
|
5795
|
+
|
|
5796
|
+
// Walk the active element chain through shadow roots
|
|
5797
|
+
const actives = this._getActiveElements();
|
|
5798
|
+
|
|
5799
|
+
let idx = focusables.findIndex((el) => actives.includes(el));
|
|
5800
|
+
|
|
5801
|
+
if (idx === -1) { // eslint-disable-line no-magic-numbers
|
|
5802
|
+
// Focus is not on a known element — move to first/last
|
|
5803
|
+
idx = direction === 1 ? -1 : focusables.length; // eslint-disable-line no-magic-numbers
|
|
5804
|
+
}
|
|
5805
|
+
|
|
5806
|
+
// Try each element in order, skipping any that can't receive focus
|
|
5807
|
+
// (e.g. hidden elements, elements in collapsed sections)
|
|
5808
|
+
for (let index = 0; index < focusables.length; index++) { // eslint-disable-line no-plusplus
|
|
5809
|
+
let nextIdx = idx + direction;
|
|
5810
|
+
|
|
5811
|
+
// Wrap around
|
|
5812
|
+
if (nextIdx < 0) {
|
|
5813
|
+
nextIdx = focusables.length - 1;
|
|
5814
|
+
} else if (nextIdx >= focusables.length) {
|
|
5815
|
+
nextIdx = 0;
|
|
5816
|
+
}
|
|
5817
|
+
|
|
5818
|
+
focusables[nextIdx].focus();
|
|
5819
|
+
|
|
5820
|
+
// Verify focus actually moved to the target
|
|
5821
|
+
const newActives = this._getActiveElements();
|
|
5822
|
+
|
|
5823
|
+
if (newActives.includes(focusables[nextIdx])) {
|
|
5824
|
+
return;
|
|
5825
|
+
}
|
|
5826
|
+
|
|
5827
|
+
// Focus didn't stick — skip this element and try the next
|
|
5828
|
+
idx = nextIdx;
|
|
5829
|
+
}
|
|
5830
|
+
};
|
|
5831
|
+
this.addEventListener('keydown', this._bibTabHandler);
|
|
5832
|
+
|
|
5833
|
+
// Move initial focus into the bib content, matching FocusTrap behavior
|
|
5834
|
+
requestAnimationFrame(() => {
|
|
5835
|
+
const focusables = getFocusableElements(this.bibContent);
|
|
5836
|
+
if (focusables.length) {
|
|
5837
|
+
focusables[0].focus();
|
|
5838
|
+
}
|
|
5839
|
+
});
|
|
5840
|
+
} else {
|
|
5841
|
+
// Normal desktop: use FocusTrap on the bib element.
|
|
5842
|
+
// Defer focusFirstElement to the next frame because the popover
|
|
5843
|
+
// is positioned asynchronously by Floating UI — calling focus()
|
|
5844
|
+
// synchronously here would target elements with zero dimensions
|
|
5845
|
+
// and the focus call would be silently ignored.
|
|
5846
|
+
this.focusTrap = new FocusTrap(this.bibContent);
|
|
5847
|
+
requestAnimationFrame(() => {
|
|
5848
|
+
if (this.focusTrap) {
|
|
5849
|
+
this.focusTrap.focusFirstElement();
|
|
5850
|
+
}
|
|
5851
|
+
});
|
|
5852
|
+
}
|
|
5650
5853
|
}
|
|
5651
5854
|
// Fullscreen: showModal() provides native focus trapping
|
|
5855
|
+
}
|
|
5856
|
+
}
|
|
5857
|
+
|
|
5858
|
+
/**
|
|
5859
|
+
* Returns the chain of active (focused) elements through shadow roots.
|
|
5860
|
+
* @private
|
|
5861
|
+
* @returns {Array<HTMLElement>}
|
|
5862
|
+
*/
|
|
5863
|
+
_getActiveElements() {
|
|
5864
|
+
let { activeElement } = document;
|
|
5865
|
+
const actives = [activeElement];
|
|
5866
|
+
|
|
5867
|
+
while (activeElement?.shadowRoot?.activeElement) {
|
|
5868
|
+
activeElement = activeElement.shadowRoot.activeElement;
|
|
5869
|
+
actives.push(activeElement);
|
|
5870
|
+
}
|
|
5871
|
+
|
|
5872
|
+
return actives;
|
|
5873
|
+
}
|
|
5874
|
+
|
|
5875
|
+
/**
|
|
5876
|
+
* Sets `inert` on sibling elements of the dropdown's top-level host
|
|
5877
|
+
* so that content outside the dropdown is not interactive while the modal is open.
|
|
5878
|
+
* Walks up through shadow DOM boundaries to find the outermost host element
|
|
5879
|
+
* in the light DOM, then sets `inert` on siblings at each ancestor level
|
|
5880
|
+
* to ensure all page content outside the host subtree is inert.
|
|
5881
|
+
* @private
|
|
5882
|
+
*/
|
|
5883
|
+
_setPageInert() {
|
|
5884
|
+
if (this._inertSiblings) {
|
|
5652
5885
|
return;
|
|
5653
5886
|
}
|
|
5654
5887
|
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5888
|
+
this._inertSiblings = [];
|
|
5889
|
+
|
|
5890
|
+
// Walk up through shadow DOM boundaries to find the topmost host
|
|
5891
|
+
// element in the light DOM. For example, if this dropdown is inside
|
|
5892
|
+
// auro-datepicker's shadow DOM, we walk up to the datepicker element
|
|
5893
|
+
// so we set inert on its siblings — not on the datepicker itself.
|
|
5894
|
+
let host = this;
|
|
5895
|
+
while (host.getRootNode() instanceof ShadowRoot) {
|
|
5896
|
+
host = host.getRootNode().host;
|
|
5897
|
+
}
|
|
5898
|
+
|
|
5899
|
+
// Walk up the ancestor chain, inerting siblings at each level
|
|
5900
|
+
// to ensure the entire page outside the host subtree is inert.
|
|
5901
|
+
// Uses a reference counter (data-auro-inert-count) so multiple
|
|
5902
|
+
// simultaneous modal dropdowns share inert state safely.
|
|
5903
|
+
let current = host;
|
|
5904
|
+
while (current.parentElement) {
|
|
5905
|
+
const parent = current.parentElement;
|
|
5906
|
+
for (const sibling of parent.children) {
|
|
5907
|
+
if (sibling !== current) {
|
|
5908
|
+
const count = parseInt(sibling.dataset.auroInertCount || '0', 10);
|
|
5909
|
+
if (count === 0) {
|
|
5910
|
+
sibling.dataset.auroInertWas = sibling.inert ? 'true' : 'false';
|
|
5911
|
+
}
|
|
5912
|
+
sibling.dataset.auroInertCount = String(count + 1);
|
|
5913
|
+
sibling.inert = true;
|
|
5914
|
+
this._inertSiblings.push(sibling);
|
|
5915
|
+
}
|
|
5916
|
+
}
|
|
5917
|
+
current = parent;
|
|
5918
|
+
}
|
|
5919
|
+
}
|
|
5920
|
+
|
|
5921
|
+
/**
|
|
5922
|
+
* Restores `inert` state on siblings that were tracked by `_setPageInert`.
|
|
5923
|
+
* Uses reference counting so inert is only cleared when the last modal
|
|
5924
|
+
* dropdown releases a given element. Preserves the original inert state
|
|
5925
|
+
* so externally-inerted elements are not inadvertently re-enabled.
|
|
5926
|
+
* @private
|
|
5927
|
+
*/
|
|
5928
|
+
_clearPageInert() {
|
|
5929
|
+
if (this._inertSiblings) {
|
|
5930
|
+
for (const sibling of this._inertSiblings) {
|
|
5931
|
+
const count = parseInt(sibling.dataset.auroInertCount || '1', 10) - 1;
|
|
5932
|
+
if (count <= 0) {
|
|
5933
|
+
const wasInert = sibling.dataset.auroInertWas === 'true';
|
|
5934
|
+
delete sibling.dataset.auroInertCount;
|
|
5935
|
+
delete sibling.dataset.auroInertWas;
|
|
5936
|
+
sibling.inert = wasInert;
|
|
5937
|
+
} else {
|
|
5938
|
+
sibling.dataset.auroInertCount = String(count);
|
|
5939
|
+
}
|
|
5940
|
+
}
|
|
5941
|
+
this._inertSiblings = undefined;
|
|
5658
5942
|
}
|
|
5659
5943
|
}
|
|
5660
5944
|
|
|
@@ -5893,6 +6177,7 @@ class AuroDropdown extends AuroElement {
|
|
|
5893
6177
|
shape="${this.shape}"
|
|
5894
6178
|
?data-show="${this.isPopoverVisible}"
|
|
5895
6179
|
?isfullscreen="${this.isBibFullscreen}"
|
|
6180
|
+
?desktopmodal="${this.desktopModal}"
|
|
5896
6181
|
.dialogLabel="${this.bibDialogLabel}"
|
|
5897
6182
|
${ref(this.bibElement)}
|
|
5898
6183
|
>
|
|
@@ -6260,6 +6545,14 @@ class AuroBibtemplate extends LitElement {
|
|
|
6260
6545
|
large: {
|
|
6261
6546
|
type: Boolean,
|
|
6262
6547
|
reflect: true
|
|
6548
|
+
},
|
|
6549
|
+
|
|
6550
|
+
/**
|
|
6551
|
+
* If declared, the footer slot will be rendered even when not in fullscreen mode.
|
|
6552
|
+
*/
|
|
6553
|
+
showFooter: {
|
|
6554
|
+
type: Boolean,
|
|
6555
|
+
reflect: true
|
|
6263
6556
|
}
|
|
6264
6557
|
};
|
|
6265
6558
|
}
|
|
@@ -6362,7 +6655,7 @@ class AuroBibtemplate extends LitElement {
|
|
|
6362
6655
|
<slot></slot>
|
|
6363
6656
|
</div>
|
|
6364
6657
|
|
|
6365
|
-
${this.isFullscreen ? html`
|
|
6658
|
+
${this.isFullscreen || this.showFooter ? html`
|
|
6366
6659
|
<div id="footerContainer">
|
|
6367
6660
|
<slot name="footer"></slot>
|
|
6368
6661
|
</div>` : null}
|
|
@@ -6599,7 +6892,7 @@ class AuroHelpText extends LitElement {
|
|
|
6599
6892
|
}
|
|
6600
6893
|
}
|
|
6601
6894
|
|
|
6602
|
-
var formkitVersion = '
|
|
6895
|
+
var formkitVersion = '202606181613';
|
|
6603
6896
|
|
|
6604
6897
|
var styleCss = css`.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}.body-default{font-size:var(--wcss-body-default-font-size, 1rem);font-weight:var(--wcss-body-default-weight, );line-height:var(--wcss-body-default-line-height, 1.5rem)}.body-default,.body-default-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-default-emphasized{font-size:var(--wcss-body-default-emphasized-font-size, 1rem);font-weight:var(--wcss-body-default-emphasized-weight, );line-height:var(--wcss-body-default-emphasized-line-height, 1.5rem)}.body-lg{font-size:var(--wcss-body-lg-font-size, 1.125rem);font-weight:var(--wcss-body-lg-weight, );line-height:var(--wcss-body-lg-line-height, 1.625rem)}.body-lg,.body-lg-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-lg-emphasized{font-size:var(--wcss-body-lg-emphasized-font-size, 1.125rem);font-weight:var(--wcss-body-lg-emphasized-weight, );line-height:var(--wcss-body-lg-emphasized-line-height, 1.625rem)}.body-sm{font-size:var(--wcss-body-sm-font-size, 0.875rem);font-weight:var(--wcss-body-sm-weight, );line-height:var(--wcss-body-sm-line-height, 1.25rem)}.body-sm,.body-sm-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-sm-emphasized{font-size:var(--wcss-body-sm-emphasized-font-size, 0.875rem);font-weight:var(--wcss-body-sm-emphasized-weight, );line-height:var(--wcss-body-sm-emphasized-line-height, 1.25rem)}.body-xs{font-size:var(--wcss-body-xs-font-size, 0.75rem);font-weight:var(--wcss-body-xs-weight, );line-height:var(--wcss-body-xs-line-height, 1rem)}.body-xs,.body-xs-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-xs-emphasized{font-size:var(--wcss-body-xs-emphasized-font-size, 0.75rem);font-weight:var(--wcss-body-xs-emphasized-weight, );line-height:var(--wcss-body-xs-emphasized-line-height, 1rem)}.body-2xs{font-size:var(--wcss-body-2xs-font-size, 0.625rem);font-weight:var(--wcss-body-2xs-weight, );line-height:var(--wcss-body-2xs-line-height, 0.875rem)}.body-2xs,.body-2xs-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-2xs-emphasized{font-size:var(--wcss-body-2xs-emphasized-font-size, 0.625rem);font-weight:var(--wcss-body-2xs-emphasized-weight, );line-height:var(--wcss-body-2xs-emphasized-line-height, 0.875rem)}.display-2xl{font-family:var(--wcss-display-2xl-family, "AS Circular"),var(--wcss-display-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-2xl-font-size, clamp(3.5rem, 6vw, 5.375rem));font-weight:var(--wcss-display-2xl-weight, 300);letter-spacing:var(--wcss-display-2xl-letter-spacing, 0);line-height:var(--wcss-display-2xl-line-height, 1.3)}.display-xl{font-family:var(--wcss-display-xl-family, "AS Circular"),var(--wcss-display-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xl-font-size, clamp(3rem, 5.3333333333vw, 4.5rem));font-weight:var(--wcss-display-xl-weight, 300);letter-spacing:var(--wcss-display-xl-letter-spacing, 0);line-height:var(--wcss-display-xl-line-height, 1.3)}.display-lg{font-family:var(--wcss-display-lg-family, "AS Circular"),var(--wcss-display-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-lg-font-size, clamp(2.75rem, 4.6666666667vw, 4rem));font-weight:var(--wcss-display-lg-weight, 300);letter-spacing:var(--wcss-display-lg-letter-spacing, 0);line-height:var(--wcss-display-lg-line-height, 1.3)}.display-md{font-family:var(--wcss-display-md-family, "AS Circular"),var(--wcss-display-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-md-font-size, clamp(2.5rem, 4vw, 3.5rem));font-weight:var(--wcss-display-md-weight, 300);letter-spacing:var(--wcss-display-md-letter-spacing, 0);line-height:var(--wcss-display-md-line-height, 1.3)}.display-sm{font-family:var(--wcss-display-sm-family, "AS Circular"),var(--wcss-display-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-sm-font-size, clamp(2rem, 3.6666666667vw, 3rem));font-weight:var(--wcss-display-sm-weight, 300);letter-spacing:var(--wcss-display-sm-letter-spacing, 0);line-height:var(--wcss-display-sm-line-height, 1.3)}.display-xs{font-family:var(--wcss-display-xs-family, "AS Circular"),var(--wcss-display-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xs-font-size, clamp(1.75rem, 3vw, 2.375rem));font-weight:var(--wcss-display-xs-weight, 300);letter-spacing:var(--wcss-display-xs-letter-spacing, 0);line-height:var(--wcss-display-xs-line-height, 1.3)}.heading-xl{font-family:var(--wcss-heading-xl-family, "AS Circular"),var(--wcss-heading-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xl-font-size, clamp(2rem, 3vw, 2.5rem));font-weight:var(--wcss-heading-xl-weight, 300);letter-spacing:var(--wcss-heading-xl-letter-spacing, 0);line-height:var(--wcss-heading-xl-line-height, 1.3)}.heading-lg{font-family:var(--wcss-heading-lg-family, "AS Circular"),var(--wcss-heading-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-lg-font-size, clamp(1.75rem, 2.6666666667vw, 2.25rem));font-weight:var(--wcss-heading-lg-weight, 300);letter-spacing:var(--wcss-heading-lg-letter-spacing, 0);line-height:var(--wcss-heading-lg-line-height, 1.3)}.heading-md{font-family:var(--wcss-heading-md-family, "AS Circular"),var(--wcss-heading-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-md-font-size, clamp(1.625rem, 2.3333333333vw, 1.75rem));font-weight:var(--wcss-heading-md-weight, 300);letter-spacing:var(--wcss-heading-md-letter-spacing, 0);line-height:var(--wcss-heading-md-line-height, 1.3)}.heading-sm{font-family:var(--wcss-heading-sm-family, "AS Circular"),var(--wcss-heading-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-sm-font-size, clamp(1.375rem, 2vw, 1.5rem));font-weight:var(--wcss-heading-sm-weight, 300);letter-spacing:var(--wcss-heading-sm-letter-spacing, 0);line-height:var(--wcss-heading-sm-line-height, 1.3)}.heading-xs{font-family:var(--wcss-heading-xs-family, "AS Circular"),var(--wcss-heading-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xs-font-size, clamp(1.25rem, 1.6666666667vw, 1.25rem));font-weight:var(--wcss-heading-xs-weight, 300);letter-spacing:var(--wcss-heading-xs-letter-spacing, 0);line-height:var(--wcss-heading-xs-line-height, 1.3)}.heading-2xs{font-family:var(--wcss-heading-2xs-family, "AS Circular"),var(--wcss-heading-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-2xs-font-size, clamp(1.125rem, 1.5vw, 1.125rem));font-weight:var(--wcss-heading-2xs-weight, 300);letter-spacing:var(--wcss-heading-2xs-letter-spacing, 0);line-height:var(--wcss-heading-2xs-line-height, 1.3)}.accent-2xl{font-family:var(--wcss-accent-2xl-family, "Good OT"),var(--wcss-accent-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xl-font-size, clamp(2rem, 3.1666666667vw, 2.375rem));font-weight:var(--wcss-accent-2xl-weight, 450);letter-spacing:var(--wcss-accent-2xl-letter-spacing, 0.05em);line-height:var(--wcss-accent-2xl-line-height, 1)}.accent-2xl,.accent-xl{text-transform:uppercase}.accent-xl{font-family:var(--wcss-accent-xl-family, "Good OT"),var(--wcss-accent-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xl-font-size, clamp(1.625rem, 2.3333333333vw, 2rem));font-weight:var(--wcss-accent-xl-weight, 450);letter-spacing:var(--wcss-accent-xl-letter-spacing, 0.05em);line-height:var(--wcss-accent-xl-line-height, 1.3)}.accent-lg{font-family:var(--wcss-accent-lg-family, "Good OT"),var(--wcss-accent-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-lg-font-size, clamp(1.5rem, 2.1666666667vw, 1.75rem));font-weight:var(--wcss-accent-lg-weight, 450);letter-spacing:var(--wcss-accent-lg-letter-spacing, 0.05em);line-height:var(--wcss-accent-lg-line-height, 1.3)}.accent-lg,.accent-md{text-transform:uppercase}.accent-md{font-family:var(--wcss-accent-md-family, "Good OT"),var(--wcss-accent-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-md-font-size, clamp(1.375rem, 1.8333333333vw, 1.5rem));font-weight:var(--wcss-accent-md-weight, 500);letter-spacing:var(--wcss-accent-md-letter-spacing, 0.05em);line-height:var(--wcss-accent-md-line-height, 1.3)}.accent-sm{font-family:var(--wcss-accent-sm-family, "Good OT"),var(--wcss-accent-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-sm-font-size, clamp(1.125rem, 1.5vw, 1.25rem));font-weight:var(--wcss-accent-sm-weight, 500);letter-spacing:var(--wcss-accent-sm-letter-spacing, 0.05em);line-height:var(--wcss-accent-sm-line-height, 1.3)}.accent-sm,.accent-xs{text-transform:uppercase}.accent-xs{font-family:var(--wcss-accent-xs-family, "Good OT"),var(--wcss-accent-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xs-font-size, clamp(1rem, 1.3333333333vw, 1rem));font-weight:var(--wcss-accent-xs-weight, 500);letter-spacing:var(--wcss-accent-xs-letter-spacing, 0.1em);line-height:var(--wcss-accent-xs-line-height, 1.3)}.accent-2xs{font-family:var(--wcss-accent-2xs-family, "Good OT"),var(--wcss-accent-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xs-font-size, clamp(0.875rem, 1.1666666667vw, 0.875rem));font-weight:var(--wcss-accent-2xs-weight, 450);letter-spacing:var(--wcss-accent-2xs-letter-spacing, 0.1em);line-height:var(--wcss-accent-2xs-line-height, 1.3);text-transform:uppercase}[auro-dropdown]{--ds-auro-dropdown-trigger-border-color: var(--ds-auro-select-border-color);--ds-auro-dropdown-trigger-background-color: var(--ds-auro-select-background-color);--ds-auro-dropdown-trigger-container-color: var(--ds-auro-select-background-color);--ds-auro-dropdown-trigger-outline-color: var(--ds-auro-select-outline-color)}:host{display:inline-block;text-align:left;vertical-align:top}:host([layout*=emphasized]) [auro-dropdown],:host([layout*=snowflake]) [auro-dropdown]{--ds-auro-select-border-color: transparent}:host([layout*=emphasized]) .mainContent,:host([layout*=snowflake]) .mainContent{text-align:center}.mainContent{position:relative;display:flex;overflow:hidden;flex:1;flex-direction:column;align-items:center;justify-content:center}.valueContainer [slot=displayValue]{display:none}.accents{display:flex;flex-direction:row;align-items:center;justify-content:center}::slotted([slot=typeIcon]){margin-right:var(--ds-size-100, 0.5rem)}.displayValue{display:block}.displayValue:not(.force){display:none}.displayValue:not(.force).hasContent:is(.withValue):not(.hasFocus){display:block}.triggerContent{display:flex;width:100%;align-items:center;justify-content:center}:host([layout*=emphasized]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem) 0 var(--ds-size-300, 1.5rem)}:host([layout*=snowflake]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem) 0 var(--ds-size-200, 1rem)}:host([layout*=snowflake]) label{padding-block:var(--ds-size-25, 0.125rem)}:host([layout*=classic]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem)}:host([layout*=classic]) .mainContent{align-items:start}:host([layout*=classic]) label{overflow:hidden;cursor:text;text-overflow:ellipsis;white-space:nowrap}:host([layout*=classic]) .value{height:auto}label{color:var(--ds-auro-select-label-text-color)}:host(:is([validity]:not([validity=valid]))) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-basic-color-status-error, #e31f26);--ds-auro-select-outline-color: var(--ds-basic-color-status-error, #e31f26);--ds-auro-dropdown-helptext-text-color: var(--ds-basic-color-texticon-default, #2a2a2a)}:host([ondark]:is([validity]:not([validity=valid]))) [auro-dropdown],:host([appearance=inverse]:is([validity]:not([validity=valid]))) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8);--ds-auro-select-outline-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8);--ds-auro-dropdown-helptext-text-color: var(--ds-basic-color-texticon-inverse, #ffffff)}#slotHolder{display:none}:host([fluid]){width:100%}:host([disabled]){pointer-events:none;user-select:none}:host([disabled]:not([ondark])) [auro-dropdown],:host([disabled]:not([appearance=inverse])) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-basic-color-border-subtle, #dddddd)}:host(:not([layout*=classic])[disabled][ondark]) [auro-dropdown],:host(:not([layout*=classic])[disabled][appearance=inverse]) [auro-dropdown]{--ds-auro-select-border-color: transparent}`;
|
|
6605
6898
|
|
|
@@ -6704,6 +6997,16 @@ class AuroSelect extends AuroElement$1 {
|
|
|
6704
6997
|
* @private
|
|
6705
6998
|
*/
|
|
6706
6999
|
this.hasDisplayValueContent = false;
|
|
7000
|
+
|
|
7001
|
+
/**
|
|
7002
|
+
* @private
|
|
7003
|
+
*/
|
|
7004
|
+
this.typeaheadBuffer = '';
|
|
7005
|
+
|
|
7006
|
+
/**
|
|
7007
|
+
* @private
|
|
7008
|
+
*/
|
|
7009
|
+
this._typeaheadTimeout = null;
|
|
6707
7010
|
}
|
|
6708
7011
|
|
|
6709
7012
|
/**
|
|
@@ -6716,6 +7019,7 @@ class AuroSelect extends AuroElement$1 {
|
|
|
6716
7019
|
this.fullscreenBreakpoint = 'sm';
|
|
6717
7020
|
this.onDark = false;
|
|
6718
7021
|
this.isPopoverVisible = false;
|
|
7022
|
+
this.typeaheadTimeoutMs = 500;
|
|
6719
7023
|
|
|
6720
7024
|
// Layout Config
|
|
6721
7025
|
this.layout = 'classic';
|
|
@@ -7019,6 +7323,16 @@ class AuroSelect extends AuroElement$1 {
|
|
|
7019
7323
|
attribute: false
|
|
7020
7324
|
},
|
|
7021
7325
|
|
|
7326
|
+
/**
|
|
7327
|
+
* Milliseconds of keyboard inactivity before the type-ahead buffer resets.
|
|
7328
|
+
* Increase for users who type slowly.
|
|
7329
|
+
* @default 500
|
|
7330
|
+
*/
|
|
7331
|
+
typeaheadTimeoutMs: {
|
|
7332
|
+
type: Number,
|
|
7333
|
+
reflect: true
|
|
7334
|
+
},
|
|
7335
|
+
|
|
7022
7336
|
/**
|
|
7023
7337
|
* Specifies the `validityState` this element is in.
|
|
7024
7338
|
*/
|
|
@@ -7151,7 +7465,7 @@ class AuroSelect extends AuroElement$1 {
|
|
|
7151
7465
|
this.menu.updateActiveOption(this.optionSelected[0]);
|
|
7152
7466
|
} else {
|
|
7153
7467
|
// If no activeOption has yet to be set, then make the first enabled option active by default
|
|
7154
|
-
const firstActive = this.menu
|
|
7468
|
+
const [firstActive] = getEnabledOptions(this.menu);
|
|
7155
7469
|
this.menu.updateActiveOption(firstActive);
|
|
7156
7470
|
}
|
|
7157
7471
|
}
|
|
@@ -7375,12 +7689,23 @@ class AuroSelect extends AuroElement$1 {
|
|
|
7375
7689
|
this.menu.multiSelect = this.multiSelect;
|
|
7376
7690
|
}
|
|
7377
7691
|
|
|
7692
|
+
// Menu's items are populated by initItems() during its firstUpdated/slotchange.
|
|
7693
|
+
// Since the parent select's firstUpdated runs before the child menu's, call initItems()
|
|
7694
|
+
// here so renderNativeSelect can render the native <option> list on first paint.
|
|
7695
|
+
if (typeof this.menu.initItems === 'function') {
|
|
7696
|
+
this.menu.initItems();
|
|
7697
|
+
}
|
|
7378
7698
|
this.options = this.menu.options;
|
|
7379
7699
|
this.updateOptionPositions();
|
|
7380
7700
|
this.menu.addEventListener("auroMenu-loadingChange", (event) => this.handleMenuLoadingChange(event));
|
|
7381
7701
|
|
|
7382
|
-
this.menu.addEventListener("auroMenu-
|
|
7383
|
-
this.
|
|
7702
|
+
this.menu.addEventListener("auroMenu-selectValueFailure", () => {
|
|
7703
|
+
this.value = undefined;
|
|
7704
|
+
this.optionSelected = this.multiSelect ? [] : undefined;
|
|
7705
|
+
// The trigger label is rendered imperatively into #value, so a property
|
|
7706
|
+
// change alone won't clear it. Refresh so stale text doesn't linger when
|
|
7707
|
+
// a runtime value change fails to match any option.
|
|
7708
|
+
this.updateDisplayedValue();
|
|
7384
7709
|
});
|
|
7385
7710
|
|
|
7386
7711
|
this.menu.addEventListener('auroMenu-activatedOption', (evt) => {
|
|
@@ -7402,16 +7727,20 @@ class AuroSelect extends AuroElement$1 {
|
|
|
7402
7727
|
}
|
|
7403
7728
|
});
|
|
7404
7729
|
|
|
7405
|
-
this.menu.addEventListener('auroMenu-selectedOption', (
|
|
7730
|
+
this.menu.addEventListener('auroMenu-selectedOption', () => {
|
|
7406
7731
|
|
|
7407
7732
|
// Update the displayed value
|
|
7408
7733
|
this.updateDisplayedValue();
|
|
7409
7734
|
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
this.value = event.detail.stringValue;
|
|
7735
|
+
this.value = this.menu.value;
|
|
7413
7736
|
|
|
7414
|
-
|
|
7737
|
+
// Clone the multiselect array so external mutation of select.optionSelected
|
|
7738
|
+
// can't reach back into menu's internal state through a shared reference.
|
|
7739
|
+
let nextSelected = this.menu.optionSelected;
|
|
7740
|
+
if (this.multiSelect) {
|
|
7741
|
+
nextSelected = Array.isArray(nextSelected) ? [...nextSelected] : [];
|
|
7742
|
+
}
|
|
7743
|
+
this.optionSelected = nextSelected;
|
|
7415
7744
|
|
|
7416
7745
|
if (this.dropdown.isPopoverVisible && !this.multiSelect) {
|
|
7417
7746
|
this.dropdown.hide();
|
|
@@ -7420,7 +7749,7 @@ class AuroSelect extends AuroElement$1 {
|
|
|
7420
7749
|
|
|
7421
7750
|
// Announce the selection after the dropdown closes so it isn't
|
|
7422
7751
|
// overridden by VoiceOver's "collapsed" announcement from aria-expanded.
|
|
7423
|
-
const selectedValue =
|
|
7752
|
+
const selectedValue = this.menu.currentLabel;
|
|
7424
7753
|
const announcementDelay = 300;
|
|
7425
7754
|
setTimeout(() => {
|
|
7426
7755
|
announceToScreenReader(this._getAnnouncementRoot(), `${selectedValue}, selected`);
|
|
@@ -7443,6 +7772,7 @@ class AuroSelect extends AuroElement$1 {
|
|
|
7443
7772
|
this.addEventListener('blur', () => {
|
|
7444
7773
|
this.validate();
|
|
7445
7774
|
this.hasFocus = false;
|
|
7775
|
+
this._clearTypeaheadBuffer();
|
|
7446
7776
|
});
|
|
7447
7777
|
}
|
|
7448
7778
|
|
|
@@ -7456,41 +7786,89 @@ class AuroSelect extends AuroElement$1 {
|
|
|
7456
7786
|
}
|
|
7457
7787
|
}
|
|
7458
7788
|
|
|
7789
|
+
/**
|
|
7790
|
+
* Returns the lowercase, trimmed text content of a menu option.
|
|
7791
|
+
* @private
|
|
7792
|
+
* @param {HTMLElement} option - The menu option element.
|
|
7793
|
+
* @returns {string}
|
|
7794
|
+
*/
|
|
7795
|
+
_getOptionDisplayText(option) {
|
|
7796
|
+
return (option.textContent || '').trim().toLowerCase();
|
|
7797
|
+
}
|
|
7798
|
+
|
|
7799
|
+
/**
|
|
7800
|
+
* Empties the type-ahead buffer and cancels any pending reset timeout.
|
|
7801
|
+
* Called when focus leaves the component, when Escape closes the bib, and on disconnect
|
|
7802
|
+
* so a stale buffer never bridges into a fresh interaction.
|
|
7803
|
+
* @private
|
|
7804
|
+
*/
|
|
7805
|
+
_clearTypeaheadBuffer() {
|
|
7806
|
+
if (this._typeaheadTimeout) {
|
|
7807
|
+
clearTimeout(this._typeaheadTimeout);
|
|
7808
|
+
this._typeaheadTimeout = null;
|
|
7809
|
+
}
|
|
7810
|
+
this.typeaheadBuffer = '';
|
|
7811
|
+
}
|
|
7812
|
+
|
|
7459
7813
|
/**
|
|
7460
7814
|
* Updates the active option in the menu based on keyboard input.
|
|
7815
|
+
*
|
|
7816
|
+
* Implements the WAI-ARIA APG Listbox type-ahead pattern: accumulates printable
|
|
7817
|
+
* keystrokes into a buffer that resets after `typeaheadTimeoutMs` of inactivity.
|
|
7818
|
+
* A multi-character buffer matches the first option whose displayed text starts
|
|
7819
|
+
* with the buffer; repeating a single character cycles through options that start
|
|
7820
|
+
* with that character.
|
|
7461
7821
|
* @private
|
|
7462
7822
|
* @param {string} _key - The key pressed by the user.
|
|
7463
7823
|
* @returns {void}
|
|
7464
7824
|
*/
|
|
7465
7825
|
updateActiveOptionBasedOnKey(_key) {
|
|
7826
|
+
// Ignore non-printable keys (Shift, ArrowDown, Tab, etc.)
|
|
7827
|
+
if (typeof _key !== 'string' || _key.length !== 1) {
|
|
7828
|
+
return;
|
|
7829
|
+
}
|
|
7466
7830
|
|
|
7467
|
-
//
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
//
|
|
7471
|
-
|
|
7831
|
+
// No selectable options to match against — clear any stale buffer/timer so
|
|
7832
|
+
// Space stays a bib toggle and the next keystroke after fresh options load
|
|
7833
|
+
// starts cleanly. Uses auro-menuoption's `isActive` getter, which excludes
|
|
7834
|
+
// disabled, hidden, and static options (e.g. `static nomatch` placeholders).
|
|
7835
|
+
// Checked BEFORE mutating the buffer.
|
|
7836
|
+
const options = (this.menu && this.menu.options ? this.menu.options : []).filter((option) => option.isActive);
|
|
7837
|
+
if (!options.length) {
|
|
7838
|
+
this._clearTypeaheadBuffer();
|
|
7839
|
+
return;
|
|
7840
|
+
}
|
|
7472
7841
|
|
|
7473
|
-
|
|
7474
|
-
this.lastLetter = key;
|
|
7842
|
+
const key = _key.toLowerCase();
|
|
7475
7843
|
|
|
7476
|
-
//
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
|
|
7480
|
-
|
|
7844
|
+
// Reset the buffer after a period of inactivity
|
|
7845
|
+
if (this._typeaheadTimeout) {
|
|
7846
|
+
clearTimeout(this._typeaheadTimeout);
|
|
7847
|
+
}
|
|
7848
|
+
this._typeaheadTimeout = setTimeout(() => {
|
|
7849
|
+
this._clearTypeaheadBuffer();
|
|
7850
|
+
}, this.typeaheadTimeoutMs);
|
|
7481
7851
|
|
|
7482
|
-
|
|
7483
|
-
if (letterOptions.length) {
|
|
7852
|
+
this.typeaheadBuffer += key;
|
|
7484
7853
|
|
|
7485
|
-
|
|
7486
|
-
this.dropdown.show();
|
|
7854
|
+
const isRepeatedChar = this.typeaheadBuffer.length > 1 && new Set(this.typeaheadBuffer).size === 1;
|
|
7487
7855
|
|
|
7488
|
-
|
|
7489
|
-
|
|
7856
|
+
let match = null;
|
|
7857
|
+
if (isRepeatedChar) {
|
|
7858
|
+
const matches = options.filter((option) => this._getOptionDisplayText(option).startsWith(key));
|
|
7859
|
+
if (matches.length) {
|
|
7860
|
+
const cycleIndex = (this.typeaheadBuffer.length - 1) % matches.length;
|
|
7861
|
+
match = matches[cycleIndex];
|
|
7862
|
+
}
|
|
7863
|
+
} else {
|
|
7864
|
+
match = options.find((option) => this._getOptionDisplayText(option).startsWith(this.typeaheadBuffer));
|
|
7865
|
+
}
|
|
7490
7866
|
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7867
|
+
if (match) {
|
|
7868
|
+
if (!this.dropdown.isPopoverVisible) {
|
|
7869
|
+
this.dropdown.show();
|
|
7870
|
+
}
|
|
7871
|
+
this.menu.updateActiveOption(match);
|
|
7494
7872
|
}
|
|
7495
7873
|
}
|
|
7496
7874
|
|
|
@@ -7604,6 +7982,11 @@ class AuroSelect extends AuroElement$1 {
|
|
|
7604
7982
|
}
|
|
7605
7983
|
}
|
|
7606
7984
|
|
|
7985
|
+
disconnectedCallback() {
|
|
7986
|
+
super.disconnectedCallback();
|
|
7987
|
+
this._clearTypeaheadBuffer();
|
|
7988
|
+
}
|
|
7989
|
+
|
|
7607
7990
|
// lifecycle runs only after the element's DOM has been updated the first time
|
|
7608
7991
|
firstUpdated() {
|
|
7609
7992
|
// Add the tag name as an attribute if it is different than the component name
|
|
@@ -7616,7 +7999,7 @@ class AuroSelect extends AuroElement$1 {
|
|
|
7616
7999
|
|
|
7617
8000
|
setMenuValue(value) {
|
|
7618
8001
|
if (!this.menu) return;
|
|
7619
|
-
this.menu.value
|
|
8002
|
+
this.menu.selectByValue(value);
|
|
7620
8003
|
}
|
|
7621
8004
|
|
|
7622
8005
|
/**
|