@aurodesignsystem/auro-formkit 5.10.0 → 5.11.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/CHANGELOG.md +55 -15
- package/components/bibtemplate/dist/auro-bibtemplate.d.ts +6 -0
- package/components/bibtemplate/dist/index.js +12 -0
- package/components/bibtemplate/dist/registered.js +12 -0
- package/components/checkbox/demo/api.min.js +3 -3
- package/components/checkbox/demo/index.min.js +3 -3
- package/components/checkbox/dist/index.js +3 -3
- package/components/checkbox/dist/registered.js +3 -3
- package/components/combobox/demo/api.min.js +1140 -305
- package/components/combobox/demo/index.min.js +1140 -305
- package/components/combobox/dist/auro-combobox.d.ts +24 -1
- package/components/combobox/dist/comboboxKeyboardStrategy.d.ts +6 -0
- package/components/combobox/dist/index.js +1082 -264
- package/components/combobox/dist/registered.js +1082 -264
- package/components/counter/demo/api.min.js +583 -172
- package/components/counter/demo/index.min.js +583 -172
- package/components/counter/dist/auro-counter.d.ts +8 -0
- package/components/counter/dist/buttonVersion.d.ts +1 -1
- package/components/counter/dist/iconVersion.d.ts +1 -1
- package/components/counter/dist/index.js +583 -172
- package/components/counter/dist/registered.js +583 -172
- package/components/datepicker/demo/api.md +108 -85
- package/components/datepicker/demo/api.min.js +872 -257
- package/components/datepicker/demo/index.md +18 -12
- package/components/datepicker/demo/index.min.js +872 -257
- package/components/datepicker/dist/auro-calendar.d.ts +6 -0
- package/components/datepicker/dist/auro-datepicker.d.ts +11 -1
- package/components/datepicker/dist/index.js +819 -208
- package/components/datepicker/dist/registered.js +819 -208
- package/components/dropdown/demo/api.md +15 -17
- package/components/dropdown/demo/api.min.js +537 -183
- package/components/dropdown/demo/index.min.js +537 -183
- package/components/dropdown/dist/auro-dropdown.d.ts +27 -1
- package/components/dropdown/dist/auro-dropdownBib.d.ts +87 -0
- package/components/dropdown/dist/index.js +514 -160
- package/components/dropdown/dist/keyboardUtils.d.ts +18 -0
- package/components/dropdown/dist/registered.js +514 -160
- package/components/form/README.md +47 -2
- package/components/form/demo/api.js +2 -0
- package/components/form/demo/api.md +303 -30
- package/components/form/demo/api.min.js +69256 -62
- package/components/form/demo/index.html +0 -1
- package/components/form/demo/index.js +1 -0
- package/components/form/demo/index.md +1 -275
- package/components/form/demo/index.min.js +69255 -62
- package/components/form/demo/readme.md +47 -2
- package/components/form/demo/working.html +123 -32
- package/components/form/dist/auro-form.d.ts +98 -61
- package/components/form/dist/index.js +135 -51
- package/components/form/dist/registered.js +135 -51
- package/components/input/demo/api.md +1 -0
- package/components/input/demo/api.min.js +78 -24
- package/components/input/demo/index.min.js +78 -24
- package/components/input/dist/base-input.d.ts +34 -0
- package/components/input/dist/index.js +78 -24
- package/components/input/dist/registered.js +78 -24
- package/components/menu/demo/api.md +4 -10
- package/components/menu/demo/api.min.js +18 -5
- package/components/menu/demo/index.min.js +18 -5
- package/components/menu/dist/auro-menuoption.d.ts +0 -8
- package/components/menu/dist/iconVersion.d.ts +1 -1
- package/components/menu/dist/index.js +18 -5
- package/components/menu/dist/registered.js +18 -5
- package/components/radio/demo/api.min.js +3 -3
- package/components/radio/demo/index.min.js +3 -3
- package/components/radio/dist/index.js +3 -3
- package/components/radio/dist/registered.js +3 -3
- package/components/select/demo/api.js +2 -0
- package/components/select/demo/api.md +333 -78
- package/components/select/demo/api.min.js +945 -282
- package/components/select/demo/index.min.js +933 -282
- package/components/select/dist/auro-select.d.ts +26 -0
- package/components/select/dist/index.js +881 -247
- package/components/select/dist/registered.js +881 -247
- package/components/select/dist/selectKeyboardStrategy.d.ts +8 -0
- package/custom-elements.json +596 -89
- package/package.json +7 -5
|
@@ -256,7 +256,7 @@ let p$3 = class p{registerComponent(t,a){customElements.get(t)||customElements.d
|
|
|
256
256
|
</div>
|
|
257
257
|
`}};
|
|
258
258
|
|
|
259
|
-
var iconVersion$2 = '9.1.
|
|
259
|
+
var iconVersion$2 = '9.1.2';
|
|
260
260
|
|
|
261
261
|
class DateFormatter {
|
|
262
262
|
|
|
@@ -1014,7 +1014,7 @@ class AuroFormValidation {
|
|
|
1014
1014
|
}
|
|
1015
1015
|
}
|
|
1016
1016
|
|
|
1017
|
-
if (!hasValue && elem.required && elem.touched) {
|
|
1017
|
+
if (!hasValue && elem.required && (force || elem.touched)) {
|
|
1018
1018
|
elem.validity = 'valueMissing';
|
|
1019
1019
|
elem.errorMessage = elem.setCustomValidityValueMissing || elem.setCustomValidity || '';
|
|
1020
1020
|
} else if (hasValue && this.runtimeUtils.elementMatch(elem, 'auro-input')) {
|
|
@@ -1038,7 +1038,7 @@ class AuroFormValidation {
|
|
|
1038
1038
|
if (!isCombobox || isCombobox && !elem.persistInput) {
|
|
1039
1039
|
|
|
1040
1040
|
// run validation on all inputs since we're going to use them to set the validity of this component
|
|
1041
|
-
this.auroInputElements.forEach(input => input.validate());
|
|
1041
|
+
this.auroInputElements.forEach(input => input.validate(force));
|
|
1042
1042
|
|
|
1043
1043
|
// Reset element validity to the validity of the input
|
|
1044
1044
|
elem.validity = this.auroInputElements[0].validity;
|
|
@@ -1129,6 +1129,34 @@ class AuroFormValidation {
|
|
|
1129
1129
|
}
|
|
1130
1130
|
}
|
|
1131
1131
|
|
|
1132
|
+
/**
|
|
1133
|
+
* Announces text to screen readers via an `aria-live` region inside the given shadow root.
|
|
1134
|
+
*
|
|
1135
|
+
* Expects the shadow root to contain an element with `id="srAnnouncement"`.
|
|
1136
|
+
* The text is cleared and re-set inside a `requestAnimationFrame` so that
|
|
1137
|
+
* repeated identical announcements still fire, and is cleared again after
|
|
1138
|
+
* {@link ANNOUNCEMENT_DURATION_MS} so VoiceOver cannot swipe to stale text.
|
|
1139
|
+
*
|
|
1140
|
+
* @param {ShadowRoot} shadowRoot - The shadow root containing the live region.
|
|
1141
|
+
* @param {string} text - The text to announce.
|
|
1142
|
+
*/
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
/**
|
|
1146
|
+
* Schedules a callback after two animation frames.
|
|
1147
|
+
*
|
|
1148
|
+
* Used when opening a fullscreen dialog to wait for the dialog to render
|
|
1149
|
+
* (first frame) and then for a Lit update cycle to complete (second frame)
|
|
1150
|
+
* before performing an action like focusing the close button.
|
|
1151
|
+
*
|
|
1152
|
+
* @param {Function} fn - The callback to execute after two animation frames.
|
|
1153
|
+
*/
|
|
1154
|
+
function doubleRaf(fn) {
|
|
1155
|
+
requestAnimationFrame(() => {
|
|
1156
|
+
requestAnimationFrame(fn);
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1132
1160
|
// Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
|
|
1133
1161
|
// See LICENSE in the project root for license information.
|
|
1134
1162
|
|
|
@@ -1392,7 +1420,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
|
|
|
1392
1420
|
}
|
|
1393
1421
|
};
|
|
1394
1422
|
|
|
1395
|
-
var formkitVersion$1 = '
|
|
1423
|
+
var formkitVersion$1 = '202603102257';
|
|
1396
1424
|
|
|
1397
1425
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
1398
1426
|
// See LICENSE in the project root for license information.
|
|
@@ -1409,6 +1437,13 @@ var formkitVersion$1 = '202602140013';
|
|
|
1409
1437
|
* @slot description - Descriptive content for the counter.
|
|
1410
1438
|
*/
|
|
1411
1439
|
class AuroCounter extends LitElement {
|
|
1440
|
+
static get shadowRootOptions() {
|
|
1441
|
+
return {
|
|
1442
|
+
...LitElement.shadowRootOptions,
|
|
1443
|
+
delegatesFocus: true,
|
|
1444
|
+
};
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1412
1447
|
constructor() {
|
|
1413
1448
|
super();
|
|
1414
1449
|
|
|
@@ -1455,14 +1490,6 @@ class AuroCounter extends LitElement {
|
|
|
1455
1490
|
*/
|
|
1456
1491
|
this.runtimeUtils = new AuroLibraryRuntimeUtils$4();
|
|
1457
1492
|
|
|
1458
|
-
/**
|
|
1459
|
-
* @private
|
|
1460
|
-
* @property {boolean} delegatesFocus - Whether the shadow root delegates focus.
|
|
1461
|
-
*/
|
|
1462
|
-
this.constructor.shadowRootOptions = {
|
|
1463
|
-
...LitElement.shadowRootOptions,
|
|
1464
|
-
delegatesFocus: true,
|
|
1465
|
-
};
|
|
1466
1493
|
}
|
|
1467
1494
|
|
|
1468
1495
|
connectedCallback() {
|
|
@@ -1777,7 +1804,7 @@ class AuroCounter extends LitElement {
|
|
|
1777
1804
|
aria-valuemax="${this.max}"
|
|
1778
1805
|
aria-valuemin="${this.min}"
|
|
1779
1806
|
aria-valuenow="${this.value}"
|
|
1780
|
-
aria-valuetext="${this.value !== undefined ? this.value : this.min}"
|
|
1807
|
+
aria-valuetext="'${this.value !== undefined ? this.value : this.min}'"
|
|
1781
1808
|
role="spinbutton"
|
|
1782
1809
|
tabindex="${this.disabled ? '-1' : '0'}"
|
|
1783
1810
|
>
|
|
@@ -3544,11 +3571,9 @@ const computePosition = (reference, floating, options) => {
|
|
|
3544
3571
|
/* eslint-disable line-comment-position, no-inline-comments */
|
|
3545
3572
|
|
|
3546
3573
|
|
|
3547
|
-
|
|
3548
3574
|
const MAX_CONFIGURATION_COUNT = 10;
|
|
3549
3575
|
|
|
3550
3576
|
class AuroFloatingUI {
|
|
3551
|
-
|
|
3552
3577
|
/**
|
|
3553
3578
|
* @private
|
|
3554
3579
|
*/
|
|
@@ -3563,7 +3588,11 @@ class AuroFloatingUI {
|
|
|
3563
3588
|
* @private
|
|
3564
3589
|
*/
|
|
3565
3590
|
static setupMousePressChecker() {
|
|
3566
|
-
if (
|
|
3591
|
+
if (
|
|
3592
|
+
!AuroFloatingUI.isMousePressHandlerInitialized &&
|
|
3593
|
+
window &&
|
|
3594
|
+
window.addEventListener
|
|
3595
|
+
) {
|
|
3567
3596
|
AuroFloatingUI.isMousePressHandlerInitialized = true;
|
|
3568
3597
|
|
|
3569
3598
|
// Track timeout for isMousePressed reset to avoid race conditions
|
|
@@ -3571,7 +3600,7 @@ class AuroFloatingUI {
|
|
|
3571
3600
|
AuroFloatingUI._mousePressedTimeout = null;
|
|
3572
3601
|
}
|
|
3573
3602
|
const mouseEventGlobalHandler = (event) => {
|
|
3574
|
-
const isPressed = event.type ===
|
|
3603
|
+
const isPressed = event.type === "mousedown";
|
|
3575
3604
|
if (isPressed) {
|
|
3576
3605
|
// Clear any pending timeout to prevent race condition
|
|
3577
3606
|
if (AuroFloatingUI._mousePressedTimeout !== null) {
|
|
@@ -3590,8 +3619,8 @@ class AuroFloatingUI {
|
|
|
3590
3619
|
}
|
|
3591
3620
|
};
|
|
3592
3621
|
|
|
3593
|
-
window.addEventListener(
|
|
3594
|
-
window.addEventListener(
|
|
3622
|
+
window.addEventListener("mousedown", mouseEventGlobalHandler);
|
|
3623
|
+
window.addEventListener("mouseup", mouseEventGlobalHandler);
|
|
3595
3624
|
}
|
|
3596
3625
|
}
|
|
3597
3626
|
|
|
@@ -3639,11 +3668,12 @@ class AuroFloatingUI {
|
|
|
3639
3668
|
// mirror the boxsize from bibSizer
|
|
3640
3669
|
if (this.element.bibSizer && this.element.matchWidth) {
|
|
3641
3670
|
const sizerStyle = window.getComputedStyle(this.element.bibSizer);
|
|
3642
|
-
const bibContent =
|
|
3643
|
-
|
|
3671
|
+
const bibContent =
|
|
3672
|
+
this.element.bib.shadowRoot.querySelector(".container");
|
|
3673
|
+
if (sizerStyle.width !== "0px") {
|
|
3644
3674
|
bibContent.style.width = sizerStyle.width;
|
|
3645
3675
|
}
|
|
3646
|
-
if (sizerStyle.height !==
|
|
3676
|
+
if (sizerStyle.height !== "0px") {
|
|
3647
3677
|
bibContent.style.height = sizerStyle.height;
|
|
3648
3678
|
}
|
|
3649
3679
|
bibContent.style.maxWidth = sizerStyle.maxWidth;
|
|
@@ -3661,28 +3691,34 @@ class AuroFloatingUI {
|
|
|
3661
3691
|
* @returns {String} The positioning strategy, one of 'fullscreen', 'floating', 'cover'.
|
|
3662
3692
|
*/
|
|
3663
3693
|
getPositioningStrategy() {
|
|
3664
|
-
const breakpoint =
|
|
3694
|
+
const breakpoint =
|
|
3695
|
+
this.element.bib.mobileFullscreenBreakpoint ||
|
|
3696
|
+
this.element.floaterConfig?.fullscreenBreakpoint;
|
|
3665
3697
|
switch (this.behavior) {
|
|
3666
3698
|
case "tooltip":
|
|
3667
3699
|
return "floating";
|
|
3668
3700
|
case "dialog":
|
|
3669
3701
|
case "drawer":
|
|
3670
3702
|
if (breakpoint) {
|
|
3671
|
-
const smallerThanBreakpoint = window.matchMedia(
|
|
3703
|
+
const smallerThanBreakpoint = window.matchMedia(
|
|
3704
|
+
`(max-width: ${breakpoint})`,
|
|
3705
|
+
).matches;
|
|
3672
3706
|
|
|
3673
3707
|
this.element.expanded = smallerThanBreakpoint;
|
|
3674
3708
|
}
|
|
3675
3709
|
if (this.element.nested) {
|
|
3676
3710
|
return "cover";
|
|
3677
3711
|
}
|
|
3678
|
-
return
|
|
3712
|
+
return "fullscreen";
|
|
3679
3713
|
case "dropdown":
|
|
3680
3714
|
case undefined:
|
|
3681
3715
|
case null:
|
|
3682
3716
|
if (breakpoint) {
|
|
3683
|
-
const smallerThanBreakpoint = window.matchMedia(
|
|
3717
|
+
const smallerThanBreakpoint = window.matchMedia(
|
|
3718
|
+
`(max-width: ${breakpoint})`,
|
|
3719
|
+
).matches;
|
|
3684
3720
|
if (smallerThanBreakpoint) {
|
|
3685
|
-
return
|
|
3721
|
+
return "fullscreen";
|
|
3686
3722
|
}
|
|
3687
3723
|
}
|
|
3688
3724
|
return "floating";
|
|
@@ -3703,37 +3739,39 @@ class AuroFloatingUI {
|
|
|
3703
3739
|
const strategy = this.getPositioningStrategy();
|
|
3704
3740
|
this.configureBibStrategy(strategy);
|
|
3705
3741
|
|
|
3706
|
-
if (strategy ===
|
|
3742
|
+
if (strategy === "floating") {
|
|
3707
3743
|
this.mirrorSize();
|
|
3708
3744
|
// Define the middlware for the floater configuration
|
|
3709
3745
|
const middleware = [
|
|
3710
3746
|
offset(this.element.floaterConfig?.offset || 0),
|
|
3711
|
-
...this.element.floaterConfig?.shift ? [shift()] : [], // Add shift middleware if shift is enabled.
|
|
3712
|
-
...this.element.floaterConfig?.flip ? [flip()] : [], // Add flip middleware if flip is enabled.
|
|
3713
|
-
...this.element.floaterConfig?.autoPlacement ? [autoPlacement()] : [], // Add autoPlacement middleware if autoPlacement is enabled.
|
|
3747
|
+
...(this.element.floaterConfig?.shift ? [shift()] : []), // Add shift middleware if shift is enabled.
|
|
3748
|
+
...(this.element.floaterConfig?.flip ? [flip()] : []), // Add flip middleware if flip is enabled.
|
|
3749
|
+
...(this.element.floaterConfig?.autoPlacement ? [autoPlacement()] : []), // Add autoPlacement middleware if autoPlacement is enabled.
|
|
3714
3750
|
];
|
|
3715
3751
|
|
|
3716
3752
|
// Compute the position of the bib
|
|
3717
3753
|
computePosition(this.element.trigger, this.element.bib, {
|
|
3718
|
-
strategy: this.element.floaterConfig?.strategy ||
|
|
3754
|
+
strategy: this.element.floaterConfig?.strategy || "fixed",
|
|
3719
3755
|
placement: this.element.floaterConfig?.placement,
|
|
3720
|
-
middleware: middleware || []
|
|
3721
|
-
}).then(({ x, y }) => {
|
|
3756
|
+
middleware: middleware || [],
|
|
3757
|
+
}).then(({ x, y }) => {
|
|
3758
|
+
// eslint-disable-line id-length
|
|
3722
3759
|
Object.assign(this.element.bib.style, {
|
|
3723
3760
|
left: `${x}px`,
|
|
3724
3761
|
top: `${y}px`,
|
|
3725
3762
|
});
|
|
3726
3763
|
});
|
|
3727
|
-
} else if (strategy ===
|
|
3764
|
+
} else if (strategy === "cover") {
|
|
3728
3765
|
// Compute the position of the bib
|
|
3729
3766
|
computePosition(this.element.parentNode, this.element.bib, {
|
|
3730
|
-
placement:
|
|
3731
|
-
}).then(({ x, y }) => {
|
|
3767
|
+
placement: "bottom-start",
|
|
3768
|
+
}).then(({ x, y }) => {
|
|
3769
|
+
// eslint-disable-line id-length
|
|
3732
3770
|
Object.assign(this.element.bib.style, {
|
|
3733
3771
|
left: `${x}px`,
|
|
3734
3772
|
top: `${y - this.element.parentNode.offsetHeight}px`,
|
|
3735
3773
|
width: `${this.element.parentNode.offsetWidth}px`,
|
|
3736
|
-
height: `${this.element.parentNode.offsetHeight}px
|
|
3774
|
+
height: `${this.element.parentNode.offsetHeight}px`,
|
|
3737
3775
|
});
|
|
3738
3776
|
});
|
|
3739
3777
|
}
|
|
@@ -3746,12 +3784,12 @@ class AuroFloatingUI {
|
|
|
3746
3784
|
*/
|
|
3747
3785
|
lockScroll(lock = true) {
|
|
3748
3786
|
if (lock) {
|
|
3749
|
-
document.body.style.overflow =
|
|
3787
|
+
document.body.style.overflow = "hidden"; // hide body's scrollbar
|
|
3750
3788
|
|
|
3751
3789
|
// Move `bib` by the amount the viewport is shifted to stay aligned in fullscreen.
|
|
3752
3790
|
this.element.bib.style.transform = `translateY(${window?.visualViewport?.offsetTop}px)`;
|
|
3753
3791
|
} else {
|
|
3754
|
-
document.body.style.overflow =
|
|
3792
|
+
document.body.style.overflow = "";
|
|
3755
3793
|
}
|
|
3756
3794
|
}
|
|
3757
3795
|
|
|
@@ -3765,23 +3803,24 @@ class AuroFloatingUI {
|
|
|
3765
3803
|
* @param {string} strategy - The positioning strategy ('fullscreen' or 'floating').
|
|
3766
3804
|
*/
|
|
3767
3805
|
configureBibStrategy(value) {
|
|
3768
|
-
if (value ===
|
|
3806
|
+
if (value === "fullscreen") {
|
|
3769
3807
|
this.element.isBibFullscreen = true;
|
|
3770
3808
|
// reset the prev position
|
|
3771
|
-
this.element.bib.setAttribute(
|
|
3772
|
-
this.element.bib.style.position =
|
|
3809
|
+
this.element.bib.setAttribute("isfullscreen", "");
|
|
3810
|
+
this.element.bib.style.position = "fixed";
|
|
3773
3811
|
this.element.bib.style.top = "0px";
|
|
3774
3812
|
this.element.bib.style.left = "0px";
|
|
3775
|
-
this.element.bib.style.width =
|
|
3776
|
-
this.element.bib.style.height =
|
|
3777
|
-
this.element.style.contain =
|
|
3813
|
+
this.element.bib.style.width = "";
|
|
3814
|
+
this.element.bib.style.height = "";
|
|
3815
|
+
this.element.style.contain = "";
|
|
3778
3816
|
|
|
3779
3817
|
// reset the size that was mirroring `size` css-part
|
|
3780
|
-
const bibContent =
|
|
3818
|
+
const bibContent =
|
|
3819
|
+
this.element.bib.shadowRoot.querySelector(".container");
|
|
3781
3820
|
if (bibContent) {
|
|
3782
|
-
bibContent.style.width =
|
|
3783
|
-
bibContent.style.height =
|
|
3784
|
-
bibContent.style.maxWidth =
|
|
3821
|
+
bibContent.style.width = "";
|
|
3822
|
+
bibContent.style.height = "";
|
|
3823
|
+
bibContent.style.maxWidth = "";
|
|
3785
3824
|
bibContent.style.maxHeight = `${window?.visualViewport?.height}px`;
|
|
3786
3825
|
this.configureTrial = 0;
|
|
3787
3826
|
} else if (this.configureTrial < MAX_CONFIGURATION_COUNT) {
|
|
@@ -3796,21 +3835,26 @@ class AuroFloatingUI {
|
|
|
3796
3835
|
this.lockScroll(true);
|
|
3797
3836
|
}
|
|
3798
3837
|
} else {
|
|
3799
|
-
this.element.bib.style.position =
|
|
3800
|
-
this.element.bib.removeAttribute(
|
|
3838
|
+
this.element.bib.style.position = "";
|
|
3839
|
+
this.element.bib.removeAttribute("isfullscreen");
|
|
3801
3840
|
this.element.isBibFullscreen = false;
|
|
3802
|
-
this.element.style.contain =
|
|
3841
|
+
this.element.style.contain = "layout";
|
|
3803
3842
|
}
|
|
3804
3843
|
|
|
3805
3844
|
const isChanged = this.strategy && this.strategy !== value;
|
|
3806
3845
|
this.strategy = value;
|
|
3807
3846
|
if (isChanged) {
|
|
3808
|
-
const event = new CustomEvent(
|
|
3809
|
-
|
|
3810
|
-
|
|
3847
|
+
const event = new CustomEvent(
|
|
3848
|
+
this.eventPrefix
|
|
3849
|
+
? `${this.eventPrefix}-strategy-change`
|
|
3850
|
+
: "strategy-change",
|
|
3851
|
+
{
|
|
3852
|
+
detail: {
|
|
3853
|
+
value,
|
|
3854
|
+
},
|
|
3855
|
+
composed: true,
|
|
3811
3856
|
},
|
|
3812
|
-
|
|
3813
|
-
});
|
|
3857
|
+
);
|
|
3814
3858
|
|
|
3815
3859
|
this.element.dispatchEvent(event);
|
|
3816
3860
|
}
|
|
@@ -3842,19 +3886,24 @@ class AuroFloatingUI {
|
|
|
3842
3886
|
return;
|
|
3843
3887
|
}
|
|
3844
3888
|
|
|
3845
|
-
if (
|
|
3846
|
-
this.element.
|
|
3889
|
+
if (
|
|
3890
|
+
this.element.noHideOnThisFocusLoss ||
|
|
3891
|
+
this.element.hasAttribute("noHideOnThisFocusLoss")
|
|
3892
|
+
) {
|
|
3847
3893
|
return;
|
|
3848
3894
|
}
|
|
3849
3895
|
|
|
3850
3896
|
const { activeElement } = document;
|
|
3851
3897
|
// if focus is still inside of trigger or bib, do not close
|
|
3852
|
-
if (
|
|
3898
|
+
if (
|
|
3899
|
+
this.element.contains(activeElement) ||
|
|
3900
|
+
this.element.bib?.contains(activeElement)
|
|
3901
|
+
) {
|
|
3853
3902
|
return;
|
|
3854
3903
|
}
|
|
3855
3904
|
|
|
3856
3905
|
// if fullscreen bib is in fullscreen mode, do not close
|
|
3857
|
-
if (this.element.bib.hasAttribute(
|
|
3906
|
+
if (this.element.bib.hasAttribute("isfullscreen")) {
|
|
3858
3907
|
return;
|
|
3859
3908
|
}
|
|
3860
3909
|
|
|
@@ -3866,12 +3915,27 @@ class AuroFloatingUI {
|
|
|
3866
3915
|
this.focusHandler = () => this.handleFocusLoss();
|
|
3867
3916
|
|
|
3868
3917
|
this.clickHandler = (evt) => {
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3918
|
+
// When the bib is fullscreen (modal dialog), don't close on outside
|
|
3919
|
+
// clicks. VoiceOver's synthetic click events inside a top-layer modal
|
|
3920
|
+
// <dialog> may not include the bib in composedPath(), causing false
|
|
3921
|
+
// positives. This mirrors the fullscreen guard in handleFocusLoss().
|
|
3922
|
+
if (this.element.bib && this.element.bib.hasAttribute("isfullscreen")) {
|
|
3923
|
+
return;
|
|
3924
|
+
}
|
|
3873
3925
|
|
|
3874
|
-
|
|
3926
|
+
if (
|
|
3927
|
+
(!evt.composedPath().includes(this.element.trigger) &&
|
|
3928
|
+
!evt.composedPath().includes(this.element.bib)) ||
|
|
3929
|
+
(this.element.bib.backdrop &&
|
|
3930
|
+
evt.composedPath().includes(this.element.bib.backdrop))
|
|
3931
|
+
) {
|
|
3932
|
+
const existedVisibleFloatingUI =
|
|
3933
|
+
document.expandedAuroFormkitDropdown || document.expandedAuroFloater;
|
|
3934
|
+
|
|
3935
|
+
if (
|
|
3936
|
+
existedVisibleFloatingUI &&
|
|
3937
|
+
existedVisibleFloatingUI.element.isPopoverVisible
|
|
3938
|
+
) {
|
|
3875
3939
|
// if something else is open, close that
|
|
3876
3940
|
existedVisibleFloatingUI.hideBib();
|
|
3877
3941
|
document.expandedAuroFormkitDropdown = null;
|
|
@@ -3884,9 +3948,14 @@ class AuroFloatingUI {
|
|
|
3884
3948
|
|
|
3885
3949
|
// ESC key handler
|
|
3886
3950
|
this.keyDownHandler = (evt) => {
|
|
3887
|
-
if (evt.key ===
|
|
3888
|
-
const existedVisibleFloatingUI =
|
|
3889
|
-
|
|
3951
|
+
if (evt.key === "Escape" && this.element.isPopoverVisible) {
|
|
3952
|
+
const existedVisibleFloatingUI =
|
|
3953
|
+
document.expandedAuroFormkitDropdown || document.expandedAuroFloater;
|
|
3954
|
+
if (
|
|
3955
|
+
existedVisibleFloatingUI &&
|
|
3956
|
+
existedVisibleFloatingUI !== this &&
|
|
3957
|
+
existedVisibleFloatingUI.element.isPopoverVisible
|
|
3958
|
+
) {
|
|
3890
3959
|
// if something else is open, let it handle itself
|
|
3891
3960
|
return;
|
|
3892
3961
|
}
|
|
@@ -3894,17 +3963,17 @@ class AuroFloatingUI {
|
|
|
3894
3963
|
}
|
|
3895
3964
|
};
|
|
3896
3965
|
|
|
3897
|
-
if (this.behavior !==
|
|
3966
|
+
if (this.behavior !== "drawer" && this.behavior !== "dialog") {
|
|
3898
3967
|
// Add event listeners using the stored references
|
|
3899
|
-
document.addEventListener(
|
|
3968
|
+
document.addEventListener("focusin", this.focusHandler);
|
|
3900
3969
|
}
|
|
3901
3970
|
|
|
3902
|
-
document.addEventListener(
|
|
3971
|
+
document.addEventListener("keydown", this.keyDownHandler);
|
|
3903
3972
|
|
|
3904
3973
|
// send this task to the end of queue to prevent conflicting
|
|
3905
3974
|
// it conflicts if showBib gets call from a button that's not this.element.trigger
|
|
3906
3975
|
setTimeout(() => {
|
|
3907
|
-
window.addEventListener(
|
|
3976
|
+
window.addEventListener("click", this.clickHandler);
|
|
3908
3977
|
}, 0);
|
|
3909
3978
|
}
|
|
3910
3979
|
|
|
@@ -3912,34 +3981,38 @@ class AuroFloatingUI {
|
|
|
3912
3981
|
// Remove event listeners if they exist
|
|
3913
3982
|
|
|
3914
3983
|
if (this.focusHandler) {
|
|
3915
|
-
document.removeEventListener(
|
|
3984
|
+
document.removeEventListener("focusin", this.focusHandler);
|
|
3916
3985
|
this.focusHandler = null;
|
|
3917
3986
|
}
|
|
3918
3987
|
|
|
3919
3988
|
if (this.clickHandler) {
|
|
3920
|
-
window.removeEventListener(
|
|
3989
|
+
window.removeEventListener("click", this.clickHandler);
|
|
3921
3990
|
this.clickHandler = null;
|
|
3922
3991
|
}
|
|
3923
3992
|
|
|
3924
3993
|
if (this.keyDownHandler) {
|
|
3925
|
-
document.removeEventListener(
|
|
3994
|
+
document.removeEventListener("keydown", this.keyDownHandler);
|
|
3926
3995
|
this.keyDownHandler = null;
|
|
3927
3996
|
}
|
|
3928
3997
|
}
|
|
3929
3998
|
|
|
3930
3999
|
handleUpdate(changedProperties) {
|
|
3931
|
-
if (changedProperties.has(
|
|
4000
|
+
if (changedProperties.has("isPopoverVisible")) {
|
|
3932
4001
|
this.updateState();
|
|
3933
4002
|
}
|
|
3934
4003
|
}
|
|
3935
4004
|
|
|
3936
4005
|
updateCurrentExpandedDropdown() {
|
|
3937
4006
|
// Close any other dropdown that is already open
|
|
3938
|
-
const existedVisibleFloatingUI =
|
|
3939
|
-
|
|
4007
|
+
const existedVisibleFloatingUI =
|
|
4008
|
+
document.expandedAuroFormkitDropdown || document.expandedAuroFloater;
|
|
4009
|
+
if (
|
|
4010
|
+
existedVisibleFloatingUI &&
|
|
4011
|
+
existedVisibleFloatingUI !== this &&
|
|
3940
4012
|
existedVisibleFloatingUI.element.isPopoverVisible &&
|
|
3941
|
-
|
|
3942
|
-
|
|
4013
|
+
existedVisibleFloatingUI.eventPrefix === this.eventPrefix
|
|
4014
|
+
) {
|
|
4015
|
+
existedVisibleFloatingUI.hideBib();
|
|
3943
4016
|
}
|
|
3944
4017
|
|
|
3945
4018
|
document.expandedAuroFloater = this;
|
|
@@ -3948,7 +4021,7 @@ class AuroFloatingUI {
|
|
|
3948
4021
|
showBib() {
|
|
3949
4022
|
if (!this.element.disabled && !this.showing) {
|
|
3950
4023
|
this.updateCurrentExpandedDropdown();
|
|
3951
|
-
this.element.triggerChevron?.setAttribute(
|
|
4024
|
+
this.element.triggerChevron?.setAttribute("data-expanded", true);
|
|
3952
4025
|
|
|
3953
4026
|
// prevent double showing: isPopovervisible gets first and showBib gets called later
|
|
3954
4027
|
if (!this.showing) {
|
|
@@ -3962,9 +4035,13 @@ class AuroFloatingUI {
|
|
|
3962
4035
|
}
|
|
3963
4036
|
|
|
3964
4037
|
// Setup auto update to handle resize and scroll
|
|
3965
|
-
this.element.cleanup = autoUpdate(
|
|
3966
|
-
this.
|
|
3967
|
-
|
|
4038
|
+
this.element.cleanup = autoUpdate(
|
|
4039
|
+
this.element.trigger || this.element.parentNode,
|
|
4040
|
+
this.element.bib,
|
|
4041
|
+
() => {
|
|
4042
|
+
this.position();
|
|
4043
|
+
},
|
|
4044
|
+
);
|
|
3968
4045
|
}
|
|
3969
4046
|
}
|
|
3970
4047
|
|
|
@@ -3975,7 +4052,7 @@ class AuroFloatingUI {
|
|
|
3975
4052
|
hideBib(eventType = "unknown") {
|
|
3976
4053
|
if (!this.element.disabled && !this.element.noToggle) {
|
|
3977
4054
|
this.lockScroll(false);
|
|
3978
|
-
this.element.triggerChevron?.removeAttribute(
|
|
4055
|
+
this.element.triggerChevron?.removeAttribute("data-expanded");
|
|
3979
4056
|
|
|
3980
4057
|
if (this.element.isPopoverVisible) {
|
|
3981
4058
|
this.element.isPopoverVisible = false;
|
|
@@ -3995,13 +4072,16 @@ class AuroFloatingUI {
|
|
|
3995
4072
|
* @param {String} eventType - The event type that triggered the toggle action.
|
|
3996
4073
|
*/
|
|
3997
4074
|
dispatchEventDropdownToggle(eventType) {
|
|
3998
|
-
const event = new CustomEvent(
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4075
|
+
const event = new CustomEvent(
|
|
4076
|
+
this.eventPrefix ? `${this.eventPrefix}-toggled` : "toggled",
|
|
4077
|
+
{
|
|
4078
|
+
detail: {
|
|
4079
|
+
expanded: this.showing,
|
|
4080
|
+
eventType: eventType || "unknown",
|
|
4081
|
+
},
|
|
4082
|
+
composed: true,
|
|
4002
4083
|
},
|
|
4003
|
-
|
|
4004
|
-
});
|
|
4084
|
+
);
|
|
4005
4085
|
|
|
4006
4086
|
this.element.dispatchEvent(event);
|
|
4007
4087
|
}
|
|
@@ -4013,12 +4093,15 @@ class AuroFloatingUI {
|
|
|
4013
4093
|
this.showBib();
|
|
4014
4094
|
}
|
|
4015
4095
|
|
|
4016
|
-
const event = new CustomEvent(
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4096
|
+
const event = new CustomEvent(
|
|
4097
|
+
this.eventPrefix ? `${this.eventPrefix}-triggerClick` : "triggerClick",
|
|
4098
|
+
{
|
|
4099
|
+
composed: true,
|
|
4100
|
+
detail: {
|
|
4101
|
+
expanded: this.element.isPopoverVisible,
|
|
4102
|
+
},
|
|
4103
|
+
},
|
|
4104
|
+
);
|
|
4022
4105
|
|
|
4023
4106
|
this.element.dispatchEvent(event);
|
|
4024
4107
|
}
|
|
@@ -4026,30 +4109,32 @@ class AuroFloatingUI {
|
|
|
4026
4109
|
handleEvent(event) {
|
|
4027
4110
|
if (!this.element.disableEventShow) {
|
|
4028
4111
|
switch (event.type) {
|
|
4029
|
-
case
|
|
4112
|
+
case "keydown": {
|
|
4030
4113
|
// Support both Enter and Space keys for accessibility
|
|
4031
4114
|
// Space is included as it's expected behavior for interactive elements
|
|
4032
4115
|
|
|
4033
4116
|
const origin = event.composedPath()[0];
|
|
4034
|
-
if (
|
|
4035
|
-
|
|
4117
|
+
if (
|
|
4118
|
+
event.key === "Enter" ||
|
|
4119
|
+
(event.key === " " && (!origin || origin.tagName !== "INPUT"))
|
|
4120
|
+
) {
|
|
4036
4121
|
event.preventDefault();
|
|
4037
4122
|
this.handleClick();
|
|
4038
4123
|
}
|
|
4039
4124
|
break;
|
|
4040
|
-
|
|
4125
|
+
}
|
|
4126
|
+
case "mouseenter":
|
|
4041
4127
|
if (this.element.hoverToggle) {
|
|
4042
4128
|
this.showBib();
|
|
4043
4129
|
}
|
|
4044
4130
|
break;
|
|
4045
|
-
case
|
|
4131
|
+
case "mouseleave":
|
|
4046
4132
|
if (this.element.hoverToggle) {
|
|
4047
4133
|
this.hideBib("mouseleave");
|
|
4048
4134
|
}
|
|
4049
4135
|
break;
|
|
4050
|
-
case
|
|
4136
|
+
case "focus":
|
|
4051
4137
|
if (this.element.focusShow) {
|
|
4052
|
-
|
|
4053
4138
|
/*
|
|
4054
4139
|
This needs to better handle clicking that gives focus -
|
|
4055
4140
|
currently it shows and then immediately hides the bib
|
|
@@ -4057,12 +4142,12 @@ class AuroFloatingUI {
|
|
|
4057
4142
|
this.showBib();
|
|
4058
4143
|
}
|
|
4059
4144
|
break;
|
|
4060
|
-
case
|
|
4145
|
+
case "blur":
|
|
4061
4146
|
// send this task 100ms later queue to
|
|
4062
4147
|
// wait a frame in case focus moves within the floating element/bib
|
|
4063
4148
|
setTimeout(() => this.handleFocusLoss(), 0);
|
|
4064
4149
|
break;
|
|
4065
|
-
case
|
|
4150
|
+
case "click":
|
|
4066
4151
|
if (document.activeElement === document.body) {
|
|
4067
4152
|
event.currentTarget.focus();
|
|
4068
4153
|
}
|
|
@@ -4081,15 +4166,15 @@ class AuroFloatingUI {
|
|
|
4081
4166
|
*/
|
|
4082
4167
|
handleTriggerTabIndex() {
|
|
4083
4168
|
const focusableElementSelectors = [
|
|
4084
|
-
|
|
4085
|
-
|
|
4169
|
+
"a",
|
|
4170
|
+
"button",
|
|
4086
4171
|
'input:not([type="hidden"])',
|
|
4087
|
-
|
|
4088
|
-
|
|
4172
|
+
"select",
|
|
4173
|
+
"textarea",
|
|
4089
4174
|
'[tabindex]:not([tabindex="-1"])',
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4175
|
+
"auro-button",
|
|
4176
|
+
"auro-input",
|
|
4177
|
+
"auro-hyperlink",
|
|
4093
4178
|
];
|
|
4094
4179
|
|
|
4095
4180
|
const triggerNode = this.element.querySelectorAll('[slot="trigger"]')[0];
|
|
@@ -4117,10 +4202,10 @@ class AuroFloatingUI {
|
|
|
4117
4202
|
* @param {*} eventPrefix
|
|
4118
4203
|
*/
|
|
4119
4204
|
regenerateBibId() {
|
|
4120
|
-
this.id = this.element.getAttribute(
|
|
4205
|
+
this.id = this.element.getAttribute("id");
|
|
4121
4206
|
if (!this.id) {
|
|
4122
4207
|
this.id = window.crypto.randomUUID();
|
|
4123
|
-
this.element.setAttribute(
|
|
4208
|
+
this.element.setAttribute("id", this.id);
|
|
4124
4209
|
}
|
|
4125
4210
|
|
|
4126
4211
|
this.element.bib.setAttribute("id", `${this.id}-floater-bib`);
|
|
@@ -4141,11 +4226,15 @@ class AuroFloatingUI {
|
|
|
4141
4226
|
if (this.element.trigger) {
|
|
4142
4227
|
this.disconnect();
|
|
4143
4228
|
}
|
|
4144
|
-
this.element.trigger =
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4229
|
+
this.element.trigger =
|
|
4230
|
+
this.element.triggerElement ||
|
|
4231
|
+
this.element.shadowRoot.querySelector("#trigger") ||
|
|
4232
|
+
this.element.trigger;
|
|
4233
|
+
this.element.bib =
|
|
4234
|
+
this.element.shadowRoot.querySelector("#bib") || this.element.bib;
|
|
4235
|
+
this.element.bibSizer = this.element.shadowRoot.querySelector("#bibSizer");
|
|
4236
|
+
this.element.triggerChevron =
|
|
4237
|
+
this.element.shadowRoot.querySelector("#showStateIcon");
|
|
4149
4238
|
|
|
4150
4239
|
if (this.element.floaterConfig) {
|
|
4151
4240
|
this.element.hoverToggle = this.element.floaterConfig.hoverToggle;
|
|
@@ -4156,12 +4245,12 @@ class AuroFloatingUI {
|
|
|
4156
4245
|
|
|
4157
4246
|
this.handleEvent = this.handleEvent.bind(this);
|
|
4158
4247
|
if (this.element.trigger) {
|
|
4159
|
-
this.element.trigger.addEventListener(
|
|
4160
|
-
this.element.trigger.addEventListener(
|
|
4161
|
-
this.element.trigger.addEventListener(
|
|
4162
|
-
this.element.trigger.addEventListener(
|
|
4163
|
-
this.element.trigger.addEventListener(
|
|
4164
|
-
this.element.trigger.addEventListener(
|
|
4248
|
+
this.element.trigger.addEventListener("keydown", this.handleEvent);
|
|
4249
|
+
this.element.trigger.addEventListener("click", this.handleEvent);
|
|
4250
|
+
this.element.trigger.addEventListener("mouseenter", this.handleEvent);
|
|
4251
|
+
this.element.trigger.addEventListener("mouseleave", this.handleEvent);
|
|
4252
|
+
this.element.trigger.addEventListener("focus", this.handleEvent);
|
|
4253
|
+
this.element.trigger.addEventListener("blur", this.handleEvent);
|
|
4165
4254
|
}
|
|
4166
4255
|
}
|
|
4167
4256
|
|
|
@@ -4176,12 +4265,18 @@ class AuroFloatingUI {
|
|
|
4176
4265
|
|
|
4177
4266
|
// Remove event & keyboard listeners
|
|
4178
4267
|
if (this.element?.trigger) {
|
|
4179
|
-
this.element.trigger.removeEventListener(
|
|
4180
|
-
this.element.trigger.removeEventListener(
|
|
4181
|
-
this.element.trigger.removeEventListener(
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4268
|
+
this.element.trigger.removeEventListener("keydown", this.handleEvent);
|
|
4269
|
+
this.element.trigger.removeEventListener("click", this.handleEvent);
|
|
4270
|
+
this.element.trigger.removeEventListener(
|
|
4271
|
+
"mouseenter",
|
|
4272
|
+
this.handleEvent,
|
|
4273
|
+
);
|
|
4274
|
+
this.element.trigger.removeEventListener(
|
|
4275
|
+
"mouseleave",
|
|
4276
|
+
this.handleEvent,
|
|
4277
|
+
);
|
|
4278
|
+
this.element.trigger.removeEventListener("focus", this.handleEvent);
|
|
4279
|
+
this.element.trigger.removeEventListener("blur", this.handleEvent);
|
|
4185
4280
|
}
|
|
4186
4281
|
}
|
|
4187
4282
|
}
|
|
@@ -4628,7 +4723,7 @@ let p$2 = class p{registerComponent(t,a){customElements.get(t)||customElements.d
|
|
|
4628
4723
|
|
|
4629
4724
|
var iconVersion$1 = '9.1.2';
|
|
4630
4725
|
|
|
4631
|
-
var styleCss$2 = css`:host{position:fixed;z-index:var(--depth-tooltip, 400);display:none;isolation:isolate}:host(:not([matchWidth])) .container{min-width:fit-content}:host([isfullscreen]){position:fixed;top:0;left:0}:host([isfullscreen]) .container{width:100dvw;max-width:none;height:100dvh;max-height:none;border-radius:unset;margin-top:0;box-shadow:unset;overscroll-behavior:contain}:host([data-show]){display:flex}:host([common]:not([isfullscreen])) .container,:host([rounded]:not([isfullscreen])) .container{border-radius:var(--ds-border-radius, 0.375rem)}:host([common][isfullscreen]) .container,:host([rounded][isfullscreen]) .container{border-radius:unset;box-shadow:unset}
|
|
4726
|
+
var styleCss$2 = css`:host{position:fixed;z-index:var(--depth-tooltip, 400);display:none;isolation:isolate}:host dialog{width:auto;max-width:none;height:auto;max-height:none;padding:0;border:none;margin:0;outline:none;transform:translateZ(0)}:host dialog::backdrop{background:transparent}:host(:not([isfullscreen])) dialog{position:relative;inset:unset}:host(:not([isfullscreen])) .container.shape-box{border-radius:unset}:host(:not([isfullscreen])) .container[class*=shape-pill],:host(:not([isfullscreen])) .container[class*=shape-snowflake]{border-radius:30px}:host(:not([isfullscreen])) .container[class*=shape-rounded]{border-radius:16px}:host(:not([matchWidth])) .container{min-width:fit-content}:host([isfullscreen]){position:fixed;top:0;left:0}:host([isfullscreen]) .container{width:100dvw;max-width:none;height:100dvh;max-height:none;border-radius:unset;margin-top:0;box-shadow:unset;overscroll-behavior:contain}:host([isfullscreen]) .container::backdrop{background:var(--ds-color-background-primary, #fff)}:host([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}`;
|
|
4632
4727
|
|
|
4633
4728
|
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)}`;
|
|
4634
4729
|
|
|
@@ -4636,6 +4731,8 @@ var tokensCss$1 = css`:host(:not([ondark])),:host(:not([appearance=inverse])){--
|
|
|
4636
4731
|
|
|
4637
4732
|
// Copyright (c) 2020 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
4638
4733
|
// See LICENSE in the project root for license information.
|
|
4734
|
+
/* eslint-disable max-lines */
|
|
4735
|
+
// ---------------------------------------------------------------------
|
|
4639
4736
|
|
|
4640
4737
|
|
|
4641
4738
|
const DESIGN_TOKEN_BREAKPOINT_PREFIX = '--ds-grid-breakpoint-';
|
|
@@ -4730,6 +4827,28 @@ class AuroDropdownBib extends LitElement {
|
|
|
4730
4827
|
shape: {
|
|
4731
4828
|
type: String,
|
|
4732
4829
|
reflect: true
|
|
4830
|
+
},
|
|
4831
|
+
|
|
4832
|
+
/**
|
|
4833
|
+
* Accessible label for the dialog element, used when displayed as a modal.
|
|
4834
|
+
* Applied via aria-labelledby on a visually hidden element rather than
|
|
4835
|
+
* aria-label because iOS VoiceOver does not reliably read aria-label
|
|
4836
|
+
* on <dialog> elements.
|
|
4837
|
+
* @private
|
|
4838
|
+
*/
|
|
4839
|
+
dialogLabel: {
|
|
4840
|
+
type: String
|
|
4841
|
+
},
|
|
4842
|
+
|
|
4843
|
+
/**
|
|
4844
|
+
* Overrides the native role of the dialog element.
|
|
4845
|
+
* For example, set to `"presentation"` on desktop combobox to prevent
|
|
4846
|
+
* VoiceOver from announcing "listbox inside of a dialog".
|
|
4847
|
+
* When `undefined`, the dialog keeps its native role.
|
|
4848
|
+
* @private
|
|
4849
|
+
*/
|
|
4850
|
+
dialogRole: {
|
|
4851
|
+
type: String
|
|
4733
4852
|
}
|
|
4734
4853
|
};
|
|
4735
4854
|
}
|
|
@@ -4797,7 +4916,10 @@ class AuroDropdownBib extends LitElement {
|
|
|
4797
4916
|
firstUpdated(changedProperties) {
|
|
4798
4917
|
super.firstUpdated(changedProperties);
|
|
4799
4918
|
|
|
4800
|
-
|
|
4919
|
+
const dialog = this.shadowRoot.querySelector('dialog');
|
|
4920
|
+
this._setupCancelHandler(dialog);
|
|
4921
|
+
this._setupKeyboardBridge(dialog);
|
|
4922
|
+
|
|
4801
4923
|
this.dispatchEvent(new CustomEvent('auro-dropdownbib-connected', {
|
|
4802
4924
|
bubbles: true,
|
|
4803
4925
|
composed: true,
|
|
@@ -4807,6 +4929,189 @@ class AuroDropdownBib extends LitElement {
|
|
|
4807
4929
|
}));
|
|
4808
4930
|
}
|
|
4809
4931
|
|
|
4932
|
+
/**
|
|
4933
|
+
* Forwards the dialog's native `cancel` event (fired on ESC) as
|
|
4934
|
+
* an `auro-bib-cancel` custom event so parent components can close.
|
|
4935
|
+
* @param {HTMLDialogElement} dialog
|
|
4936
|
+
* @private
|
|
4937
|
+
*/
|
|
4938
|
+
_setupCancelHandler(dialog) {
|
|
4939
|
+
dialog.addEventListener('cancel', (event) => {
|
|
4940
|
+
event.preventDefault();
|
|
4941
|
+
this.dispatchEvent(new CustomEvent('auro-bib-cancel', {
|
|
4942
|
+
bubbles: true,
|
|
4943
|
+
composed: true
|
|
4944
|
+
}));
|
|
4945
|
+
});
|
|
4946
|
+
}
|
|
4947
|
+
|
|
4948
|
+
/**
|
|
4949
|
+
* showModal() creates a closed focus scope — keyboard events inside
|
|
4950
|
+
* the dialog's shadow DOM do NOT bubble out to the combobox/select
|
|
4951
|
+
* keydown handlers in the parent shadow DOM. This handler bridges
|
|
4952
|
+
* that gap by re-dispatching navigation keys so they cross the
|
|
4953
|
+
* shadow boundary and reach the menu navigation logic in the parent
|
|
4954
|
+
* component.
|
|
4955
|
+
*
|
|
4956
|
+
* The trade-off: intercepting these keys means native keyboard
|
|
4957
|
+
* behaviors that would normally "just work" must be manually
|
|
4958
|
+
* re-implemented here:
|
|
4959
|
+
*
|
|
4960
|
+
* - Enter on buttons: Custom elements (auro-button) don't get the
|
|
4961
|
+
* native Enter→click that <button> provides, so we call .click()
|
|
4962
|
+
* directly when Enter is pressed on a button-like element.
|
|
4963
|
+
*
|
|
4964
|
+
* - Tab: Intercepted and re-dispatched so parent components
|
|
4965
|
+
* (select/combobox) can select the active option and close the
|
|
4966
|
+
* dialog. The <dialog> provides containment and isolation
|
|
4967
|
+
* (inert background, VoiceOver focus trapping, top layer), while
|
|
4968
|
+
* the content inside is a role="listbox" navigated via
|
|
4969
|
+
* aria-activedescendant (options are not focusable). Tab keyboard
|
|
4970
|
+
* behavior follows listbox conventions (select + close) because
|
|
4971
|
+
* the dialog's native Tab trap only cycles between the close
|
|
4972
|
+
* button and browser chrome.
|
|
4973
|
+
*
|
|
4974
|
+
* - Escape: The native <dialog> fires a `cancel` event on ESC
|
|
4975
|
+
* (handled by _setupCancelHandler), so the re-dispatched Escape
|
|
4976
|
+
* is a secondary path for parent components that also listen for
|
|
4977
|
+
* Escape keydown.
|
|
4978
|
+
*
|
|
4979
|
+
* @param {HTMLDialogElement} dialog
|
|
4980
|
+
* @private
|
|
4981
|
+
*/
|
|
4982
|
+
_setupKeyboardBridge(dialog) {
|
|
4983
|
+
const navKeys = new Set([
|
|
4984
|
+
'ArrowUp',
|
|
4985
|
+
'ArrowDown',
|
|
4986
|
+
'Enter',
|
|
4987
|
+
'Escape',
|
|
4988
|
+
'Tab'
|
|
4989
|
+
]);
|
|
4990
|
+
|
|
4991
|
+
dialog.addEventListener('keydown', (event) => {
|
|
4992
|
+
if (!navKeys.has(event.key)) {
|
|
4993
|
+
return;
|
|
4994
|
+
}
|
|
4995
|
+
|
|
4996
|
+
// Custom elements (auro-button) don't get the native Enter→click
|
|
4997
|
+
// behavior that <button> has. Find the button in the composed path
|
|
4998
|
+
// and click it directly.
|
|
4999
|
+
if (event.key === 'Enter') {
|
|
5000
|
+
const buttonSelector = 'button, [role="button"], auro-button, [auro-button]';
|
|
5001
|
+
const btn = event.composedPath().find((el) => el.matches && el.matches(buttonSelector));
|
|
5002
|
+
if (btn) {
|
|
5003
|
+
event.preventDefault();
|
|
5004
|
+
event.stopPropagation();
|
|
5005
|
+
btn.click();
|
|
5006
|
+
return;
|
|
5007
|
+
}
|
|
5008
|
+
}
|
|
5009
|
+
|
|
5010
|
+
event.preventDefault();
|
|
5011
|
+
event.stopPropagation();
|
|
5012
|
+
const newEvent = new KeyboardEvent('keydown', {
|
|
5013
|
+
key: event.key,
|
|
5014
|
+
code: event.code,
|
|
5015
|
+
shiftKey: event.shiftKey,
|
|
5016
|
+
altKey: event.altKey,
|
|
5017
|
+
ctrlKey: event.ctrlKey,
|
|
5018
|
+
metaKey: event.metaKey,
|
|
5019
|
+
bubbles: true,
|
|
5020
|
+
composed: true,
|
|
5021
|
+
cancelable: true
|
|
5022
|
+
});
|
|
5023
|
+
this.dispatchEvent(newEvent);
|
|
5024
|
+
});
|
|
5025
|
+
}
|
|
5026
|
+
|
|
5027
|
+
/**
|
|
5028
|
+
* Blocks touch-driven page scroll while a fullscreen modal dialog is open.
|
|
5029
|
+
*
|
|
5030
|
+
* The showModal() function places the dialog in the browser's **top layer**,
|
|
5031
|
+
* which is a separate rendering layer above the normal DOM. On mobile, the
|
|
5032
|
+
* compositor processes visual-viewport panning before top-layer touch
|
|
5033
|
+
* handling. This means the entire viewport — including the top-layer dialog
|
|
5034
|
+
* — can be panned by a touch gesture, causing the page behind the dialog to
|
|
5035
|
+
* scroll into view. To prevent this, we add a touchmove listener that cancels
|
|
5036
|
+
* the event if the touch started outside the dialog or any scrollable child within it.
|
|
5037
|
+
*
|
|
5038
|
+
* @private
|
|
5039
|
+
*/
|
|
5040
|
+
_lockTouchScroll() {
|
|
5041
|
+
const dialog = this.shadowRoot.querySelector('dialog');
|
|
5042
|
+
|
|
5043
|
+
this._touchMoveHandler = (event) => {
|
|
5044
|
+
// Walk the composed path (which crosses shadow DOM boundaries) to
|
|
5045
|
+
// check whether the touch started inside a scrollable element that
|
|
5046
|
+
// lives within the dialog. If so, allow the scroll.
|
|
5047
|
+
for (const el of event.composedPath()) {
|
|
5048
|
+
if (el === dialog) {
|
|
5049
|
+
// Reached the dialog boundary without finding a scrollable child.
|
|
5050
|
+
break;
|
|
5051
|
+
}
|
|
5052
|
+
if (el instanceof HTMLElement && el.scrollHeight > el.clientHeight) {
|
|
5053
|
+
const { overflowY } = getComputedStyle(el);
|
|
5054
|
+
if (overflowY === 'auto' || overflowY === 'scroll') {
|
|
5055
|
+
return;
|
|
5056
|
+
}
|
|
5057
|
+
}
|
|
5058
|
+
}
|
|
5059
|
+
|
|
5060
|
+
event.preventDefault();
|
|
5061
|
+
};
|
|
5062
|
+
|
|
5063
|
+
document.addEventListener('touchmove', this._touchMoveHandler, { passive: false });
|
|
5064
|
+
}
|
|
5065
|
+
|
|
5066
|
+
/**
|
|
5067
|
+
* Removes the touchmove listener added by _lockTouchScroll().
|
|
5068
|
+
* @private
|
|
5069
|
+
*/
|
|
5070
|
+
_unlockTouchScroll() {
|
|
5071
|
+
if (this._touchMoveHandler) {
|
|
5072
|
+
document.removeEventListener('touchmove', this._touchMoveHandler);
|
|
5073
|
+
this._touchMoveHandler = undefined;
|
|
5074
|
+
}
|
|
5075
|
+
}
|
|
5076
|
+
|
|
5077
|
+
open(modal = true) {
|
|
5078
|
+
const dialog = this.shadowRoot.querySelector('dialog');
|
|
5079
|
+
if (dialog && !dialog.open) {
|
|
5080
|
+
if (modal) {
|
|
5081
|
+
// Prevent showModal() from scrolling the page to bring the dialog
|
|
5082
|
+
// into view. Locking overflow on <html> blocks the viewport scroll
|
|
5083
|
+
// that browsers perform natively; we release it immediately after
|
|
5084
|
+
// so it doesn't interfere with the modal's focus management.
|
|
5085
|
+
const { documentElement } = document;
|
|
5086
|
+
const prevOverflow = documentElement.style.overflow;
|
|
5087
|
+
documentElement.style.overflow = 'hidden';
|
|
5088
|
+
|
|
5089
|
+
dialog.showModal();
|
|
5090
|
+
|
|
5091
|
+
documentElement.style.overflow = prevOverflow;
|
|
5092
|
+
|
|
5093
|
+
this._lockTouchScroll();
|
|
5094
|
+
|
|
5095
|
+
} else {
|
|
5096
|
+
// Use setAttribute instead of dialog.show() to avoid the dialog
|
|
5097
|
+
// focusing steps which steal focus from the trigger and cause
|
|
5098
|
+
// the floater's handleFocusLoss() to immediately hide the bib.
|
|
5099
|
+
dialog.setAttribute('open', '');
|
|
5100
|
+
}
|
|
5101
|
+
}
|
|
5102
|
+
}
|
|
5103
|
+
|
|
5104
|
+
/**
|
|
5105
|
+
* Closes the dialog.
|
|
5106
|
+
*/
|
|
5107
|
+
close() {
|
|
5108
|
+
const dialog = this.shadowRoot.querySelector('dialog');
|
|
5109
|
+
if (dialog && dialog.open) {
|
|
5110
|
+
this._unlockTouchScroll();
|
|
5111
|
+
dialog.close();
|
|
5112
|
+
}
|
|
5113
|
+
}
|
|
5114
|
+
|
|
4810
5115
|
// function that renders the HTML and CSS into the scope of the component
|
|
4811
5116
|
render() {
|
|
4812
5117
|
const classes = {
|
|
@@ -4818,9 +5123,10 @@ class AuroDropdownBib extends LitElement {
|
|
|
4818
5123
|
classes[`shape-${this.shape}`] = true;
|
|
4819
5124
|
|
|
4820
5125
|
return html`
|
|
4821
|
-
<
|
|
5126
|
+
<dialog class="${classMap(classes)}" part="bibContainer" role="${ifDefined(this.dialogRole)}" aria-labelledby="${ifDefined(this.dialogLabel ? 'dialogLabel' : undefined)}">
|
|
5127
|
+
${this.dialogLabel ? html`<span id="dialogLabel" class="util_displayHiddenVisually" aria-hidden="true">${this.dialogLabel}</span>` : ''}
|
|
4822
5128
|
<slot></slot>
|
|
4823
|
-
</
|
|
5129
|
+
</dialog>
|
|
4824
5130
|
`;
|
|
4825
5131
|
}
|
|
4826
5132
|
}
|
|
@@ -4829,7 +5135,7 @@ var shapeSizeCss = css`.shape-classic-xl,.shape-classic-lg,.shape-classic-md,.sh
|
|
|
4829
5135
|
|
|
4830
5136
|
var colorCss$1$1 = css`:host(:not([layout*=classic])){--ds-auro-dropdown-trigger-border-color: transparent}:host(:not([disabled],[onDark])) .wrapper:focus-within,:host(:not([disabled],[onDark])) .wrapper:active,:host(:not([disabled],[appearance=inverse])) .wrapper:focus-within,:host(:not([disabled],[appearance=inverse])) .wrapper:active{--ds-auro-dropdown-trigger-border-color: var(--ds-advanced-color-state-focused, #01426a);--ds-auro-dropdown-trigger-outline-color: var(--ds-advanced-color-state-focused, #01426a)}:host(:not([disabled],[onDark])) .wrapper:hover,:host(:not([disabled],[appearance=inverse])) .wrapper:hover{--ds-auro-dropdown-trigger-background-color: var(--ds-auro-dropdown-trigger-hover-background-color)}:host(:not([ondark])) .wrapper,:host(:not([appearance=inverse])) .wrapper{border-color:var(--ds-auro-dropdown-trigger-border-color);background-color:var(--ds-auro-dropdown-trigger-background-color);color:var(--ds-auro-dropdown-trigger-text-color)}:host(:not([onDark])[disabled]),:host(:not([appearance=inverse])[disabled]){--ds-auro-dropdown-trigger-text-color: var(--ds-basic-color-texticon-disabled, #d0d0d0);--ds-auro-dropdown-label-text-color: var(--ds-basic-color-texticon-disabled, #d0d0d0);--ds-auro-dropdown-trigger-border-color: var(--ds-basic-color-border-subtle, #dddddd)}:host(:not([onDark])[disabled]) #triggerLabel,:host(:not([appearance=inverse])[disabled]) #triggerLabel{cursor:default}:host(:not([ondark])[error]),:host(:not([appearance=inverse])[error]){--ds-auro-dropdown-trigger-border-color: var(--ds-basic-color-status-error, #e31f26)}:host(:not([disabled])[onDark]) .wrapper:focus-within,:host(:not([disabled])[onDark]) .wrapper:active,:host(:not([disabled])[appearance=inverse]) .wrapper:focus-within,:host(:not([disabled])[appearance=inverse]) .wrapper:active{--ds-auro-dropdown-trigger-border-color: var(--ds-advanced-color-state-focused-inverse, #ffffff);--ds-auro-dropdown-trigger-outline-color: var(--ds-advanced-color-state-focused-inverse, #ffffff)}:host(:not([disabled])[onDark]) .wrapper:hover,:host(:not([disabled])[appearance=inverse]) .wrapper:hover{--ds-auro-dropdown-trigger-background-color: var(--ds-auro-dropdown-trigger-hover-background-color)}:host([onDark]) .label,:host([onDark]) .helpText,:host([appearance=inverse]) .label,:host([appearance=inverse]) .helpText{color:var(--ds-auro-dropdown-label-text-color)}:host([onDark]) .wrapper,:host([appearance=inverse]) .wrapper{border-color:var(--ds-auro-dropdown-trigger-border-color);background-color:var(--ds-auro-dropdown-trigger-background-color);color:var(--ds-auro-dropdown-trigger-text-color)}:host([onDark][disabled]),:host([appearance=inverse][disabled]){--ds-auro-dropdown-trigger-text-color: var(--ds-basic-color-texticon-inverse-disabled, #7e8894);--ds-auro-dropdown-label-text-color: var(--ds-basic-color-texticon-inverse-disabled, #7e8894);--ds-auro-dropdown-trigger-container-color: var(--ds-advanced-color-shared-background-inverse-disabled, rgba(255, 255, 255, 0.1))}:host([onDark][disabled]) #triggerLabel,:host([appearance=inverse][disabled]) #triggerLabel{cursor:default}:host([ondark][error]),:host([appearance=inverse][error]){--ds-auro-dropdown-trigger-border-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8)}`;
|
|
4831
5137
|
|
|
4832
|
-
var styleCss$1$1 = css`:host{position:relative;display:block;text-align:left}
|
|
5138
|
+
var styleCss$1$1 = css`:host{position:relative;display:block;text-align:left}:host([open]){z-index:var(--depth-tooltip, 400)}.wrapper{display:flex;flex:1;flex-direction:row;align-items:center;justify-content:center;outline:none}.triggerContentWrapper{display:flex;overflow:hidden;width:100%;flex:1;align-items:center;justify-content:center;text-overflow:ellipsis;white-space:nowrap}:host([matchwidth]) #bibSizer{width:100%}`;
|
|
4833
5139
|
|
|
4834
5140
|
var classicColorCss = css``;
|
|
4835
5141
|
|
|
@@ -5067,7 +5373,7 @@ class AuroHelpText extends LitElement {
|
|
|
5067
5373
|
}
|
|
5068
5374
|
}
|
|
5069
5375
|
|
|
5070
|
-
var formkitVersion = '
|
|
5376
|
+
var formkitVersion = '202603102257';
|
|
5071
5377
|
|
|
5072
5378
|
let AuroElement$1 = class AuroElement extends LitElement {
|
|
5073
5379
|
static get properties() {
|
|
@@ -5181,7 +5487,7 @@ let AuroElement$1 = class AuroElement extends LitElement {
|
|
|
5181
5487
|
* The `auro-dropdown` element provides a way to place content in a bib that can be toggled.
|
|
5182
5488
|
* @customElement auro-dropdown
|
|
5183
5489
|
*
|
|
5184
|
-
* @slot - Default slot for the
|
|
5490
|
+
* @slot - Default slot for the dropdown bib content.
|
|
5185
5491
|
* @slot helpText - Defines the content of the helpText.
|
|
5186
5492
|
* @slot trigger - Defines the content of the trigger.
|
|
5187
5493
|
* @csspart trigger - The trigger content container.
|
|
@@ -5193,6 +5499,13 @@ let AuroElement$1 = class AuroElement extends LitElement {
|
|
|
5193
5499
|
* @event auroDropdown-idAdded - Notifies consumers that the unique ID for the dropdown bib has been generated.
|
|
5194
5500
|
*/
|
|
5195
5501
|
class AuroDropdown extends AuroElement$1 {
|
|
5502
|
+
static get shadowRootOptions() {
|
|
5503
|
+
return {
|
|
5504
|
+
...AuroElement$1.shadowRootOptions,
|
|
5505
|
+
delegatesFocus: true,
|
|
5506
|
+
};
|
|
5507
|
+
}
|
|
5508
|
+
|
|
5196
5509
|
constructor() {
|
|
5197
5510
|
super();
|
|
5198
5511
|
|
|
@@ -5258,15 +5571,6 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5258
5571
|
this.shift = false;
|
|
5259
5572
|
this.autoPlacement = false;
|
|
5260
5573
|
|
|
5261
|
-
/**
|
|
5262
|
-
* @private
|
|
5263
|
-
* @property {boolean} delegatesFocus - Whether the shadow root delegates focus.
|
|
5264
|
-
*/
|
|
5265
|
-
this.constructor.shadowRootOptions = {
|
|
5266
|
-
...LitElement.shadowRootOptions,
|
|
5267
|
-
delegatesFocus: true,
|
|
5268
|
-
};
|
|
5269
|
-
|
|
5270
5574
|
/**
|
|
5271
5575
|
* @private
|
|
5272
5576
|
*/
|
|
@@ -5340,6 +5644,18 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5340
5644
|
*/
|
|
5341
5645
|
show() {
|
|
5342
5646
|
this.floater.showBib();
|
|
5647
|
+
|
|
5648
|
+
// Open dialog synchronously so callers remain in the user gesture
|
|
5649
|
+
// chain. This is critical for mobile browsers (iOS Safari) to keep
|
|
5650
|
+
// the virtual keyboard open when transitioning from the trigger
|
|
5651
|
+
// input to an input inside the fullscreen dialog. Without this,
|
|
5652
|
+
// showModal() fires asynchronously via Lit's update cycle, which
|
|
5653
|
+
// falls outside the user activation window and causes iOS to
|
|
5654
|
+
// dismiss the keyboard.
|
|
5655
|
+
if (this.isBibFullscreen && this.bibElement && this.bibElement.value) {
|
|
5656
|
+
const useModal = !this.disableFocusTrap;
|
|
5657
|
+
this.bibElement.value.open(useModal);
|
|
5658
|
+
}
|
|
5343
5659
|
}
|
|
5344
5660
|
|
|
5345
5661
|
/**
|
|
@@ -5347,13 +5663,37 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5347
5663
|
* If not, trigger element will get focus.
|
|
5348
5664
|
*/
|
|
5349
5665
|
focus() {
|
|
5350
|
-
if (this.isPopoverVisible && this.
|
|
5351
|
-
this.
|
|
5666
|
+
if (this.isPopoverVisible && this.bibContent) {
|
|
5667
|
+
const focusables = getFocusableElements(this.bibContent);
|
|
5668
|
+
if (focusables.length > 0) {
|
|
5669
|
+
focusables[0].focus();
|
|
5670
|
+
}
|
|
5352
5671
|
} else {
|
|
5353
5672
|
this.trigger.focus();
|
|
5354
5673
|
}
|
|
5355
5674
|
}
|
|
5356
5675
|
|
|
5676
|
+
/**
|
|
5677
|
+
* Sets the active descendant element for accessibility.
|
|
5678
|
+
* Uses ariaActiveDescendantElement to cross shadow DOM boundaries.
|
|
5679
|
+
* This function is used in components that contain `auro-dropdown` to set the active descendant.
|
|
5680
|
+
* @private
|
|
5681
|
+
* @param {HTMLElement|null} element - The element to set as the active descendant, or null to clear.
|
|
5682
|
+
* @returns {void}
|
|
5683
|
+
*/
|
|
5684
|
+
setActiveDescendant(element) {
|
|
5685
|
+
if (!this.trigger) {
|
|
5686
|
+
return;
|
|
5687
|
+
}
|
|
5688
|
+
|
|
5689
|
+
if (element) {
|
|
5690
|
+
this.trigger.ariaActiveDescendantElement = element;
|
|
5691
|
+
} else {
|
|
5692
|
+
this.trigger.ariaActiveDescendantElement = null;
|
|
5693
|
+
this.trigger.removeAttribute('aria-activedescendant');
|
|
5694
|
+
}
|
|
5695
|
+
}
|
|
5696
|
+
|
|
5357
5697
|
// function to define props used within the scope of this component
|
|
5358
5698
|
static get properties() {
|
|
5359
5699
|
return {
|
|
@@ -5611,6 +5951,16 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5611
5951
|
*/
|
|
5612
5952
|
tabIndex: {
|
|
5613
5953
|
type: Number
|
|
5954
|
+
},
|
|
5955
|
+
|
|
5956
|
+
/**
|
|
5957
|
+
* Accessible label for the dropdown bib dialog element.
|
|
5958
|
+
* @private
|
|
5959
|
+
*/
|
|
5960
|
+
bibDialogLabel: {
|
|
5961
|
+
type: String,
|
|
5962
|
+
attribute: false,
|
|
5963
|
+
reflect: false
|
|
5614
5964
|
}
|
|
5615
5965
|
};
|
|
5616
5966
|
}
|
|
@@ -5662,7 +6012,10 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5662
6012
|
|
|
5663
6013
|
disconnectedCallback() {
|
|
5664
6014
|
super.disconnectedCallback();
|
|
5665
|
-
this.floater
|
|
6015
|
+
if (this.floater) {
|
|
6016
|
+
this.floater.hideBib('disconnect');
|
|
6017
|
+
this.floater.disconnect();
|
|
6018
|
+
}
|
|
5666
6019
|
this.clearTriggerFocusEventBinding();
|
|
5667
6020
|
}
|
|
5668
6021
|
|
|
@@ -5684,11 +6037,22 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5684
6037
|
|
|
5685
6038
|
if (changedProperties.has('isPopoverVisible') && this.bibElement.value) {
|
|
5686
6039
|
if (this.isPopoverVisible) {
|
|
5687
|
-
|
|
6040
|
+
// Fullscreen: use showModal() for native accessibility (inert outside, focus trap)
|
|
6041
|
+
// Desktop: use show() for Floating UI positioning + FocusTrap for focus management
|
|
6042
|
+
const useModal = this.isBibFullscreen && !this.disableFocusTrap;
|
|
6043
|
+
this.bibElement.value.open(useModal);
|
|
5688
6044
|
} else {
|
|
5689
|
-
this.bibElement.value.
|
|
6045
|
+
this.bibElement.value.close();
|
|
5690
6046
|
}
|
|
5691
6047
|
}
|
|
6048
|
+
|
|
6049
|
+
// When fullscreen strategy changes while open, re-open dialog with correct mode
|
|
6050
|
+
// (e.g. resizing from desktop → mobile while dropdown is open)
|
|
6051
|
+
if (changedProperties.has('isBibFullscreen') && this.isPopoverVisible && this.bibElement.value) {
|
|
6052
|
+
const useModal = this.isBibFullscreen && !this.disableFocusTrap;
|
|
6053
|
+
this.bibElement.value.close();
|
|
6054
|
+
this.bibElement.value.open(useModal);
|
|
6055
|
+
}
|
|
5692
6056
|
}
|
|
5693
6057
|
|
|
5694
6058
|
/**
|
|
@@ -5706,11 +6070,28 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5706
6070
|
}
|
|
5707
6071
|
|
|
5708
6072
|
firstUpdated() {
|
|
5709
|
-
|
|
5710
6073
|
// Configure the floater to, this will generate the ID for the bib
|
|
5711
6074
|
this.floater.configure(this, 'auroDropdown');
|
|
6075
|
+
|
|
6076
|
+
// Prevent `contain: layout` on the dropdown host. Layout containment
|
|
6077
|
+
// creates a containing block for position:fixed descendants (the bib),
|
|
6078
|
+
// which clips the bib inside ancestor overflow contexts such as a
|
|
6079
|
+
// <dialog> element. Without it, the bib's position:fixed is relative
|
|
6080
|
+
// to the viewport, letting Floating UI's flip middleware detect
|
|
6081
|
+
// viewport boundaries and the bib escape overflow clipping.
|
|
6082
|
+
const origConfigureBibStrategy = this.floater.configureBibStrategy.bind(this.floater);
|
|
6083
|
+
this.floater.configureBibStrategy = (value) => {
|
|
6084
|
+
origConfigureBibStrategy(value);
|
|
6085
|
+
this.style.contain = '';
|
|
6086
|
+
};
|
|
6087
|
+
|
|
5712
6088
|
this.addEventListener('auroDropdown-toggled', this.handleDropdownToggle);
|
|
5713
6089
|
|
|
6090
|
+
// Handle ESC key from dialog's cancel event
|
|
6091
|
+
this.addEventListener('auro-bib-cancel', () => {
|
|
6092
|
+
this.floater.hideBib('keydown');
|
|
6093
|
+
});
|
|
6094
|
+
|
|
5714
6095
|
/**
|
|
5715
6096
|
* @description Let subscribers know that the dropdown ID ha been generated and added.
|
|
5716
6097
|
* @event auroDropdown-idAdded
|
|
@@ -5718,9 +6099,9 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5718
6099
|
*/
|
|
5719
6100
|
this.dispatchEvent(new CustomEvent('auroDropdown-idAdded', {detail: {id: this.floater.element.id}}));
|
|
5720
6101
|
|
|
5721
|
-
// Set the bib ID locally
|
|
6102
|
+
// Set the bib ID locally for aria-controls (must be in the same shadow root as the trigger)
|
|
5722
6103
|
if (!this.triggerContentFocusable) {
|
|
5723
|
-
this.dropdownId = this.floater.element.id;
|
|
6104
|
+
this.dropdownId = this.floater.element.bib.id;
|
|
5724
6105
|
}
|
|
5725
6106
|
|
|
5726
6107
|
this.bibContent = this.floater.element.bib;
|
|
@@ -5780,21 +6161,20 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5780
6161
|
* @private
|
|
5781
6162
|
*/
|
|
5782
6163
|
updateFocusTrap() {
|
|
5783
|
-
// If the dropdown is open, create a focus trap and focus the first element
|
|
5784
6164
|
if (this.isPopoverVisible && !this.disableFocusTrap) {
|
|
5785
|
-
|
|
5786
|
-
|
|
6165
|
+
if (!this.isBibFullscreen) {
|
|
6166
|
+
// Desktop: show() doesn't trap focus, so use FocusTrap
|
|
6167
|
+
this.focusTrap = new FocusTrap(this.bibContent);
|
|
6168
|
+
this.focusTrap.focusFirstElement();
|
|
6169
|
+
}
|
|
6170
|
+
// Fullscreen: showModal() provides native focus trapping
|
|
5787
6171
|
return;
|
|
5788
6172
|
}
|
|
5789
6173
|
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
6174
|
+
if (this.focusTrap) {
|
|
6175
|
+
this.focusTrap.disconnect();
|
|
6176
|
+
this.focusTrap = undefined;
|
|
5793
6177
|
}
|
|
5794
|
-
|
|
5795
|
-
// If the dropdown is not open, disconnect the focus trap if it exists
|
|
5796
|
-
this.focusTrap.disconnect();
|
|
5797
|
-
this.focusTrap = undefined;
|
|
5798
6178
|
}
|
|
5799
6179
|
|
|
5800
6180
|
/**
|
|
@@ -6010,13 +6390,14 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
6010
6390
|
<div
|
|
6011
6391
|
id="showStateIcon"
|
|
6012
6392
|
class="chevron"
|
|
6013
|
-
part="chevron"
|
|
6393
|
+
part="chevron"
|
|
6394
|
+
aria-hidden="true">
|
|
6014
6395
|
<${this.iconTag}
|
|
6015
6396
|
category="interface"
|
|
6016
6397
|
name="${this.isPopoverVisible ? 'chevron-up' : `chevron-down`}"
|
|
6017
6398
|
appearance="${this.onDark ? 'inverse' : this.appearance}"
|
|
6018
|
-
variant="${this.disabled ? 'disabled' : 'muted'}"
|
|
6019
|
-
>
|
|
6399
|
+
variant="${this.disabled ? 'disabled' : 'muted'}"
|
|
6400
|
+
ariaHidden="true">
|
|
6020
6401
|
</${this.iconTag}>
|
|
6021
6402
|
</div>
|
|
6022
6403
|
` : undefined }
|
|
@@ -6030,8 +6411,8 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
6030
6411
|
shape="${this.shape}"
|
|
6031
6412
|
?data-show="${this.isPopoverVisible}"
|
|
6032
6413
|
?isfullscreen="${this.isBibFullscreen}"
|
|
6414
|
+
.dialogLabel="${this.bibDialogLabel}"
|
|
6033
6415
|
${ref(this.bibElement)}
|
|
6034
|
-
popover="manual"
|
|
6035
6416
|
>
|
|
6036
6417
|
<div class="slotContent">
|
|
6037
6418
|
<slot @slotchange="${this.handleDefaultSlot}"></slot>
|
|
@@ -6438,6 +6819,18 @@ class AuroBibtemplate extends LitElement {
|
|
|
6438
6819
|
this.removeEventListener('touchmove', this.preventBodyScroll, { passive: false });
|
|
6439
6820
|
}
|
|
6440
6821
|
|
|
6822
|
+
/**
|
|
6823
|
+
* Focuses the close button inside the bibtemplate's shadow DOM.
|
|
6824
|
+
* Used by parent components to set initial focus when the fullscreen dialog opens.
|
|
6825
|
+
* @returns {void}
|
|
6826
|
+
*/
|
|
6827
|
+
focusCloseButton() {
|
|
6828
|
+
const closeBtn = this.shadowRoot.querySelector('#closeButton');
|
|
6829
|
+
if (closeBtn) {
|
|
6830
|
+
closeBtn.focus();
|
|
6831
|
+
}
|
|
6832
|
+
}
|
|
6833
|
+
|
|
6441
6834
|
onCloseButtonClick() {
|
|
6442
6835
|
this.dispatchEvent(new Event("close-click", { bubbles: true,
|
|
6443
6836
|
composed: true }));
|
|
@@ -7114,6 +7507,24 @@ class AuroCounterGroup extends AuroElement {
|
|
|
7114
7507
|
this.dropdown.hide();
|
|
7115
7508
|
}
|
|
7116
7509
|
});
|
|
7510
|
+
|
|
7511
|
+
// Focus close button when fullscreen dialog opens
|
|
7512
|
+
this.dropdown.addEventListener('auroDropdown-toggled', () => {
|
|
7513
|
+
if (this.dropdown.isPopoverVisible && this.dropdown.isBibFullscreen) {
|
|
7514
|
+
doubleRaf(() => {
|
|
7515
|
+
this.bibtemplate.focusCloseButton();
|
|
7516
|
+
});
|
|
7517
|
+
}
|
|
7518
|
+
});
|
|
7519
|
+
|
|
7520
|
+
// Tab closes the fullscreen dialog
|
|
7521
|
+
// The dialog event bridge intercepts Tab and re-dispatches it as a
|
|
7522
|
+
// composed keydown; this listener catches the re-dispatched event.
|
|
7523
|
+
this.addEventListener('keydown', (evt) => {
|
|
7524
|
+
if (evt.key === 'Tab' && this.dropdown.isPopoverVisible && this.dropdown.isBibFullscreen) {
|
|
7525
|
+
this.dropdown.hide();
|
|
7526
|
+
}
|
|
7527
|
+
});
|
|
7117
7528
|
}
|
|
7118
7529
|
|
|
7119
7530
|
/**
|