@ionic/core 7.4.4-dev.11696956070.1faa3cfe → 7.4.4-dev.11699471770.1b7273c4
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/alert.js +8 -0
- package/components/checkbox.js +0 -3
- package/components/data.js +96 -22
- package/components/haptic.js +1 -0
- package/components/index.js +1 -0
- package/components/ion-datetime-button.js +4 -4
- package/components/ion-datetime.js +3 -3
- package/components/ion-nav.js +1 -0
- package/components/ion-router.js +3 -0
- package/components/ion-select.js +1 -1
- package/components/ion-toast.js +157 -13
- package/components/ion-toggle.js +0 -3
- package/components/ios.transition.js +1 -0
- package/components/overlays.js +1 -0
- package/components/radio-group.js +1 -1
- package/components/radio.js +1 -4
- package/dist/cjs/{button-active-c358e83c.js → button-active-f2147e85.js} +1 -1
- package/dist/cjs/{data-db832785.js → data-c8d21093.js} +96 -22
- package/dist/cjs/{haptic-c5f6b4d5.js → haptic-678abc9f.js} +1 -0
- package/dist/cjs/{index-fa649bd8.js → index-33d2809c.js} +2 -2
- package/dist/cjs/index.cjs.js +6 -4
- package/dist/cjs/ion-action-sheet.cjs.entry.js +3 -3
- package/dist/cjs/ion-alert.cjs.entry.js +11 -3
- package/dist/cjs/ion-app_8.cjs.entry.js +1 -1
- package/dist/cjs/ion-checkbox.cjs.entry.js +0 -3
- package/dist/cjs/ion-datetime-button.cjs.entry.js +4 -4
- package/dist/cjs/ion-datetime_3.cjs.entry.js +5 -5
- package/dist/cjs/ion-loading.cjs.entry.js +1 -1
- package/dist/cjs/ion-menu_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-modal.cjs.entry.js +2 -2
- package/dist/cjs/ion-nav_2.cjs.entry.js +2 -1
- package/dist/cjs/ion-picker-column-internal.cjs.entry.js +1 -1
- package/dist/cjs/ion-popover.cjs.entry.js +2 -2
- package/dist/cjs/ion-radio_2.cjs.entry.js +2 -5
- package/dist/cjs/ion-refresher_2.cjs.entry.js +1 -1
- package/dist/cjs/ion-reorder_2.cjs.entry.js +1 -1
- package/dist/cjs/ion-route_4.cjs.entry.js +3 -0
- package/dist/cjs/ion-select_3.cjs.entry.js +2 -2
- package/dist/cjs/ion-toast.cjs.entry.js +174 -32
- package/dist/cjs/ion-toggle.cjs.entry.js +1 -4
- package/dist/cjs/ionic.cjs.js +1 -1
- package/dist/cjs/{ios.transition-4195d10d.js → ios.transition-8ddf91e6.js} +2 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{md.transition-0713f667.js → md.transition-44ff8566.js} +1 -1
- package/dist/cjs/{overlays-efc9d511.js → overlays-9cab437c.js} +1 -0
- package/dist/collection/components/alert/alert.js +8 -0
- package/dist/collection/components/alert/test/a11y/alert.e2e.js +11 -0
- package/dist/collection/components/checkbox/checkbox.js +0 -3
- package/dist/collection/components/datetime/datetime.js +12 -6
- package/dist/collection/components/datetime/test/hour-cycle/datetime.e2e.js +14 -0
- package/dist/collection/components/datetime/utils/data.js +33 -7
- package/dist/collection/components/datetime/utils/format.js +27 -10
- package/dist/collection/components/datetime/utils/helpers.js +37 -5
- package/dist/collection/components/datetime-button/datetime-button.js +4 -4
- package/dist/collection/components/nav/nav.js +1 -0
- package/dist/collection/components/radio/radio.js +1 -4
- package/dist/collection/components/radio-group/radio-group.js +1 -1
- package/dist/collection/components/router/router.js +2 -0
- package/dist/collection/components/router/utils/path.js +1 -0
- package/dist/collection/components/select/select.js +1 -1
- package/dist/collection/components/toast/animations/ios.enter.js +2 -3
- package/dist/collection/components/toast/animations/ios.leave.js +2 -3
- package/dist/collection/components/toast/animations/md.enter.js +2 -3
- package/dist/collection/components/toast/animations/utils.js +85 -0
- package/dist/collection/components/toast/test/position-anchor/toast.e2e.js +45 -0
- package/dist/collection/components/toast/toast.js +98 -9
- package/dist/collection/components/toggle/toggle.js +0 -3
- package/dist/collection/index.js +1 -0
- package/dist/collection/utils/native/haptic.js +1 -0
- package/dist/collection/utils/overlays.js +1 -0
- package/dist/collection/utils/transition/ios.transition.js +1 -0
- package/dist/docs.json +73 -10
- package/dist/esm/{button-active-7180a130.js → button-active-3dd473a1.js} +1 -1
- package/dist/esm/{data-009dbf15.js → data-44d9e816.js} +96 -22
- package/dist/esm/{haptic-6447af60.js → haptic-1243b917.js} +1 -0
- package/dist/esm/{index-0b0dd67c.js → index-6e10cd02.js} +2 -2
- package/dist/esm/index.js +5 -4
- package/dist/esm/ion-action-sheet.entry.js +3 -3
- package/dist/esm/ion-alert.entry.js +11 -3
- package/dist/esm/ion-app_8.entry.js +1 -1
- package/dist/esm/ion-checkbox.entry.js +0 -3
- package/dist/esm/ion-datetime-button.entry.js +4 -4
- package/dist/esm/ion-datetime_3.entry.js +5 -5
- package/dist/esm/ion-loading.entry.js +1 -1
- package/dist/esm/ion-menu_3.entry.js +1 -1
- package/dist/esm/ion-modal.entry.js +2 -2
- package/dist/esm/ion-nav_2.entry.js +2 -1
- package/dist/esm/ion-picker-column-internal.entry.js +1 -1
- package/dist/esm/ion-popover.entry.js +2 -2
- package/dist/esm/ion-radio_2.entry.js +2 -5
- package/dist/esm/ion-refresher_2.entry.js +1 -1
- package/dist/esm/ion-reorder_2.entry.js +1 -1
- package/dist/esm/ion-route_4.entry.js +3 -0
- package/dist/esm/ion-select_3.entry.js +2 -2
- package/dist/esm/ion-toast.entry.js +157 -15
- package/dist/esm/ion-toggle.entry.js +1 -4
- package/dist/esm/ionic.js +1 -1
- package/dist/esm/{ios.transition-875ba2ea.js → ios.transition-6707a3a1.js} +2 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{md.transition-54c79f72.js → md.transition-957964fd.js} +1 -1
- package/dist/esm/{overlays-84621c0a.js → overlays-753933fc.js} +1 -0
- package/dist/esm-es5/{button-active-7180a130.js → button-active-3dd473a1.js} +1 -1
- package/dist/esm-es5/data-44d9e816.js +4 -0
- package/dist/esm-es5/{index-0b0dd67c.js → index-6e10cd02.js} +1 -1
- package/dist/esm-es5/index.js +1 -1
- package/dist/esm-es5/ion-action-sheet.entry.js +1 -1
- package/dist/esm-es5/ion-alert.entry.js +1 -1
- package/dist/esm-es5/ion-app_8.entry.js +1 -1
- package/dist/esm-es5/ion-checkbox.entry.js +1 -1
- package/dist/esm-es5/ion-datetime-button.entry.js +1 -1
- package/dist/esm-es5/ion-datetime_3.entry.js +1 -1
- package/dist/esm-es5/ion-loading.entry.js +1 -1
- package/dist/esm-es5/ion-menu_3.entry.js +1 -1
- package/dist/esm-es5/ion-modal.entry.js +1 -1
- package/dist/esm-es5/ion-nav_2.entry.js +1 -1
- package/dist/esm-es5/ion-picker-column-internal.entry.js +1 -1
- package/dist/esm-es5/ion-popover.entry.js +1 -1
- package/dist/esm-es5/ion-radio_2.entry.js +1 -1
- package/dist/esm-es5/ion-refresher_2.entry.js +1 -1
- package/dist/esm-es5/ion-reorder_2.entry.js +1 -1
- package/dist/esm-es5/ion-select_3.entry.js +1 -1
- package/dist/esm-es5/ion-toast.entry.js +1 -1
- package/dist/esm-es5/ion-toggle.entry.js +1 -1
- package/dist/esm-es5/ionic.js +1 -1
- package/dist/esm-es5/{ios.transition-875ba2ea.js → ios.transition-6707a3a1.js} +1 -1
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/{md.transition-54c79f72.js → md.transition-957964fd.js} +1 -1
- package/dist/html.html-data.json +11 -1
- package/dist/ionic/index.esm.js +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/{p-2134558d.entry.js → p-0023e6eb.entry.js} +1 -1
- package/dist/ionic/{p-0dcdf480.system.entry.js → p-00f709ca.system.entry.js} +1 -1
- package/dist/ionic/{p-2330af92.system.entry.js → p-037e2738.system.entry.js} +1 -1
- package/dist/ionic/{p-678f37d7.entry.js → p-03f7e3cc.entry.js} +1 -1
- package/dist/ionic/{p-8c17d825.js → p-0d198537.js} +1 -1
- package/dist/ionic/p-100ea813.system.entry.js +4 -0
- package/dist/ionic/{p-f4267847.system.entry.js → p-10fcb3a3.system.entry.js} +1 -1
- package/dist/ionic/{p-00d3814a.system.entry.js → p-14fd96a2.system.entry.js} +1 -1
- package/dist/ionic/p-17240d90.js +4 -0
- package/dist/ionic/{p-af39c1c5.js → p-1d9b39f3.js} +1 -1
- package/dist/ionic/{p-a1528344.entry.js → p-2acea831.entry.js} +1 -1
- package/dist/ionic/{p-cd075e75.system.entry.js → p-2c9e9915.system.entry.js} +1 -1
- package/dist/ionic/{p-979dc719.entry.js → p-44fa0a61.entry.js} +1 -1
- package/dist/ionic/p-469d6a98.entry.js +4 -0
- package/dist/ionic/p-4965f2d7.entry.js +4 -0
- package/dist/ionic/p-520789c2.js +4 -0
- package/dist/ionic/{p-24952f8a.system.entry.js → p-5cafe439.system.entry.js} +1 -1
- package/dist/ionic/{p-eaa58d23.entry.js → p-60dee335.entry.js} +1 -1
- package/dist/ionic/p-68b405cc.entry.js +4 -0
- package/dist/ionic/p-73eba881.system.js +1 -1
- package/dist/ionic/{p-0c7d0167.system.entry.js → p-7520e873.system.entry.js} +1 -1
- package/dist/ionic/{p-df951755.system.entry.js → p-88a1a4fe.system.entry.js} +1 -1
- package/dist/ionic/{p-0fc8a522.system.entry.js → p-8957b1de.system.entry.js} +1 -1
- package/dist/ionic/{p-9e6bf328.system.js → p-90012797.system.js} +1 -1
- package/dist/ionic/{p-4c274938.entry.js → p-93c4333b.entry.js} +1 -1
- package/dist/ionic/{p-a8403bed.system.entry.js → p-9736406a.system.entry.js} +1 -1
- package/dist/ionic/{p-0e070fbe.entry.js → p-9b796813.entry.js} +1 -1
- package/dist/ionic/p-9bd70bd2.entry.js +4 -0
- package/dist/ionic/{p-2062958e.js → p-9dbc208c.js} +1 -1
- package/dist/ionic/{p-52e5f8f0.system.entry.js → p-a157df46.system.entry.js} +1 -1
- package/dist/ionic/{p-a6c52452.entry.js → p-a7361c85.entry.js} +1 -1
- package/dist/ionic/{p-d511de89.system.entry.js → p-aa4b083c.system.entry.js} +1 -1
- package/dist/ionic/p-aae05032.entry.js +4 -0
- package/dist/ionic/{p-e92068d4.system.entry.js → p-ae8121f5.system.entry.js} +1 -1
- package/dist/ionic/{p-d17638e9.system.js → p-b25a96b7.system.js} +1 -1
- package/dist/ionic/{p-53d4606a.entry.js → p-b4f14d9e.entry.js} +1 -1
- package/dist/ionic/p-b8c3f071.system.js +4 -0
- package/dist/ionic/p-b92d3bf2.system.js +4 -0
- package/dist/ionic/{p-ab37db48.entry.js → p-be02d76a.entry.js} +1 -1
- package/dist/ionic/{p-7061fa75.system.entry.js → p-c215a78a.system.entry.js} +1 -1
- package/dist/ionic/{p-67e21699.entry.js → p-c42d0ea3.entry.js} +1 -1
- package/dist/ionic/{p-32eaa293.entry.js → p-cb16123b.entry.js} +1 -1
- package/dist/ionic/p-d0d59328.entry.js +4 -0
- package/dist/ionic/{p-b7258ddb.system.js → p-e0f66356.system.js} +1 -1
- package/dist/ionic/{p-f1c2678b.system.entry.js → p-e62d80e5.system.entry.js} +1 -1
- package/dist/ionic/{p-3d278648.system.entry.js → p-e690be9f.system.entry.js} +1 -1
- package/dist/ionic/{p-7c901810.system.js → p-ec25d547.system.js} +1 -1
- package/dist/ionic/{p-77b9d68a.system.entry.js → p-fe268c4d.system.entry.js} +1 -1
- package/dist/types/components/datetime/datetime-interface.d.ts +1 -0
- package/dist/types/components/datetime/datetime.d.ts +2 -2
- package/dist/types/components/datetime/utils/data.d.ts +3 -3
- package/dist/types/components/datetime/utils/format.d.ts +3 -3
- package/dist/types/components/datetime/utils/helpers.d.ts +15 -1
- package/dist/types/components/toast/animations/ios.enter.d.ts +2 -1
- package/dist/types/components/toast/animations/ios.leave.d.ts +2 -2
- package/dist/types/components/toast/animations/md.enter.d.ts +2 -1
- package/dist/types/components/toast/animations/utils.d.ts +18 -0
- package/dist/types/components/toast/toast-interface.d.ts +11 -0
- package/dist/types/components/toast/toast.d.ts +21 -1
- package/dist/types/components.d.ts +16 -8
- package/dist/types/index.d.ts +1 -0
- package/hydrate/index.js +274 -51
- package/package.json +4 -5
- package/dist/esm-es5/data-009dbf15.js +0 -4
- package/dist/ionic/p-07c816fb.entry.js +0 -4
- package/dist/ionic/p-15278928.entry.js +0 -4
- package/dist/ionic/p-44ef7224.system.js +0 -4
- package/dist/ionic/p-63b4ef44.system.entry.js +0 -4
- package/dist/ionic/p-775f3749.entry.js +0 -4
- package/dist/ionic/p-77872abc.entry.js +0 -4
- package/dist/ionic/p-7cfd253c.js +0 -4
- package/dist/ionic/p-8b33cfef.entry.js +0 -4
- package/dist/ionic/p-c5395981.js +0 -4
- package/dist/ionic/p-c9524896.system.js +0 -4
- package/dist/ionic/p-d055bba9.entry.js +0 -4
- /package/dist/esm-es5/{haptic-6447af60.js → haptic-1243b917.js} +0 -0
- /package/dist/esm-es5/{overlays-84621c0a.js → overlays-753933fc.js} +0 -0
- /package/dist/ionic/{p-c8ec0d79.system.js → p-82c72668.system.js} +0 -0
- /package/dist/ionic/{p-14d7b7e2.system.js → p-b4b4bb29.system.js} +0 -0
- /package/dist/ionic/{p-bb6f38ed.js → p-b923f3d7.js} +0 -0
- /package/dist/ionic/{p-68a3da51.js → p-ee8881d0.js} +0 -0
|
@@ -6,13 +6,12 @@ import { getElementRoot } from "../../../utils/helpers";
|
|
|
6
6
|
/**
|
|
7
7
|
* iOS Toast Enter Animation
|
|
8
8
|
*/
|
|
9
|
-
export const iosEnterAnimation = (baseEl,
|
|
9
|
+
export const iosEnterAnimation = (baseEl, opts) => {
|
|
10
10
|
const baseAnimation = createAnimation();
|
|
11
11
|
const wrapperAnimation = createAnimation();
|
|
12
|
+
const { position, top, bottom } = opts;
|
|
12
13
|
const root = getElementRoot(baseEl);
|
|
13
14
|
const wrapperEl = root.querySelector('.toast-wrapper');
|
|
14
|
-
const bottom = `calc(-10px - var(--ion-safe-area-bottom, 0px))`;
|
|
15
|
-
const top = `calc(10px + var(--ion-safe-area-top, 0px))`;
|
|
16
15
|
wrapperAnimation.addElement(wrapperEl);
|
|
17
16
|
switch (position) {
|
|
18
17
|
case 'top':
|
|
@@ -6,13 +6,12 @@ import { getElementRoot } from "../../../utils/helpers";
|
|
|
6
6
|
/**
|
|
7
7
|
* iOS Toast Leave Animation
|
|
8
8
|
*/
|
|
9
|
-
export const iosLeaveAnimation = (baseEl,
|
|
9
|
+
export const iosLeaveAnimation = (baseEl, opts) => {
|
|
10
10
|
const baseAnimation = createAnimation();
|
|
11
11
|
const wrapperAnimation = createAnimation();
|
|
12
|
+
const { position, top, bottom } = opts;
|
|
12
13
|
const root = getElementRoot(baseEl);
|
|
13
14
|
const wrapperEl = root.querySelector('.toast-wrapper');
|
|
14
|
-
const bottom = `calc(-10px - var(--ion-safe-area-bottom, 0px))`;
|
|
15
|
-
const top = `calc(10px + var(--ion-safe-area-top, 0px))`;
|
|
16
15
|
wrapperAnimation.addElement(wrapperEl);
|
|
17
16
|
switch (position) {
|
|
18
17
|
case 'top':
|
|
@@ -6,13 +6,12 @@ import { getElementRoot } from "../../../utils/helpers";
|
|
|
6
6
|
/**
|
|
7
7
|
* MD Toast Enter Animation
|
|
8
8
|
*/
|
|
9
|
-
export const mdEnterAnimation = (baseEl,
|
|
9
|
+
export const mdEnterAnimation = (baseEl, opts) => {
|
|
10
10
|
const baseAnimation = createAnimation();
|
|
11
11
|
const wrapperAnimation = createAnimation();
|
|
12
|
+
const { position, top, bottom } = opts;
|
|
12
13
|
const root = getElementRoot(baseEl);
|
|
13
14
|
const wrapperEl = root.querySelector('.toast-wrapper');
|
|
14
|
-
const bottom = `calc(8px + var(--ion-safe-area-bottom, 0px))`;
|
|
15
|
-
const top = `calc(8px + var(--ion-safe-area-top, 0px))`;
|
|
16
15
|
wrapperAnimation.addElement(wrapperEl);
|
|
17
16
|
switch (position) {
|
|
18
17
|
case 'top':
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
|
+
*/
|
|
4
|
+
import { win } from "../../../utils/browser/index";
|
|
5
|
+
import { printIonWarning } from "../../../utils/logging/index";
|
|
6
|
+
/**
|
|
7
|
+
* Calculate the CSS top and bottom position of the toast, to be used
|
|
8
|
+
* as starting points for the animation keyframes.
|
|
9
|
+
*
|
|
10
|
+
* Note that MD animates bottom-positioned toasts using style.bottom,
|
|
11
|
+
* which calculates from the bottom edge of the screen, while iOS uses
|
|
12
|
+
* translateY, which calculates from the top edge of the screen. This
|
|
13
|
+
* is why the bottom calculates differ slightly between modes.
|
|
14
|
+
*
|
|
15
|
+
* @param position The value of the toast's position prop.
|
|
16
|
+
* @param positionAnchor The element the toast should be anchored to,
|
|
17
|
+
* if applicable.
|
|
18
|
+
* @param mode The toast component's mode (md, ios, etc).
|
|
19
|
+
* @param toast A reference to the toast element itself.
|
|
20
|
+
*/
|
|
21
|
+
export function getAnimationPosition(position, positionAnchor, mode, toast) {
|
|
22
|
+
/**
|
|
23
|
+
* Start with a predefined offset from the edge the toast will be
|
|
24
|
+
* positioned relative to, whether on the screen or anchor element.
|
|
25
|
+
*/
|
|
26
|
+
let offset;
|
|
27
|
+
if (mode === 'md') {
|
|
28
|
+
offset = 8;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
offset = position === 'top' ? 10 : -10;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* If positionAnchor is defined, add in the distance from the target
|
|
35
|
+
* screen edge to the target anchor edge. For position="top", the
|
|
36
|
+
* bottom anchor edge is targeted. For position="bottom", the top
|
|
37
|
+
* anchor edge is targeted.
|
|
38
|
+
*/
|
|
39
|
+
if (positionAnchor && win) {
|
|
40
|
+
warnIfAnchorIsHidden(positionAnchor, toast);
|
|
41
|
+
const box = positionAnchor.getBoundingClientRect();
|
|
42
|
+
if (position === 'top') {
|
|
43
|
+
offset += box.bottom;
|
|
44
|
+
}
|
|
45
|
+
else if (position === 'bottom') {
|
|
46
|
+
/**
|
|
47
|
+
* Just box.top is the distance from the top edge of the screen
|
|
48
|
+
* to the top edge of the anchor. We want to calculate from the
|
|
49
|
+
* bottom edge of the screen instead.
|
|
50
|
+
*/
|
|
51
|
+
if (mode === 'md') {
|
|
52
|
+
offset += win.innerHeight - box.top;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
offset -= win.innerHeight - box.top;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* We don't include safe area here because that should already be
|
|
60
|
+
* accounted for when checking the position of the anchor.
|
|
61
|
+
*/
|
|
62
|
+
return {
|
|
63
|
+
top: `${offset}px`,
|
|
64
|
+
bottom: `${offset}px`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
return {
|
|
69
|
+
top: `calc(${offset}px + var(--ion-safe-area-top, 0px))`,
|
|
70
|
+
bottom: mode === 'md'
|
|
71
|
+
? `calc(${offset}px + var(--ion-safe-area-bottom, 0px))`
|
|
72
|
+
: `calc(${offset}px - var(--ion-safe-area-bottom, 0px))`,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* If the anchor element is hidden, getBoundingClientRect()
|
|
78
|
+
* will return all 0s for it, which can cause unexpected
|
|
79
|
+
* results in the position calculation when animating.
|
|
80
|
+
*/
|
|
81
|
+
function warnIfAnchorIsHidden(positionAnchor, toast) {
|
|
82
|
+
if (positionAnchor.offsetParent === null) {
|
|
83
|
+
printIonWarning('The positionAnchor element for ion-toast was found in the DOM, but appears to be hidden. This may lead to unexpected positioning of the toast.', toast);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
|
+
*/
|
|
4
|
+
import { expect } from "@playwright/test";
|
|
5
|
+
import { configs, test } from "../../../../utils/test/playwright/index";
|
|
6
|
+
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
7
|
+
test.describe(title('toast: positionAnchor'), () => {
|
|
8
|
+
test.beforeEach(async ({ page }) => {
|
|
9
|
+
await page.goto('/src/components/toast/test/position-anchor', config);
|
|
10
|
+
/**
|
|
11
|
+
* We need to screenshot the whole page to ensure the toasts are positioned
|
|
12
|
+
* correctly, but we don't need much extra white space between the header
|
|
13
|
+
* and footer.
|
|
14
|
+
*/
|
|
15
|
+
await page.setViewportSize({
|
|
16
|
+
width: 425,
|
|
17
|
+
height: 425,
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
test('should place top-position toast underneath anchor', async ({ page }) => {
|
|
21
|
+
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
|
|
22
|
+
await page.click('#headerAnchor');
|
|
23
|
+
await ionToastDidPresent.next();
|
|
24
|
+
await expect(page).toHaveScreenshot(screenshot(`toast-header-anchor`));
|
|
25
|
+
});
|
|
26
|
+
test('should place bottom-position toast above anchor', async ({ page }) => {
|
|
27
|
+
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
|
|
28
|
+
await page.click('#footerAnchor');
|
|
29
|
+
await ionToastDidPresent.next();
|
|
30
|
+
await expect(page).toHaveScreenshot(screenshot(`toast-footer-anchor`));
|
|
31
|
+
});
|
|
32
|
+
test('should ignore anchor for middle-position toast', async ({ page }) => {
|
|
33
|
+
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
|
|
34
|
+
await page.click('#middleAnchor');
|
|
35
|
+
await ionToastDidPresent.next();
|
|
36
|
+
await expect(page).toHaveScreenshot(screenshot(`toast-middle-anchor`));
|
|
37
|
+
});
|
|
38
|
+
test('should correctly anchor toast when using an element reference', async ({ page }) => {
|
|
39
|
+
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
|
|
40
|
+
await page.click('#headerElAnchor');
|
|
41
|
+
await ionToastDidPresent.next();
|
|
42
|
+
await expect(page).toHaveScreenshot(screenshot(`toast-header-el-anchor`));
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -15,6 +15,7 @@ import { iosEnterAnimation } from "./animations/ios.enter";
|
|
|
15
15
|
import { iosLeaveAnimation } from "./animations/ios.leave";
|
|
16
16
|
import { mdEnterAnimation } from "./animations/md.enter";
|
|
17
17
|
import { mdLeaveAnimation } from "./animations/md.leave";
|
|
18
|
+
import { getAnimationPosition } from "./animations/utils";
|
|
18
19
|
// TODO(FW-2832): types
|
|
19
20
|
/**
|
|
20
21
|
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
|
@@ -54,6 +55,7 @@ export class Toast {
|
|
|
54
55
|
this.message = undefined;
|
|
55
56
|
this.keyboardClose = false;
|
|
56
57
|
this.position = 'bottom';
|
|
58
|
+
this.positionAnchor = undefined;
|
|
57
59
|
this.buttons = undefined;
|
|
58
60
|
this.translucent = false;
|
|
59
61
|
this.animated = true;
|
|
@@ -101,7 +103,19 @@ export class Toast {
|
|
|
101
103
|
async present() {
|
|
102
104
|
const unlock = await this.lockController.lock();
|
|
103
105
|
await this.delegateController.attachViewToDom();
|
|
104
|
-
|
|
106
|
+
const { el, position } = this;
|
|
107
|
+
const anchor = this.getAnchorElement();
|
|
108
|
+
const animationPosition = getAnimationPosition(position, anchor, getIonMode(this), el);
|
|
109
|
+
/**
|
|
110
|
+
* Cache the calculated position of the toast, so we can re-use it
|
|
111
|
+
* in the dismiss animation.
|
|
112
|
+
*/
|
|
113
|
+
this.lastPresentedPosition = animationPosition;
|
|
114
|
+
await present(this, 'toastEnter', iosEnterAnimation, mdEnterAnimation, {
|
|
115
|
+
position,
|
|
116
|
+
top: animationPosition.top,
|
|
117
|
+
bottom: animationPosition.bottom,
|
|
118
|
+
});
|
|
105
119
|
/**
|
|
106
120
|
* Content is revealed to screen readers after
|
|
107
121
|
* the transition to avoid jank since this
|
|
@@ -123,15 +137,28 @@ export class Toast {
|
|
|
123
137
|
* Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
|
|
124
138
|
*/
|
|
125
139
|
async dismiss(data, role) {
|
|
140
|
+
var _a, _b;
|
|
126
141
|
const unlock = await this.lockController.lock();
|
|
127
|
-
|
|
128
|
-
|
|
142
|
+
const { durationTimeout, position, lastPresentedPosition } = this;
|
|
143
|
+
if (durationTimeout) {
|
|
144
|
+
clearTimeout(durationTimeout);
|
|
129
145
|
}
|
|
130
|
-
const dismissed = await dismiss(this, data, role, 'toastLeave', iosLeaveAnimation, mdLeaveAnimation,
|
|
146
|
+
const dismissed = await dismiss(this, data, role, 'toastLeave', iosLeaveAnimation, mdLeaveAnimation,
|
|
147
|
+
/**
|
|
148
|
+
* Fetch the cached position that was calculated back in the present
|
|
149
|
+
* animation. We always want to animate the dismiss from the same
|
|
150
|
+
* position the present stopped at, so the animation looks continuous.
|
|
151
|
+
*/
|
|
152
|
+
{
|
|
153
|
+
position,
|
|
154
|
+
top: (_a = lastPresentedPosition === null || lastPresentedPosition === void 0 ? void 0 : lastPresentedPosition.top) !== null && _a !== void 0 ? _a : '',
|
|
155
|
+
bottom: (_b = lastPresentedPosition === null || lastPresentedPosition === void 0 ? void 0 : lastPresentedPosition.bottom) !== null && _b !== void 0 ? _b : '',
|
|
156
|
+
});
|
|
131
157
|
if (dismissed) {
|
|
132
158
|
this.delegateController.removeViewFromDom();
|
|
133
159
|
this.revealContentToScreenReader = false;
|
|
134
160
|
}
|
|
161
|
+
this.lastPresentedPosition = undefined;
|
|
135
162
|
unlock();
|
|
136
163
|
return dismissed;
|
|
137
164
|
}
|
|
@@ -155,6 +182,44 @@ export class Toast {
|
|
|
155
182
|
: [];
|
|
156
183
|
return buttons;
|
|
157
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Returns the element specified by the positionAnchor prop,
|
|
187
|
+
* or undefined if prop's value is an ID string and the element
|
|
188
|
+
* is not found in the DOM.
|
|
189
|
+
*/
|
|
190
|
+
getAnchorElement() {
|
|
191
|
+
const { position, positionAnchor, el } = this;
|
|
192
|
+
/**
|
|
193
|
+
* If positionAnchor is undefined then
|
|
194
|
+
* no anchor should be used when presenting the toast.
|
|
195
|
+
*/
|
|
196
|
+
if (positionAnchor === undefined) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (position === 'middle' && positionAnchor !== undefined) {
|
|
200
|
+
printIonWarning('The positionAnchor property is ignored when using position="middle".', this.el);
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
if (typeof positionAnchor === 'string') {
|
|
204
|
+
/**
|
|
205
|
+
* If the anchor is defined as an ID, find the element.
|
|
206
|
+
* We do this on every present so the toast doesn't need
|
|
207
|
+
* to account for the surrounding DOM changing since the
|
|
208
|
+
* last time it was presented.
|
|
209
|
+
*/
|
|
210
|
+
const foundEl = document.getElementById(positionAnchor);
|
|
211
|
+
if (foundEl === null) {
|
|
212
|
+
printIonWarning(`An anchor element with an ID of "${positionAnchor}" was not found in the DOM.`, el);
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
return foundEl;
|
|
216
|
+
}
|
|
217
|
+
if (positionAnchor instanceof HTMLElement) {
|
|
218
|
+
return positionAnchor;
|
|
219
|
+
}
|
|
220
|
+
printIonWarning('Invalid positionAnchor value:', positionAnchor, el);
|
|
221
|
+
return undefined;
|
|
222
|
+
}
|
|
158
223
|
async buttonClick(button) {
|
|
159
224
|
const role = button.role;
|
|
160
225
|
if (isCancel(role)) {
|
|
@@ -517,12 +582,34 @@ export class Toast {
|
|
|
517
582
|
"optional": false,
|
|
518
583
|
"docs": {
|
|
519
584
|
"tags": [],
|
|
520
|
-
"text": "The position of the toast on the screen."
|
|
585
|
+
"text": "The starting position of the toast on the screen. Can be tweaked further\nusing the `positionAnchor` property."
|
|
521
586
|
},
|
|
522
587
|
"attribute": "position",
|
|
523
588
|
"reflect": false,
|
|
524
589
|
"defaultValue": "'bottom'"
|
|
525
590
|
},
|
|
591
|
+
"positionAnchor": {
|
|
592
|
+
"type": "string",
|
|
593
|
+
"mutable": false,
|
|
594
|
+
"complexType": {
|
|
595
|
+
"original": "HTMLElement | string",
|
|
596
|
+
"resolved": "HTMLElement | string | undefined",
|
|
597
|
+
"references": {
|
|
598
|
+
"HTMLElement": {
|
|
599
|
+
"location": "global",
|
|
600
|
+
"id": "global::HTMLElement"
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
},
|
|
604
|
+
"required": false,
|
|
605
|
+
"optional": true,
|
|
606
|
+
"docs": {
|
|
607
|
+
"tags": [],
|
|
608
|
+
"text": "The element to anchor the toast's position to. Can be set as a direct reference\nor the ID of the element. With `position=\"bottom\"`, the toast will sit above the\nchosen element. With `position=\"top\"`, the toast will sit below the chosen element.\nWith `position=\"middle\"`, the value of `positionAnchor` is ignored."
|
|
609
|
+
},
|
|
610
|
+
"attribute": "position-anchor",
|
|
611
|
+
"reflect": false
|
|
612
|
+
},
|
|
526
613
|
"buttons": {
|
|
527
614
|
"type": "unknown",
|
|
528
615
|
"mutable": false,
|
|
@@ -813,8 +900,9 @@ export class Toast {
|
|
|
813
900
|
"id": "global::Promise"
|
|
814
901
|
},
|
|
815
902
|
"ToastPresentOptions": {
|
|
816
|
-
"location": "
|
|
817
|
-
"
|
|
903
|
+
"location": "import",
|
|
904
|
+
"path": "./toast-interface",
|
|
905
|
+
"id": "src/components/toast/toast-interface.ts::ToastPresentOptions"
|
|
818
906
|
}
|
|
819
907
|
},
|
|
820
908
|
"return": "Promise<void>"
|
|
@@ -846,8 +934,9 @@ export class Toast {
|
|
|
846
934
|
"id": "global::Promise"
|
|
847
935
|
},
|
|
848
936
|
"ToastDismissOptions": {
|
|
849
|
-
"location": "
|
|
850
|
-
"
|
|
937
|
+
"location": "import",
|
|
938
|
+
"path": "./toast-interface",
|
|
939
|
+
"id": "src/components/toast/toast-interface.ts::ToastDismissOptions"
|
|
851
940
|
}
|
|
852
941
|
},
|
|
853
942
|
"return": "Promise<boolean>"
|
package/dist/collection/index.js
CHANGED
|
@@ -13,6 +13,7 @@ export { componentOnReady } from './utils/helpers';
|
|
|
13
13
|
export { isPlatform, getPlatforms } from './utils/platform';
|
|
14
14
|
export { IonicSafeString } from './utils/sanitization';
|
|
15
15
|
export { getMode, setupConfig } from './utils/config';
|
|
16
|
+
export { openURL } from './utils/theme';
|
|
16
17
|
export { LIFECYCLE_WILL_ENTER, LIFECYCLE_DID_ENTER, LIFECYCLE_WILL_LEAVE, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_UNLOAD, } from './components/nav/constants';
|
|
17
18
|
export { menuController } from './utils/menu-controller';
|
|
18
19
|
export { alertController, actionSheetController, modalController, loadingController, pickerController, popoverController, toastController, } from './utils/overlays';
|
|
@@ -75,6 +75,7 @@ const HapticEngine = {
|
|
|
75
75
|
* if the browser does not support the Vibrate API.
|
|
76
76
|
*/
|
|
77
77
|
if ((capacitor === null || capacitor === void 0 ? void 0 : capacitor.getPlatform()) === 'web') {
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
|
|
78
79
|
return typeof navigator !== 'undefined' && navigator.vibrate !== undefined;
|
|
79
80
|
}
|
|
80
81
|
return true;
|
|
@@ -68,6 +68,7 @@ export const setOverlayId = (el) => {
|
|
|
68
68
|
return el.id;
|
|
69
69
|
};
|
|
70
70
|
export const createOverlay = (tagName, opts) => {
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
|
|
71
72
|
if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined') {
|
|
72
73
|
return window.customElements.whenDefined(tagName).then(() => {
|
|
73
74
|
const element = document.createElement(tagName);
|
|
@@ -202,6 +202,7 @@ export const iosTransitionAnimation = (navEl, opts) => {
|
|
|
202
202
|
.easing(opts.easing || EASING)
|
|
203
203
|
.fill('both')
|
|
204
204
|
.beforeRemoveClass('ion-page-invisible');
|
|
205
|
+
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
|
|
205
206
|
if (leavingEl && navEl !== null && navEl !== undefined) {
|
|
206
207
|
const navDecorAnimation = createAnimation();
|
|
207
208
|
navDecorAnimation.addElement(navEl);
|
package/dist/docs.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"timestamp": "2023-
|
|
2
|
+
"timestamp": "2023-11-08T19:31:44",
|
|
3
3
|
"compiler": {
|
|
4
4
|
"name": "@stencil/core",
|
|
5
5
|
"version": "4.4.0",
|
|
@@ -7102,11 +7102,17 @@
|
|
|
7102
7102
|
},
|
|
7103
7103
|
{
|
|
7104
7104
|
"name": "hourCycle",
|
|
7105
|
-
"type": "\"h12\" | \"h23\" | undefined",
|
|
7105
|
+
"type": "\"h11\" | \"h12\" | \"h23\" | \"h24\" | undefined",
|
|
7106
7106
|
"complexType": {
|
|
7107
|
-
"original": "
|
|
7108
|
-
"resolved": "\"h12\" | \"h23\" | undefined",
|
|
7109
|
-
"references": {
|
|
7107
|
+
"original": "DatetimeHourCycle",
|
|
7108
|
+
"resolved": "\"h11\" | \"h12\" | \"h23\" | \"h24\" | undefined",
|
|
7109
|
+
"references": {
|
|
7110
|
+
"DatetimeHourCycle": {
|
|
7111
|
+
"location": "import",
|
|
7112
|
+
"path": "./datetime-interface",
|
|
7113
|
+
"id": "src/components/datetime/datetime-interface.ts::DatetimeHourCycle"
|
|
7114
|
+
}
|
|
7115
|
+
}
|
|
7110
7116
|
},
|
|
7111
7117
|
"mutable": false,
|
|
7112
7118
|
"attr": "hour-cycle",
|
|
@@ -7114,6 +7120,10 @@
|
|
|
7114
7120
|
"docs": "The hour cycle of the `ion-datetime`. If no value is set, this is\nspecified by the current locale.",
|
|
7115
7121
|
"docsTags": [],
|
|
7116
7122
|
"values": [
|
|
7123
|
+
{
|
|
7124
|
+
"value": "h11",
|
|
7125
|
+
"type": "string"
|
|
7126
|
+
},
|
|
7117
7127
|
{
|
|
7118
7128
|
"value": "h12",
|
|
7119
7129
|
"type": "string"
|
|
@@ -7122,6 +7132,10 @@
|
|
|
7122
7132
|
"value": "h23",
|
|
7123
7133
|
"type": "string"
|
|
7124
7134
|
},
|
|
7135
|
+
{
|
|
7136
|
+
"value": "h24",
|
|
7137
|
+
"type": "string"
|
|
7138
|
+
},
|
|
7125
7139
|
{
|
|
7126
7140
|
"type": "undefined"
|
|
7127
7141
|
}
|
|
@@ -27719,7 +27733,7 @@
|
|
|
27719
27733
|
"mutable": false,
|
|
27720
27734
|
"attr": "position",
|
|
27721
27735
|
"reflectToAttr": false,
|
|
27722
|
-
"docs": "The position of the toast on the screen.",
|
|
27736
|
+
"docs": "The starting position of the toast on the screen. Can be tweaked further\nusing the `positionAnchor` property.",
|
|
27723
27737
|
"docsTags": [],
|
|
27724
27738
|
"default": "'bottom'",
|
|
27725
27739
|
"values": [
|
|
@@ -27739,6 +27753,38 @@
|
|
|
27739
27753
|
"optional": false,
|
|
27740
27754
|
"required": false
|
|
27741
27755
|
},
|
|
27756
|
+
{
|
|
27757
|
+
"name": "positionAnchor",
|
|
27758
|
+
"type": "HTMLElement | string | undefined",
|
|
27759
|
+
"complexType": {
|
|
27760
|
+
"original": "HTMLElement | string",
|
|
27761
|
+
"resolved": "HTMLElement | string | undefined",
|
|
27762
|
+
"references": {
|
|
27763
|
+
"HTMLElement": {
|
|
27764
|
+
"location": "global",
|
|
27765
|
+
"id": "global::HTMLElement"
|
|
27766
|
+
}
|
|
27767
|
+
}
|
|
27768
|
+
},
|
|
27769
|
+
"mutable": false,
|
|
27770
|
+
"attr": "position-anchor",
|
|
27771
|
+
"reflectToAttr": false,
|
|
27772
|
+
"docs": "The element to anchor the toast's position to. Can be set as a direct reference\nor the ID of the element. With `position=\"bottom\"`, the toast will sit above the\nchosen element. With `position=\"top\"`, the toast will sit below the chosen element.\nWith `position=\"middle\"`, the value of `positionAnchor` is ignored.",
|
|
27773
|
+
"docsTags": [],
|
|
27774
|
+
"values": [
|
|
27775
|
+
{
|
|
27776
|
+
"type": "HTMLElement"
|
|
27777
|
+
},
|
|
27778
|
+
{
|
|
27779
|
+
"type": "string"
|
|
27780
|
+
},
|
|
27781
|
+
{
|
|
27782
|
+
"type": "undefined"
|
|
27783
|
+
}
|
|
27784
|
+
],
|
|
27785
|
+
"optional": true,
|
|
27786
|
+
"required": false
|
|
27787
|
+
},
|
|
27742
27788
|
{
|
|
27743
27789
|
"name": "translucent",
|
|
27744
27790
|
"type": "boolean",
|
|
@@ -27821,8 +27867,9 @@
|
|
|
27821
27867
|
"id": "global::Promise"
|
|
27822
27868
|
},
|
|
27823
27869
|
"ToastDismissOptions": {
|
|
27824
|
-
"location": "
|
|
27825
|
-
"
|
|
27870
|
+
"location": "import",
|
|
27871
|
+
"path": "./toast-interface",
|
|
27872
|
+
"id": "src/components/toast/toast-interface.ts::ToastDismissOptions"
|
|
27826
27873
|
}
|
|
27827
27874
|
},
|
|
27828
27875
|
"return": "Promise<boolean>"
|
|
@@ -27918,8 +27965,9 @@
|
|
|
27918
27965
|
"id": "global::Promise"
|
|
27919
27966
|
},
|
|
27920
27967
|
"ToastPresentOptions": {
|
|
27921
|
-
"location": "
|
|
27922
|
-
"
|
|
27968
|
+
"location": "import",
|
|
27969
|
+
"path": "./toast-interface",
|
|
27970
|
+
"id": "src/components/toast/toast-interface.ts::ToastPresentOptions"
|
|
27923
27971
|
}
|
|
27924
27972
|
},
|
|
27925
27973
|
"return": "Promise<void>"
|
|
@@ -28995,6 +29043,11 @@
|
|
|
28995
29043
|
"docstring": "",
|
|
28996
29044
|
"path": "src/components/datetime/datetime-interface.ts"
|
|
28997
29045
|
},
|
|
29046
|
+
"src/components/datetime/datetime-interface.ts::DatetimeHourCycle": {
|
|
29047
|
+
"declaration": "export type DatetimeHourCycle = 'h11' | 'h12' | 'h23' | 'h24';",
|
|
29048
|
+
"docstring": "",
|
|
29049
|
+
"path": "src/components/datetime/datetime-interface.ts"
|
|
29050
|
+
},
|
|
28998
29051
|
"src/components/datetime/datetime-interface.ts::DatetimeChangeEventDetail": {
|
|
28999
29052
|
"declaration": "export interface DatetimeChangeEventDetail {\n value?: string | string[] | null;\n}",
|
|
29000
29053
|
"docstring": "",
|
|
@@ -29290,6 +29343,16 @@
|
|
|
29290
29343
|
"docstring": "",
|
|
29291
29344
|
"path": "src/components/toast/toast-interface.ts"
|
|
29292
29345
|
},
|
|
29346
|
+
"src/components/toast/toast-interface.ts::ToastPresentOptions": {
|
|
29347
|
+
"declaration": "export type ToastPresentOptions = ToastPositionAlias & ToastAnimationPosition;",
|
|
29348
|
+
"docstring": "",
|
|
29349
|
+
"path": "src/components/toast/toast-interface.ts"
|
|
29350
|
+
},
|
|
29351
|
+
"src/components/toast/toast-interface.ts::ToastDismissOptions": {
|
|
29352
|
+
"declaration": "export type ToastDismissOptions = ToastPositionAlias & ToastAnimationPosition;",
|
|
29353
|
+
"docstring": "",
|
|
29354
|
+
"path": "src/components/toast/toast-interface.ts"
|
|
29355
|
+
},
|
|
29293
29356
|
"src/components/toggle/toggle-interface.ts::ToggleChangeEventDetail": {
|
|
29294
29357
|
"declaration": "export interface ToggleChangeEventDetail<T = any> {\n value: T;\n checked: boolean;\n}",
|
|
29295
29358
|
"docstring": "",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
4
|
import { w as writeTask } from './index-cb894020.js';
|
|
5
|
-
import { h as hapticSelectionEnd, a as hapticSelectionStart, b as hapticSelectionChanged } from './haptic-
|
|
5
|
+
import { h as hapticSelectionEnd, a as hapticSelectionStart, b as hapticSelectionChanged } from './haptic-1243b917.js';
|
|
6
6
|
import { createGesture } from './index-ff313b19.js';
|
|
7
7
|
|
|
8
8
|
const createButtonActiveGesture = (el, isButton) => {
|