@aurodesignsystem-dev/auro-formkit 0.0.0-pr1488.2 → 0.0.0-pr1489.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/customize.min.js +1 -1
- package/components/checkbox/demo/getting-started.min.js +1 -1
- package/components/checkbox/demo/index.min.js +1 -1
- package/components/checkbox/demo/pages.json +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 +1 -1
- package/components/checkbox/dist/registered.js +1 -1
- package/components/combobox/demo/customize.min.js +234 -16
- package/components/combobox/demo/getting-started.min.js +234 -16
- package/components/combobox/demo/index.min.js +234 -16
- package/components/combobox/demo/pages.json +1 -1
- package/components/combobox/demo/why-combobox.html +57 -0
- package/components/combobox/demo/why-combobox.md +113 -0
- package/components/combobox/dist/index.js +234 -16
- package/components/combobox/dist/registered.js +234 -16
- package/components/counter/demo/customize.min.js +233 -15
- package/components/counter/demo/index.min.js +233 -15
- package/components/counter/demo/keyboard-behavior.md +1 -0
- package/components/counter/demo/pages.json +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 +10 -2
- package/components/counter/dist/registered.js +10 -2
- package/components/datepicker/demo/accessibility.md +51 -3
- package/components/datepicker/demo/api.md +11 -2
- package/components/datepicker/demo/customize.html +2 -0
- package/components/datepicker/demo/customize.js +19 -0
- package/components/datepicker/demo/customize.md +72 -8
- package/components/datepicker/demo/customize.min.js +26029 -0
- package/components/datepicker/demo/design.md +3 -1
- package/components/datepicker/demo/index.js +5 -1
- package/components/datepicker/demo/index.md +83 -2
- package/components/datepicker/demo/index.min.js +1564 -96
- package/components/datepicker/demo/keyboard-behavior.md +201 -2
- package/components/datepicker/demo/pages.json +1 -1
- package/components/datepicker/demo/voiceover.md +19 -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 +1489 -97
- package/components/datepicker/dist/registered.js +1489 -97
- package/components/datepicker/dist/src/auro-calendar-cell.d.ts +66 -1
- package/components/datepicker/dist/src/auro-calendar-month.d.ts +28 -0
- package/components/datepicker/dist/src/auro-calendar.d.ts +100 -0
- package/components/datepicker/dist/src/auro-datepicker.d.ts +88 -0
- package/components/datepicker/dist/src/datepickerKeyboardStrategy.d.ts +5 -3
- package/components/dropdown/demo/accessibility.md +11 -0
- package/components/dropdown/demo/api.md +1 -0
- package/components/dropdown/demo/customize.md +3 -0
- package/components/dropdown/demo/customize.min.js +223 -13
- package/components/dropdown/demo/getting-started.min.js +223 -13
- package/components/dropdown/demo/index.min.js +223 -13
- package/components/dropdown/demo/keyboard-behavior.md +1 -0
- package/components/dropdown/demo/pages.json +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 +33 -1
- package/components/dropdown/dist/index.js +223 -13
- package/components/dropdown/dist/registered.js +223 -13
- package/components/form/demo/customize.min.js +2191 -145
- package/components/form/demo/getting-started.min.js +2191 -145
- package/components/form/demo/index.min.js +2191 -145
- package/components/form/demo/pages.json +1 -1
- package/components/form/demo/registerDemoDeps.min.js +2191 -145
- package/components/form/demo/why-form.html +57 -0
- package/components/form/demo/why-form.md +101 -0
- package/components/input/demo/customize.min.js +1 -1
- package/components/input/demo/getting-started.min.js +1 -1
- package/components/input/demo/index.min.js +1 -1
- package/components/input/demo/pages.json +1 -1
- package/components/input/demo/why-input.html +57 -0
- package/components/input/demo/why-input.md +121 -0
- package/components/input/dist/index.js +1 -1
- package/components/input/dist/registered.js +1 -1
- package/components/menu/demo/pages.json +1 -1
- package/components/menu/demo/why-menu.html +57 -0
- package/components/menu/demo/why-menu.md +104 -0
- package/components/radio/demo/customize.min.js +2186 -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 +2205 -0
- package/components/radio/demo/index.min.js +1 -1
- package/components/radio/demo/pages.json +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 +1 -1
- package/components/radio/dist/registered.js +1 -1
- package/components/select/demo/customize.min.js +233 -15
- package/components/select/demo/getting-started.min.js +233 -15
- package/components/select/demo/index.min.js +233 -15
- package/components/select/demo/keyboard-behavior.md +1 -0
- package/components/select/demo/pages.json +1 -1
- package/components/select/demo/why-select.html +57 -0
- package/components/select/demo/why-select.md +128 -0
- package/components/select/dist/index.js +233 -15
- package/components/select/dist/registered.js +233 -15
- package/custom-elements.json +745 -28
- package/package.json +2 -2
|
@@ -4662,7 +4662,7 @@ function applyKeyboardStrategy(component, strategy, options = {}) {
|
|
|
4662
4662
|
});
|
|
4663
4663
|
}
|
|
4664
4664
|
|
|
4665
|
-
var styleCss$2$1 = i$7`:host{position:fixed;z-index:var(--depth-tooltip, 400);display:none;isolation:isolate}:host dialog{width:auto;max-width:none;height:auto;max-height:none;padding:0;border:none;margin:0;outline:none;transform:translateZ(0)}:host dialog::backdrop{background:transparent}:host(:not([isfullscreen])) dialog{position:relative;inset:unset}:host(:not([isfullscreen])) .container.shape-box{border-radius:unset}:host(:not([isfullscreen])) .container[class*=shape-pill],:host(:not([isfullscreen])) .container[class*=shape-snowflake]{border-radius:30px}:host(:not([isfullscreen])) .container[class*=shape-rounded]{border-radius:16px}:host(:not([matchWidth])) .container{min-width:fit-content}:host([isfullscreen]){position:fixed;top:0;left:0}:host([isfullscreen]) .container{width:100dvw;max-width:none;height:100dvh;max-height:none;border-radius:unset;margin-top:0;box-shadow:unset;overscroll-behavior:contain}:host([isfullscreen]) .container::backdrop{background:var(--ds-color-background-primary, #fff)}:host(:popover-open){position:fixed;overflow:visible;padding:0;border:none;margin:0;background:transparent;inset:unset;outline:none}:host([data-show]){display:flex}:host([common]:not([isfullscreen])) .container,:host([rounded]:not([isfullscreen])) .container{border-radius:var(--ds-border-radius, 0.375rem)}:host([common][isfullscreen]) .container,:host([rounded][isfullscreen]) .container{border-radius:unset;box-shadow:unset}.container{display:inline-block;overflow:auto;box-sizing:border-box;border-radius:var(--ds-border-radius, 0.375rem);margin:var(--ds-size-50, 0.25rem) 0}.util_displayHiddenVisually{position:absolute;overflow:hidden;width:1px;height:1px;padding:0;border:0;margin:-1px;clip-path:inset(50%);white-space:nowrap}`;
|
|
4665
|
+
var styleCss$2$1 = i$7`:host{position:fixed;z-index:var(--depth-tooltip, 400);display:none;isolation:isolate}:host dialog{width:auto;max-width:none;height:auto;max-height:none;padding:0;border:none;margin:0;outline:none;transform:translateZ(0)}:host dialog::backdrop{background:transparent}:host(:not([isfullscreen])) dialog{position:relative;inset:unset}:host(:not([isfullscreen])) .container.shape-box{border-radius:unset}:host(:not([isfullscreen])) .container[class*=shape-pill],:host(:not([isfullscreen])) .container[class*=shape-snowflake]{border-radius:30px}:host(:not([isfullscreen])) .container[class*=shape-rounded]{border-radius:16px}:host([desktopmodal]:popover-open)::backdrop{background:transparent}:host(:not([matchWidth])) .container{min-width:fit-content}:host([isfullscreen]){position:fixed;top:0;left:0}:host([isfullscreen]) .container{width:100dvw;max-width:none;height:100dvh;max-height:none;border-radius:unset;margin-top:0;box-shadow:unset;overscroll-behavior:contain}:host([isfullscreen]) .container::backdrop{background:var(--ds-color-background-primary, #fff)}:host(:popover-open){position:fixed;overflow:visible;padding:0;border:none;margin:0;background:transparent;inset:unset;outline:none}:host([data-show]){display:flex}:host([common]:not([isfullscreen])) .container,:host([rounded]:not([isfullscreen])) .container{border-radius:var(--ds-border-radius, 0.375rem)}:host([common][isfullscreen]) .container,:host([rounded][isfullscreen]) .container{border-radius:unset;box-shadow:unset}.container{display:inline-block;overflow:auto;box-sizing:border-box;border-radius:var(--ds-border-radius, 0.375rem);margin:var(--ds-size-50, 0.25rem) 0}.util_displayHiddenVisually{position:absolute;overflow:hidden;width:1px;height:1px;padding:0;border:0;margin:-1px;clip-path:inset(50%);white-space:nowrap}`;
|
|
4666
4666
|
|
|
4667
4667
|
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)}`;
|
|
4668
4668
|
|
|
@@ -5293,7 +5293,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$4 {
|
|
|
5293
5293
|
}
|
|
5294
5294
|
};
|
|
5295
5295
|
|
|
5296
|
-
var formkitVersion$2 = '
|
|
5296
|
+
var formkitVersion$2 = '202606011856';
|
|
5297
5297
|
|
|
5298
5298
|
let AuroElement$2 = class AuroElement extends i$4 {
|
|
5299
5299
|
static get properties() {
|
|
@@ -5473,6 +5473,7 @@ class AuroDropdown extends AuroElement$2 {
|
|
|
5473
5473
|
_intializeDefaults() {
|
|
5474
5474
|
this.appearance = 'default';
|
|
5475
5475
|
this.chevron = false;
|
|
5476
|
+
this.desktopModal = false;
|
|
5476
5477
|
this.disabled = false;
|
|
5477
5478
|
this.disableKeyboardHandling = false;
|
|
5478
5479
|
this.error = false;
|
|
@@ -5653,6 +5654,14 @@ class AuroDropdown extends AuroElement$2 {
|
|
|
5653
5654
|
reflect: true
|
|
5654
5655
|
},
|
|
5655
5656
|
|
|
5657
|
+
/**
|
|
5658
|
+
* If declared, the dropdown will behave as a modal dialog when in a desktop viewport size.
|
|
5659
|
+
*/
|
|
5660
|
+
desktopModal: {
|
|
5661
|
+
type: Boolean,
|
|
5662
|
+
reflect: true
|
|
5663
|
+
},
|
|
5664
|
+
|
|
5656
5665
|
/**
|
|
5657
5666
|
* If declared, the dropdown will only show by calling the API .show() public method.
|
|
5658
5667
|
*/
|
|
@@ -5940,6 +5949,15 @@ class AuroDropdown extends AuroElement$2 {
|
|
|
5940
5949
|
|
|
5941
5950
|
disconnectedCallback() {
|
|
5942
5951
|
super.disconnectedCallback();
|
|
5952
|
+
this._clearPageInert();
|
|
5953
|
+
if (this._bibTabHandler) {
|
|
5954
|
+
this.removeEventListener('keydown', this._bibTabHandler);
|
|
5955
|
+
this._bibTabHandler = undefined;
|
|
5956
|
+
}
|
|
5957
|
+
if (this.focusTrap) {
|
|
5958
|
+
this.focusTrap.disconnect();
|
|
5959
|
+
this.focusTrap = undefined;
|
|
5960
|
+
}
|
|
5943
5961
|
if (this.floater) {
|
|
5944
5962
|
this.floater.hideBib('disconnect');
|
|
5945
5963
|
this.floater.disconnect();
|
|
@@ -5967,19 +5985,45 @@ class AuroDropdown extends AuroElement$2 {
|
|
|
5967
5985
|
if (this.isPopoverVisible) {
|
|
5968
5986
|
// Fullscreen: use showModal() for native accessibility (inert outside, focus trap)
|
|
5969
5987
|
// Desktop: use show() for Floating UI positioning + FocusTrap for focus management
|
|
5970
|
-
|
|
5971
|
-
this.
|
|
5988
|
+
this.bibElement.value.open(this.isBibFullscreen);
|
|
5989
|
+
this.updateFocusTrap();
|
|
5990
|
+
|
|
5991
|
+
// Desktop modal: make siblings inert so content outside is not interactive
|
|
5992
|
+
if (this.desktopModal && !this.isBibFullscreen) {
|
|
5993
|
+
this._setPageInert();
|
|
5994
|
+
}
|
|
5972
5995
|
} else {
|
|
5973
5996
|
this.bibElement.value.close();
|
|
5997
|
+
this._clearPageInert();
|
|
5974
5998
|
}
|
|
5975
5999
|
}
|
|
5976
6000
|
|
|
5977
6001
|
// When fullscreen strategy changes while open, re-open dialog with correct mode
|
|
5978
6002
|
// (e.g. resizing from desktop → mobile while dropdown is open)
|
|
5979
6003
|
if (changedProperties.has('isBibFullscreen') && this.isPopoverVisible && this.bibElement.value) {
|
|
5980
|
-
const useModal = this.isBibFullscreen;
|
|
5981
6004
|
this.bibElement.value.close();
|
|
5982
|
-
this.bibElement.value.open(
|
|
6005
|
+
this.bibElement.value.open(this.isBibFullscreen);
|
|
6006
|
+
|
|
6007
|
+
// Re-initialize focus management for the new strategy
|
|
6008
|
+
this.updateFocusTrap();
|
|
6009
|
+
|
|
6010
|
+
// Toggle inert: desktop modal needs it, fullscreen showModal() handles it natively
|
|
6011
|
+
if (this.desktopModal && !this.isBibFullscreen) {
|
|
6012
|
+
this._setPageInert();
|
|
6013
|
+
} else {
|
|
6014
|
+
this._clearPageInert();
|
|
6015
|
+
}
|
|
6016
|
+
}
|
|
6017
|
+
|
|
6018
|
+
// Handle desktopModal toggled while the dropdown is already open.
|
|
6019
|
+
// Re-initialize focus trapping and page inert state to match the new mode.
|
|
6020
|
+
if (changedProperties.has('desktopModal') && this.isPopoverVisible && !this.isBibFullscreen) {
|
|
6021
|
+
this.updateFocusTrap();
|
|
6022
|
+
if (this.desktopModal) {
|
|
6023
|
+
this._setPageInert();
|
|
6024
|
+
} else {
|
|
6025
|
+
this._clearPageInert();
|
|
6026
|
+
}
|
|
5983
6027
|
}
|
|
5984
6028
|
}
|
|
5985
6029
|
|
|
@@ -5989,8 +6033,14 @@ class AuroDropdown extends AuroElement$2 {
|
|
|
5989
6033
|
* @param {CustomEvent} event - The custom event that contains the dropdown toggle information.
|
|
5990
6034
|
*/
|
|
5991
6035
|
handleDropdownToggle(event) {
|
|
5992
|
-
this.updateFocusTrap();
|
|
5993
6036
|
this.isPopoverVisible = event.detail.expanded;
|
|
6037
|
+
|
|
6038
|
+
// Tear down FocusTrap when closing. Creation happens in updated()
|
|
6039
|
+
// after the dialog is open so getFocusableElements can find content.
|
|
6040
|
+
if (!this.isPopoverVisible) {
|
|
6041
|
+
this.updateFocusTrap();
|
|
6042
|
+
}
|
|
6043
|
+
|
|
5994
6044
|
const eventType = event.detail.eventType || "unknown";
|
|
5995
6045
|
if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
|
|
5996
6046
|
this.trigger.focus();
|
|
@@ -6089,19 +6139,178 @@ class AuroDropdown extends AuroElement$2 {
|
|
|
6089
6139
|
* @private
|
|
6090
6140
|
*/
|
|
6091
6141
|
updateFocusTrap() {
|
|
6142
|
+
// Always clean up existing handlers/traps before setting up new ones
|
|
6143
|
+
// to prevent duplicate listeners on repeated calls.
|
|
6144
|
+
if (this._bibTabHandler) {
|
|
6145
|
+
this.removeEventListener('keydown', this._bibTabHandler);
|
|
6146
|
+
this._bibTabHandler = undefined;
|
|
6147
|
+
}
|
|
6148
|
+
|
|
6149
|
+
if (this.focusTrap) {
|
|
6150
|
+
this.focusTrap.disconnect();
|
|
6151
|
+
this.focusTrap = undefined;
|
|
6152
|
+
}
|
|
6153
|
+
|
|
6092
6154
|
if (this.isPopoverVisible) {
|
|
6093
6155
|
if (!this.isBibFullscreen) {
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6156
|
+
if (this.desktopModal) {
|
|
6157
|
+
// Desktop modal: trap focus only within the bib content.
|
|
6158
|
+
// Can't use FocusTrap on the bib element because keydown events
|
|
6159
|
+
// from slotted content bubble through the dropdown host (light DOM),
|
|
6160
|
+
// not through the bib (shadow projection target). Using FocusTrap
|
|
6161
|
+
// on the dropdown would include the trigger in the tab cycle.
|
|
6162
|
+
// Instead, listen for Tab on the dropdown and manually wrap focus
|
|
6163
|
+
// within the bib's focusable elements.
|
|
6164
|
+
this._bibTabHandler = (event) => {
|
|
6165
|
+
if (event.key !== 'Tab') {
|
|
6166
|
+
return;
|
|
6167
|
+
}
|
|
6168
|
+
|
|
6169
|
+
// Collect focusable elements from the bib content.
|
|
6170
|
+
const focusables = getFocusableElements(this.bibContent);
|
|
6171
|
+
|
|
6172
|
+
// Fallback: try from slotted content directly
|
|
6173
|
+
if (!focusables.length) {
|
|
6174
|
+
const slot = this.shadowRoot.querySelector('.slotContent slot');
|
|
6175
|
+
const assignedNodes = slot ? slot.assignedNodes({ flatten: true }) : [];
|
|
6176
|
+
|
|
6177
|
+
for (const node of assignedNodes) {
|
|
6178
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
6179
|
+
focusables.push(...getFocusableElements(node));
|
|
6180
|
+
}
|
|
6181
|
+
}
|
|
6182
|
+
}
|
|
6183
|
+
|
|
6184
|
+
if (!focusables.length) {
|
|
6185
|
+
return;
|
|
6186
|
+
}
|
|
6187
|
+
|
|
6188
|
+
event.preventDefault();
|
|
6189
|
+
|
|
6190
|
+
const direction = event.shiftKey ? -1 : 1; // eslint-disable-line no-magic-numbers
|
|
6191
|
+
|
|
6192
|
+
// Walk the active element chain through shadow roots
|
|
6193
|
+
const actives = this._getActiveElements();
|
|
6194
|
+
|
|
6195
|
+
let idx = focusables.findIndex((el) => actives.includes(el));
|
|
6196
|
+
|
|
6197
|
+
if (idx === -1) { // eslint-disable-line no-magic-numbers
|
|
6198
|
+
// Focus is not on a known element — move to first/last
|
|
6199
|
+
idx = direction === 1 ? -1 : focusables.length; // eslint-disable-line no-magic-numbers
|
|
6200
|
+
}
|
|
6201
|
+
|
|
6202
|
+
// Try each element in order, skipping any that can't receive focus
|
|
6203
|
+
// (e.g. hidden elements, elements in collapsed sections)
|
|
6204
|
+
for (let index = 0; index < focusables.length; index++) { // eslint-disable-line no-plusplus
|
|
6205
|
+
let nextIdx = idx + direction;
|
|
6206
|
+
|
|
6207
|
+
// Wrap around
|
|
6208
|
+
if (nextIdx < 0) {
|
|
6209
|
+
nextIdx = focusables.length - 1;
|
|
6210
|
+
} else if (nextIdx >= focusables.length) {
|
|
6211
|
+
nextIdx = 0;
|
|
6212
|
+
}
|
|
6213
|
+
|
|
6214
|
+
focusables[nextIdx].focus();
|
|
6215
|
+
|
|
6216
|
+
// Verify focus actually moved to the target
|
|
6217
|
+
const newActives = this._getActiveElements();
|
|
6218
|
+
|
|
6219
|
+
if (newActives.includes(focusables[nextIdx])) {
|
|
6220
|
+
return;
|
|
6221
|
+
}
|
|
6222
|
+
|
|
6223
|
+
// Focus didn't stick — skip this element and try the next
|
|
6224
|
+
idx = nextIdx;
|
|
6225
|
+
}
|
|
6226
|
+
};
|
|
6227
|
+
this.addEventListener('keydown', this._bibTabHandler);
|
|
6228
|
+
|
|
6229
|
+
// Move initial focus into the bib content, matching FocusTrap behavior
|
|
6230
|
+
requestAnimationFrame(() => {
|
|
6231
|
+
const focusables = getFocusableElements(this.bibContent);
|
|
6232
|
+
if (focusables.length) {
|
|
6233
|
+
focusables[0].focus();
|
|
6234
|
+
}
|
|
6235
|
+
});
|
|
6236
|
+
} else {
|
|
6237
|
+
// Normal desktop: use FocusTrap on the bib element
|
|
6238
|
+
this.focusTrap = new FocusTrap(this.bibContent);
|
|
6239
|
+
this.focusTrap.focusFirstElement();
|
|
6240
|
+
}
|
|
6097
6241
|
}
|
|
6098
6242
|
// Fullscreen: showModal() provides native focus trapping
|
|
6243
|
+
}
|
|
6244
|
+
}
|
|
6245
|
+
|
|
6246
|
+
/**
|
|
6247
|
+
* Returns the chain of active (focused) elements through shadow roots.
|
|
6248
|
+
* @private
|
|
6249
|
+
* @returns {Array<HTMLElement>}
|
|
6250
|
+
*/
|
|
6251
|
+
_getActiveElements() {
|
|
6252
|
+
let { activeElement } = document;
|
|
6253
|
+
const actives = [activeElement];
|
|
6254
|
+
|
|
6255
|
+
while (activeElement?.shadowRoot?.activeElement) {
|
|
6256
|
+
activeElement = activeElement.shadowRoot.activeElement;
|
|
6257
|
+
actives.push(activeElement);
|
|
6258
|
+
}
|
|
6259
|
+
|
|
6260
|
+
return actives;
|
|
6261
|
+
}
|
|
6262
|
+
|
|
6263
|
+
/**
|
|
6264
|
+
* Sets `inert` on sibling elements of the dropdown's top-level host
|
|
6265
|
+
* so that content outside the dropdown is not interactive while the modal is open.
|
|
6266
|
+
* Walks up through shadow DOM boundaries to find the outermost host element
|
|
6267
|
+
* in the light DOM, then sets `inert` on siblings at each ancestor level
|
|
6268
|
+
* to ensure all page content outside the host subtree is inert.
|
|
6269
|
+
* @private
|
|
6270
|
+
*/
|
|
6271
|
+
_setPageInert() {
|
|
6272
|
+
if (this._inertSiblings) {
|
|
6099
6273
|
return;
|
|
6100
6274
|
}
|
|
6101
6275
|
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6276
|
+
this._inertSiblings = [];
|
|
6277
|
+
|
|
6278
|
+
// Walk up through shadow DOM boundaries to find the topmost host
|
|
6279
|
+
// element in the light DOM. For example, if this dropdown is inside
|
|
6280
|
+
// auro-datepicker's shadow DOM, we walk up to the datepicker element
|
|
6281
|
+
// so we set inert on its siblings — not on the datepicker itself.
|
|
6282
|
+
let host = this;
|
|
6283
|
+
while (host.getRootNode() instanceof ShadowRoot) {
|
|
6284
|
+
host = host.getRootNode().host;
|
|
6285
|
+
}
|
|
6286
|
+
|
|
6287
|
+
// Walk up the ancestor chain, inerting siblings at each level
|
|
6288
|
+
// to ensure the entire page outside the host subtree is inert.
|
|
6289
|
+
let current = host;
|
|
6290
|
+
while (current.parentElement) {
|
|
6291
|
+
const parent = current.parentElement;
|
|
6292
|
+
for (const sibling of parent.children) {
|
|
6293
|
+
if (sibling !== current) {
|
|
6294
|
+
this._inertSiblings.push({ element: sibling, wasInert: sibling.inert });
|
|
6295
|
+
sibling.inert = true;
|
|
6296
|
+
}
|
|
6297
|
+
}
|
|
6298
|
+
current = parent;
|
|
6299
|
+
}
|
|
6300
|
+
}
|
|
6301
|
+
|
|
6302
|
+
/**
|
|
6303
|
+
* Restores `inert` state on siblings that were tracked by `_setPageInert`.
|
|
6304
|
+
* Preserves the previous inert state so externally-inerted elements are
|
|
6305
|
+
* not inadvertently re-enabled.
|
|
6306
|
+
* @private
|
|
6307
|
+
*/
|
|
6308
|
+
_clearPageInert() {
|
|
6309
|
+
if (this._inertSiblings) {
|
|
6310
|
+
for (const entry of this._inertSiblings) {
|
|
6311
|
+
entry.element.inert = entry.wasInert;
|
|
6312
|
+
}
|
|
6313
|
+
this._inertSiblings = undefined;
|
|
6105
6314
|
}
|
|
6106
6315
|
}
|
|
6107
6316
|
|
|
@@ -6340,6 +6549,7 @@ class AuroDropdown extends AuroElement$2 {
|
|
|
6340
6549
|
shape="${this.shape}"
|
|
6341
6550
|
?data-show="${this.isPopoverVisible}"
|
|
6342
6551
|
?isfullscreen="${this.isBibFullscreen}"
|
|
6552
|
+
?desktopmodal="${this.desktopModal}"
|
|
6343
6553
|
.dialogLabel="${this.bibDialogLabel}"
|
|
6344
6554
|
${n$2(this.bibElement)}
|
|
6345
6555
|
>
|
|
@@ -13045,7 +13255,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$4 {
|
|
|
13045
13255
|
}
|
|
13046
13256
|
};
|
|
13047
13257
|
|
|
13048
|
-
var formkitVersion$1 = '
|
|
13258
|
+
var formkitVersion$1 = '202606011856';
|
|
13049
13259
|
|
|
13050
13260
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
13051
13261
|
// See LICENSE in the project root for license information.
|
|
@@ -13999,6 +14209,14 @@ class AuroBibtemplate extends i$4 {
|
|
|
13999
14209
|
large: {
|
|
14000
14210
|
type: Boolean,
|
|
14001
14211
|
reflect: true
|
|
14212
|
+
},
|
|
14213
|
+
|
|
14214
|
+
/**
|
|
14215
|
+
* If declared, the footer slot will be rendered even when not in fullscreen mode.
|
|
14216
|
+
*/
|
|
14217
|
+
showFooter: {
|
|
14218
|
+
type: Boolean,
|
|
14219
|
+
reflect: true
|
|
14002
14220
|
}
|
|
14003
14221
|
};
|
|
14004
14222
|
}
|
|
@@ -14101,7 +14319,7 @@ class AuroBibtemplate extends i$4 {
|
|
|
14101
14319
|
<slot></slot>
|
|
14102
14320
|
</div>
|
|
14103
14321
|
|
|
14104
|
-
${this.isFullscreen ? u$7`
|
|
14322
|
+
${this.isFullscreen || this.showFooter ? u$7`
|
|
14105
14323
|
<div id="footerContainer">
|
|
14106
14324
|
<slot name="footer"></slot>
|
|
14107
14325
|
</div>` : null}
|
|
@@ -14110,7 +14328,7 @@ class AuroBibtemplate extends i$4 {
|
|
|
14110
14328
|
}
|
|
14111
14329
|
}
|
|
14112
14330
|
|
|
14113
|
-
var formkitVersion = '
|
|
14331
|
+
var formkitVersion = '202606011856';
|
|
14114
14332
|
|
|
14115
14333
|
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}`;
|
|
14116
14334
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
["accessibility.md","api.md","customize.md","design.md","getting-started.md","index.md","keyboard-behavior.md","voiceover.md","readme.md"]
|
|
1
|
+
["accessibility.md","api.md","customize.md","design.md","getting-started.md","index.md","keyboard-behavior.md","voiceover.md","why-combobox.md","readme.md"]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
|
|
3
|
+
See LICENSE in the project root for license information.
|
|
4
|
+
|
|
5
|
+
HTML in this document is standardized and NOT to be edited.
|
|
6
|
+
All demo code should be added/edited in ./demo/why-combobox.md
|
|
7
|
+
|
|
8
|
+
With the exception of adding custom elements if needed for the demo.
|
|
9
|
+
|
|
10
|
+
----------------------- DO NOT EDIT -----------------------------
|
|
11
|
+
|
|
12
|
+
-->
|
|
13
|
+
|
|
14
|
+
<!DOCTYPE html>
|
|
15
|
+
<html lang="en">
|
|
16
|
+
<head>
|
|
17
|
+
<meta charset="UTF-8" />
|
|
18
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
19
|
+
<title>Auro Web Component Demo | auro-combobox | Why auro-combobox</title>
|
|
20
|
+
|
|
21
|
+
<!-- highlight.js Stylesheet -->
|
|
22
|
+
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/github.min.css"/>
|
|
23
|
+
|
|
24
|
+
<!-- Legacy reference is still needed to support auro-combobox's use of legacy token values at this time -->
|
|
25
|
+
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@aurodesignsystem/design-tokens@latest/dist/legacy/auro-classic/CSSCustomProperties.css"/>
|
|
26
|
+
|
|
27
|
+
<!-- Design Token Alaska Theme -->
|
|
28
|
+
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@aurodesignsystem/design-tokens@latest/dist/themes/alaska/CSSCustomProperties--alaska.min.css"/>
|
|
29
|
+
|
|
30
|
+
<!-- Webcore Stylesheet Alaska Theme -->
|
|
31
|
+
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@aurodesignsystem/webcorestylesheets@latest/dist/bundled/themes/alaska.global.min.css" />
|
|
32
|
+
|
|
33
|
+
<!-- Demo Specific Styles -->
|
|
34
|
+
<link rel="stylesheet" type="text/css" href="./styles.min.css" />
|
|
35
|
+
<style>
|
|
36
|
+
table {
|
|
37
|
+
--ds-color-container-secondary-default: transparent;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
tr:not(:last-of-type) {
|
|
41
|
+
border-bottom: 1px solid var(--ds-color-border-tertiary-default);
|
|
42
|
+
}
|
|
43
|
+
</style>
|
|
44
|
+
</head>
|
|
45
|
+
<body class="auro-markdown">
|
|
46
|
+
<main></main>
|
|
47
|
+
|
|
48
|
+
<script type="module">
|
|
49
|
+
import { renderPage } from './demo-support.min.js';
|
|
50
|
+
await renderPage('./why-combobox.md');
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<!-- If additional elements are needed for the demo, add them here. -->
|
|
54
|
+
<script src="https://cdn.jsdelivr.net/npm/@aurodesignsystem/auro-header@latest/+esm" type="module"></script>
|
|
55
|
+
<script src="https://cdn.jsdelivr.net/npm/@aurodesignsystem/auro-hyperlink@latest/+esm" type="module"></script>
|
|
56
|
+
</body>
|
|
57
|
+
</html>
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<auro-header level="1" id="overview">Why auro-combobox?</auro-header>
|
|
2
|
+
<p>The native <code><input list></code> with <code><datalist></code> provides a basic autocomplete experience, but it cannot be styled, has no concept of required selection, and offers no mobile-friendly layout. <code>auro-combobox</code> is a fully featured autocomplete and selection component designed for real-world use.</p>
|
|
3
|
+
<auro-header level="2" id="accessibility">Accessibility</auro-header>
|
|
4
|
+
<p>Native <code><datalist></code> support varies between browsers. Some announce suggestion counts, others do not. Keyboard behavior is inconsistent, and there is no standard way to communicate selection state to screen readers.</p>
|
|
5
|
+
<p><code>auro-combobox</code> provides:</p>
|
|
6
|
+
<ul>
|
|
7
|
+
<li><strong>ARIA combobox pattern</strong> — The input carries <code>aria-expanded</code>, <code>aria-owns</code>, and <code>aria-haspopup</code> to properly describe the relationship between the input and the suggestions list.</li>
|
|
8
|
+
<li><strong>Active descendant tracking</strong> — <code>aria-activedescendant</code> moves with keyboard navigation so screen readers announce the highlighted option without moving DOM focus.</li>
|
|
9
|
+
<li><strong>Live region announcements</strong> — Selections are announced via <code>aria-live="polite"</code>, and validation errors use <code>aria-live="assertive"</code>.</li>
|
|
10
|
+
<li><strong>Full keyboard navigation</strong> — Arrow keys navigate options, Enter selects, Escape closes, Home/End jump to boundaries. A dedicated keyboard strategy handles all interactions.</li>
|
|
11
|
+
</ul>
|
|
12
|
+
<auro-header level="2" id="dualBehaviorModes">Dual behavior modes</auro-header>
|
|
13
|
+
<p>Native <code><datalist></code> always allows freeform input. There is no way to restrict the user to only the provided options.</p>
|
|
14
|
+
<p><code>auro-combobox</code> supports two modes:</p>
|
|
15
|
+
<ul>
|
|
16
|
+
<li><strong>Suggestion mode</strong> (default) — The user can type any value. Suggestions are offered but not required.</li>
|
|
17
|
+
<li><strong>Filter mode</strong> — The user must select from the available options. Typed text filters the list but cannot be submitted as a value. Validation enforces this constraint.</li>
|
|
18
|
+
</ul>
|
|
19
|
+
<auro-header level="2" id="realtimeFiltering">Real-time filtering</auro-header>
|
|
20
|
+
<p><code><datalist></code> filtering is browser-controlled and cannot be customized. Some browsers match from the start of the option text, others match anywhere.</p>
|
|
21
|
+
<p><code>auro-combobox</code> filters options as the user types, with full control:</p>
|
|
22
|
+
<ul>
|
|
23
|
+
<li><code>noFilter</code> disables filtering to show all options regardless of input</li>
|
|
24
|
+
<li><code>matchWord</code> highlights the matched portion of each option</li>
|
|
25
|
+
<li><code>persistInput</code> keeps the filter text visible after selection</li>
|
|
26
|
+
</ul>
|
|
27
|
+
<auro-header level="2" id="responsiveLayout">Responsive layout</auro-header>
|
|
28
|
+
<p>Native <code><datalist></code> renders a small browser-controlled popup that cannot be repositioned or resized.</p>
|
|
29
|
+
<p><code>auro-combobox</code> adapts to the viewport:</p>
|
|
30
|
+
<ul>
|
|
31
|
+
<li><strong>Desktop</strong> — Suggestions appear as a positioned dropdown using Floating UI, with configurable placement, offset, flip, and shift behavior</li>
|
|
32
|
+
<li><strong>Mobile</strong> — Suggestions open in a fullscreen dialog via <code>showModal()</code>, with a configurable breakpoint (<code>fullscreenBreakpoint</code>)</li>
|
|
33
|
+
<li><strong>Width matching</strong> — The dropdown can match the input width or size independently</li>
|
|
34
|
+
</ul>
|
|
35
|
+
<auro-header level="2" id="validation">Validation</auro-header>
|
|
36
|
+
<p>Native <code><datalist></code> has no built-in validation beyond standard <code>required</code>.</p>
|
|
37
|
+
<p><code>auro-combobox</code> integrates with the Auro form validation system:</p>
|
|
38
|
+
<ul>
|
|
39
|
+
<li>Required field validation with mode-aware messaging (separate messages for suggestion vs. filter mode)</li>
|
|
40
|
+
<li>Custom error messages per validity state (<code>setCustomValidityCustomError</code>, <code>setCustomValidityValueMissing</code>, <code>setCustomValidityValueMissingFilter</code>)</li>
|
|
41
|
+
<li>Validation on blur with <code>noValidate</code> opt-out</li>
|
|
42
|
+
<li>Error display via help text with <code>role="alert"</code></li>
|
|
43
|
+
</ul>
|
|
44
|
+
<auro-header level="2" id="inputMasking">Input masking</auro-header>
|
|
45
|
+
<p><code><datalist></code> inputs have no formatting support.</p>
|
|
46
|
+
<p><code>auro-combobox</code> supports input masks via the <code>format</code> attribute, enabling structured input (e.g., dates, phone numbers) while still offering suggestions.</p>
|
|
47
|
+
<auro-header level="2" id="designSystemIntegration">Design system integration</auro-header>
|
|
48
|
+
<p><code><datalist></code> styling is entirely browser-controlled. The popup cannot be themed, and option rendering is limited to plain text.</p>
|
|
49
|
+
<p><code>auro-combobox</code> is built with the Auro Design System:</p>
|
|
50
|
+
<ul>
|
|
51
|
+
<li>Three layout options: classic, emphasized, and snowflake</li>
|
|
52
|
+
<li>Light and dark theme support (<code>appearance</code>)</li>
|
|
53
|
+
<li>Checkmarks on selected options</li>
|
|
54
|
+
<li>Rich HTML content in options (icons, descriptions, nested structure)</li>
|
|
55
|
+
<li>CSS <code>::part()</code> selectors for styling</li>
|
|
56
|
+
</ul>
|
|
57
|
+
<auro-header level="2" id="summary">Summary</auro-header>
|
|
58
|
+
<table>
|
|
59
|
+
<thead>
|
|
60
|
+
<tr>
|
|
61
|
+
<th>Capability</th>
|
|
62
|
+
<th><code><input list></code> + <code><datalist></code></th>
|
|
63
|
+
<th><code>auro-combobox</code></th>
|
|
64
|
+
</tr>
|
|
65
|
+
</thead>
|
|
66
|
+
<tbody>
|
|
67
|
+
<tr>
|
|
68
|
+
<td>Restrict to options only</td>
|
|
69
|
+
<td>No</td>
|
|
70
|
+
<td>Yes (filter mode)</td>
|
|
71
|
+
</tr>
|
|
72
|
+
<tr>
|
|
73
|
+
<td>Real-time filtering control</td>
|
|
74
|
+
<td>Browser-controlled</td>
|
|
75
|
+
<td>Fully configurable</td>
|
|
76
|
+
</tr>
|
|
77
|
+
<tr>
|
|
78
|
+
<td>Keyboard navigation</td>
|
|
79
|
+
<td>Inconsistent</td>
|
|
80
|
+
<td>Full arrow/Enter/Escape/Home/End</td>
|
|
81
|
+
</tr>
|
|
82
|
+
<tr>
|
|
83
|
+
<td>Screen reader announcements</td>
|
|
84
|
+
<td>Inconsistent</td>
|
|
85
|
+
<td>Live regions and active descendant</td>
|
|
86
|
+
</tr>
|
|
87
|
+
<tr>
|
|
88
|
+
<td>Mobile fullscreen</td>
|
|
89
|
+
<td>No</td>
|
|
90
|
+
<td>Automatic at breakpoint</td>
|
|
91
|
+
</tr>
|
|
92
|
+
<tr>
|
|
93
|
+
<td>Input masking</td>
|
|
94
|
+
<td>No</td>
|
|
95
|
+
<td>Yes (format attribute)</td>
|
|
96
|
+
</tr>
|
|
97
|
+
<tr>
|
|
98
|
+
<td>Custom validation messages</td>
|
|
99
|
+
<td>No</td>
|
|
100
|
+
<td>Per-constraint messages</td>
|
|
101
|
+
</tr>
|
|
102
|
+
<tr>
|
|
103
|
+
<td>Rich option content</td>
|
|
104
|
+
<td>Plain text only</td>
|
|
105
|
+
<td>Full HTML</td>
|
|
106
|
+
</tr>
|
|
107
|
+
<tr>
|
|
108
|
+
<td>Theming</td>
|
|
109
|
+
<td>No</td>
|
|
110
|
+
<td>Three layouts + appearance modes</td>
|
|
111
|
+
</tr>
|
|
112
|
+
</tbody>
|
|
113
|
+
</table>
|