@ionic/core 8.7.18-dev.11770674094.18396f54 → 8.7.18-dev.11770916502.174efd7f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/modal.js +100 -26
- package/dist/cjs/ion-modal.cjs.entry.js +100 -26
- package/dist/collection/components/modal/modal.ios.css +6 -1
- package/dist/collection/components/modal/modal.js +56 -23
- package/dist/collection/components/modal/modal.md.css +6 -1
- package/dist/collection/components/modal/safe-area-utils.js +44 -2
- package/dist/docs.json +1 -1
- package/dist/esm/ion-modal.entry.js +100 -26
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-3e69999d.entry.js +4 -0
- package/dist/types/components/modal/modal.d.ts +12 -0
- package/dist/types/components/modal/safe-area-utils.d.ts +16 -5
- package/hydrate/index.js +100 -26
- package/hydrate/index.mjs +100 -26
- package/package.json +1 -1
- package/dist/ionic/p-36d78f36.entry.js +0 -4
|
@@ -21,7 +21,7 @@ import { mdEnterAnimation } from "./animations/md.enter";
|
|
|
21
21
|
import { mdLeaveAnimation } from "./animations/md.leave";
|
|
22
22
|
import { createSheetGesture } from "./gestures/sheet";
|
|
23
23
|
import { createSwipeToCloseGesture, SwipeToCloseDefaults } from "./gestures/swipe-to-close";
|
|
24
|
-
import { getInitialSafeAreaConfig, getPositionBasedSafeAreaConfig, applySafeAreaOverrides, clearSafeAreaOverrides, } from "./safe-area-utils";
|
|
24
|
+
import { getInitialSafeAreaConfig, getPositionBasedSafeAreaConfig, applySafeAreaOverrides, clearSafeAreaOverrides, getRootSafeAreaTop, } from "./safe-area-utils";
|
|
25
25
|
import { setCardStatusBarDark, setCardStatusBarDefault } from "./utils";
|
|
26
26
|
// TODO(FW-2832): types
|
|
27
27
|
/**
|
|
@@ -233,13 +233,31 @@ export class Modal {
|
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
235
|
onWindowResize() {
|
|
236
|
-
|
|
237
|
-
if (getIonMode(this) !== 'ios' || !this.presentingElement || this.enterAnimation || this.leaveAnimation) {
|
|
236
|
+
if (!this.presented)
|
|
238
237
|
return;
|
|
239
|
-
}
|
|
240
238
|
clearTimeout(this.resizeTimeout);
|
|
241
239
|
this.resizeTimeout = setTimeout(() => {
|
|
242
|
-
this.
|
|
240
|
+
const context = this.getSafeAreaContext();
|
|
241
|
+
// iOS card modals: handle portrait/landscape view transitions
|
|
242
|
+
if (context.isCardModal && !this.enterAnimation && !this.leaveAnimation) {
|
|
243
|
+
this.handleViewTransition();
|
|
244
|
+
}
|
|
245
|
+
// Sheet modals: re-compute the internal offset property since safe-area
|
|
246
|
+
// values may change on device rotation (e.g., portrait notch vs landscape).
|
|
247
|
+
if (context.isSheetModal) {
|
|
248
|
+
this.updateSheetOffsetTop();
|
|
249
|
+
}
|
|
250
|
+
// Regular (non-sheet, non-card) modals: update safe-area overrides
|
|
251
|
+
// since the viewport may have crossed the centered-dialog breakpoint.
|
|
252
|
+
if (!context.isSheetModal && !context.isCardModal) {
|
|
253
|
+
this.updateSafeAreaOverrides();
|
|
254
|
+
// Re-evaluate fullscreen safe-area padding: clear first, then re-apply
|
|
255
|
+
if (this.wrapperEl) {
|
|
256
|
+
this.wrapperEl.style.removeProperty('height');
|
|
257
|
+
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
258
|
+
}
|
|
259
|
+
this.applyFullscreenSafeArea();
|
|
260
|
+
}
|
|
243
261
|
}, 50); // Debounce to avoid excessive calls during active resizing
|
|
244
262
|
}
|
|
245
263
|
breakpointsChanged(breakpoints) {
|
|
@@ -553,8 +571,6 @@ export class Modal {
|
|
|
553
571
|
if (this.currentBreakpoint !== breakpoint) {
|
|
554
572
|
this.currentBreakpoint = breakpoint;
|
|
555
573
|
this.ionBreakpointDidChange.emit({ breakpoint });
|
|
556
|
-
// Update safe-area overrides based on new position
|
|
557
|
-
this.updateSafeAreaOverrides();
|
|
558
574
|
}
|
|
559
575
|
});
|
|
560
576
|
this.gesture = gesture;
|
|
@@ -668,6 +684,9 @@ export class Modal {
|
|
|
668
684
|
if (this.gestureAnimationDismissing && role !== GESTURE) {
|
|
669
685
|
return false;
|
|
670
686
|
}
|
|
687
|
+
// Cancel any pending resize timeout to prevent stale updates during dismiss
|
|
688
|
+
clearTimeout(this.resizeTimeout);
|
|
689
|
+
this.resizeTimeout = undefined;
|
|
671
690
|
/**
|
|
672
691
|
* Because the canDismiss check below is async,
|
|
673
692
|
* we need to claim a lock before the check happens,
|
|
@@ -995,11 +1014,30 @@ export class Modal {
|
|
|
995
1014
|
/**
|
|
996
1015
|
* Sets initial safe-area overrides before modal animation.
|
|
997
1016
|
* Called in present() before animation starts.
|
|
1017
|
+
*
|
|
1018
|
+
* For sheet modals, the SCSS --height formula uses --ion-modal-offset-top
|
|
1019
|
+
* (an internal property) instead of --ion-safe-area-top. We resolve the
|
|
1020
|
+
* root safe-area-top to pixels and set --ion-modal-offset-top, decoupling
|
|
1021
|
+
* the height calculation from --ion-safe-area-top (which is zeroed for
|
|
1022
|
+
* sheets to prevent header content from getting double-offset padding).
|
|
998
1023
|
*/
|
|
999
1024
|
setInitialSafeAreaOverrides() {
|
|
1000
1025
|
const context = this.getSafeAreaContext();
|
|
1001
1026
|
const safeAreaConfig = getInitialSafeAreaConfig(context);
|
|
1002
1027
|
applySafeAreaOverrides(this.el, safeAreaConfig);
|
|
1028
|
+
// Set the internal offset property with the resolved root safe-area-top value
|
|
1029
|
+
if (context.isSheetModal) {
|
|
1030
|
+
this.updateSheetOffsetTop();
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Resolves the current root --ion-safe-area-top value and sets the
|
|
1035
|
+
* internal --ion-modal-offset-top property on the host element.
|
|
1036
|
+
* Called on present and on resize (e.g., device rotation changes safe-area).
|
|
1037
|
+
*/
|
|
1038
|
+
updateSheetOffsetTop() {
|
|
1039
|
+
const safeAreaTop = getRootSafeAreaTop();
|
|
1040
|
+
this.el.style.setProperty('--ion-modal-offset-top', `${safeAreaTop}px`);
|
|
1003
1041
|
}
|
|
1004
1042
|
/**
|
|
1005
1043
|
* Updates safe-area overrides during dynamic state changes.
|
|
@@ -1008,19 +1046,10 @@ export class Modal {
|
|
|
1008
1046
|
updateSafeAreaOverrides() {
|
|
1009
1047
|
const { wrapperEl, el } = this;
|
|
1010
1048
|
const context = this.getSafeAreaContext();
|
|
1011
|
-
// Sheet modals:
|
|
1012
|
-
//
|
|
1013
|
-
|
|
1014
|
-
if (context.isSheetModal) {
|
|
1015
|
-
const needsTopSafeArea = context.currentBreakpoint === 1;
|
|
1016
|
-
applySafeAreaOverrides(el, {
|
|
1017
|
-
top: needsTopSafeArea ? 'inherit' : '0px',
|
|
1018
|
-
bottom: 'inherit',
|
|
1019
|
-
left: '0px',
|
|
1020
|
-
right: '0px',
|
|
1021
|
-
});
|
|
1049
|
+
// Sheet modals: safe-area is fully determined at presentation time
|
|
1050
|
+
// (top is always 0px, height is frozen). Nothing to update.
|
|
1051
|
+
if (context.isSheetModal)
|
|
1022
1052
|
return;
|
|
1023
|
-
}
|
|
1024
1053
|
// Card modals have fixed safe-area requirements set by initial prediction.
|
|
1025
1054
|
if (context.isCardModal)
|
|
1026
1055
|
return;
|
|
@@ -1046,6 +1075,8 @@ export class Modal {
|
|
|
1046
1075
|
// Check for standard Ionic layout children (ion-content, ion-footer),
|
|
1047
1076
|
// searching one level deep for wrapped components (e.g.,
|
|
1048
1077
|
// <app-footer><ion-footer>...</ion-footer></app-footer>).
|
|
1078
|
+
// Note: uses a manual loop instead of querySelector(':scope > ...') because
|
|
1079
|
+
// Stencil's mock-doc (used in spec tests) does not support :scope.
|
|
1049
1080
|
let hasContent = false;
|
|
1050
1081
|
let hasFooter = false;
|
|
1051
1082
|
for (const child of Array.from(el.children)) {
|
|
@@ -1078,6 +1109,8 @@ export class Modal {
|
|
|
1078
1109
|
*/
|
|
1079
1110
|
cleanupSafeAreaOverrides() {
|
|
1080
1111
|
clearSafeAreaOverrides(this.el);
|
|
1112
|
+
// Remove internal sheet offset property
|
|
1113
|
+
this.el.style.removeProperty('--ion-modal-offset-top');
|
|
1081
1114
|
if (this.wrapperEl) {
|
|
1082
1115
|
this.wrapperEl.style.removeProperty('height');
|
|
1083
1116
|
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
@@ -1090,20 +1123,20 @@ export class Modal {
|
|
|
1090
1123
|
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
1091
1124
|
const isHandleCycle = handleBehavior === 'cycle';
|
|
1092
1125
|
const isSheetModalWithHandle = isSheetModal && showHandle;
|
|
1093
|
-
return (h(Host, Object.assign({ key: '
|
|
1126
|
+
return (h(Host, Object.assign({ key: '038ae26c2cb040043c7d0c217a4de6a7ae909235', "no-router": true,
|
|
1094
1127
|
// Allow the modal to be navigable when the handle is focusable
|
|
1095
1128
|
tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
|
|
1096
1129
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
1097
|
-
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), h("ion-backdrop", { key: '
|
|
1130
|
+
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), h("ion-backdrop", { key: '6bab796467b370e79b24ce17c5a3d51adb07ee8c', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'b9a19e86a2c7f079c88ef7a914c7c890aa601887', class: "modal-shadow" }), h("div", Object.assign({ key: 'f4315c34aa78be4e3540361755964be2ddf43265',
|
|
1098
1131
|
/*
|
|
1099
1132
|
role and aria-modal must be used on the
|
|
1100
1133
|
same element. They must also be set inside the
|
|
1101
1134
|
shadow DOM otherwise ion-button will not be highlighted
|
|
1102
1135
|
when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
|
|
1103
1136
|
*/
|
|
1104
|
-
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '
|
|
1137
|
+
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '3f7792bd65e0f8634e62bf27f9edcb636a03030a', class: "modal-handle",
|
|
1105
1138
|
// Prevents the handle from receiving keyboard focus when it does not cycle
|
|
1106
|
-
tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), h("slot", { key: '
|
|
1139
|
+
tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), h("slot", { key: '001e5b01831e240bd98f75ff62446b90b64d8394', onSlotchange: this.onSlotChange }))));
|
|
1107
1140
|
}
|
|
1108
1141
|
static get is() { return "ion-modal"; }
|
|
1109
1142
|
static get encapsulation() { return "shadow"; }
|
|
@@ -186,9 +186,14 @@ ion-backdrop {
|
|
|
186
186
|
/**
|
|
187
187
|
* Ensure that the sheet modal does not
|
|
188
188
|
* completely cover the content.
|
|
189
|
+
*
|
|
190
|
+
* --ion-modal-offset-top is an internal property set by modal.tsx
|
|
191
|
+
* with the resolved root safe-area-top pixel value. This decouples
|
|
192
|
+
* the height calculation from --ion-safe-area-top (which is zeroed
|
|
193
|
+
* for sheet modals to prevent header double-padding).
|
|
189
194
|
*/
|
|
190
195
|
:host(.modal-sheet) {
|
|
191
|
-
--height: calc(100% - (var(--ion-
|
|
196
|
+
--height: calc(100% - (var(--ion-modal-offset-top, 0px) + 10px));
|
|
192
197
|
}
|
|
193
198
|
|
|
194
199
|
:host(.modal-sheet) .modal-wrapper,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
4
|
import { win } from "../../utils/browser/index";
|
|
5
|
+
import { raf } from "../../utils/helpers";
|
|
5
6
|
/**
|
|
6
7
|
* These thresholds match the SCSS media query breakpoints in modal.vars.scss
|
|
7
8
|
* that trigger the centered dialog layout (non-fullscreen modal).
|
|
@@ -14,6 +15,11 @@ import { win } from "../../utils/browser/index";
|
|
|
14
15
|
const MODAL_INSET_MIN_WIDTH = 768;
|
|
15
16
|
const MODAL_INSET_MIN_HEIGHT = 600;
|
|
16
17
|
const EDGE_THRESHOLD = 5;
|
|
18
|
+
/**
|
|
19
|
+
* Cache for resolved root safe-area-top value, invalidated once per frame.
|
|
20
|
+
*/
|
|
21
|
+
let cachedRootSafeAreaTop = null;
|
|
22
|
+
let cacheInvalidationScheduled = false;
|
|
17
23
|
/**
|
|
18
24
|
* Determines if the current viewport meets the CSS media query conditions
|
|
19
25
|
* that cause regular modals to render as centered dialogs instead of fullscreen.
|
|
@@ -25,6 +31,38 @@ const isCenteredDialogViewport = () => {
|
|
|
25
31
|
return win.matchMedia(`(min-width: ${MODAL_INSET_MIN_WIDTH}px) and (min-height: ${MODAL_INSET_MIN_HEIGHT}px)`)
|
|
26
32
|
.matches;
|
|
27
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* Resolves the current root --ion-safe-area-top value to pixels.
|
|
36
|
+
* Uses a temporary element because getComputedStyle on :root returns
|
|
37
|
+
* the declared value of custom properties (e.g. "env(safe-area-inset-top)")
|
|
38
|
+
* rather than a resolved number.
|
|
39
|
+
*
|
|
40
|
+
* Results are cached for the current frame to avoid repeated reflows.
|
|
41
|
+
*/
|
|
42
|
+
export const getRootSafeAreaTop = () => {
|
|
43
|
+
if (cachedRootSafeAreaTop !== null) {
|
|
44
|
+
return cachedRootSafeAreaTop;
|
|
45
|
+
}
|
|
46
|
+
const doc = win === null || win === void 0 ? void 0 : win.document;
|
|
47
|
+
if (!(doc === null || doc === void 0 ? void 0 : doc.body)) {
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
const el = doc.createElement('div');
|
|
51
|
+
el.style.cssText =
|
|
52
|
+
'position:fixed;visibility:hidden;pointer-events:none;top:0;left:0;' + 'padding-top:var(--ion-safe-area-top,0px);';
|
|
53
|
+
doc.body.appendChild(el);
|
|
54
|
+
const value = parseFloat(getComputedStyle(el).paddingTop) || 0;
|
|
55
|
+
el.remove();
|
|
56
|
+
cachedRootSafeAreaTop = value;
|
|
57
|
+
if (!cacheInvalidationScheduled) {
|
|
58
|
+
cacheInvalidationScheduled = true;
|
|
59
|
+
raf(() => {
|
|
60
|
+
cachedRootSafeAreaTop = null;
|
|
61
|
+
cacheInvalidationScheduled = false;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return value;
|
|
65
|
+
};
|
|
28
66
|
/**
|
|
29
67
|
* Returns the initial safe-area configuration based on modal type.
|
|
30
68
|
* This is called before animation starts and uses configuration-based prediction.
|
|
@@ -34,10 +72,14 @@ const isCenteredDialogViewport = () => {
|
|
|
34
72
|
*/
|
|
35
73
|
export const getInitialSafeAreaConfig = (context) => {
|
|
36
74
|
const { isSheetModal, isCardModal } = context;
|
|
37
|
-
// Sheet modals
|
|
75
|
+
// Sheet modals always zero top safe-area. The sheet height offset from the
|
|
76
|
+
// top edge is handled by --ion-modal-offset-top (set in modal.tsx) using
|
|
77
|
+
// the resolved root value, so --ion-safe-area-top is never needed for
|
|
78
|
+
// height calculation. Keeping it at 0px prevents header content from
|
|
79
|
+
// getting double-offset padding.
|
|
38
80
|
if (isSheetModal) {
|
|
39
81
|
return {
|
|
40
|
-
top:
|
|
82
|
+
top: '0px',
|
|
41
83
|
bottom: 'inherit',
|
|
42
84
|
left: '0px',
|
|
43
85
|
right: '0px',
|
package/dist/docs.json
CHANGED
|
@@ -1484,6 +1484,11 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1484
1484
|
const MODAL_INSET_MIN_WIDTH = 768;
|
|
1485
1485
|
const MODAL_INSET_MIN_HEIGHT = 600;
|
|
1486
1486
|
const EDGE_THRESHOLD = 5;
|
|
1487
|
+
/**
|
|
1488
|
+
* Cache for resolved root safe-area-top value, invalidated once per frame.
|
|
1489
|
+
*/
|
|
1490
|
+
let cachedRootSafeAreaTop = null;
|
|
1491
|
+
let cacheInvalidationScheduled = false;
|
|
1487
1492
|
/**
|
|
1488
1493
|
* Determines if the current viewport meets the CSS media query conditions
|
|
1489
1494
|
* that cause regular modals to render as centered dialogs instead of fullscreen.
|
|
@@ -1495,6 +1500,38 @@ const isCenteredDialogViewport = () => {
|
|
|
1495
1500
|
return win.matchMedia(`(min-width: ${MODAL_INSET_MIN_WIDTH}px) and (min-height: ${MODAL_INSET_MIN_HEIGHT}px)`)
|
|
1496
1501
|
.matches;
|
|
1497
1502
|
};
|
|
1503
|
+
/**
|
|
1504
|
+
* Resolves the current root --ion-safe-area-top value to pixels.
|
|
1505
|
+
* Uses a temporary element because getComputedStyle on :root returns
|
|
1506
|
+
* the declared value of custom properties (e.g. "env(safe-area-inset-top)")
|
|
1507
|
+
* rather than a resolved number.
|
|
1508
|
+
*
|
|
1509
|
+
* Results are cached for the current frame to avoid repeated reflows.
|
|
1510
|
+
*/
|
|
1511
|
+
const getRootSafeAreaTop = () => {
|
|
1512
|
+
if (cachedRootSafeAreaTop !== null) {
|
|
1513
|
+
return cachedRootSafeAreaTop;
|
|
1514
|
+
}
|
|
1515
|
+
const doc = win === null || win === void 0 ? void 0 : win.document;
|
|
1516
|
+
if (!(doc === null || doc === void 0 ? void 0 : doc.body)) {
|
|
1517
|
+
return 0;
|
|
1518
|
+
}
|
|
1519
|
+
const el = doc.createElement('div');
|
|
1520
|
+
el.style.cssText =
|
|
1521
|
+
'position:fixed;visibility:hidden;pointer-events:none;top:0;left:0;' + 'padding-top:var(--ion-safe-area-top,0px);';
|
|
1522
|
+
doc.body.appendChild(el);
|
|
1523
|
+
const value = parseFloat(getComputedStyle(el).paddingTop) || 0;
|
|
1524
|
+
el.remove();
|
|
1525
|
+
cachedRootSafeAreaTop = value;
|
|
1526
|
+
if (!cacheInvalidationScheduled) {
|
|
1527
|
+
cacheInvalidationScheduled = true;
|
|
1528
|
+
raf(() => {
|
|
1529
|
+
cachedRootSafeAreaTop = null;
|
|
1530
|
+
cacheInvalidationScheduled = false;
|
|
1531
|
+
});
|
|
1532
|
+
}
|
|
1533
|
+
return value;
|
|
1534
|
+
};
|
|
1498
1535
|
/**
|
|
1499
1536
|
* Returns the initial safe-area configuration based on modal type.
|
|
1500
1537
|
* This is called before animation starts and uses configuration-based prediction.
|
|
@@ -1504,10 +1541,14 @@ const isCenteredDialogViewport = () => {
|
|
|
1504
1541
|
*/
|
|
1505
1542
|
const getInitialSafeAreaConfig = (context) => {
|
|
1506
1543
|
const { isSheetModal, isCardModal } = context;
|
|
1507
|
-
// Sheet modals
|
|
1544
|
+
// Sheet modals always zero top safe-area. The sheet height offset from the
|
|
1545
|
+
// top edge is handled by --ion-modal-offset-top (set in modal.tsx) using
|
|
1546
|
+
// the resolved root value, so --ion-safe-area-top is never needed for
|
|
1547
|
+
// height calculation. Keeping it at 0px prevents header content from
|
|
1548
|
+
// getting double-offset padding.
|
|
1508
1549
|
if (isSheetModal) {
|
|
1509
1550
|
return {
|
|
1510
|
-
top:
|
|
1551
|
+
top: '0px',
|
|
1511
1552
|
bottom: 'inherit',
|
|
1512
1553
|
left: '0px',
|
|
1513
1554
|
right: '0px',
|
|
@@ -1592,9 +1633,9 @@ const clearSafeAreaOverrides = (hostEl) => {
|
|
|
1592
1633
|
hostEl.style.removeProperty('--ion-safe-area-right');
|
|
1593
1634
|
};
|
|
1594
1635
|
|
|
1595
|
-
const modalIosCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-
|
|
1636
|
+
const modalIosCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-modal-offset-top, 0px) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}";
|
|
1596
1637
|
|
|
1597
|
-
const modalMdCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-
|
|
1638
|
+
const modalMdCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-modal-offset-top, 0px) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}";
|
|
1598
1639
|
|
|
1599
1640
|
const Modal = class {
|
|
1600
1641
|
constructor(hostRef) {
|
|
@@ -1807,13 +1848,31 @@ const Modal = class {
|
|
|
1807
1848
|
}
|
|
1808
1849
|
}
|
|
1809
1850
|
onWindowResize() {
|
|
1810
|
-
|
|
1811
|
-
if (getIonMode(this) !== 'ios' || !this.presentingElement || this.enterAnimation || this.leaveAnimation) {
|
|
1851
|
+
if (!this.presented)
|
|
1812
1852
|
return;
|
|
1813
|
-
}
|
|
1814
1853
|
clearTimeout(this.resizeTimeout);
|
|
1815
1854
|
this.resizeTimeout = setTimeout(() => {
|
|
1816
|
-
this.
|
|
1855
|
+
const context = this.getSafeAreaContext();
|
|
1856
|
+
// iOS card modals: handle portrait/landscape view transitions
|
|
1857
|
+
if (context.isCardModal && !this.enterAnimation && !this.leaveAnimation) {
|
|
1858
|
+
this.handleViewTransition();
|
|
1859
|
+
}
|
|
1860
|
+
// Sheet modals: re-compute the internal offset property since safe-area
|
|
1861
|
+
// values may change on device rotation (e.g., portrait notch vs landscape).
|
|
1862
|
+
if (context.isSheetModal) {
|
|
1863
|
+
this.updateSheetOffsetTop();
|
|
1864
|
+
}
|
|
1865
|
+
// Regular (non-sheet, non-card) modals: update safe-area overrides
|
|
1866
|
+
// since the viewport may have crossed the centered-dialog breakpoint.
|
|
1867
|
+
if (!context.isSheetModal && !context.isCardModal) {
|
|
1868
|
+
this.updateSafeAreaOverrides();
|
|
1869
|
+
// Re-evaluate fullscreen safe-area padding: clear first, then re-apply
|
|
1870
|
+
if (this.wrapperEl) {
|
|
1871
|
+
this.wrapperEl.style.removeProperty('height');
|
|
1872
|
+
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
1873
|
+
}
|
|
1874
|
+
this.applyFullscreenSafeArea();
|
|
1875
|
+
}
|
|
1817
1876
|
}, 50); // Debounce to avoid excessive calls during active resizing
|
|
1818
1877
|
}
|
|
1819
1878
|
breakpointsChanged(breakpoints) {
|
|
@@ -2127,8 +2186,6 @@ const Modal = class {
|
|
|
2127
2186
|
if (this.currentBreakpoint !== breakpoint) {
|
|
2128
2187
|
this.currentBreakpoint = breakpoint;
|
|
2129
2188
|
this.ionBreakpointDidChange.emit({ breakpoint });
|
|
2130
|
-
// Update safe-area overrides based on new position
|
|
2131
|
-
this.updateSafeAreaOverrides();
|
|
2132
2189
|
}
|
|
2133
2190
|
});
|
|
2134
2191
|
this.gesture = gesture;
|
|
@@ -2242,6 +2299,9 @@ const Modal = class {
|
|
|
2242
2299
|
if (this.gestureAnimationDismissing && role !== GESTURE) {
|
|
2243
2300
|
return false;
|
|
2244
2301
|
}
|
|
2302
|
+
// Cancel any pending resize timeout to prevent stale updates during dismiss
|
|
2303
|
+
clearTimeout(this.resizeTimeout);
|
|
2304
|
+
this.resizeTimeout = undefined;
|
|
2245
2305
|
/**
|
|
2246
2306
|
* Because the canDismiss check below is async,
|
|
2247
2307
|
* we need to claim a lock before the check happens,
|
|
@@ -2561,11 +2621,30 @@ const Modal = class {
|
|
|
2561
2621
|
/**
|
|
2562
2622
|
* Sets initial safe-area overrides before modal animation.
|
|
2563
2623
|
* Called in present() before animation starts.
|
|
2624
|
+
*
|
|
2625
|
+
* For sheet modals, the SCSS --height formula uses --ion-modal-offset-top
|
|
2626
|
+
* (an internal property) instead of --ion-safe-area-top. We resolve the
|
|
2627
|
+
* root safe-area-top to pixels and set --ion-modal-offset-top, decoupling
|
|
2628
|
+
* the height calculation from --ion-safe-area-top (which is zeroed for
|
|
2629
|
+
* sheets to prevent header content from getting double-offset padding).
|
|
2564
2630
|
*/
|
|
2565
2631
|
setInitialSafeAreaOverrides() {
|
|
2566
2632
|
const context = this.getSafeAreaContext();
|
|
2567
2633
|
const safeAreaConfig = getInitialSafeAreaConfig(context);
|
|
2568
2634
|
applySafeAreaOverrides(this.el, safeAreaConfig);
|
|
2635
|
+
// Set the internal offset property with the resolved root safe-area-top value
|
|
2636
|
+
if (context.isSheetModal) {
|
|
2637
|
+
this.updateSheetOffsetTop();
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
/**
|
|
2641
|
+
* Resolves the current root --ion-safe-area-top value and sets the
|
|
2642
|
+
* internal --ion-modal-offset-top property on the host element.
|
|
2643
|
+
* Called on present and on resize (e.g., device rotation changes safe-area).
|
|
2644
|
+
*/
|
|
2645
|
+
updateSheetOffsetTop() {
|
|
2646
|
+
const safeAreaTop = getRootSafeAreaTop();
|
|
2647
|
+
this.el.style.setProperty('--ion-modal-offset-top', `${safeAreaTop}px`);
|
|
2569
2648
|
}
|
|
2570
2649
|
/**
|
|
2571
2650
|
* Updates safe-area overrides during dynamic state changes.
|
|
@@ -2574,19 +2653,10 @@ const Modal = class {
|
|
|
2574
2653
|
updateSafeAreaOverrides() {
|
|
2575
2654
|
const { wrapperEl, el } = this;
|
|
2576
2655
|
const context = this.getSafeAreaContext();
|
|
2577
|
-
// Sheet modals:
|
|
2578
|
-
//
|
|
2579
|
-
|
|
2580
|
-
if (context.isSheetModal) {
|
|
2581
|
-
const needsTopSafeArea = context.currentBreakpoint === 1;
|
|
2582
|
-
applySafeAreaOverrides(el, {
|
|
2583
|
-
top: needsTopSafeArea ? 'inherit' : '0px',
|
|
2584
|
-
bottom: 'inherit',
|
|
2585
|
-
left: '0px',
|
|
2586
|
-
right: '0px',
|
|
2587
|
-
});
|
|
2656
|
+
// Sheet modals: safe-area is fully determined at presentation time
|
|
2657
|
+
// (top is always 0px, height is frozen). Nothing to update.
|
|
2658
|
+
if (context.isSheetModal)
|
|
2588
2659
|
return;
|
|
2589
|
-
}
|
|
2590
2660
|
// Card modals have fixed safe-area requirements set by initial prediction.
|
|
2591
2661
|
if (context.isCardModal)
|
|
2592
2662
|
return;
|
|
@@ -2612,6 +2682,8 @@ const Modal = class {
|
|
|
2612
2682
|
// Check for standard Ionic layout children (ion-content, ion-footer),
|
|
2613
2683
|
// searching one level deep for wrapped components (e.g.,
|
|
2614
2684
|
// <app-footer><ion-footer>...</ion-footer></app-footer>).
|
|
2685
|
+
// Note: uses a manual loop instead of querySelector(':scope > ...') because
|
|
2686
|
+
// Stencil's mock-doc (used in spec tests) does not support :scope.
|
|
2615
2687
|
let hasContent = false;
|
|
2616
2688
|
let hasFooter = false;
|
|
2617
2689
|
for (const child of Array.from(el.children)) {
|
|
@@ -2644,6 +2716,8 @@ const Modal = class {
|
|
|
2644
2716
|
*/
|
|
2645
2717
|
cleanupSafeAreaOverrides() {
|
|
2646
2718
|
clearSafeAreaOverrides(this.el);
|
|
2719
|
+
// Remove internal sheet offset property
|
|
2720
|
+
this.el.style.removeProperty('--ion-modal-offset-top');
|
|
2647
2721
|
if (this.wrapperEl) {
|
|
2648
2722
|
this.wrapperEl.style.removeProperty('height');
|
|
2649
2723
|
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
@@ -2656,20 +2730,20 @@ const Modal = class {
|
|
|
2656
2730
|
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
2657
2731
|
const isHandleCycle = handleBehavior === 'cycle';
|
|
2658
2732
|
const isSheetModalWithHandle = isSheetModal && showHandle;
|
|
2659
|
-
return (h(Host, Object.assign({ key: '
|
|
2733
|
+
return (h(Host, Object.assign({ key: '038ae26c2cb040043c7d0c217a4de6a7ae909235', "no-router": true,
|
|
2660
2734
|
// Allow the modal to be navigable when the handle is focusable
|
|
2661
2735
|
tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
|
|
2662
2736
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
2663
|
-
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), h("ion-backdrop", { key: '
|
|
2737
|
+
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), h("ion-backdrop", { key: '6bab796467b370e79b24ce17c5a3d51adb07ee8c', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'b9a19e86a2c7f079c88ef7a914c7c890aa601887', class: "modal-shadow" }), h("div", Object.assign({ key: 'f4315c34aa78be4e3540361755964be2ddf43265',
|
|
2664
2738
|
/*
|
|
2665
2739
|
role and aria-modal must be used on the
|
|
2666
2740
|
same element. They must also be set inside the
|
|
2667
2741
|
shadow DOM otherwise ion-button will not be highlighted
|
|
2668
2742
|
when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
|
|
2669
2743
|
*/
|
|
2670
|
-
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '
|
|
2744
|
+
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '3f7792bd65e0f8634e62bf27f9edcb636a03030a', class: "modal-handle",
|
|
2671
2745
|
// Prevents the handle from receiving keyboard focus when it does not cycle
|
|
2672
|
-
tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), h("slot", { key: '
|
|
2746
|
+
tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), h("slot", { key: '001e5b01831e240bd98f75ff62446b90b64d8394', onSlotchange: this.onSlotChange }))));
|
|
2673
2747
|
}
|
|
2674
2748
|
get el() { return getElement(this); }
|
|
2675
2749
|
static get watchers() { return {
|