@ionic/core 8.6.3-dev.11751378808.12cc4a5c → 8.6.3-dev.11751478001.1cb7436f
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/focus-visible.js +27 -18
- package/components/ion-select.js +3 -3
- package/components/modal.js +8 -220
- package/dist/cjs/{focus-visible-CCvKiLh3.js → focus-visible-ZV7jHMPt.js} +27 -18
- package/dist/cjs/ion-app_8.cjs.entry.js +1 -1
- package/dist/cjs/ion-datetime_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-modal.cjs.entry.js +8 -220
- package/dist/cjs/ion-select_3.cjs.entry.js +3 -3
- package/dist/collection/components/modal/animations/ios.enter.js +2 -2
- package/dist/collection/components/modal/animations/ios.leave.js +2 -2
- package/dist/collection/components/modal/modal.js +4 -87
- package/dist/collection/components/select/select.js +3 -3
- package/dist/collection/utils/focus-visible.js +27 -18
- package/dist/docs.json +1 -1
- package/dist/esm/{focus-visible-BmVRXR1y.js → focus-visible-DZ2gZBzK.js} +27 -18
- package/dist/esm/ion-app_8.entry.js +1 -1
- package/dist/esm/ion-datetime_3.entry.js +1 -1
- package/dist/esm/ion-modal.entry.js +8 -220
- package/dist/esm/ion-select_3.entry.js +3 -3
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/{p-01123ecf.entry.js → p-2d46fbe7.entry.js} +1 -1
- package/dist/ionic/{p-5f671887.entry.js → p-78a61b3f.entry.js} +1 -1
- package/dist/ionic/p-7d5cf8c1.entry.js +4 -0
- package/dist/ionic/p-9e32212d.entry.js +4 -0
- package/dist/ionic/p-DZ2gZBzK.js +4 -0
- package/dist/types/components/modal/modal.d.ts +0 -6
- package/hydrate/index.js +38 -241
- package/hydrate/index.mjs +38 -241
- package/package.json +1 -1
- package/dist/collection/components/modal/animations/ios.transition.js +0 -143
- package/dist/ionic/p-4ddc10ef.entry.js +0 -4
- package/dist/ionic/p-6f74a187.entry.js +0 -4
- package/dist/ionic/p-BmVRXR1y.js +0 -4
- package/dist/types/components/modal/animations/ios.transition.d.ts +0 -14
package/hydrate/index.mjs
CHANGED
|
@@ -10412,33 +10412,44 @@ const FOCUS_KEYS = [
|
|
|
10412
10412
|
];
|
|
10413
10413
|
const startFocusVisible = (rootEl) => {
|
|
10414
10414
|
let currentFocus = [];
|
|
10415
|
-
|
|
10415
|
+
// Tracks if the last interaction was a pointer event (mouse, touch, pen)
|
|
10416
|
+
// Used to distinguish between pointer and keyboard navigation for focus styling
|
|
10417
|
+
let hadPointerEvent = false;
|
|
10416
10418
|
const ref = rootEl ? rootEl.shadowRoot : document;
|
|
10417
10419
|
const root = rootEl ? rootEl : document.body;
|
|
10420
|
+
// Adds or removes the focused class for styling
|
|
10418
10421
|
const setFocus = (elements) => {
|
|
10419
10422
|
currentFocus.forEach((el) => el.classList.remove(ION_FOCUSED));
|
|
10420
10423
|
elements.forEach((el) => el.classList.add(ION_FOCUSED));
|
|
10421
10424
|
currentFocus = elements;
|
|
10422
10425
|
};
|
|
10423
|
-
|
|
10424
|
-
|
|
10425
|
-
|
|
10426
|
+
// Do not set focus on pointer interactions
|
|
10427
|
+
const pointerDown = (ev) => {
|
|
10428
|
+
if (ev instanceof PointerEvent && ev.pointerType !== '') {
|
|
10429
|
+
hadPointerEvent = true;
|
|
10430
|
+
// Reset after the event loop so only the immediate focusin is suppressed
|
|
10431
|
+
setTimeout(() => {
|
|
10432
|
+
hadPointerEvent = false;
|
|
10433
|
+
}, 0);
|
|
10434
|
+
}
|
|
10426
10435
|
};
|
|
10436
|
+
// Clear hadPointerEvent so keyboard navigation shows focus
|
|
10437
|
+
// Also, clear focus if the key is not a navigation key
|
|
10427
10438
|
const onKeydown = (ev) => {
|
|
10428
|
-
|
|
10429
|
-
|
|
10439
|
+
hadPointerEvent = false;
|
|
10440
|
+
const keyboardEvent = ev;
|
|
10441
|
+
if (!FOCUS_KEYS.includes(keyboardEvent.key)) {
|
|
10430
10442
|
setFocus([]);
|
|
10431
10443
|
}
|
|
10432
10444
|
};
|
|
10445
|
+
// Set focus if the last interaction was NOT a pointer event
|
|
10446
|
+
// This works around iOS/Safari bugs where keydown is not fired for Tab
|
|
10433
10447
|
const onFocusin = (ev) => {
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
}
|
|
10440
|
-
return false;
|
|
10441
|
-
});
|
|
10448
|
+
const target = ev.target;
|
|
10449
|
+
if (target.classList.contains(ION_FOCUSABLE) && !hadPointerEvent) {
|
|
10450
|
+
const toFocus = ev
|
|
10451
|
+
.composedPath()
|
|
10452
|
+
.filter((el) => el instanceof HTMLElement && el.classList.contains(ION_FOCUSABLE));
|
|
10442
10453
|
setFocus(toFocus);
|
|
10443
10454
|
}
|
|
10444
10455
|
};
|
|
@@ -10450,14 +10461,12 @@ const startFocusVisible = (rootEl) => {
|
|
|
10450
10461
|
ref.addEventListener('keydown', onKeydown);
|
|
10451
10462
|
ref.addEventListener('focusin', onFocusin);
|
|
10452
10463
|
ref.addEventListener('focusout', onFocusout);
|
|
10453
|
-
ref.addEventListener('
|
|
10454
|
-
ref.addEventListener('mousedown', pointerDown);
|
|
10464
|
+
ref.addEventListener('pointerdown', pointerDown, { passive: true });
|
|
10455
10465
|
const destroy = () => {
|
|
10456
10466
|
ref.removeEventListener('keydown', onKeydown);
|
|
10457
10467
|
ref.removeEventListener('focusin', onFocusin);
|
|
10458
10468
|
ref.removeEventListener('focusout', onFocusout);
|
|
10459
|
-
ref.removeEventListener('
|
|
10460
|
-
ref.removeEventListener('mousedown', pointerDown);
|
|
10469
|
+
ref.removeEventListener('pointerdown', pointerDown);
|
|
10461
10470
|
};
|
|
10462
10471
|
return {
|
|
10463
10472
|
destroy,
|
|
@@ -21216,7 +21225,7 @@ const iosEnterAnimation$3 = (baseEl, opts) => {
|
|
|
21216
21225
|
baseAnimation.addAnimation(contentAnimation);
|
|
21217
21226
|
}
|
|
21218
21227
|
if (presentingEl) {
|
|
21219
|
-
const
|
|
21228
|
+
const isMobile = window.innerWidth < 768;
|
|
21220
21229
|
const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
|
|
21221
21230
|
const presentingElRoot = getElementRoot(presentingEl);
|
|
21222
21231
|
const presentingAnimation = createAnimation().beforeStyles({
|
|
@@ -21225,7 +21234,7 @@ const iosEnterAnimation$3 = (baseEl, opts) => {
|
|
|
21225
21234
|
overflow: 'hidden',
|
|
21226
21235
|
});
|
|
21227
21236
|
const bodyEl = document.body;
|
|
21228
|
-
if (
|
|
21237
|
+
if (isMobile) {
|
|
21229
21238
|
/**
|
|
21230
21239
|
* Fallback for browsers that does not support `max()` (ex: Firefox)
|
|
21231
21240
|
* No need to worry about statusbar padding since engines like Gecko
|
|
@@ -21303,7 +21312,7 @@ const iosLeaveAnimation$3 = (baseEl, opts, duration = 500) => {
|
|
|
21303
21312
|
.duration(duration)
|
|
21304
21313
|
.addAnimation(wrapperAnimation);
|
|
21305
21314
|
if (presentingEl) {
|
|
21306
|
-
const
|
|
21315
|
+
const isMobile = window.innerWidth < 768;
|
|
21307
21316
|
const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
|
|
21308
21317
|
const presentingElRoot = getElementRoot(presentingEl);
|
|
21309
21318
|
const presentingAnimation = createAnimation()
|
|
@@ -21321,7 +21330,7 @@ const iosLeaveAnimation$3 = (baseEl, opts, duration = 500) => {
|
|
|
21321
21330
|
}
|
|
21322
21331
|
});
|
|
21323
21332
|
const bodyEl = document.body;
|
|
21324
|
-
if (
|
|
21333
|
+
if (isMobile) {
|
|
21325
21334
|
const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
|
|
21326
21335
|
const modalTransform = hasCardModal ? '-10px' : transformOffset;
|
|
21327
21336
|
const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
|
|
@@ -21368,144 +21377,6 @@ const iosLeaveAnimation$3 = (baseEl, opts, duration = 500) => {
|
|
|
21368
21377
|
return baseAnimation;
|
|
21369
21378
|
};
|
|
21370
21379
|
|
|
21371
|
-
/**
|
|
21372
|
-
* Transition animation from portrait view to landscape view
|
|
21373
|
-
* This handles the case where a card modal is open in portrait view
|
|
21374
|
-
* and the user switches to landscape view
|
|
21375
|
-
*/
|
|
21376
|
-
const portraitToLandscapeTransition = (baseEl, opts, duration = 300) => {
|
|
21377
|
-
const { presentingEl } = opts;
|
|
21378
|
-
if (!presentingEl) {
|
|
21379
|
-
// No transition needed for non-card modals
|
|
21380
|
-
return createAnimation('portrait-to-landscape-transition');
|
|
21381
|
-
}
|
|
21382
|
-
const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
|
|
21383
|
-
const presentingElRoot = getElementRoot(presentingEl);
|
|
21384
|
-
const bodyEl = document.body;
|
|
21385
|
-
const baseAnimation = createAnimation('portrait-to-landscape-transition')
|
|
21386
|
-
.addElement(baseEl)
|
|
21387
|
-
.easing('cubic-bezier(0.32,0.72,0,1)')
|
|
21388
|
-
.duration(duration);
|
|
21389
|
-
const presentingAnimation = createAnimation().beforeStyles({
|
|
21390
|
-
transform: 'translateY(0)',
|
|
21391
|
-
'transform-origin': 'top center',
|
|
21392
|
-
overflow: 'hidden',
|
|
21393
|
-
});
|
|
21394
|
-
if (!hasCardModal) {
|
|
21395
|
-
// Non-card modal: transition from portrait state to landscape state
|
|
21396
|
-
// Portrait: presentingEl has transform and body has black background
|
|
21397
|
-
// Landscape: no transform, no body background, modal wrapper opacity changes
|
|
21398
|
-
const root = getElementRoot(baseEl);
|
|
21399
|
-
const wrapperAnimation = createAnimation()
|
|
21400
|
-
.addElement(root.querySelectorAll('.modal-wrapper, .modal-shadow'))
|
|
21401
|
-
.fromTo('opacity', '1', '1'); // Keep wrapper visible in landscape
|
|
21402
|
-
const backdropAnimation = createAnimation()
|
|
21403
|
-
.addElement(root.querySelector('ion-backdrop'))
|
|
21404
|
-
.fromTo('opacity', 'var(--backdrop-opacity)', 'var(--backdrop-opacity)'); // Keep backdrop visible
|
|
21405
|
-
// Animate presentingEl from portrait state back to normal
|
|
21406
|
-
const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
|
|
21407
|
-
const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
|
|
21408
|
-
const fromTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
|
|
21409
|
-
presentingAnimation
|
|
21410
|
-
.addElement(presentingEl)
|
|
21411
|
-
.afterStyles({
|
|
21412
|
-
transform: 'translateY(0px) scale(1)',
|
|
21413
|
-
'border-radius': '0px',
|
|
21414
|
-
})
|
|
21415
|
-
.beforeAddWrite(() => bodyEl.style.setProperty('background-color', ''))
|
|
21416
|
-
.fromTo('transform', fromTransform, 'translateY(0px) scale(1)')
|
|
21417
|
-
.fromTo('filter', 'contrast(0.85)', 'contrast(1)')
|
|
21418
|
-
.fromTo('border-radius', '10px 10px 0 0', '0px');
|
|
21419
|
-
baseAnimation.addAnimation([presentingAnimation, wrapperAnimation, backdropAnimation]);
|
|
21420
|
-
}
|
|
21421
|
-
else {
|
|
21422
|
-
// Card modal: transition from portrait card state to landscape card state
|
|
21423
|
-
const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
|
|
21424
|
-
const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
|
|
21425
|
-
const fromTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
|
|
21426
|
-
const toTransform = `translateY(-10px) scale(${toPresentingScale})`;
|
|
21427
|
-
presentingAnimation
|
|
21428
|
-
.addElement(presentingElRoot.querySelector('.modal-wrapper'))
|
|
21429
|
-
.fromTo('transform', fromTransform, toTransform)
|
|
21430
|
-
.fromTo('filter', 'contrast(0.85)', 'contrast(0.85)'); // Keep same contrast for card
|
|
21431
|
-
const shadowAnimation = createAnimation()
|
|
21432
|
-
.addElement(presentingElRoot.querySelector('.modal-shadow'))
|
|
21433
|
-
.fromTo('opacity', '0', '0') // Shadow stays hidden in landscape for card modals
|
|
21434
|
-
.fromTo('transform', fromTransform, toTransform);
|
|
21435
|
-
baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
|
|
21436
|
-
}
|
|
21437
|
-
return baseAnimation;
|
|
21438
|
-
};
|
|
21439
|
-
/**
|
|
21440
|
-
* Transition animation from landscape view to portrait view
|
|
21441
|
-
* This handles the case where a card modal is open in landscape view
|
|
21442
|
-
* and the user switches to portrait view
|
|
21443
|
-
*/
|
|
21444
|
-
const landscapeToPortraitTransition = (baseEl, opts, duration = 300) => {
|
|
21445
|
-
const { presentingEl } = opts;
|
|
21446
|
-
if (!presentingEl) {
|
|
21447
|
-
// No transition needed for non-card modals
|
|
21448
|
-
return createAnimation('landscape-to-portrait-transition');
|
|
21449
|
-
}
|
|
21450
|
-
const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
|
|
21451
|
-
const presentingElRoot = getElementRoot(presentingEl);
|
|
21452
|
-
const bodyEl = document.body;
|
|
21453
|
-
const baseAnimation = createAnimation('landscape-to-portrait-transition')
|
|
21454
|
-
.addElement(baseEl)
|
|
21455
|
-
.easing('cubic-bezier(0.32,0.72,0,1)')
|
|
21456
|
-
.duration(duration);
|
|
21457
|
-
const presentingAnimation = createAnimation().beforeStyles({
|
|
21458
|
-
transform: 'translateY(0)',
|
|
21459
|
-
'transform-origin': 'top center',
|
|
21460
|
-
overflow: 'hidden',
|
|
21461
|
-
});
|
|
21462
|
-
if (!hasCardModal) {
|
|
21463
|
-
// Non-card modal: transition from landscape state to portrait state
|
|
21464
|
-
const root = getElementRoot(baseEl);
|
|
21465
|
-
const wrapperAnimation = createAnimation()
|
|
21466
|
-
.addElement(root.querySelectorAll('.modal-wrapper, .modal-shadow'))
|
|
21467
|
-
.fromTo('opacity', '1', '1'); // Keep wrapper visible
|
|
21468
|
-
const backdropAnimation = createAnimation()
|
|
21469
|
-
.addElement(root.querySelector('ion-backdrop'))
|
|
21470
|
-
.fromTo('opacity', 'var(--backdrop-opacity)', 'var(--backdrop-opacity)'); // Keep backdrop visible
|
|
21471
|
-
// Animate presentingEl from normal state to portrait state
|
|
21472
|
-
const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
|
|
21473
|
-
const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
|
|
21474
|
-
const toTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
|
|
21475
|
-
presentingAnimation
|
|
21476
|
-
.addElement(presentingEl)
|
|
21477
|
-
.afterStyles({
|
|
21478
|
-
transform: toTransform,
|
|
21479
|
-
'border-radius': '10px 10px 0 0',
|
|
21480
|
-
filter: 'contrast(0.85)',
|
|
21481
|
-
overflow: 'hidden',
|
|
21482
|
-
'transform-origin': 'top center',
|
|
21483
|
-
})
|
|
21484
|
-
.beforeAddWrite(() => bodyEl.style.setProperty('background-color', 'black'))
|
|
21485
|
-
.fromTo('transform', 'translateY(0px) scale(1)', toTransform)
|
|
21486
|
-
.fromTo('filter', 'contrast(1)', 'contrast(0.85)')
|
|
21487
|
-
.fromTo('border-radius', '0px', '10px 10px 0 0');
|
|
21488
|
-
baseAnimation.addAnimation([presentingAnimation, wrapperAnimation, backdropAnimation]);
|
|
21489
|
-
}
|
|
21490
|
-
else {
|
|
21491
|
-
// Card modal: transition from landscape card state to portrait card state
|
|
21492
|
-
const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
|
|
21493
|
-
const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
|
|
21494
|
-
const fromTransform = `translateY(-10px) scale(${toPresentingScale})`;
|
|
21495
|
-
const toTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
|
|
21496
|
-
presentingAnimation
|
|
21497
|
-
.addElement(presentingElRoot.querySelector('.modal-wrapper'))
|
|
21498
|
-
.fromTo('transform', fromTransform, toTransform)
|
|
21499
|
-
.fromTo('filter', 'contrast(0.85)', 'contrast(0.85)'); // Keep same contrast for card
|
|
21500
|
-
const shadowAnimation = createAnimation()
|
|
21501
|
-
.addElement(presentingElRoot.querySelector('.modal-shadow'))
|
|
21502
|
-
.fromTo('opacity', '0', '0') // Shadow stays hidden
|
|
21503
|
-
.fromTo('transform', fromTransform, toTransform);
|
|
21504
|
-
baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
|
|
21505
|
-
}
|
|
21506
|
-
return baseAnimation;
|
|
21507
|
-
};
|
|
21508
|
-
|
|
21509
21380
|
const createEnterAnimation = () => {
|
|
21510
21381
|
const backdropAnimation = createAnimation()
|
|
21511
21382
|
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
|
|
@@ -22297,7 +22168,6 @@ class Modal {
|
|
|
22297
22168
|
}
|
|
22298
22169
|
disconnectedCallback() {
|
|
22299
22170
|
this.triggerController.removeClickListener();
|
|
22300
|
-
this.cleanupViewTransitionListener();
|
|
22301
22171
|
}
|
|
22302
22172
|
componentWillLoad() {
|
|
22303
22173
|
var _a;
|
|
@@ -22508,8 +22378,6 @@ class Modal {
|
|
|
22508
22378
|
else if (hasCardModal) {
|
|
22509
22379
|
this.initSwipeToClose();
|
|
22510
22380
|
}
|
|
22511
|
-
// Initialize view transition listener for iOS card modals
|
|
22512
|
-
this.initViewTransitionListener();
|
|
22513
22381
|
unlock();
|
|
22514
22382
|
}
|
|
22515
22383
|
initSwipeToClose() {
|
|
@@ -22663,7 +22531,6 @@ class Modal {
|
|
|
22663
22531
|
if (this.gesture) {
|
|
22664
22532
|
this.gesture.destroy();
|
|
22665
22533
|
}
|
|
22666
|
-
this.cleanupViewTransitionListener();
|
|
22667
22534
|
}
|
|
22668
22535
|
this.currentBreakpoint = undefined;
|
|
22669
22536
|
this.animation = undefined;
|
|
@@ -22739,76 +22606,6 @@ class Modal {
|
|
|
22739
22606
|
await this.setCurrentBreakpoint(nextBreakpoint);
|
|
22740
22607
|
return true;
|
|
22741
22608
|
}
|
|
22742
|
-
initViewTransitionListener() {
|
|
22743
|
-
// Only enable for iOS card modals when no custom animations are provided
|
|
22744
|
-
if (getIonMode$1(this) !== 'ios' || !this.presentingElement || this.enterAnimation || this.leaveAnimation) {
|
|
22745
|
-
return;
|
|
22746
|
-
}
|
|
22747
|
-
// Set initial view state
|
|
22748
|
-
this.currentViewIsPortrait = window.innerWidth < 768;
|
|
22749
|
-
// Create debounced resize handler
|
|
22750
|
-
let resizeTimeout;
|
|
22751
|
-
this.resizeListener = () => {
|
|
22752
|
-
clearTimeout(resizeTimeout);
|
|
22753
|
-
resizeTimeout = setTimeout(() => {
|
|
22754
|
-
this.handleViewTransition();
|
|
22755
|
-
}, 100); // Debounce for 100ms to avoid excessive calls
|
|
22756
|
-
};
|
|
22757
|
-
window.addEventListener('resize', this.resizeListener);
|
|
22758
|
-
}
|
|
22759
|
-
handleViewTransition() {
|
|
22760
|
-
const isPortrait = window.innerWidth < 768;
|
|
22761
|
-
// Only transition if view state actually changed
|
|
22762
|
-
if (this.currentViewIsPortrait === isPortrait) {
|
|
22763
|
-
return;
|
|
22764
|
-
}
|
|
22765
|
-
// Cancel any ongoing transition animation
|
|
22766
|
-
if (this.viewTransitionAnimation) {
|
|
22767
|
-
this.viewTransitionAnimation.destroy();
|
|
22768
|
-
this.viewTransitionAnimation = undefined;
|
|
22769
|
-
}
|
|
22770
|
-
const { presentingElement } = this;
|
|
22771
|
-
if (!presentingElement) {
|
|
22772
|
-
return;
|
|
22773
|
-
}
|
|
22774
|
-
// Create transition animation
|
|
22775
|
-
let transitionAnimation;
|
|
22776
|
-
if (this.currentViewIsPortrait && !isPortrait) {
|
|
22777
|
-
// Portrait to landscape transition
|
|
22778
|
-
transitionAnimation = portraitToLandscapeTransition(this.el, {
|
|
22779
|
-
presentingEl: presentingElement});
|
|
22780
|
-
}
|
|
22781
|
-
else {
|
|
22782
|
-
// Landscape to portrait transition
|
|
22783
|
-
transitionAnimation = landscapeToPortraitTransition(this.el, {
|
|
22784
|
-
presentingEl: presentingElement});
|
|
22785
|
-
}
|
|
22786
|
-
// Update state and play animation
|
|
22787
|
-
this.currentViewIsPortrait = isPortrait;
|
|
22788
|
-
this.viewTransitionAnimation = transitionAnimation;
|
|
22789
|
-
transitionAnimation.play().then(() => {
|
|
22790
|
-
this.viewTransitionAnimation = undefined;
|
|
22791
|
-
});
|
|
22792
|
-
}
|
|
22793
|
-
cleanupViewTransitionListener() {
|
|
22794
|
-
const hasCardView = !!this.resizeListener;
|
|
22795
|
-
if (this.resizeListener) {
|
|
22796
|
-
window.removeEventListener('resize', this.resizeListener);
|
|
22797
|
-
this.resizeListener = undefined;
|
|
22798
|
-
}
|
|
22799
|
-
if (this.viewTransitionAnimation) {
|
|
22800
|
-
this.viewTransitionAnimation.destroy();
|
|
22801
|
-
this.viewTransitionAnimation = undefined;
|
|
22802
|
-
}
|
|
22803
|
-
if (hasCardView) {
|
|
22804
|
-
// If we had a card view, let's trigger the view transition
|
|
22805
|
-
// one last time to make sure we're in the right state.
|
|
22806
|
-
// This will prevent tricky things like resizing the modal causing
|
|
22807
|
-
// it to dismiss programatically too quickly and preventing the view transition
|
|
22808
|
-
// from being applied.
|
|
22809
|
-
this.handleViewTransition();
|
|
22810
|
-
}
|
|
22811
|
-
}
|
|
22812
22609
|
render() {
|
|
22813
22610
|
const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap, expandToScroll, } = this;
|
|
22814
22611
|
const showHandle = handle !== false && isSheetModal;
|
|
@@ -22816,20 +22613,20 @@ class Modal {
|
|
|
22816
22613
|
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
22817
22614
|
const isHandleCycle = handleBehavior === 'cycle';
|
|
22818
22615
|
const isSheetModalWithHandle = isSheetModal && showHandle;
|
|
22819
|
-
return (hAsync(Host, Object.assign({ key: '
|
|
22616
|
+
return (hAsync(Host, Object.assign({ key: '8add05bb43a2cdb5e3cf180147d31eb85a018fe0', "no-router": true,
|
|
22820
22617
|
// Allow the modal to be navigable when the handle is focusable
|
|
22821
22618
|
tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
|
|
22822
22619
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
22823
|
-
}, 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 }), hAsync("ion-backdrop", { key: '
|
|
22620
|
+
}, 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 }), hAsync("ion-backdrop", { key: '90a6605a9564a699d6f66cf71cf6b506796a2963', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && hAsync("div", { key: 'a97d071395333bf803c0a9347bda000cf7500d8d', class: "modal-shadow" }), hAsync("div", Object.assign({ key: 'e7b7985c7414a13e3ba8dcecf497b76e92edf53e',
|
|
22824
22621
|
/*
|
|
22825
22622
|
role and aria-modal must be used on the
|
|
22826
22623
|
same element. They must also be set inside the
|
|
22827
22624
|
shadow DOM otherwise ion-button will not be highlighted
|
|
22828
22625
|
when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
|
|
22829
22626
|
*/
|
|
22830
|
-
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (hAsync("button", { key: '
|
|
22627
|
+
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (hAsync("button", { key: '8258b65570b11a8ee9c9df2537d6419cd2e34536', class: "modal-handle",
|
|
22831
22628
|
// Prevents the handle from receiving keyboard focus when it does not cycle
|
|
22832
|
-
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) })), hAsync("slot", { key: '
|
|
22629
|
+
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) })), hAsync("slot", { key: '394370d0ed03ee03152f8f8abae7ff7664ca5c13' }))));
|
|
22833
22630
|
}
|
|
22834
22631
|
get el() { return getElement(this); }
|
|
22835
22632
|
static get watchers() { return {
|
|
@@ -32854,7 +32651,7 @@ class Select {
|
|
|
32854
32651
|
const scrollSelectedIntoView = () => {
|
|
32855
32652
|
const indexOfSelected = this.childOpts.findIndex((o) => o.value === this.value);
|
|
32856
32653
|
if (indexOfSelected > -1) {
|
|
32857
|
-
const selectedItem = overlay.querySelector(`.select-interface-option:nth-
|
|
32654
|
+
const selectedItem = overlay.querySelector(`.select-interface-option:nth-of-type(${indexOfSelected + 1})`);
|
|
32858
32655
|
if (selectedItem) {
|
|
32859
32656
|
/**
|
|
32860
32657
|
* Browsers such as Firefox do not
|
|
@@ -33374,7 +33171,7 @@ class Select {
|
|
|
33374
33171
|
* TODO(FW-5592): Remove hasStartEndSlots condition
|
|
33375
33172
|
*/
|
|
33376
33173
|
const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || isExpanded || hasStartEndSlots));
|
|
33377
|
-
return (hAsync(Host, { key: '
|
|
33174
|
+
return (hAsync(Host, { key: 'c03fb65e8fc9f9aab295e07b282377d57d910519', onClick: this.onClick, class: createColorClasses$1(this.color, {
|
|
33378
33175
|
[mode]: true,
|
|
33379
33176
|
'in-item': inItem,
|
|
33380
33177
|
'in-item-color': hostContext('ion-item.ion-color', el),
|
|
@@ -33392,7 +33189,7 @@ class Select {
|
|
|
33392
33189
|
[`select-justify-${justify}`]: justifyEnabled,
|
|
33393
33190
|
[`select-shape-${shape}`]: shape !== undefined,
|
|
33394
33191
|
[`select-label-placement-${labelPlacement}`]: true,
|
|
33395
|
-
}) }, hAsync("label", { key: '
|
|
33192
|
+
}) }, hAsync("label", { key: '0d0c8ec55269adcac625f2899a547f4e7f3e3741', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: 'f6dfc93c0e23cbe75a2947abde67d842db2dad78', class: "select-wrapper-inner" }, hAsync("slot", { key: '957bfadf9f101f519091419a362d3abdc2be66f6', name: "start" }), hAsync("div", { key: 'ca349202a484e7f2e884533fd330f0b136754f7d', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), hAsync("slot", { key: 'f0e62a6533ff1c8f62bd2d27f60b23385c4fa9ed', name: "end" }), !hasFloatingOrStackedLabel && this.renderSelectIcon()), hasFloatingOrStackedLabel && this.renderSelectIcon(), shouldRenderHighlight && hAsync("div", { key: 'fb840d46bafafb09898ebeebbe8c181906a3d8a2', class: "select-highlight" })), this.renderBottomContent()));
|
|
33396
33193
|
}
|
|
33397
33194
|
get el() { return getElement(this); }
|
|
33398
33195
|
static get watchers() { return {
|
package/package.json
CHANGED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
|
-
*/
|
|
4
|
-
import { createAnimation } from "../../../utils/animation/animation";
|
|
5
|
-
import { getElementRoot } from "../../../utils/helpers";
|
|
6
|
-
import { SwipeToCloseDefaults } from "../gestures/swipe-to-close";
|
|
7
|
-
/**
|
|
8
|
-
* Transition animation from portrait view to landscape view
|
|
9
|
-
* This handles the case where a card modal is open in portrait view
|
|
10
|
-
* and the user switches to landscape view
|
|
11
|
-
*/
|
|
12
|
-
export const portraitToLandscapeTransition = (baseEl, opts, duration = 300) => {
|
|
13
|
-
const { presentingEl } = opts;
|
|
14
|
-
if (!presentingEl) {
|
|
15
|
-
// No transition needed for non-card modals
|
|
16
|
-
return createAnimation('portrait-to-landscape-transition');
|
|
17
|
-
}
|
|
18
|
-
const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
|
|
19
|
-
const presentingElRoot = getElementRoot(presentingEl);
|
|
20
|
-
const bodyEl = document.body;
|
|
21
|
-
const baseAnimation = createAnimation('portrait-to-landscape-transition')
|
|
22
|
-
.addElement(baseEl)
|
|
23
|
-
.easing('cubic-bezier(0.32,0.72,0,1)')
|
|
24
|
-
.duration(duration);
|
|
25
|
-
const presentingAnimation = createAnimation().beforeStyles({
|
|
26
|
-
transform: 'translateY(0)',
|
|
27
|
-
'transform-origin': 'top center',
|
|
28
|
-
overflow: 'hidden',
|
|
29
|
-
});
|
|
30
|
-
if (!hasCardModal) {
|
|
31
|
-
// Non-card modal: transition from portrait state to landscape state
|
|
32
|
-
// Portrait: presentingEl has transform and body has black background
|
|
33
|
-
// Landscape: no transform, no body background, modal wrapper opacity changes
|
|
34
|
-
const root = getElementRoot(baseEl);
|
|
35
|
-
const wrapperAnimation = createAnimation()
|
|
36
|
-
.addElement(root.querySelectorAll('.modal-wrapper, .modal-shadow'))
|
|
37
|
-
.fromTo('opacity', '1', '1'); // Keep wrapper visible in landscape
|
|
38
|
-
const backdropAnimation = createAnimation()
|
|
39
|
-
.addElement(root.querySelector('ion-backdrop'))
|
|
40
|
-
.fromTo('opacity', 'var(--backdrop-opacity)', 'var(--backdrop-opacity)'); // Keep backdrop visible
|
|
41
|
-
// Animate presentingEl from portrait state back to normal
|
|
42
|
-
const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
|
|
43
|
-
const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
|
|
44
|
-
const fromTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
|
|
45
|
-
presentingAnimation
|
|
46
|
-
.addElement(presentingEl)
|
|
47
|
-
.afterStyles({
|
|
48
|
-
transform: 'translateY(0px) scale(1)',
|
|
49
|
-
'border-radius': '0px',
|
|
50
|
-
})
|
|
51
|
-
.beforeAddWrite(() => bodyEl.style.setProperty('background-color', ''))
|
|
52
|
-
.fromTo('transform', fromTransform, 'translateY(0px) scale(1)')
|
|
53
|
-
.fromTo('filter', 'contrast(0.85)', 'contrast(1)')
|
|
54
|
-
.fromTo('border-radius', '10px 10px 0 0', '0px');
|
|
55
|
-
baseAnimation.addAnimation([presentingAnimation, wrapperAnimation, backdropAnimation]);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
// Card modal: transition from portrait card state to landscape card state
|
|
59
|
-
const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
|
|
60
|
-
const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
|
|
61
|
-
const fromTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
|
|
62
|
-
const toTransform = `translateY(-10px) scale(${toPresentingScale})`;
|
|
63
|
-
presentingAnimation
|
|
64
|
-
.addElement(presentingElRoot.querySelector('.modal-wrapper'))
|
|
65
|
-
.fromTo('transform', fromTransform, toTransform)
|
|
66
|
-
.fromTo('filter', 'contrast(0.85)', 'contrast(0.85)'); // Keep same contrast for card
|
|
67
|
-
const shadowAnimation = createAnimation()
|
|
68
|
-
.addElement(presentingElRoot.querySelector('.modal-shadow'))
|
|
69
|
-
.fromTo('opacity', '0', '0') // Shadow stays hidden in landscape for card modals
|
|
70
|
-
.fromTo('transform', fromTransform, toTransform);
|
|
71
|
-
baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
|
|
72
|
-
}
|
|
73
|
-
return baseAnimation;
|
|
74
|
-
};
|
|
75
|
-
/**
|
|
76
|
-
* Transition animation from landscape view to portrait view
|
|
77
|
-
* This handles the case where a card modal is open in landscape view
|
|
78
|
-
* and the user switches to portrait view
|
|
79
|
-
*/
|
|
80
|
-
export const landscapeToPortraitTransition = (baseEl, opts, duration = 300) => {
|
|
81
|
-
const { presentingEl } = opts;
|
|
82
|
-
if (!presentingEl) {
|
|
83
|
-
// No transition needed for non-card modals
|
|
84
|
-
return createAnimation('landscape-to-portrait-transition');
|
|
85
|
-
}
|
|
86
|
-
const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
|
|
87
|
-
const presentingElRoot = getElementRoot(presentingEl);
|
|
88
|
-
const bodyEl = document.body;
|
|
89
|
-
const baseAnimation = createAnimation('landscape-to-portrait-transition')
|
|
90
|
-
.addElement(baseEl)
|
|
91
|
-
.easing('cubic-bezier(0.32,0.72,0,1)')
|
|
92
|
-
.duration(duration);
|
|
93
|
-
const presentingAnimation = createAnimation().beforeStyles({
|
|
94
|
-
transform: 'translateY(0)',
|
|
95
|
-
'transform-origin': 'top center',
|
|
96
|
-
overflow: 'hidden',
|
|
97
|
-
});
|
|
98
|
-
if (!hasCardModal) {
|
|
99
|
-
// Non-card modal: transition from landscape state to portrait state
|
|
100
|
-
const root = getElementRoot(baseEl);
|
|
101
|
-
const wrapperAnimation = createAnimation()
|
|
102
|
-
.addElement(root.querySelectorAll('.modal-wrapper, .modal-shadow'))
|
|
103
|
-
.fromTo('opacity', '1', '1'); // Keep wrapper visible
|
|
104
|
-
const backdropAnimation = createAnimation()
|
|
105
|
-
.addElement(root.querySelector('ion-backdrop'))
|
|
106
|
-
.fromTo('opacity', 'var(--backdrop-opacity)', 'var(--backdrop-opacity)'); // Keep backdrop visible
|
|
107
|
-
// Animate presentingEl from normal state to portrait state
|
|
108
|
-
const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
|
|
109
|
-
const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
|
|
110
|
-
const toTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
|
|
111
|
-
presentingAnimation
|
|
112
|
-
.addElement(presentingEl)
|
|
113
|
-
.afterStyles({
|
|
114
|
-
transform: toTransform,
|
|
115
|
-
'border-radius': '10px 10px 0 0',
|
|
116
|
-
filter: 'contrast(0.85)',
|
|
117
|
-
overflow: 'hidden',
|
|
118
|
-
'transform-origin': 'top center',
|
|
119
|
-
})
|
|
120
|
-
.beforeAddWrite(() => bodyEl.style.setProperty('background-color', 'black'))
|
|
121
|
-
.fromTo('transform', 'translateY(0px) scale(1)', toTransform)
|
|
122
|
-
.fromTo('filter', 'contrast(1)', 'contrast(0.85)')
|
|
123
|
-
.fromTo('border-radius', '0px', '10px 10px 0 0');
|
|
124
|
-
baseAnimation.addAnimation([presentingAnimation, wrapperAnimation, backdropAnimation]);
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
// Card modal: transition from landscape card state to portrait card state
|
|
128
|
-
const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
|
|
129
|
-
const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
|
|
130
|
-
const fromTransform = `translateY(-10px) scale(${toPresentingScale})`;
|
|
131
|
-
const toTransform = `translateY(${transformOffset}) scale(${toPresentingScale})`;
|
|
132
|
-
presentingAnimation
|
|
133
|
-
.addElement(presentingElRoot.querySelector('.modal-wrapper'))
|
|
134
|
-
.fromTo('transform', fromTransform, toTransform)
|
|
135
|
-
.fromTo('filter', 'contrast(0.85)', 'contrast(0.85)'); // Keep same contrast for card
|
|
136
|
-
const shadowAnimation = createAnimation()
|
|
137
|
-
.addElement(presentingElRoot.querySelector('.modal-shadow'))
|
|
138
|
-
.fromTo('opacity', '0', '0') // Shadow stays hidden
|
|
139
|
-
.fromTo('transform', fromTransform, toTransform);
|
|
140
|
-
baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
|
|
141
|
-
}
|
|
142
|
-
return baseAnimation;
|
|
143
|
-
};
|