@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
|
@@ -300,7 +300,7 @@ let p$3 = class p{registerComponent(t,a){customElements.get(t)||customElements.d
|
|
|
300
300
|
</div>
|
|
301
301
|
`}};
|
|
302
302
|
|
|
303
|
-
var iconVersion$2 = '9.1.
|
|
303
|
+
var iconVersion$2 = '9.1.2';
|
|
304
304
|
|
|
305
305
|
class DateFormatter {
|
|
306
306
|
|
|
@@ -1058,7 +1058,7 @@ class AuroFormValidation {
|
|
|
1058
1058
|
}
|
|
1059
1059
|
}
|
|
1060
1060
|
|
|
1061
|
-
if (!hasValue && elem.required && elem.touched) {
|
|
1061
|
+
if (!hasValue && elem.required && (force || elem.touched)) {
|
|
1062
1062
|
elem.validity = 'valueMissing';
|
|
1063
1063
|
elem.errorMessage = elem.setCustomValidityValueMissing || elem.setCustomValidity || '';
|
|
1064
1064
|
} else if (hasValue && this.runtimeUtils.elementMatch(elem, 'auro-input')) {
|
|
@@ -1082,7 +1082,7 @@ class AuroFormValidation {
|
|
|
1082
1082
|
if (!isCombobox || isCombobox && !elem.persistInput) {
|
|
1083
1083
|
|
|
1084
1084
|
// run validation on all inputs since we're going to use them to set the validity of this component
|
|
1085
|
-
this.auroInputElements.forEach(input => input.validate());
|
|
1085
|
+
this.auroInputElements.forEach(input => input.validate(force));
|
|
1086
1086
|
|
|
1087
1087
|
// Reset element validity to the validity of the input
|
|
1088
1088
|
elem.validity = this.auroInputElements[0].validity;
|
|
@@ -1173,6 +1173,34 @@ class AuroFormValidation {
|
|
|
1173
1173
|
}
|
|
1174
1174
|
}
|
|
1175
1175
|
|
|
1176
|
+
/**
|
|
1177
|
+
* Announces text to screen readers via an `aria-live` region inside the given shadow root.
|
|
1178
|
+
*
|
|
1179
|
+
* Expects the shadow root to contain an element with `id="srAnnouncement"`.
|
|
1180
|
+
* The text is cleared and re-set inside a `requestAnimationFrame` so that
|
|
1181
|
+
* repeated identical announcements still fire, and is cleared again after
|
|
1182
|
+
* {@link ANNOUNCEMENT_DURATION_MS} so VoiceOver cannot swipe to stale text.
|
|
1183
|
+
*
|
|
1184
|
+
* @param {ShadowRoot} shadowRoot - The shadow root containing the live region.
|
|
1185
|
+
* @param {string} text - The text to announce.
|
|
1186
|
+
*/
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
/**
|
|
1190
|
+
* Schedules a callback after two animation frames.
|
|
1191
|
+
*
|
|
1192
|
+
* Used when opening a fullscreen dialog to wait for the dialog to render
|
|
1193
|
+
* (first frame) and then for a Lit update cycle to complete (second frame)
|
|
1194
|
+
* before performing an action like focusing the close button.
|
|
1195
|
+
*
|
|
1196
|
+
* @param {Function} fn - The callback to execute after two animation frames.
|
|
1197
|
+
*/
|
|
1198
|
+
function doubleRaf(fn) {
|
|
1199
|
+
requestAnimationFrame(() => {
|
|
1200
|
+
requestAnimationFrame(fn);
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1176
1204
|
// Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
|
|
1177
1205
|
// See LICENSE in the project root for license information.
|
|
1178
1206
|
|
|
@@ -1442,7 +1470,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$2 {
|
|
|
1442
1470
|
}
|
|
1443
1471
|
};
|
|
1444
1472
|
|
|
1445
|
-
var formkitVersion$1 = '
|
|
1473
|
+
var formkitVersion$1 = '202603102257';
|
|
1446
1474
|
|
|
1447
1475
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
1448
1476
|
// See LICENSE in the project root for license information.
|
|
@@ -1459,6 +1487,13 @@ var formkitVersion$1 = '202602140013';
|
|
|
1459
1487
|
* @slot description - Descriptive content for the counter.
|
|
1460
1488
|
*/
|
|
1461
1489
|
class AuroCounter extends i$2 {
|
|
1490
|
+
static get shadowRootOptions() {
|
|
1491
|
+
return {
|
|
1492
|
+
...i$2.shadowRootOptions,
|
|
1493
|
+
delegatesFocus: true,
|
|
1494
|
+
};
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1462
1497
|
constructor() {
|
|
1463
1498
|
super();
|
|
1464
1499
|
|
|
@@ -1505,14 +1540,6 @@ class AuroCounter extends i$2 {
|
|
|
1505
1540
|
*/
|
|
1506
1541
|
this.runtimeUtils = new AuroLibraryRuntimeUtils$4();
|
|
1507
1542
|
|
|
1508
|
-
/**
|
|
1509
|
-
* @private
|
|
1510
|
-
* @property {boolean} delegatesFocus - Whether the shadow root delegates focus.
|
|
1511
|
-
*/
|
|
1512
|
-
this.constructor.shadowRootOptions = {
|
|
1513
|
-
...i$2.shadowRootOptions,
|
|
1514
|
-
delegatesFocus: true,
|
|
1515
|
-
};
|
|
1516
1543
|
}
|
|
1517
1544
|
|
|
1518
1545
|
connectedCallback() {
|
|
@@ -1827,7 +1854,7 @@ class AuroCounter extends i$2 {
|
|
|
1827
1854
|
aria-valuemax="${this.max}"
|
|
1828
1855
|
aria-valuemin="${this.min}"
|
|
1829
1856
|
aria-valuenow="${this.value}"
|
|
1830
|
-
aria-valuetext="${this.value !== undefined ? this.value : this.min}"
|
|
1857
|
+
aria-valuetext="'${this.value !== undefined ? this.value : this.min}'"
|
|
1831
1858
|
role="spinbutton"
|
|
1832
1859
|
tabindex="${this.disabled ? '-1' : '0'}"
|
|
1833
1860
|
>
|
|
@@ -3612,11 +3639,9 @@ const computePosition = (reference, floating, options) => {
|
|
|
3612
3639
|
/* eslint-disable line-comment-position, no-inline-comments */
|
|
3613
3640
|
|
|
3614
3641
|
|
|
3615
|
-
|
|
3616
3642
|
const MAX_CONFIGURATION_COUNT = 10;
|
|
3617
3643
|
|
|
3618
3644
|
class AuroFloatingUI {
|
|
3619
|
-
|
|
3620
3645
|
/**
|
|
3621
3646
|
* @private
|
|
3622
3647
|
*/
|
|
@@ -3631,7 +3656,11 @@ class AuroFloatingUI {
|
|
|
3631
3656
|
* @private
|
|
3632
3657
|
*/
|
|
3633
3658
|
static setupMousePressChecker() {
|
|
3634
|
-
if (
|
|
3659
|
+
if (
|
|
3660
|
+
!AuroFloatingUI.isMousePressHandlerInitialized &&
|
|
3661
|
+
window &&
|
|
3662
|
+
window.addEventListener
|
|
3663
|
+
) {
|
|
3635
3664
|
AuroFloatingUI.isMousePressHandlerInitialized = true;
|
|
3636
3665
|
|
|
3637
3666
|
// Track timeout for isMousePressed reset to avoid race conditions
|
|
@@ -3639,7 +3668,7 @@ class AuroFloatingUI {
|
|
|
3639
3668
|
AuroFloatingUI._mousePressedTimeout = null;
|
|
3640
3669
|
}
|
|
3641
3670
|
const mouseEventGlobalHandler = (event) => {
|
|
3642
|
-
const isPressed = event.type ===
|
|
3671
|
+
const isPressed = event.type === "mousedown";
|
|
3643
3672
|
if (isPressed) {
|
|
3644
3673
|
// Clear any pending timeout to prevent race condition
|
|
3645
3674
|
if (AuroFloatingUI._mousePressedTimeout !== null) {
|
|
@@ -3658,8 +3687,8 @@ class AuroFloatingUI {
|
|
|
3658
3687
|
}
|
|
3659
3688
|
};
|
|
3660
3689
|
|
|
3661
|
-
window.addEventListener(
|
|
3662
|
-
window.addEventListener(
|
|
3690
|
+
window.addEventListener("mousedown", mouseEventGlobalHandler);
|
|
3691
|
+
window.addEventListener("mouseup", mouseEventGlobalHandler);
|
|
3663
3692
|
}
|
|
3664
3693
|
}
|
|
3665
3694
|
|
|
@@ -3707,11 +3736,12 @@ class AuroFloatingUI {
|
|
|
3707
3736
|
// mirror the boxsize from bibSizer
|
|
3708
3737
|
if (this.element.bibSizer && this.element.matchWidth) {
|
|
3709
3738
|
const sizerStyle = window.getComputedStyle(this.element.bibSizer);
|
|
3710
|
-
const bibContent =
|
|
3711
|
-
|
|
3739
|
+
const bibContent =
|
|
3740
|
+
this.element.bib.shadowRoot.querySelector(".container");
|
|
3741
|
+
if (sizerStyle.width !== "0px") {
|
|
3712
3742
|
bibContent.style.width = sizerStyle.width;
|
|
3713
3743
|
}
|
|
3714
|
-
if (sizerStyle.height !==
|
|
3744
|
+
if (sizerStyle.height !== "0px") {
|
|
3715
3745
|
bibContent.style.height = sizerStyle.height;
|
|
3716
3746
|
}
|
|
3717
3747
|
bibContent.style.maxWidth = sizerStyle.maxWidth;
|
|
@@ -3729,28 +3759,34 @@ class AuroFloatingUI {
|
|
|
3729
3759
|
* @returns {String} The positioning strategy, one of 'fullscreen', 'floating', 'cover'.
|
|
3730
3760
|
*/
|
|
3731
3761
|
getPositioningStrategy() {
|
|
3732
|
-
const breakpoint =
|
|
3762
|
+
const breakpoint =
|
|
3763
|
+
this.element.bib.mobileFullscreenBreakpoint ||
|
|
3764
|
+
this.element.floaterConfig?.fullscreenBreakpoint;
|
|
3733
3765
|
switch (this.behavior) {
|
|
3734
3766
|
case "tooltip":
|
|
3735
3767
|
return "floating";
|
|
3736
3768
|
case "dialog":
|
|
3737
3769
|
case "drawer":
|
|
3738
3770
|
if (breakpoint) {
|
|
3739
|
-
const smallerThanBreakpoint = window.matchMedia(
|
|
3771
|
+
const smallerThanBreakpoint = window.matchMedia(
|
|
3772
|
+
`(max-width: ${breakpoint})`,
|
|
3773
|
+
).matches;
|
|
3740
3774
|
|
|
3741
3775
|
this.element.expanded = smallerThanBreakpoint;
|
|
3742
3776
|
}
|
|
3743
3777
|
if (this.element.nested) {
|
|
3744
3778
|
return "cover";
|
|
3745
3779
|
}
|
|
3746
|
-
return
|
|
3780
|
+
return "fullscreen";
|
|
3747
3781
|
case "dropdown":
|
|
3748
3782
|
case undefined:
|
|
3749
3783
|
case null:
|
|
3750
3784
|
if (breakpoint) {
|
|
3751
|
-
const smallerThanBreakpoint = window.matchMedia(
|
|
3785
|
+
const smallerThanBreakpoint = window.matchMedia(
|
|
3786
|
+
`(max-width: ${breakpoint})`,
|
|
3787
|
+
).matches;
|
|
3752
3788
|
if (smallerThanBreakpoint) {
|
|
3753
|
-
return
|
|
3789
|
+
return "fullscreen";
|
|
3754
3790
|
}
|
|
3755
3791
|
}
|
|
3756
3792
|
return "floating";
|
|
@@ -3771,37 +3807,39 @@ class AuroFloatingUI {
|
|
|
3771
3807
|
const strategy = this.getPositioningStrategy();
|
|
3772
3808
|
this.configureBibStrategy(strategy);
|
|
3773
3809
|
|
|
3774
|
-
if (strategy ===
|
|
3810
|
+
if (strategy === "floating") {
|
|
3775
3811
|
this.mirrorSize();
|
|
3776
3812
|
// Define the middlware for the floater configuration
|
|
3777
3813
|
const middleware = [
|
|
3778
3814
|
offset(this.element.floaterConfig?.offset || 0),
|
|
3779
|
-
...this.element.floaterConfig?.shift ? [shift()] : [], // Add shift middleware if shift is enabled.
|
|
3780
|
-
...this.element.floaterConfig?.flip ? [flip()] : [], // Add flip middleware if flip is enabled.
|
|
3781
|
-
...this.element.floaterConfig?.autoPlacement ? [autoPlacement()] : [], // Add autoPlacement middleware if autoPlacement is enabled.
|
|
3815
|
+
...(this.element.floaterConfig?.shift ? [shift()] : []), // Add shift middleware if shift is enabled.
|
|
3816
|
+
...(this.element.floaterConfig?.flip ? [flip()] : []), // Add flip middleware if flip is enabled.
|
|
3817
|
+
...(this.element.floaterConfig?.autoPlacement ? [autoPlacement()] : []), // Add autoPlacement middleware if autoPlacement is enabled.
|
|
3782
3818
|
];
|
|
3783
3819
|
|
|
3784
3820
|
// Compute the position of the bib
|
|
3785
3821
|
computePosition(this.element.trigger, this.element.bib, {
|
|
3786
|
-
strategy: this.element.floaterConfig?.strategy ||
|
|
3822
|
+
strategy: this.element.floaterConfig?.strategy || "fixed",
|
|
3787
3823
|
placement: this.element.floaterConfig?.placement,
|
|
3788
|
-
middleware: middleware || []
|
|
3789
|
-
}).then(({ x, y }) => {
|
|
3824
|
+
middleware: middleware || [],
|
|
3825
|
+
}).then(({ x, y }) => {
|
|
3826
|
+
// eslint-disable-line id-length
|
|
3790
3827
|
Object.assign(this.element.bib.style, {
|
|
3791
3828
|
left: `${x}px`,
|
|
3792
3829
|
top: `${y}px`,
|
|
3793
3830
|
});
|
|
3794
3831
|
});
|
|
3795
|
-
} else if (strategy ===
|
|
3832
|
+
} else if (strategy === "cover") {
|
|
3796
3833
|
// Compute the position of the bib
|
|
3797
3834
|
computePosition(this.element.parentNode, this.element.bib, {
|
|
3798
|
-
placement:
|
|
3799
|
-
}).then(({ x, y }) => {
|
|
3835
|
+
placement: "bottom-start",
|
|
3836
|
+
}).then(({ x, y }) => {
|
|
3837
|
+
// eslint-disable-line id-length
|
|
3800
3838
|
Object.assign(this.element.bib.style, {
|
|
3801
3839
|
left: `${x}px`,
|
|
3802
3840
|
top: `${y - this.element.parentNode.offsetHeight}px`,
|
|
3803
3841
|
width: `${this.element.parentNode.offsetWidth}px`,
|
|
3804
|
-
height: `${this.element.parentNode.offsetHeight}px
|
|
3842
|
+
height: `${this.element.parentNode.offsetHeight}px`,
|
|
3805
3843
|
});
|
|
3806
3844
|
});
|
|
3807
3845
|
}
|
|
@@ -3814,12 +3852,12 @@ class AuroFloatingUI {
|
|
|
3814
3852
|
*/
|
|
3815
3853
|
lockScroll(lock = true) {
|
|
3816
3854
|
if (lock) {
|
|
3817
|
-
document.body.style.overflow =
|
|
3855
|
+
document.body.style.overflow = "hidden"; // hide body's scrollbar
|
|
3818
3856
|
|
|
3819
3857
|
// Move `bib` by the amount the viewport is shifted to stay aligned in fullscreen.
|
|
3820
3858
|
this.element.bib.style.transform = `translateY(${window?.visualViewport?.offsetTop}px)`;
|
|
3821
3859
|
} else {
|
|
3822
|
-
document.body.style.overflow =
|
|
3860
|
+
document.body.style.overflow = "";
|
|
3823
3861
|
}
|
|
3824
3862
|
}
|
|
3825
3863
|
|
|
@@ -3833,23 +3871,24 @@ class AuroFloatingUI {
|
|
|
3833
3871
|
* @param {string} strategy - The positioning strategy ('fullscreen' or 'floating').
|
|
3834
3872
|
*/
|
|
3835
3873
|
configureBibStrategy(value) {
|
|
3836
|
-
if (value ===
|
|
3874
|
+
if (value === "fullscreen") {
|
|
3837
3875
|
this.element.isBibFullscreen = true;
|
|
3838
3876
|
// reset the prev position
|
|
3839
|
-
this.element.bib.setAttribute(
|
|
3840
|
-
this.element.bib.style.position =
|
|
3877
|
+
this.element.bib.setAttribute("isfullscreen", "");
|
|
3878
|
+
this.element.bib.style.position = "fixed";
|
|
3841
3879
|
this.element.bib.style.top = "0px";
|
|
3842
3880
|
this.element.bib.style.left = "0px";
|
|
3843
|
-
this.element.bib.style.width =
|
|
3844
|
-
this.element.bib.style.height =
|
|
3845
|
-
this.element.style.contain =
|
|
3881
|
+
this.element.bib.style.width = "";
|
|
3882
|
+
this.element.bib.style.height = "";
|
|
3883
|
+
this.element.style.contain = "";
|
|
3846
3884
|
|
|
3847
3885
|
// reset the size that was mirroring `size` css-part
|
|
3848
|
-
const bibContent =
|
|
3886
|
+
const bibContent =
|
|
3887
|
+
this.element.bib.shadowRoot.querySelector(".container");
|
|
3849
3888
|
if (bibContent) {
|
|
3850
|
-
bibContent.style.width =
|
|
3851
|
-
bibContent.style.height =
|
|
3852
|
-
bibContent.style.maxWidth =
|
|
3889
|
+
bibContent.style.width = "";
|
|
3890
|
+
bibContent.style.height = "";
|
|
3891
|
+
bibContent.style.maxWidth = "";
|
|
3853
3892
|
bibContent.style.maxHeight = `${window?.visualViewport?.height}px`;
|
|
3854
3893
|
this.configureTrial = 0;
|
|
3855
3894
|
} else if (this.configureTrial < MAX_CONFIGURATION_COUNT) {
|
|
@@ -3864,21 +3903,26 @@ class AuroFloatingUI {
|
|
|
3864
3903
|
this.lockScroll(true);
|
|
3865
3904
|
}
|
|
3866
3905
|
} else {
|
|
3867
|
-
this.element.bib.style.position =
|
|
3868
|
-
this.element.bib.removeAttribute(
|
|
3906
|
+
this.element.bib.style.position = "";
|
|
3907
|
+
this.element.bib.removeAttribute("isfullscreen");
|
|
3869
3908
|
this.element.isBibFullscreen = false;
|
|
3870
|
-
this.element.style.contain =
|
|
3909
|
+
this.element.style.contain = "layout";
|
|
3871
3910
|
}
|
|
3872
3911
|
|
|
3873
3912
|
const isChanged = this.strategy && this.strategy !== value;
|
|
3874
3913
|
this.strategy = value;
|
|
3875
3914
|
if (isChanged) {
|
|
3876
|
-
const event = new CustomEvent(
|
|
3877
|
-
|
|
3878
|
-
|
|
3915
|
+
const event = new CustomEvent(
|
|
3916
|
+
this.eventPrefix
|
|
3917
|
+
? `${this.eventPrefix}-strategy-change`
|
|
3918
|
+
: "strategy-change",
|
|
3919
|
+
{
|
|
3920
|
+
detail: {
|
|
3921
|
+
value,
|
|
3922
|
+
},
|
|
3923
|
+
composed: true,
|
|
3879
3924
|
},
|
|
3880
|
-
|
|
3881
|
-
});
|
|
3925
|
+
);
|
|
3882
3926
|
|
|
3883
3927
|
this.element.dispatchEvent(event);
|
|
3884
3928
|
}
|
|
@@ -3910,19 +3954,24 @@ class AuroFloatingUI {
|
|
|
3910
3954
|
return;
|
|
3911
3955
|
}
|
|
3912
3956
|
|
|
3913
|
-
if (
|
|
3914
|
-
this.element.
|
|
3957
|
+
if (
|
|
3958
|
+
this.element.noHideOnThisFocusLoss ||
|
|
3959
|
+
this.element.hasAttribute("noHideOnThisFocusLoss")
|
|
3960
|
+
) {
|
|
3915
3961
|
return;
|
|
3916
3962
|
}
|
|
3917
3963
|
|
|
3918
3964
|
const { activeElement } = document;
|
|
3919
3965
|
// if focus is still inside of trigger or bib, do not close
|
|
3920
|
-
if (
|
|
3966
|
+
if (
|
|
3967
|
+
this.element.contains(activeElement) ||
|
|
3968
|
+
this.element.bib?.contains(activeElement)
|
|
3969
|
+
) {
|
|
3921
3970
|
return;
|
|
3922
3971
|
}
|
|
3923
3972
|
|
|
3924
3973
|
// if fullscreen bib is in fullscreen mode, do not close
|
|
3925
|
-
if (this.element.bib.hasAttribute(
|
|
3974
|
+
if (this.element.bib.hasAttribute("isfullscreen")) {
|
|
3926
3975
|
return;
|
|
3927
3976
|
}
|
|
3928
3977
|
|
|
@@ -3934,12 +3983,27 @@ class AuroFloatingUI {
|
|
|
3934
3983
|
this.focusHandler = () => this.handleFocusLoss();
|
|
3935
3984
|
|
|
3936
3985
|
this.clickHandler = (evt) => {
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3986
|
+
// When the bib is fullscreen (modal dialog), don't close on outside
|
|
3987
|
+
// clicks. VoiceOver's synthetic click events inside a top-layer modal
|
|
3988
|
+
// <dialog> may not include the bib in composedPath(), causing false
|
|
3989
|
+
// positives. This mirrors the fullscreen guard in handleFocusLoss().
|
|
3990
|
+
if (this.element.bib && this.element.bib.hasAttribute("isfullscreen")) {
|
|
3991
|
+
return;
|
|
3992
|
+
}
|
|
3941
3993
|
|
|
3942
|
-
|
|
3994
|
+
if (
|
|
3995
|
+
(!evt.composedPath().includes(this.element.trigger) &&
|
|
3996
|
+
!evt.composedPath().includes(this.element.bib)) ||
|
|
3997
|
+
(this.element.bib.backdrop &&
|
|
3998
|
+
evt.composedPath().includes(this.element.bib.backdrop))
|
|
3999
|
+
) {
|
|
4000
|
+
const existedVisibleFloatingUI =
|
|
4001
|
+
document.expandedAuroFormkitDropdown || document.expandedAuroFloater;
|
|
4002
|
+
|
|
4003
|
+
if (
|
|
4004
|
+
existedVisibleFloatingUI &&
|
|
4005
|
+
existedVisibleFloatingUI.element.isPopoverVisible
|
|
4006
|
+
) {
|
|
3943
4007
|
// if something else is open, close that
|
|
3944
4008
|
existedVisibleFloatingUI.hideBib();
|
|
3945
4009
|
document.expandedAuroFormkitDropdown = null;
|
|
@@ -3952,9 +4016,14 @@ class AuroFloatingUI {
|
|
|
3952
4016
|
|
|
3953
4017
|
// ESC key handler
|
|
3954
4018
|
this.keyDownHandler = (evt) => {
|
|
3955
|
-
if (evt.key ===
|
|
3956
|
-
const existedVisibleFloatingUI =
|
|
3957
|
-
|
|
4019
|
+
if (evt.key === "Escape" && this.element.isPopoverVisible) {
|
|
4020
|
+
const existedVisibleFloatingUI =
|
|
4021
|
+
document.expandedAuroFormkitDropdown || document.expandedAuroFloater;
|
|
4022
|
+
if (
|
|
4023
|
+
existedVisibleFloatingUI &&
|
|
4024
|
+
existedVisibleFloatingUI !== this &&
|
|
4025
|
+
existedVisibleFloatingUI.element.isPopoverVisible
|
|
4026
|
+
) {
|
|
3958
4027
|
// if something else is open, let it handle itself
|
|
3959
4028
|
return;
|
|
3960
4029
|
}
|
|
@@ -3962,17 +4031,17 @@ class AuroFloatingUI {
|
|
|
3962
4031
|
}
|
|
3963
4032
|
};
|
|
3964
4033
|
|
|
3965
|
-
if (this.behavior !==
|
|
4034
|
+
if (this.behavior !== "drawer" && this.behavior !== "dialog") {
|
|
3966
4035
|
// Add event listeners using the stored references
|
|
3967
|
-
document.addEventListener(
|
|
4036
|
+
document.addEventListener("focusin", this.focusHandler);
|
|
3968
4037
|
}
|
|
3969
4038
|
|
|
3970
|
-
document.addEventListener(
|
|
4039
|
+
document.addEventListener("keydown", this.keyDownHandler);
|
|
3971
4040
|
|
|
3972
4041
|
// send this task to the end of queue to prevent conflicting
|
|
3973
4042
|
// it conflicts if showBib gets call from a button that's not this.element.trigger
|
|
3974
4043
|
setTimeout(() => {
|
|
3975
|
-
window.addEventListener(
|
|
4044
|
+
window.addEventListener("click", this.clickHandler);
|
|
3976
4045
|
}, 0);
|
|
3977
4046
|
}
|
|
3978
4047
|
|
|
@@ -3980,34 +4049,38 @@ class AuroFloatingUI {
|
|
|
3980
4049
|
// Remove event listeners if they exist
|
|
3981
4050
|
|
|
3982
4051
|
if (this.focusHandler) {
|
|
3983
|
-
document.removeEventListener(
|
|
4052
|
+
document.removeEventListener("focusin", this.focusHandler);
|
|
3984
4053
|
this.focusHandler = null;
|
|
3985
4054
|
}
|
|
3986
4055
|
|
|
3987
4056
|
if (this.clickHandler) {
|
|
3988
|
-
window.removeEventListener(
|
|
4057
|
+
window.removeEventListener("click", this.clickHandler);
|
|
3989
4058
|
this.clickHandler = null;
|
|
3990
4059
|
}
|
|
3991
4060
|
|
|
3992
4061
|
if (this.keyDownHandler) {
|
|
3993
|
-
document.removeEventListener(
|
|
4062
|
+
document.removeEventListener("keydown", this.keyDownHandler);
|
|
3994
4063
|
this.keyDownHandler = null;
|
|
3995
4064
|
}
|
|
3996
4065
|
}
|
|
3997
4066
|
|
|
3998
4067
|
handleUpdate(changedProperties) {
|
|
3999
|
-
if (changedProperties.has(
|
|
4068
|
+
if (changedProperties.has("isPopoverVisible")) {
|
|
4000
4069
|
this.updateState();
|
|
4001
4070
|
}
|
|
4002
4071
|
}
|
|
4003
4072
|
|
|
4004
4073
|
updateCurrentExpandedDropdown() {
|
|
4005
4074
|
// Close any other dropdown that is already open
|
|
4006
|
-
const existedVisibleFloatingUI =
|
|
4007
|
-
|
|
4075
|
+
const existedVisibleFloatingUI =
|
|
4076
|
+
document.expandedAuroFormkitDropdown || document.expandedAuroFloater;
|
|
4077
|
+
if (
|
|
4078
|
+
existedVisibleFloatingUI &&
|
|
4079
|
+
existedVisibleFloatingUI !== this &&
|
|
4008
4080
|
existedVisibleFloatingUI.element.isPopoverVisible &&
|
|
4009
|
-
|
|
4010
|
-
|
|
4081
|
+
existedVisibleFloatingUI.eventPrefix === this.eventPrefix
|
|
4082
|
+
) {
|
|
4083
|
+
existedVisibleFloatingUI.hideBib();
|
|
4011
4084
|
}
|
|
4012
4085
|
|
|
4013
4086
|
document.expandedAuroFloater = this;
|
|
@@ -4016,7 +4089,7 @@ class AuroFloatingUI {
|
|
|
4016
4089
|
showBib() {
|
|
4017
4090
|
if (!this.element.disabled && !this.showing) {
|
|
4018
4091
|
this.updateCurrentExpandedDropdown();
|
|
4019
|
-
this.element.triggerChevron?.setAttribute(
|
|
4092
|
+
this.element.triggerChevron?.setAttribute("data-expanded", true);
|
|
4020
4093
|
|
|
4021
4094
|
// prevent double showing: isPopovervisible gets first and showBib gets called later
|
|
4022
4095
|
if (!this.showing) {
|
|
@@ -4030,9 +4103,13 @@ class AuroFloatingUI {
|
|
|
4030
4103
|
}
|
|
4031
4104
|
|
|
4032
4105
|
// Setup auto update to handle resize and scroll
|
|
4033
|
-
this.element.cleanup = autoUpdate(
|
|
4034
|
-
this.
|
|
4035
|
-
|
|
4106
|
+
this.element.cleanup = autoUpdate(
|
|
4107
|
+
this.element.trigger || this.element.parentNode,
|
|
4108
|
+
this.element.bib,
|
|
4109
|
+
() => {
|
|
4110
|
+
this.position();
|
|
4111
|
+
},
|
|
4112
|
+
);
|
|
4036
4113
|
}
|
|
4037
4114
|
}
|
|
4038
4115
|
|
|
@@ -4043,7 +4120,7 @@ class AuroFloatingUI {
|
|
|
4043
4120
|
hideBib(eventType = "unknown") {
|
|
4044
4121
|
if (!this.element.disabled && !this.element.noToggle) {
|
|
4045
4122
|
this.lockScroll(false);
|
|
4046
|
-
this.element.triggerChevron?.removeAttribute(
|
|
4123
|
+
this.element.triggerChevron?.removeAttribute("data-expanded");
|
|
4047
4124
|
|
|
4048
4125
|
if (this.element.isPopoverVisible) {
|
|
4049
4126
|
this.element.isPopoverVisible = false;
|
|
@@ -4063,13 +4140,16 @@ class AuroFloatingUI {
|
|
|
4063
4140
|
* @param {String} eventType - The event type that triggered the toggle action.
|
|
4064
4141
|
*/
|
|
4065
4142
|
dispatchEventDropdownToggle(eventType) {
|
|
4066
|
-
const event = new CustomEvent(
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4143
|
+
const event = new CustomEvent(
|
|
4144
|
+
this.eventPrefix ? `${this.eventPrefix}-toggled` : "toggled",
|
|
4145
|
+
{
|
|
4146
|
+
detail: {
|
|
4147
|
+
expanded: this.showing,
|
|
4148
|
+
eventType: eventType || "unknown",
|
|
4149
|
+
},
|
|
4150
|
+
composed: true,
|
|
4070
4151
|
},
|
|
4071
|
-
|
|
4072
|
-
});
|
|
4152
|
+
);
|
|
4073
4153
|
|
|
4074
4154
|
this.element.dispatchEvent(event);
|
|
4075
4155
|
}
|
|
@@ -4081,12 +4161,15 @@ class AuroFloatingUI {
|
|
|
4081
4161
|
this.showBib();
|
|
4082
4162
|
}
|
|
4083
4163
|
|
|
4084
|
-
const event = new CustomEvent(
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4164
|
+
const event = new CustomEvent(
|
|
4165
|
+
this.eventPrefix ? `${this.eventPrefix}-triggerClick` : "triggerClick",
|
|
4166
|
+
{
|
|
4167
|
+
composed: true,
|
|
4168
|
+
detail: {
|
|
4169
|
+
expanded: this.element.isPopoverVisible,
|
|
4170
|
+
},
|
|
4171
|
+
},
|
|
4172
|
+
);
|
|
4090
4173
|
|
|
4091
4174
|
this.element.dispatchEvent(event);
|
|
4092
4175
|
}
|
|
@@ -4094,30 +4177,32 @@ class AuroFloatingUI {
|
|
|
4094
4177
|
handleEvent(event) {
|
|
4095
4178
|
if (!this.element.disableEventShow) {
|
|
4096
4179
|
switch (event.type) {
|
|
4097
|
-
case
|
|
4180
|
+
case "keydown": {
|
|
4098
4181
|
// Support both Enter and Space keys for accessibility
|
|
4099
4182
|
// Space is included as it's expected behavior for interactive elements
|
|
4100
4183
|
|
|
4101
4184
|
const origin = event.composedPath()[0];
|
|
4102
|
-
if (
|
|
4103
|
-
|
|
4185
|
+
if (
|
|
4186
|
+
event.key === "Enter" ||
|
|
4187
|
+
(event.key === " " && (!origin || origin.tagName !== "INPUT"))
|
|
4188
|
+
) {
|
|
4104
4189
|
event.preventDefault();
|
|
4105
4190
|
this.handleClick();
|
|
4106
4191
|
}
|
|
4107
4192
|
break;
|
|
4108
|
-
|
|
4193
|
+
}
|
|
4194
|
+
case "mouseenter":
|
|
4109
4195
|
if (this.element.hoverToggle) {
|
|
4110
4196
|
this.showBib();
|
|
4111
4197
|
}
|
|
4112
4198
|
break;
|
|
4113
|
-
case
|
|
4199
|
+
case "mouseleave":
|
|
4114
4200
|
if (this.element.hoverToggle) {
|
|
4115
4201
|
this.hideBib("mouseleave");
|
|
4116
4202
|
}
|
|
4117
4203
|
break;
|
|
4118
|
-
case
|
|
4204
|
+
case "focus":
|
|
4119
4205
|
if (this.element.focusShow) {
|
|
4120
|
-
|
|
4121
4206
|
/*
|
|
4122
4207
|
This needs to better handle clicking that gives focus -
|
|
4123
4208
|
currently it shows and then immediately hides the bib
|
|
@@ -4125,12 +4210,12 @@ class AuroFloatingUI {
|
|
|
4125
4210
|
this.showBib();
|
|
4126
4211
|
}
|
|
4127
4212
|
break;
|
|
4128
|
-
case
|
|
4213
|
+
case "blur":
|
|
4129
4214
|
// send this task 100ms later queue to
|
|
4130
4215
|
// wait a frame in case focus moves within the floating element/bib
|
|
4131
4216
|
setTimeout(() => this.handleFocusLoss(), 0);
|
|
4132
4217
|
break;
|
|
4133
|
-
case
|
|
4218
|
+
case "click":
|
|
4134
4219
|
if (document.activeElement === document.body) {
|
|
4135
4220
|
event.currentTarget.focus();
|
|
4136
4221
|
}
|
|
@@ -4149,15 +4234,15 @@ class AuroFloatingUI {
|
|
|
4149
4234
|
*/
|
|
4150
4235
|
handleTriggerTabIndex() {
|
|
4151
4236
|
const focusableElementSelectors = [
|
|
4152
|
-
|
|
4153
|
-
|
|
4237
|
+
"a",
|
|
4238
|
+
"button",
|
|
4154
4239
|
'input:not([type="hidden"])',
|
|
4155
|
-
|
|
4156
|
-
|
|
4240
|
+
"select",
|
|
4241
|
+
"textarea",
|
|
4157
4242
|
'[tabindex]:not([tabindex="-1"])',
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4243
|
+
"auro-button",
|
|
4244
|
+
"auro-input",
|
|
4245
|
+
"auro-hyperlink",
|
|
4161
4246
|
];
|
|
4162
4247
|
|
|
4163
4248
|
const triggerNode = this.element.querySelectorAll('[slot="trigger"]')[0];
|
|
@@ -4185,10 +4270,10 @@ class AuroFloatingUI {
|
|
|
4185
4270
|
* @param {*} eventPrefix
|
|
4186
4271
|
*/
|
|
4187
4272
|
regenerateBibId() {
|
|
4188
|
-
this.id = this.element.getAttribute(
|
|
4273
|
+
this.id = this.element.getAttribute("id");
|
|
4189
4274
|
if (!this.id) {
|
|
4190
4275
|
this.id = window.crypto.randomUUID();
|
|
4191
|
-
this.element.setAttribute(
|
|
4276
|
+
this.element.setAttribute("id", this.id);
|
|
4192
4277
|
}
|
|
4193
4278
|
|
|
4194
4279
|
this.element.bib.setAttribute("id", `${this.id}-floater-bib`);
|
|
@@ -4209,11 +4294,15 @@ class AuroFloatingUI {
|
|
|
4209
4294
|
if (this.element.trigger) {
|
|
4210
4295
|
this.disconnect();
|
|
4211
4296
|
}
|
|
4212
|
-
this.element.trigger =
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4297
|
+
this.element.trigger =
|
|
4298
|
+
this.element.triggerElement ||
|
|
4299
|
+
this.element.shadowRoot.querySelector("#trigger") ||
|
|
4300
|
+
this.element.trigger;
|
|
4301
|
+
this.element.bib =
|
|
4302
|
+
this.element.shadowRoot.querySelector("#bib") || this.element.bib;
|
|
4303
|
+
this.element.bibSizer = this.element.shadowRoot.querySelector("#bibSizer");
|
|
4304
|
+
this.element.triggerChevron =
|
|
4305
|
+
this.element.shadowRoot.querySelector("#showStateIcon");
|
|
4217
4306
|
|
|
4218
4307
|
if (this.element.floaterConfig) {
|
|
4219
4308
|
this.element.hoverToggle = this.element.floaterConfig.hoverToggle;
|
|
@@ -4224,12 +4313,12 @@ class AuroFloatingUI {
|
|
|
4224
4313
|
|
|
4225
4314
|
this.handleEvent = this.handleEvent.bind(this);
|
|
4226
4315
|
if (this.element.trigger) {
|
|
4227
|
-
this.element.trigger.addEventListener(
|
|
4228
|
-
this.element.trigger.addEventListener(
|
|
4229
|
-
this.element.trigger.addEventListener(
|
|
4230
|
-
this.element.trigger.addEventListener(
|
|
4231
|
-
this.element.trigger.addEventListener(
|
|
4232
|
-
this.element.trigger.addEventListener(
|
|
4316
|
+
this.element.trigger.addEventListener("keydown", this.handleEvent);
|
|
4317
|
+
this.element.trigger.addEventListener("click", this.handleEvent);
|
|
4318
|
+
this.element.trigger.addEventListener("mouseenter", this.handleEvent);
|
|
4319
|
+
this.element.trigger.addEventListener("mouseleave", this.handleEvent);
|
|
4320
|
+
this.element.trigger.addEventListener("focus", this.handleEvent);
|
|
4321
|
+
this.element.trigger.addEventListener("blur", this.handleEvent);
|
|
4233
4322
|
}
|
|
4234
4323
|
}
|
|
4235
4324
|
|
|
@@ -4244,12 +4333,18 @@ class AuroFloatingUI {
|
|
|
4244
4333
|
|
|
4245
4334
|
// Remove event & keyboard listeners
|
|
4246
4335
|
if (this.element?.trigger) {
|
|
4247
|
-
this.element.trigger.removeEventListener(
|
|
4248
|
-
this.element.trigger.removeEventListener(
|
|
4249
|
-
this.element.trigger.removeEventListener(
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4336
|
+
this.element.trigger.removeEventListener("keydown", this.handleEvent);
|
|
4337
|
+
this.element.trigger.removeEventListener("click", this.handleEvent);
|
|
4338
|
+
this.element.trigger.removeEventListener(
|
|
4339
|
+
"mouseenter",
|
|
4340
|
+
this.handleEvent,
|
|
4341
|
+
);
|
|
4342
|
+
this.element.trigger.removeEventListener(
|
|
4343
|
+
"mouseleave",
|
|
4344
|
+
this.handleEvent,
|
|
4345
|
+
);
|
|
4346
|
+
this.element.trigger.removeEventListener("focus", this.handleEvent);
|
|
4347
|
+
this.element.trigger.removeEventListener("blur", this.handleEvent);
|
|
4253
4348
|
}
|
|
4254
4349
|
}
|
|
4255
4350
|
}
|
|
@@ -4696,7 +4791,7 @@ let p$2 = class p{registerComponent(t,a){customElements.get(t)||customElements.d
|
|
|
4696
4791
|
|
|
4697
4792
|
var iconVersion$1 = '9.1.2';
|
|
4698
4793
|
|
|
4699
|
-
var styleCss$2 = i$5`: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}
|
|
4794
|
+
var styleCss$2 = i$5`: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}`;
|
|
4700
4795
|
|
|
4701
4796
|
var colorCss$2 = i$5`.container{background-color:var(--ds-auro-dropdownbib-container-color);box-shadow:var(--ds-auro-dropdownbib-boxshadow-color);color:var(--ds-auro-dropdownbib-text-color)}`;
|
|
4702
4797
|
|
|
@@ -4704,6 +4799,8 @@ var tokensCss$1 = i$5`:host(:not([ondark])),:host(:not([appearance=inverse])){--
|
|
|
4704
4799
|
|
|
4705
4800
|
// Copyright (c) 2020 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
4706
4801
|
// See LICENSE in the project root for license information.
|
|
4802
|
+
/* eslint-disable max-lines */
|
|
4803
|
+
// ---------------------------------------------------------------------
|
|
4707
4804
|
|
|
4708
4805
|
|
|
4709
4806
|
const DESIGN_TOKEN_BREAKPOINT_PREFIX = '--ds-grid-breakpoint-';
|
|
@@ -4798,6 +4895,28 @@ class AuroDropdownBib extends i$2 {
|
|
|
4798
4895
|
shape: {
|
|
4799
4896
|
type: String,
|
|
4800
4897
|
reflect: true
|
|
4898
|
+
},
|
|
4899
|
+
|
|
4900
|
+
/**
|
|
4901
|
+
* Accessible label for the dialog element, used when displayed as a modal.
|
|
4902
|
+
* Applied via aria-labelledby on a visually hidden element rather than
|
|
4903
|
+
* aria-label because iOS VoiceOver does not reliably read aria-label
|
|
4904
|
+
* on <dialog> elements.
|
|
4905
|
+
* @private
|
|
4906
|
+
*/
|
|
4907
|
+
dialogLabel: {
|
|
4908
|
+
type: String
|
|
4909
|
+
},
|
|
4910
|
+
|
|
4911
|
+
/**
|
|
4912
|
+
* Overrides the native role of the dialog element.
|
|
4913
|
+
* For example, set to `"presentation"` on desktop combobox to prevent
|
|
4914
|
+
* VoiceOver from announcing "listbox inside of a dialog".
|
|
4915
|
+
* When `undefined`, the dialog keeps its native role.
|
|
4916
|
+
* @private
|
|
4917
|
+
*/
|
|
4918
|
+
dialogRole: {
|
|
4919
|
+
type: String
|
|
4801
4920
|
}
|
|
4802
4921
|
};
|
|
4803
4922
|
}
|
|
@@ -4865,7 +4984,10 @@ class AuroDropdownBib extends i$2 {
|
|
|
4865
4984
|
firstUpdated(changedProperties) {
|
|
4866
4985
|
super.firstUpdated(changedProperties);
|
|
4867
4986
|
|
|
4868
|
-
|
|
4987
|
+
const dialog = this.shadowRoot.querySelector('dialog');
|
|
4988
|
+
this._setupCancelHandler(dialog);
|
|
4989
|
+
this._setupKeyboardBridge(dialog);
|
|
4990
|
+
|
|
4869
4991
|
this.dispatchEvent(new CustomEvent('auro-dropdownbib-connected', {
|
|
4870
4992
|
bubbles: true,
|
|
4871
4993
|
composed: true,
|
|
@@ -4875,6 +4997,189 @@ class AuroDropdownBib extends i$2 {
|
|
|
4875
4997
|
}));
|
|
4876
4998
|
}
|
|
4877
4999
|
|
|
5000
|
+
/**
|
|
5001
|
+
* Forwards the dialog's native `cancel` event (fired on ESC) as
|
|
5002
|
+
* an `auro-bib-cancel` custom event so parent components can close.
|
|
5003
|
+
* @param {HTMLDialogElement} dialog
|
|
5004
|
+
* @private
|
|
5005
|
+
*/
|
|
5006
|
+
_setupCancelHandler(dialog) {
|
|
5007
|
+
dialog.addEventListener('cancel', (event) => {
|
|
5008
|
+
event.preventDefault();
|
|
5009
|
+
this.dispatchEvent(new CustomEvent('auro-bib-cancel', {
|
|
5010
|
+
bubbles: true,
|
|
5011
|
+
composed: true
|
|
5012
|
+
}));
|
|
5013
|
+
});
|
|
5014
|
+
}
|
|
5015
|
+
|
|
5016
|
+
/**
|
|
5017
|
+
* showModal() creates a closed focus scope — keyboard events inside
|
|
5018
|
+
* the dialog's shadow DOM do NOT bubble out to the combobox/select
|
|
5019
|
+
* keydown handlers in the parent shadow DOM. This handler bridges
|
|
5020
|
+
* that gap by re-dispatching navigation keys so they cross the
|
|
5021
|
+
* shadow boundary and reach the menu navigation logic in the parent
|
|
5022
|
+
* component.
|
|
5023
|
+
*
|
|
5024
|
+
* The trade-off: intercepting these keys means native keyboard
|
|
5025
|
+
* behaviors that would normally "just work" must be manually
|
|
5026
|
+
* re-implemented here:
|
|
5027
|
+
*
|
|
5028
|
+
* - Enter on buttons: Custom elements (auro-button) don't get the
|
|
5029
|
+
* native Enter→click that <button> provides, so we call .click()
|
|
5030
|
+
* directly when Enter is pressed on a button-like element.
|
|
5031
|
+
*
|
|
5032
|
+
* - Tab: Intercepted and re-dispatched so parent components
|
|
5033
|
+
* (select/combobox) can select the active option and close the
|
|
5034
|
+
* dialog. The <dialog> provides containment and isolation
|
|
5035
|
+
* (inert background, VoiceOver focus trapping, top layer), while
|
|
5036
|
+
* the content inside is a role="listbox" navigated via
|
|
5037
|
+
* aria-activedescendant (options are not focusable). Tab keyboard
|
|
5038
|
+
* behavior follows listbox conventions (select + close) because
|
|
5039
|
+
* the dialog's native Tab trap only cycles between the close
|
|
5040
|
+
* button and browser chrome.
|
|
5041
|
+
*
|
|
5042
|
+
* - Escape: The native <dialog> fires a `cancel` event on ESC
|
|
5043
|
+
* (handled by _setupCancelHandler), so the re-dispatched Escape
|
|
5044
|
+
* is a secondary path for parent components that also listen for
|
|
5045
|
+
* Escape keydown.
|
|
5046
|
+
*
|
|
5047
|
+
* @param {HTMLDialogElement} dialog
|
|
5048
|
+
* @private
|
|
5049
|
+
*/
|
|
5050
|
+
_setupKeyboardBridge(dialog) {
|
|
5051
|
+
const navKeys = new Set([
|
|
5052
|
+
'ArrowUp',
|
|
5053
|
+
'ArrowDown',
|
|
5054
|
+
'Enter',
|
|
5055
|
+
'Escape',
|
|
5056
|
+
'Tab'
|
|
5057
|
+
]);
|
|
5058
|
+
|
|
5059
|
+
dialog.addEventListener('keydown', (event) => {
|
|
5060
|
+
if (!navKeys.has(event.key)) {
|
|
5061
|
+
return;
|
|
5062
|
+
}
|
|
5063
|
+
|
|
5064
|
+
// Custom elements (auro-button) don't get the native Enter→click
|
|
5065
|
+
// behavior that <button> has. Find the button in the composed path
|
|
5066
|
+
// and click it directly.
|
|
5067
|
+
if (event.key === 'Enter') {
|
|
5068
|
+
const buttonSelector = 'button, [role="button"], auro-button, [auro-button]';
|
|
5069
|
+
const btn = event.composedPath().find((el) => el.matches && el.matches(buttonSelector));
|
|
5070
|
+
if (btn) {
|
|
5071
|
+
event.preventDefault();
|
|
5072
|
+
event.stopPropagation();
|
|
5073
|
+
btn.click();
|
|
5074
|
+
return;
|
|
5075
|
+
}
|
|
5076
|
+
}
|
|
5077
|
+
|
|
5078
|
+
event.preventDefault();
|
|
5079
|
+
event.stopPropagation();
|
|
5080
|
+
const newEvent = new KeyboardEvent('keydown', {
|
|
5081
|
+
key: event.key,
|
|
5082
|
+
code: event.code,
|
|
5083
|
+
shiftKey: event.shiftKey,
|
|
5084
|
+
altKey: event.altKey,
|
|
5085
|
+
ctrlKey: event.ctrlKey,
|
|
5086
|
+
metaKey: event.metaKey,
|
|
5087
|
+
bubbles: true,
|
|
5088
|
+
composed: true,
|
|
5089
|
+
cancelable: true
|
|
5090
|
+
});
|
|
5091
|
+
this.dispatchEvent(newEvent);
|
|
5092
|
+
});
|
|
5093
|
+
}
|
|
5094
|
+
|
|
5095
|
+
/**
|
|
5096
|
+
* Blocks touch-driven page scroll while a fullscreen modal dialog is open.
|
|
5097
|
+
*
|
|
5098
|
+
* The showModal() function places the dialog in the browser's **top layer**,
|
|
5099
|
+
* which is a separate rendering layer above the normal DOM. On mobile, the
|
|
5100
|
+
* compositor processes visual-viewport panning before top-layer touch
|
|
5101
|
+
* handling. This means the entire viewport — including the top-layer dialog
|
|
5102
|
+
* — can be panned by a touch gesture, causing the page behind the dialog to
|
|
5103
|
+
* scroll into view. To prevent this, we add a touchmove listener that cancels
|
|
5104
|
+
* the event if the touch started outside the dialog or any scrollable child within it.
|
|
5105
|
+
*
|
|
5106
|
+
* @private
|
|
5107
|
+
*/
|
|
5108
|
+
_lockTouchScroll() {
|
|
5109
|
+
const dialog = this.shadowRoot.querySelector('dialog');
|
|
5110
|
+
|
|
5111
|
+
this._touchMoveHandler = (event) => {
|
|
5112
|
+
// Walk the composed path (which crosses shadow DOM boundaries) to
|
|
5113
|
+
// check whether the touch started inside a scrollable element that
|
|
5114
|
+
// lives within the dialog. If so, allow the scroll.
|
|
5115
|
+
for (const el of event.composedPath()) {
|
|
5116
|
+
if (el === dialog) {
|
|
5117
|
+
// Reached the dialog boundary without finding a scrollable child.
|
|
5118
|
+
break;
|
|
5119
|
+
}
|
|
5120
|
+
if (el instanceof HTMLElement && el.scrollHeight > el.clientHeight) {
|
|
5121
|
+
const { overflowY } = getComputedStyle(el);
|
|
5122
|
+
if (overflowY === 'auto' || overflowY === 'scroll') {
|
|
5123
|
+
return;
|
|
5124
|
+
}
|
|
5125
|
+
}
|
|
5126
|
+
}
|
|
5127
|
+
|
|
5128
|
+
event.preventDefault();
|
|
5129
|
+
};
|
|
5130
|
+
|
|
5131
|
+
document.addEventListener('touchmove', this._touchMoveHandler, { passive: false });
|
|
5132
|
+
}
|
|
5133
|
+
|
|
5134
|
+
/**
|
|
5135
|
+
* Removes the touchmove listener added by _lockTouchScroll().
|
|
5136
|
+
* @private
|
|
5137
|
+
*/
|
|
5138
|
+
_unlockTouchScroll() {
|
|
5139
|
+
if (this._touchMoveHandler) {
|
|
5140
|
+
document.removeEventListener('touchmove', this._touchMoveHandler);
|
|
5141
|
+
this._touchMoveHandler = undefined;
|
|
5142
|
+
}
|
|
5143
|
+
}
|
|
5144
|
+
|
|
5145
|
+
open(modal = true) {
|
|
5146
|
+
const dialog = this.shadowRoot.querySelector('dialog');
|
|
5147
|
+
if (dialog && !dialog.open) {
|
|
5148
|
+
if (modal) {
|
|
5149
|
+
// Prevent showModal() from scrolling the page to bring the dialog
|
|
5150
|
+
// into view. Locking overflow on <html> blocks the viewport scroll
|
|
5151
|
+
// that browsers perform natively; we release it immediately after
|
|
5152
|
+
// so it doesn't interfere with the modal's focus management.
|
|
5153
|
+
const { documentElement } = document;
|
|
5154
|
+
const prevOverflow = documentElement.style.overflow;
|
|
5155
|
+
documentElement.style.overflow = 'hidden';
|
|
5156
|
+
|
|
5157
|
+
dialog.showModal();
|
|
5158
|
+
|
|
5159
|
+
documentElement.style.overflow = prevOverflow;
|
|
5160
|
+
|
|
5161
|
+
this._lockTouchScroll();
|
|
5162
|
+
|
|
5163
|
+
} else {
|
|
5164
|
+
// Use setAttribute instead of dialog.show() to avoid the dialog
|
|
5165
|
+
// focusing steps which steal focus from the trigger and cause
|
|
5166
|
+
// the floater's handleFocusLoss() to immediately hide the bib.
|
|
5167
|
+
dialog.setAttribute('open', '');
|
|
5168
|
+
}
|
|
5169
|
+
}
|
|
5170
|
+
}
|
|
5171
|
+
|
|
5172
|
+
/**
|
|
5173
|
+
* Closes the dialog.
|
|
5174
|
+
*/
|
|
5175
|
+
close() {
|
|
5176
|
+
const dialog = this.shadowRoot.querySelector('dialog');
|
|
5177
|
+
if (dialog && dialog.open) {
|
|
5178
|
+
this._unlockTouchScroll();
|
|
5179
|
+
dialog.close();
|
|
5180
|
+
}
|
|
5181
|
+
}
|
|
5182
|
+
|
|
4878
5183
|
// function that renders the HTML and CSS into the scope of the component
|
|
4879
5184
|
render() {
|
|
4880
5185
|
const classes = {
|
|
@@ -4886,9 +5191,10 @@ class AuroDropdownBib extends i$2 {
|
|
|
4886
5191
|
classes[`shape-${this.shape}`] = true;
|
|
4887
5192
|
|
|
4888
5193
|
return u$5`
|
|
4889
|
-
<
|
|
5194
|
+
<dialog class="${e$2(classes)}" part="bibContainer" role="${o$2(this.dialogRole)}" aria-labelledby="${o$2(this.dialogLabel ? 'dialogLabel' : undefined)}">
|
|
5195
|
+
${this.dialogLabel ? u$5`<span id="dialogLabel" class="util_displayHiddenVisually" aria-hidden="true">${this.dialogLabel}</span>` : ''}
|
|
4890
5196
|
<slot></slot>
|
|
4891
|
-
</
|
|
5197
|
+
</dialog>
|
|
4892
5198
|
`;
|
|
4893
5199
|
}
|
|
4894
5200
|
}
|
|
@@ -4897,7 +5203,7 @@ var shapeSizeCss = i$5`.shape-classic-xl,.shape-classic-lg,.shape-classic-md,.sh
|
|
|
4897
5203
|
|
|
4898
5204
|
var colorCss$1$1 = i$5`: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)}`;
|
|
4899
5205
|
|
|
4900
|
-
var styleCss$1$1 = i$5`:host{position:relative;display:block;text-align:left}
|
|
5206
|
+
var styleCss$1$1 = i$5`: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%}`;
|
|
4901
5207
|
|
|
4902
5208
|
var classicColorCss = i$5``;
|
|
4903
5209
|
|
|
@@ -5135,7 +5441,7 @@ class AuroHelpText extends i$2 {
|
|
|
5135
5441
|
}
|
|
5136
5442
|
}
|
|
5137
5443
|
|
|
5138
|
-
var formkitVersion = '
|
|
5444
|
+
var formkitVersion = '202603102257';
|
|
5139
5445
|
|
|
5140
5446
|
let AuroElement$1 = class AuroElement extends i$2 {
|
|
5141
5447
|
static get properties() {
|
|
@@ -5249,7 +5555,7 @@ let AuroElement$1 = class AuroElement extends i$2 {
|
|
|
5249
5555
|
* The `auro-dropdown` element provides a way to place content in a bib that can be toggled.
|
|
5250
5556
|
* @customElement auro-dropdown
|
|
5251
5557
|
*
|
|
5252
|
-
* @slot - Default slot for the
|
|
5558
|
+
* @slot - Default slot for the dropdown bib content.
|
|
5253
5559
|
* @slot helpText - Defines the content of the helpText.
|
|
5254
5560
|
* @slot trigger - Defines the content of the trigger.
|
|
5255
5561
|
* @csspart trigger - The trigger content container.
|
|
@@ -5261,6 +5567,13 @@ let AuroElement$1 = class AuroElement extends i$2 {
|
|
|
5261
5567
|
* @event auroDropdown-idAdded - Notifies consumers that the unique ID for the dropdown bib has been generated.
|
|
5262
5568
|
*/
|
|
5263
5569
|
class AuroDropdown extends AuroElement$1 {
|
|
5570
|
+
static get shadowRootOptions() {
|
|
5571
|
+
return {
|
|
5572
|
+
...AuroElement$1.shadowRootOptions,
|
|
5573
|
+
delegatesFocus: true,
|
|
5574
|
+
};
|
|
5575
|
+
}
|
|
5576
|
+
|
|
5264
5577
|
constructor() {
|
|
5265
5578
|
super();
|
|
5266
5579
|
|
|
@@ -5326,15 +5639,6 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5326
5639
|
this.shift = false;
|
|
5327
5640
|
this.autoPlacement = false;
|
|
5328
5641
|
|
|
5329
|
-
/**
|
|
5330
|
-
* @private
|
|
5331
|
-
* @property {boolean} delegatesFocus - Whether the shadow root delegates focus.
|
|
5332
|
-
*/
|
|
5333
|
-
this.constructor.shadowRootOptions = {
|
|
5334
|
-
...i$2.shadowRootOptions,
|
|
5335
|
-
delegatesFocus: true,
|
|
5336
|
-
};
|
|
5337
|
-
|
|
5338
5642
|
/**
|
|
5339
5643
|
* @private
|
|
5340
5644
|
*/
|
|
@@ -5408,6 +5712,18 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5408
5712
|
*/
|
|
5409
5713
|
show() {
|
|
5410
5714
|
this.floater.showBib();
|
|
5715
|
+
|
|
5716
|
+
// Open dialog synchronously so callers remain in the user gesture
|
|
5717
|
+
// chain. This is critical for mobile browsers (iOS Safari) to keep
|
|
5718
|
+
// the virtual keyboard open when transitioning from the trigger
|
|
5719
|
+
// input to an input inside the fullscreen dialog. Without this,
|
|
5720
|
+
// showModal() fires asynchronously via Lit's update cycle, which
|
|
5721
|
+
// falls outside the user activation window and causes iOS to
|
|
5722
|
+
// dismiss the keyboard.
|
|
5723
|
+
if (this.isBibFullscreen && this.bibElement && this.bibElement.value) {
|
|
5724
|
+
const useModal = !this.disableFocusTrap;
|
|
5725
|
+
this.bibElement.value.open(useModal);
|
|
5726
|
+
}
|
|
5411
5727
|
}
|
|
5412
5728
|
|
|
5413
5729
|
/**
|
|
@@ -5415,13 +5731,37 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5415
5731
|
* If not, trigger element will get focus.
|
|
5416
5732
|
*/
|
|
5417
5733
|
focus() {
|
|
5418
|
-
if (this.isPopoverVisible && this.
|
|
5419
|
-
this.
|
|
5734
|
+
if (this.isPopoverVisible && this.bibContent) {
|
|
5735
|
+
const focusables = getFocusableElements(this.bibContent);
|
|
5736
|
+
if (focusables.length > 0) {
|
|
5737
|
+
focusables[0].focus();
|
|
5738
|
+
}
|
|
5420
5739
|
} else {
|
|
5421
5740
|
this.trigger.focus();
|
|
5422
5741
|
}
|
|
5423
5742
|
}
|
|
5424
5743
|
|
|
5744
|
+
/**
|
|
5745
|
+
* Sets the active descendant element for accessibility.
|
|
5746
|
+
* Uses ariaActiveDescendantElement to cross shadow DOM boundaries.
|
|
5747
|
+
* This function is used in components that contain `auro-dropdown` to set the active descendant.
|
|
5748
|
+
* @private
|
|
5749
|
+
* @param {HTMLElement|null} element - The element to set as the active descendant, or null to clear.
|
|
5750
|
+
* @returns {void}
|
|
5751
|
+
*/
|
|
5752
|
+
setActiveDescendant(element) {
|
|
5753
|
+
if (!this.trigger) {
|
|
5754
|
+
return;
|
|
5755
|
+
}
|
|
5756
|
+
|
|
5757
|
+
if (element) {
|
|
5758
|
+
this.trigger.ariaActiveDescendantElement = element;
|
|
5759
|
+
} else {
|
|
5760
|
+
this.trigger.ariaActiveDescendantElement = null;
|
|
5761
|
+
this.trigger.removeAttribute('aria-activedescendant');
|
|
5762
|
+
}
|
|
5763
|
+
}
|
|
5764
|
+
|
|
5425
5765
|
// function to define props used within the scope of this component
|
|
5426
5766
|
static get properties() {
|
|
5427
5767
|
return {
|
|
@@ -5679,6 +6019,16 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5679
6019
|
*/
|
|
5680
6020
|
tabIndex: {
|
|
5681
6021
|
type: Number
|
|
6022
|
+
},
|
|
6023
|
+
|
|
6024
|
+
/**
|
|
6025
|
+
* Accessible label for the dropdown bib dialog element.
|
|
6026
|
+
* @private
|
|
6027
|
+
*/
|
|
6028
|
+
bibDialogLabel: {
|
|
6029
|
+
type: String,
|
|
6030
|
+
attribute: false,
|
|
6031
|
+
reflect: false
|
|
5682
6032
|
}
|
|
5683
6033
|
};
|
|
5684
6034
|
}
|
|
@@ -5730,7 +6080,10 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5730
6080
|
|
|
5731
6081
|
disconnectedCallback() {
|
|
5732
6082
|
super.disconnectedCallback();
|
|
5733
|
-
this.floater
|
|
6083
|
+
if (this.floater) {
|
|
6084
|
+
this.floater.hideBib('disconnect');
|
|
6085
|
+
this.floater.disconnect();
|
|
6086
|
+
}
|
|
5734
6087
|
this.clearTriggerFocusEventBinding();
|
|
5735
6088
|
}
|
|
5736
6089
|
|
|
@@ -5752,11 +6105,22 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5752
6105
|
|
|
5753
6106
|
if (changedProperties.has('isPopoverVisible') && this.bibElement.value) {
|
|
5754
6107
|
if (this.isPopoverVisible) {
|
|
5755
|
-
|
|
6108
|
+
// Fullscreen: use showModal() for native accessibility (inert outside, focus trap)
|
|
6109
|
+
// Desktop: use show() for Floating UI positioning + FocusTrap for focus management
|
|
6110
|
+
const useModal = this.isBibFullscreen && !this.disableFocusTrap;
|
|
6111
|
+
this.bibElement.value.open(useModal);
|
|
5756
6112
|
} else {
|
|
5757
|
-
this.bibElement.value.
|
|
6113
|
+
this.bibElement.value.close();
|
|
5758
6114
|
}
|
|
5759
6115
|
}
|
|
6116
|
+
|
|
6117
|
+
// When fullscreen strategy changes while open, re-open dialog with correct mode
|
|
6118
|
+
// (e.g. resizing from desktop → mobile while dropdown is open)
|
|
6119
|
+
if (changedProperties.has('isBibFullscreen') && this.isPopoverVisible && this.bibElement.value) {
|
|
6120
|
+
const useModal = this.isBibFullscreen && !this.disableFocusTrap;
|
|
6121
|
+
this.bibElement.value.close();
|
|
6122
|
+
this.bibElement.value.open(useModal);
|
|
6123
|
+
}
|
|
5760
6124
|
}
|
|
5761
6125
|
|
|
5762
6126
|
/**
|
|
@@ -5774,11 +6138,28 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5774
6138
|
}
|
|
5775
6139
|
|
|
5776
6140
|
firstUpdated() {
|
|
5777
|
-
|
|
5778
6141
|
// Configure the floater to, this will generate the ID for the bib
|
|
5779
6142
|
this.floater.configure(this, 'auroDropdown');
|
|
6143
|
+
|
|
6144
|
+
// Prevent `contain: layout` on the dropdown host. Layout containment
|
|
6145
|
+
// creates a containing block for position:fixed descendants (the bib),
|
|
6146
|
+
// which clips the bib inside ancestor overflow contexts such as a
|
|
6147
|
+
// <dialog> element. Without it, the bib's position:fixed is relative
|
|
6148
|
+
// to the viewport, letting Floating UI's flip middleware detect
|
|
6149
|
+
// viewport boundaries and the bib escape overflow clipping.
|
|
6150
|
+
const origConfigureBibStrategy = this.floater.configureBibStrategy.bind(this.floater);
|
|
6151
|
+
this.floater.configureBibStrategy = (value) => {
|
|
6152
|
+
origConfigureBibStrategy(value);
|
|
6153
|
+
this.style.contain = '';
|
|
6154
|
+
};
|
|
6155
|
+
|
|
5780
6156
|
this.addEventListener('auroDropdown-toggled', this.handleDropdownToggle);
|
|
5781
6157
|
|
|
6158
|
+
// Handle ESC key from dialog's cancel event
|
|
6159
|
+
this.addEventListener('auro-bib-cancel', () => {
|
|
6160
|
+
this.floater.hideBib('keydown');
|
|
6161
|
+
});
|
|
6162
|
+
|
|
5782
6163
|
/**
|
|
5783
6164
|
* @description Let subscribers know that the dropdown ID ha been generated and added.
|
|
5784
6165
|
* @event auroDropdown-idAdded
|
|
@@ -5786,9 +6167,9 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5786
6167
|
*/
|
|
5787
6168
|
this.dispatchEvent(new CustomEvent('auroDropdown-idAdded', {detail: {id: this.floater.element.id}}));
|
|
5788
6169
|
|
|
5789
|
-
// Set the bib ID locally
|
|
6170
|
+
// Set the bib ID locally for aria-controls (must be in the same shadow root as the trigger)
|
|
5790
6171
|
if (!this.triggerContentFocusable) {
|
|
5791
|
-
this.dropdownId = this.floater.element.id;
|
|
6172
|
+
this.dropdownId = this.floater.element.bib.id;
|
|
5792
6173
|
}
|
|
5793
6174
|
|
|
5794
6175
|
this.bibContent = this.floater.element.bib;
|
|
@@ -5848,21 +6229,20 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
5848
6229
|
* @private
|
|
5849
6230
|
*/
|
|
5850
6231
|
updateFocusTrap() {
|
|
5851
|
-
// If the dropdown is open, create a focus trap and focus the first element
|
|
5852
6232
|
if (this.isPopoverVisible && !this.disableFocusTrap) {
|
|
5853
|
-
|
|
5854
|
-
|
|
6233
|
+
if (!this.isBibFullscreen) {
|
|
6234
|
+
// Desktop: show() doesn't trap focus, so use FocusTrap
|
|
6235
|
+
this.focusTrap = new FocusTrap(this.bibContent);
|
|
6236
|
+
this.focusTrap.focusFirstElement();
|
|
6237
|
+
}
|
|
6238
|
+
// Fullscreen: showModal() provides native focus trapping
|
|
5855
6239
|
return;
|
|
5856
6240
|
}
|
|
5857
6241
|
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
6242
|
+
if (this.focusTrap) {
|
|
6243
|
+
this.focusTrap.disconnect();
|
|
6244
|
+
this.focusTrap = undefined;
|
|
5861
6245
|
}
|
|
5862
|
-
|
|
5863
|
-
// If the dropdown is not open, disconnect the focus trap if it exists
|
|
5864
|
-
this.focusTrap.disconnect();
|
|
5865
|
-
this.focusTrap = undefined;
|
|
5866
6246
|
}
|
|
5867
6247
|
|
|
5868
6248
|
/**
|
|
@@ -6078,13 +6458,14 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
6078
6458
|
<div
|
|
6079
6459
|
id="showStateIcon"
|
|
6080
6460
|
class="chevron"
|
|
6081
|
-
part="chevron"
|
|
6461
|
+
part="chevron"
|
|
6462
|
+
aria-hidden="true">
|
|
6082
6463
|
<${this.iconTag}
|
|
6083
6464
|
category="interface"
|
|
6084
6465
|
name="${this.isPopoverVisible ? 'chevron-up' : `chevron-down`}"
|
|
6085
6466
|
appearance="${this.onDark ? 'inverse' : this.appearance}"
|
|
6086
|
-
variant="${this.disabled ? 'disabled' : 'muted'}"
|
|
6087
|
-
>
|
|
6467
|
+
variant="${this.disabled ? 'disabled' : 'muted'}"
|
|
6468
|
+
ariaHidden="true">
|
|
6088
6469
|
</${this.iconTag}>
|
|
6089
6470
|
</div>
|
|
6090
6471
|
` : undefined }
|
|
@@ -6098,8 +6479,8 @@ class AuroDropdown extends AuroElement$1 {
|
|
|
6098
6479
|
shape="${this.shape}"
|
|
6099
6480
|
?data-show="${this.isPopoverVisible}"
|
|
6100
6481
|
?isfullscreen="${this.isBibFullscreen}"
|
|
6482
|
+
.dialogLabel="${this.bibDialogLabel}"
|
|
6101
6483
|
${n$1(this.bibElement)}
|
|
6102
|
-
popover="manual"
|
|
6103
6484
|
>
|
|
6104
6485
|
<div class="slotContent">
|
|
6105
6486
|
<slot @slotchange="${this.handleDefaultSlot}"></slot>
|
|
@@ -6506,6 +6887,18 @@ class AuroBibtemplate extends i$2 {
|
|
|
6506
6887
|
this.removeEventListener('touchmove', this.preventBodyScroll, { passive: false });
|
|
6507
6888
|
}
|
|
6508
6889
|
|
|
6890
|
+
/**
|
|
6891
|
+
* Focuses the close button inside the bibtemplate's shadow DOM.
|
|
6892
|
+
* Used by parent components to set initial focus when the fullscreen dialog opens.
|
|
6893
|
+
* @returns {void}
|
|
6894
|
+
*/
|
|
6895
|
+
focusCloseButton() {
|
|
6896
|
+
const closeBtn = this.shadowRoot.querySelector('#closeButton');
|
|
6897
|
+
if (closeBtn) {
|
|
6898
|
+
closeBtn.focus();
|
|
6899
|
+
}
|
|
6900
|
+
}
|
|
6901
|
+
|
|
6509
6902
|
onCloseButtonClick() {
|
|
6510
6903
|
this.dispatchEvent(new Event("close-click", { bubbles: true,
|
|
6511
6904
|
composed: true }));
|
|
@@ -7182,6 +7575,24 @@ class AuroCounterGroup extends AuroElement {
|
|
|
7182
7575
|
this.dropdown.hide();
|
|
7183
7576
|
}
|
|
7184
7577
|
});
|
|
7578
|
+
|
|
7579
|
+
// Focus close button when fullscreen dialog opens
|
|
7580
|
+
this.dropdown.addEventListener('auroDropdown-toggled', () => {
|
|
7581
|
+
if (this.dropdown.isPopoverVisible && this.dropdown.isBibFullscreen) {
|
|
7582
|
+
doubleRaf(() => {
|
|
7583
|
+
this.bibtemplate.focusCloseButton();
|
|
7584
|
+
});
|
|
7585
|
+
}
|
|
7586
|
+
});
|
|
7587
|
+
|
|
7588
|
+
// Tab closes the fullscreen dialog
|
|
7589
|
+
// The dialog event bridge intercepts Tab and re-dispatches it as a
|
|
7590
|
+
// composed keydown; this listener catches the re-dispatched event.
|
|
7591
|
+
this.addEventListener('keydown', (evt) => {
|
|
7592
|
+
if (evt.key === 'Tab' && this.dropdown.isPopoverVisible && this.dropdown.isBibFullscreen) {
|
|
7593
|
+
this.dropdown.hide();
|
|
7594
|
+
}
|
|
7595
|
+
});
|
|
7185
7596
|
}
|
|
7186
7597
|
|
|
7187
7598
|
/**
|