@ionic/core 7.3.3-dev.11693454416.1cb6a7ec → 7.3.3-dev.11693592322.138d91e6
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/action-sheet.js +8 -16
- package/components/alert.js +8 -16
- package/components/framework-delegate.js +21 -2
- package/components/ion-loading.js +8 -16
- package/components/ion-modal.js +30 -29
- package/components/ion-nav-link.js +1 -7
- package/components/ion-picker.js +8 -16
- package/components/ion-router-outlet.js +1 -0
- package/components/ion-textarea.js +3 -3
- package/components/ion-toast.js +8 -16
- package/components/lock-controller.js +38 -0
- package/components/popover.js +15 -29
- package/dist/cjs/{framework-delegate-e8174951.js → framework-delegate-c0873a6f.js} +21 -2
- package/dist/cjs/index.cjs.js +2 -2
- package/dist/cjs/ion-action-sheet.cjs.entry.js +10 -18
- package/dist/cjs/ion-alert.cjs.entry.js +10 -18
- package/dist/cjs/ion-app_8.cjs.entry.js +2 -1
- package/dist/cjs/ion-datetime_3.cjs.entry.js +10 -18
- package/dist/cjs/ion-loading.cjs.entry.js +10 -18
- package/dist/cjs/ion-menu_3.cjs.entry.js +2 -2
- package/dist/cjs/ion-modal.cjs.entry.js +32 -31
- package/dist/cjs/ion-nav_2.cjs.entry.js +2 -8
- package/dist/cjs/ion-popover.cjs.entry.js +17 -31
- package/dist/cjs/ion-select_3.cjs.entry.js +2 -2
- package/dist/cjs/ion-tab_2.cjs.entry.js +1 -1
- package/dist/cjs/ion-textarea.cjs.entry.js +2 -2
- package/dist/cjs/ion-toast.cjs.entry.js +10 -18
- package/dist/cjs/ionic.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/lock-controller-4ae2eb59.js +40 -0
- package/dist/cjs/{overlays-0ea06fcb.js → overlays-5c1706ed.js} +1 -1
- package/dist/collection/components/action-sheet/action-sheet.js +8 -16
- package/dist/collection/components/alert/alert.js +8 -16
- package/dist/collection/components/datetime/test/presentation/datetime.e2e.js +48 -17
- package/dist/collection/components/loading/loading.js +8 -16
- package/dist/collection/components/modal/modal.js +30 -29
- package/dist/collection/components/nav-link/nav-link.js +1 -7
- package/dist/collection/components/picker/picker.js +8 -16
- package/dist/collection/components/popover/popover.js +15 -29
- package/dist/collection/components/popover/test/async/popover.e2e.js +42 -0
- package/dist/collection/components/progress-bar/test/buffer/progress-bar.e2e.js +20 -0
- package/dist/collection/components/progress-bar/test/determinate/progress-bar.e2e.js +20 -0
- package/dist/collection/components/radio/test/item/radio.e2e.js +1 -1
- package/dist/collection/components/router-outlet/router-outlet.js +1 -0
- package/dist/collection/components/textarea/test/bottom-content/textarea.e2e.js +6 -6
- package/dist/collection/components/textarea/test/card/textarea.e2e.js +1 -1
- package/dist/collection/components/textarea/test/color/textarea.e2e.js +15 -15
- package/dist/collection/components/textarea/test/cols/textarea.e2e.js +37 -0
- package/dist/collection/components/textarea/test/fill/textarea.e2e.js +10 -10
- package/dist/collection/components/textarea/test/highlight/textarea.e2e.js +9 -9
- package/dist/collection/components/textarea/test/item/textarea.e2e.js +2 -2
- package/dist/collection/components/textarea/test/label-placement/textarea.e2e.js +21 -21
- package/dist/collection/components/textarea/test/legacy/autogrow/textarea.e2e.js +5 -5
- package/dist/collection/components/textarea/test/states/textarea.e2e.js +2 -2
- package/dist/collection/components/textarea/textarea.ios.css +16 -0
- package/dist/collection/components/textarea/textarea.js +1 -1
- package/dist/collection/components/textarea/textarea.md.css +16 -0
- package/dist/collection/components/toast/toast.js +8 -16
- package/dist/collection/utils/framework-delegate.js +21 -2
- package/dist/collection/utils/lock-controller.js +36 -0
- package/dist/docs.json +2 -2
- package/dist/esm/{framework-delegate-2b76c681.js → framework-delegate-aa433dea.js} +21 -2
- package/dist/esm/index.js +2 -2
- package/dist/esm/ion-action-sheet.entry.js +10 -18
- package/dist/esm/ion-alert.entry.js +10 -18
- package/dist/esm/ion-app_8.entry.js +2 -1
- package/dist/esm/ion-datetime_3.entry.js +10 -18
- package/dist/esm/ion-loading.entry.js +10 -18
- package/dist/esm/ion-menu_3.entry.js +2 -2
- package/dist/esm/ion-modal.entry.js +32 -31
- package/dist/esm/ion-nav_2.entry.js +2 -8
- package/dist/esm/ion-popover.entry.js +17 -31
- package/dist/esm/ion-select_3.entry.js +2 -2
- package/dist/esm/ion-tab_2.entry.js +1 -1
- package/dist/esm/ion-textarea.entry.js +2 -2
- package/dist/esm/ion-toast.entry.js +10 -18
- package/dist/esm/ionic.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/lock-controller-e8c6c051.js +38 -0
- package/dist/esm/{overlays-c3387ec0.js → overlays-e1dadfe6.js} +1 -1
- package/dist/esm-es5/framework-delegate-aa433dea.js +4 -0
- 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-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-popover.entry.js +1 -1
- package/dist/esm-es5/ion-select_3.entry.js +1 -1
- package/dist/esm-es5/ion-tab_2.entry.js +1 -1
- package/dist/esm-es5/ion-textarea.entry.js +1 -1
- package/dist/esm-es5/ion-toast.entry.js +1 -1
- package/dist/esm-es5/ionic.js +1 -1
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/lock-controller-e8c6c051.js +4 -0
- package/dist/esm-es5/{overlays-c3387ec0.js → overlays-e1dadfe6.js} +1 -1
- package/dist/ionic/index.esm.js +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/{p-958bde76.entry.js → p-091cd81e.entry.js} +1 -1
- package/dist/ionic/{p-c32e09fe.system.entry.js → p-0b68c41d.system.entry.js} +1 -1
- package/dist/ionic/p-0cc2bf5a.system.entry.js +4 -0
- package/dist/ionic/p-208f640c.entry.js +4 -0
- package/dist/ionic/p-2539e967.system.entry.js +4 -0
- package/dist/ionic/{p-74bd26b8.system.entry.js → p-28f5715a.system.entry.js} +1 -1
- package/dist/ionic/p-38dd9aec.entry.js +4 -0
- package/dist/ionic/{p-8074bdd7.system.entry.js → p-45ee211b.system.entry.js} +1 -1
- package/dist/ionic/p-48144921.entry.js +4 -0
- package/dist/ionic/p-5009cb46.entry.js +4 -0
- package/dist/ionic/p-53b2a46f.js +4 -0
- package/dist/ionic/{p-5ef91692.js → p-582dc7c1.js} +1 -1
- package/dist/ionic/{p-c0d1e5a1.entry.js → p-5c17f888.entry.js} +1 -1
- package/dist/ionic/{p-8d9475b5.system.js → p-613d4042.system.js} +1 -1
- package/dist/ionic/p-653f2fc6.entry.js +4 -0
- package/dist/ionic/p-721933ff.system.js +1 -1
- package/dist/ionic/p-772f6c84.system.js +4 -0
- package/dist/ionic/p-87383d00.system.entry.js +4 -0
- package/dist/ionic/{p-db46fc66.system.js → p-8843b046.system.js} +1 -1
- package/dist/ionic/p-93e47822.entry.js +4 -0
- package/dist/ionic/{p-0e6ca480.entry.js → p-98ebc376.entry.js} +1 -1
- package/dist/ionic/p-9a074ed8.system.entry.js +4 -0
- package/dist/ionic/p-af0bc751.system.entry.js +4 -0
- package/dist/ionic/p-b0e9e0b8.system.entry.js +4 -0
- package/dist/ionic/p-b287ab05.js +4 -0
- package/dist/ionic/{p-81b46714.system.js → p-b32742f3.system.js} +1 -1
- package/dist/ionic/p-b3394798.system.entry.js +4 -0
- package/dist/ionic/p-bbae0ac3.system.entry.js +4 -0
- package/dist/ionic/{p-20087c90.entry.js → p-c759a704.entry.js} +1 -1
- package/dist/ionic/{p-6b9bf14c.system.entry.js → p-d1d3b740.system.entry.js} +1 -1
- package/dist/ionic/{p-8fa43732.system.entry.js → p-d693e765.system.entry.js} +1 -1
- package/dist/ionic/p-dc5942b1.entry.js +4 -0
- package/dist/ionic/{p-5c96dc4e.entry.js → p-f7faa32d.entry.js} +1 -1
- package/dist/ionic/p-fabb7294.entry.js +4 -0
- package/dist/types/components/action-sheet/action-sheet.d.ts +1 -1
- package/dist/types/components/alert/alert.d.ts +1 -1
- package/dist/types/components/loading/loading.d.ts +1 -1
- package/dist/types/components/modal/modal.d.ts +1 -1
- package/dist/types/components/picker/picker.d.ts +1 -1
- package/dist/types/components/popover/popover.d.ts +1 -1
- package/dist/types/components/toast/toast.d.ts +1 -1
- package/dist/types/utils/lock-controller.d.ts +10 -0
- package/hydrate/index.js +139 -151
- package/package.json +1 -1
- package/dist/esm-es5/framework-delegate-2b76c681.js +0 -4
- package/dist/ionic/p-06f1f560.system.entry.js +0 -4
- package/dist/ionic/p-2936ec7f.system.entry.js +0 -4
- package/dist/ionic/p-29b3e70a.entry.js +0 -4
- package/dist/ionic/p-2bc49e5d.system.entry.js +0 -4
- package/dist/ionic/p-2da3e015.system.entry.js +0 -4
- package/dist/ionic/p-423d5a4d.entry.js +0 -4
- package/dist/ionic/p-564aaba3.entry.js +0 -4
- package/dist/ionic/p-61769039.entry.js +0 -4
- package/dist/ionic/p-74723f41.entry.js +0 -4
- package/dist/ionic/p-7d93084b.entry.js +0 -4
- package/dist/ionic/p-9b3c3564.entry.js +0 -4
- package/dist/ionic/p-b34c1ae1.js +0 -4
- package/dist/ionic/p-c328936a.system.entry.js +0 -4
- package/dist/ionic/p-ccea9adc.system.entry.js +0 -4
- package/dist/ionic/p-d5db0834.system.entry.js +0 -4
- package/dist/ionic/p-d8538837.entry.js +0 -4
- package/dist/ionic/p-dd0b6889.system.entry.js +0 -4
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { Host, h } from "@stencil/core";
|
|
5
5
|
import { raf } from "../../utils/helpers";
|
|
6
|
+
import { createLockController } from "../../utils/lock-controller";
|
|
6
7
|
import { createDelegateController, createTriggerController, BACKDROP, dismiss, eventMethod, isCancel, prepareOverlay, present, safeCall, setOverlayId, } from "../../utils/overlays";
|
|
7
8
|
import { getClassMap } from "../../utils/theme";
|
|
8
9
|
import { getIonMode } from "../../global/ionic-global";
|
|
@@ -15,6 +16,7 @@ import { iosLeaveAnimation } from "./animations/ios.leave";
|
|
|
15
16
|
export class Picker {
|
|
16
17
|
constructor() {
|
|
17
18
|
this.delegateController = createDelegateController(this);
|
|
19
|
+
this.lockController = createLockController();
|
|
18
20
|
this.triggerController = createTriggerController();
|
|
19
21
|
this.onBackdropTap = () => {
|
|
20
22
|
this.dismiss(undefined, BACKDROP);
|
|
@@ -81,24 +83,13 @@ export class Picker {
|
|
|
81
83
|
* Present the picker overlay after it has been created.
|
|
82
84
|
*/
|
|
83
85
|
async present() {
|
|
84
|
-
|
|
85
|
-
* When using an inline picker
|
|
86
|
-
* and dismissing an picker it is possible to
|
|
87
|
-
* quickly present the picker while it is
|
|
88
|
-
* dismissing. We need to await any current
|
|
89
|
-
* transition to allow the dismiss to finish
|
|
90
|
-
* before presenting again.
|
|
91
|
-
*/
|
|
92
|
-
if (this.currentTransition !== undefined) {
|
|
93
|
-
await this.currentTransition;
|
|
94
|
-
}
|
|
86
|
+
const unlock = await this.lockController.lock();
|
|
95
87
|
await this.delegateController.attachViewToDom();
|
|
96
|
-
|
|
97
|
-
await this.currentTransition;
|
|
98
|
-
this.currentTransition = undefined;
|
|
88
|
+
await present(this, 'pickerEnter', iosEnterAnimation, iosEnterAnimation, undefined);
|
|
99
89
|
if (this.duration > 0) {
|
|
100
90
|
this.durationTimeout = setTimeout(() => this.dismiss(), this.duration);
|
|
101
91
|
}
|
|
92
|
+
unlock();
|
|
102
93
|
}
|
|
103
94
|
/**
|
|
104
95
|
* Dismiss the picker overlay after it has been presented.
|
|
@@ -110,14 +101,15 @@ export class Picker {
|
|
|
110
101
|
* Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
|
|
111
102
|
*/
|
|
112
103
|
async dismiss(data, role) {
|
|
104
|
+
const unlock = await this.lockController.lock();
|
|
113
105
|
if (this.durationTimeout) {
|
|
114
106
|
clearTimeout(this.durationTimeout);
|
|
115
107
|
}
|
|
116
|
-
|
|
117
|
-
const dismissed = await this.currentTransition;
|
|
108
|
+
const dismissed = await dismiss(this, data, role, 'pickerLeave', iosLeaveAnimation, iosLeaveAnimation);
|
|
118
109
|
if (dismissed) {
|
|
119
110
|
this.delegateController.removeViewFromDom();
|
|
120
111
|
}
|
|
112
|
+
unlock();
|
|
121
113
|
return dismissed;
|
|
122
114
|
}
|
|
123
115
|
/**
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { Host, h } from "@stencil/core";
|
|
5
5
|
import { CoreDelegate, attachComponent, detachComponent } from "../../utils/framework-delegate";
|
|
6
6
|
import { addEventListener, raf, hasLazyBuild } from "../../utils/helpers";
|
|
7
|
+
import { createLockController } from "../../utils/lock-controller";
|
|
7
8
|
import { printIonWarning } from "../../utils/logging/index";
|
|
8
9
|
import { BACKDROP, dismiss, eventMethod, focusFirstDescendant, prepareOverlay, present, setOverlayId, } from "../../utils/overlays";
|
|
9
10
|
import { isPlatform } from "../../utils/platform";
|
|
@@ -29,6 +30,7 @@ export class Popover {
|
|
|
29
30
|
constructor() {
|
|
30
31
|
this.parentPopover = null;
|
|
31
32
|
this.coreDelegate = CoreDelegate();
|
|
33
|
+
this.lockController = createLockController();
|
|
32
34
|
this.inline = false;
|
|
33
35
|
this.focusDescendantOnPresent = false;
|
|
34
36
|
this.onBackdropTap = () => {
|
|
@@ -202,28 +204,24 @@ export class Popover {
|
|
|
202
204
|
* was dispatched.
|
|
203
205
|
*/
|
|
204
206
|
async present(event) {
|
|
207
|
+
const unlock = await this.lockController.lock();
|
|
205
208
|
if (this.presented) {
|
|
209
|
+
unlock();
|
|
206
210
|
return;
|
|
207
211
|
}
|
|
208
|
-
/**
|
|
209
|
-
* When using an inline popover
|
|
210
|
-
* and dismissing a popover it is possible to
|
|
211
|
-
* quickly present the popover while it is
|
|
212
|
-
* dismissing. We need to await any current
|
|
213
|
-
* transition to allow the dismiss to finish
|
|
214
|
-
* before presenting again.
|
|
215
|
-
*/
|
|
216
|
-
if (this.currentTransition !== undefined) {
|
|
217
|
-
await this.currentTransition;
|
|
218
|
-
}
|
|
219
212
|
const { el } = this;
|
|
220
213
|
const { inline, delegate } = this.getDelegate(true);
|
|
214
|
+
/**
|
|
215
|
+
* Emit ionMount so JS Frameworks have an opportunity
|
|
216
|
+
* to add the child component to the DOM. The child
|
|
217
|
+
* component will be assigned to this.usersElement below.
|
|
218
|
+
*/
|
|
219
|
+
this.ionMount.emit();
|
|
221
220
|
this.usersElement = await attachComponent(delegate, el, this.component, ['popover-viewport'], this.componentProps, inline);
|
|
222
221
|
if (!this.keyboardEvents) {
|
|
223
222
|
this.configureKeyboardInteraction();
|
|
224
223
|
}
|
|
225
224
|
this.configureDismissInteraction();
|
|
226
|
-
this.ionMount.emit();
|
|
227
225
|
/**
|
|
228
226
|
* When using the lazy loaded build of Stencil, we need to wait
|
|
229
227
|
* for every Stencil component instance to be ready before presenting
|
|
@@ -246,7 +244,7 @@ export class Popover {
|
|
|
246
244
|
else if (!this.keepContentsMounted) {
|
|
247
245
|
await waitForMount();
|
|
248
246
|
}
|
|
249
|
-
|
|
247
|
+
await present(this, 'popoverEnter', iosEnterAnimation, mdEnterAnimation, {
|
|
250
248
|
event: event || this.event,
|
|
251
249
|
size: this.size,
|
|
252
250
|
trigger: this.triggerEl,
|
|
@@ -254,8 +252,6 @@ export class Popover {
|
|
|
254
252
|
side: this.side,
|
|
255
253
|
align: this.alignment,
|
|
256
254
|
});
|
|
257
|
-
await this.currentTransition;
|
|
258
|
-
this.currentTransition = undefined;
|
|
259
255
|
/**
|
|
260
256
|
* If popover is nested and was
|
|
261
257
|
* presented using the "Right" arrow key,
|
|
@@ -265,6 +261,7 @@ export class Popover {
|
|
|
265
261
|
if (this.focusDescendantOnPresent) {
|
|
266
262
|
focusFirstDescendant(this.el, this.el);
|
|
267
263
|
}
|
|
264
|
+
unlock();
|
|
268
265
|
}
|
|
269
266
|
/**
|
|
270
267
|
* Dismiss the popover overlay after it has been presented.
|
|
@@ -275,23 +272,12 @@ export class Popover {
|
|
|
275
272
|
* a parent popover if this popover is nested. Defaults to `true`.
|
|
276
273
|
*/
|
|
277
274
|
async dismiss(data, role, dismissParentPopover = true) {
|
|
278
|
-
|
|
279
|
-
* When using an inline popover
|
|
280
|
-
* and presenting a popover it is possible to
|
|
281
|
-
* quickly dismiss the popover while it is
|
|
282
|
-
* presenting. We need to await any current
|
|
283
|
-
* transition to allow the present to finish
|
|
284
|
-
* before dismissing again.
|
|
285
|
-
*/
|
|
286
|
-
if (this.currentTransition !== undefined) {
|
|
287
|
-
await this.currentTransition;
|
|
288
|
-
}
|
|
275
|
+
const unlock = await this.lockController.lock();
|
|
289
276
|
const { destroyKeyboardInteraction, destroyDismissInteraction } = this;
|
|
290
277
|
if (dismissParentPopover && this.parentPopover) {
|
|
291
278
|
this.parentPopover.dismiss(data, role, dismissParentPopover);
|
|
292
279
|
}
|
|
293
|
-
|
|
294
|
-
const shouldDismiss = await this.currentTransition;
|
|
280
|
+
const shouldDismiss = await dismiss(this, data, role, 'popoverLeave', iosLeaveAnimation, mdLeaveAnimation, this.event);
|
|
295
281
|
if (shouldDismiss) {
|
|
296
282
|
if (destroyKeyboardInteraction) {
|
|
297
283
|
destroyKeyboardInteraction();
|
|
@@ -309,7 +295,7 @@ export class Popover {
|
|
|
309
295
|
const { delegate } = this.getDelegate();
|
|
310
296
|
await detachComponent(delegate, this.usersElement);
|
|
311
297
|
}
|
|
312
|
-
|
|
298
|
+
unlock();
|
|
313
299
|
return shouldDismiss;
|
|
314
300
|
}
|
|
315
301
|
/**
|
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
/**
|
|
7
|
+
* This behavior does not vary across modes/directions
|
|
8
|
+
*/
|
|
9
|
+
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
10
|
+
test.describe(title('popover: alignment with async component'), async () => {
|
|
11
|
+
test('should align popover centered with button when component is added async', async ({ page }) => {
|
|
12
|
+
await page.goto('/src/components/popover/test/async', config);
|
|
13
|
+
const ionPopoverDidPresent = await page.spyOnEvent('ionPopoverDidPresent');
|
|
14
|
+
const button = page.locator('#button');
|
|
15
|
+
await button.click();
|
|
16
|
+
await ionPopoverDidPresent.next();
|
|
17
|
+
await expect(page).toHaveScreenshot(screenshot(`popover-async`));
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Framework delegate should fall back to returning the host
|
|
21
|
+
* component when no child content is passed otherwise
|
|
22
|
+
* the overlay will get stuck when trying to re-present.
|
|
23
|
+
*/
|
|
24
|
+
test('should open popover even if nothing was passed', async ({ page }) => {
|
|
25
|
+
await page.setContent(`
|
|
26
|
+
<ion-popover></ion-popover>
|
|
27
|
+
`, config);
|
|
28
|
+
const popover = page.locator('ion-popover');
|
|
29
|
+
const ionPopoverDidPresent = await page.spyOnEvent('ionPopoverDidPresent');
|
|
30
|
+
const ionPopoverDidDismiss = await page.spyOnEvent('ionPopoverDidDismiss');
|
|
31
|
+
await popover.evaluate((el) => el.present());
|
|
32
|
+
await ionPopoverDidPresent.next();
|
|
33
|
+
await expect(popover).toBeVisible();
|
|
34
|
+
await popover.evaluate((el) => el.dismiss());
|
|
35
|
+
await ionPopoverDidDismiss.next();
|
|
36
|
+
await expect(popover).toBeHidden();
|
|
37
|
+
await popover.evaluate((el) => el.present());
|
|
38
|
+
await ionPopoverDidPresent.next();
|
|
39
|
+
await expect(popover).toBeVisible();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
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({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
7
|
+
test.describe(title('progress-bar: buffer'), () => {
|
|
8
|
+
test.describe('with a dynamic progress value', () => {
|
|
9
|
+
test('should not have visual regressions', async ({ page }) => {
|
|
10
|
+
await page.setContent(`
|
|
11
|
+
<ion-progress-bar value="0.20" buffer="0.4"></ion-progress-bar>
|
|
12
|
+
`, config);
|
|
13
|
+
await page.setIonViewport();
|
|
14
|
+
const progressBar = await page.locator('ion-progress-bar');
|
|
15
|
+
await progressBar.evaluate((node) => (node.value = 0.8));
|
|
16
|
+
await expect(progressBar).toHaveScreenshot(screenshot(`progress-bar-buffer-dynamic-value`));
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
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({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
7
|
+
test.describe(title('progress-bar: determinate'), () => {
|
|
8
|
+
test.describe('with a dynamic progress value', () => {
|
|
9
|
+
test('should not have visual regressions', async ({ page }) => {
|
|
10
|
+
await page.setContent(`
|
|
11
|
+
<ion-progress-bar value="0.20"></ion-progress-bar>
|
|
12
|
+
`, config);
|
|
13
|
+
await page.setIonViewport();
|
|
14
|
+
const progressBar = await page.locator('ion-progress-bar');
|
|
15
|
+
await progressBar.evaluate((node) => (node.value = 0.8));
|
|
16
|
+
await expect(progressBar).toHaveScreenshot(screenshot(`progress-bar-buffer-dynamic-value`));
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -16,7 +16,7 @@ configs().forEach(({ title, screenshot, config }) => {
|
|
|
16
16
|
</ion-list>
|
|
17
17
|
`, config);
|
|
18
18
|
const list = page.locator('ion-list');
|
|
19
|
-
await expect(list).toHaveScreenshot(screenshot(`
|
|
19
|
+
await expect(list).toHaveScreenshot(screenshot(`radio-list`));
|
|
20
20
|
});
|
|
21
21
|
test('should render correctly in inset list', async ({ page }) => {
|
|
22
22
|
await page.setContent(`
|
|
@@ -41,7 +41,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
|
|
|
41
41
|
<ion-textarea class="ion-invalid ion-touched custom-textarea" label="my label" error-text="my error"></ion-textarea>
|
|
42
42
|
`, config);
|
|
43
43
|
const errorText = page.locator('ion-textarea .error-text');
|
|
44
|
-
expect(
|
|
44
|
+
await expect(errorText).toHaveScreenshot(screenshot(`textarea-error-custom-color`));
|
|
45
45
|
});
|
|
46
46
|
});
|
|
47
47
|
test.describe('textarea: hint text rendering', () => {
|
|
@@ -49,12 +49,12 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
|
|
|
49
49
|
test('should not have visual regressions when rendering helper text', async ({ page }) => {
|
|
50
50
|
await page.setContent(`<ion-textarea helper-text="my helper" label="my textarea"></ion-textarea>`, config);
|
|
51
51
|
const bottomEl = page.locator('ion-textarea .textarea-bottom');
|
|
52
|
-
expect(
|
|
52
|
+
await expect(bottomEl).toHaveScreenshot(screenshot(`textarea-bottom-content-helper`));
|
|
53
53
|
});
|
|
54
54
|
test('should not have visual regressions when rendering error text', async ({ page }) => {
|
|
55
55
|
await page.setContent(`<ion-textarea class="ion-invalid ion-touched" error-text="my helper" label="my textarea"></ion-textarea>`, config);
|
|
56
56
|
const bottomEl = page.locator('ion-textarea .textarea-bottom');
|
|
57
|
-
expect(
|
|
57
|
+
await expect(bottomEl).toHaveScreenshot(screenshot(`textarea-bottom-content-error`));
|
|
58
58
|
});
|
|
59
59
|
});
|
|
60
60
|
});
|
|
@@ -102,17 +102,17 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
|
|
|
102
102
|
test('should not have visual regressions when rendering counter', async ({ page }) => {
|
|
103
103
|
await page.setContent(`<ion-textarea counter="true" maxlength="20" label="my textarea"></ion-textarea>`, config);
|
|
104
104
|
const bottomEl = page.locator('ion-textarea .textarea-bottom');
|
|
105
|
-
expect(
|
|
105
|
+
await expect(bottomEl).toHaveScreenshot(screenshot(`textarea-bottom-content-counter`));
|
|
106
106
|
});
|
|
107
107
|
test('should not have visual regressions when rendering counter with helper text', async ({ page }) => {
|
|
108
108
|
await page.setContent(`<ion-textarea label="my textarea" counter="true" maxlength="20" helper-text="my helper"></ion-textarea>`, config);
|
|
109
109
|
const bottomEl = page.locator('ion-textarea .textarea-bottom');
|
|
110
|
-
expect(
|
|
110
|
+
await expect(bottomEl).toHaveScreenshot(screenshot(`textarea-bottom-content-counter-helper-text`));
|
|
111
111
|
});
|
|
112
112
|
test('should not have visual regressions when rendering counter with error text', async ({ page }) => {
|
|
113
113
|
await page.setContent(`<ion-textarea class="ion-invalid ion-touched" label="my textarea" counter="true" maxlength="20" error-text="my error"></ion-textarea>`, config);
|
|
114
114
|
const bottomEl = page.locator('ion-textarea .textarea-bottom');
|
|
115
|
-
expect(
|
|
115
|
+
await expect(bottomEl).toHaveScreenshot(screenshot(`textarea-bottom-content-counter-error-text`));
|
|
116
116
|
});
|
|
117
117
|
});
|
|
118
118
|
});
|
|
@@ -16,7 +16,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
|
|
|
16
16
|
</ion-card>
|
|
17
17
|
`, config);
|
|
18
18
|
const card = page.locator('ion-card');
|
|
19
|
-
expect(
|
|
19
|
+
await expect(card).toHaveScreenshot(screenshot(`textarea-card`));
|
|
20
20
|
});
|
|
21
21
|
});
|
|
22
22
|
});
|
|
@@ -22,35 +22,35 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
|
|
|
22
22
|
<ion-textarea class="has-focus" color="danger" label="Email" label-placement="start" value="hi@ionic.io"></ion-textarea>
|
|
23
23
|
`, config);
|
|
24
24
|
const textarea = page.locator('ion-textarea');
|
|
25
|
-
expect(
|
|
25
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-no-fill-color-start`));
|
|
26
26
|
});
|
|
27
27
|
test('should set label and highlight color on focus with end label placement', async ({ page }) => {
|
|
28
28
|
await page.setContent(`
|
|
29
29
|
<ion-textarea class="has-focus" color="danger" label="Email" label-placement="end" value="hi@ionic.io"></ion-textarea>
|
|
30
30
|
`, config);
|
|
31
31
|
const textarea = page.locator('ion-textarea');
|
|
32
|
-
expect(
|
|
32
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-no-fill-color-end`));
|
|
33
33
|
});
|
|
34
34
|
test('should set label and highlight color on focus with fixed label placement', async ({ page }) => {
|
|
35
35
|
await page.setContent(`
|
|
36
36
|
<ion-textarea class="has-focus" color="danger" label="Email" label-placement="fixed" value="hi@ionic.io"></ion-textarea>
|
|
37
37
|
`, config);
|
|
38
38
|
const textarea = page.locator('ion-textarea');
|
|
39
|
-
expect(
|
|
39
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-no-fill-color-fixed`));
|
|
40
40
|
});
|
|
41
41
|
test('should set label and highlight color on focus with floating label placement', async ({ page }) => {
|
|
42
42
|
await page.setContent(`
|
|
43
43
|
<ion-textarea class="has-focus" color="danger" label="Email" label-placement="floating" value="hi@ionic.io"></ion-textarea>
|
|
44
44
|
`, config);
|
|
45
45
|
const textarea = page.locator('ion-textarea');
|
|
46
|
-
expect(
|
|
46
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-no-fill-color-floating`));
|
|
47
47
|
});
|
|
48
48
|
test('should set label and highlight color on focus with stacked label placement', async ({ page }) => {
|
|
49
49
|
await page.setContent(`
|
|
50
50
|
<ion-textarea class="has-focus" color="danger" label="Email" label-placement="stacked" value="hi@ionic.io"></ion-textarea>
|
|
51
51
|
`, config);
|
|
52
52
|
const textarea = page.locator('ion-textarea');
|
|
53
|
-
expect(
|
|
53
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-no-fill-color-stacked`));
|
|
54
54
|
});
|
|
55
55
|
});
|
|
56
56
|
test.describe('textarea: fill solid', () => {
|
|
@@ -59,35 +59,35 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
|
|
|
59
59
|
<ion-textarea fill="solid" class="has-focus" color="danger" label="Email" label-placement="start" value="hi@ionic.io"></ion-textarea>
|
|
60
60
|
`, config);
|
|
61
61
|
const textarea = page.locator('ion-textarea');
|
|
62
|
-
expect(
|
|
62
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-solid-color-start`));
|
|
63
63
|
});
|
|
64
64
|
test('should set label and highlight color on focus with end label placement', async ({ page }) => {
|
|
65
65
|
await page.setContent(`
|
|
66
66
|
<ion-textarea fill="solid" class="has-focus" color="danger" label="Email" label-placement="end" value="hi@ionic.io"></ion-textarea>
|
|
67
67
|
`, config);
|
|
68
68
|
const textarea = page.locator('ion-textarea');
|
|
69
|
-
expect(
|
|
69
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-solid-color-end`));
|
|
70
70
|
});
|
|
71
71
|
test('should set label and highlight color on focus with fixed label placement', async ({ page }) => {
|
|
72
72
|
await page.setContent(`
|
|
73
73
|
<ion-textarea fill="solid" class="has-focus" color="danger" label="Email" label-placement="fixed" value="hi@ionic.io"></ion-textarea>
|
|
74
74
|
`, config);
|
|
75
75
|
const textarea = page.locator('ion-textarea');
|
|
76
|
-
expect(
|
|
76
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-solid-color-fixed`));
|
|
77
77
|
});
|
|
78
78
|
test('should set label and highlight color on focus with floating label placement', async ({ page }) => {
|
|
79
79
|
await page.setContent(`
|
|
80
80
|
<ion-textarea fill="solid" class="has-focus" color="danger" label="Email" label-placement="floating" value="hi@ionic.io"></ion-textarea>
|
|
81
81
|
`, config);
|
|
82
82
|
const textarea = page.locator('ion-textarea');
|
|
83
|
-
expect(
|
|
83
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-solid-color-floating`));
|
|
84
84
|
});
|
|
85
85
|
test('should set label and highlight color on focus with stacked label placement', async ({ page }) => {
|
|
86
86
|
await page.setContent(`
|
|
87
87
|
<ion-textarea fill="solid" class="has-focus" color="danger" label="Email" label-placement="stacked" value="hi@ionic.io"></ion-textarea>
|
|
88
88
|
`, config);
|
|
89
89
|
const textarea = page.locator('ion-textarea');
|
|
90
|
-
expect(
|
|
90
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-solid-color-stacked`));
|
|
91
91
|
});
|
|
92
92
|
});
|
|
93
93
|
test.describe('textarea: fill outline', () => {
|
|
@@ -96,35 +96,35 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
|
|
|
96
96
|
<ion-textarea fill="outline" class="has-focus" color="danger" label="Email" label-placement="start" value="hi@ionic.io"></ion-textarea>
|
|
97
97
|
`, config);
|
|
98
98
|
const textarea = page.locator('ion-textarea');
|
|
99
|
-
expect(
|
|
99
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-outline-color-start`));
|
|
100
100
|
});
|
|
101
101
|
test('should set label and highlight color on focus with end label placement', async ({ page }) => {
|
|
102
102
|
await page.setContent(`
|
|
103
103
|
<ion-textarea fill="outline" class="has-focus" color="danger" label="Email" label-placement="end" value="hi@ionic.io"></ion-textarea>
|
|
104
104
|
`, config);
|
|
105
105
|
const textarea = page.locator('ion-textarea');
|
|
106
|
-
expect(
|
|
106
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-outline-color-end`));
|
|
107
107
|
});
|
|
108
108
|
test('should set label and highlight color on focus with fixed label placement', async ({ page }) => {
|
|
109
109
|
await page.setContent(`
|
|
110
110
|
<ion-textarea fill="outline" class="has-focus" color="danger" label="Email" label-placement="fixed" value="hi@ionic.io"></ion-textarea>
|
|
111
111
|
`, config);
|
|
112
112
|
const textarea = page.locator('ion-textarea');
|
|
113
|
-
expect(
|
|
113
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-outline-color-fixed`));
|
|
114
114
|
});
|
|
115
115
|
test('should set label and highlight color on focus with floating label placement', async ({ page }) => {
|
|
116
116
|
await page.setContent(`
|
|
117
117
|
<ion-textarea fill="outline" class="has-focus" color="danger" label="Email" label-placement="floating" value="hi@ionic.io"></ion-textarea>
|
|
118
118
|
`, config);
|
|
119
119
|
const textarea = page.locator('ion-textarea');
|
|
120
|
-
expect(
|
|
120
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-outline-color-floating`));
|
|
121
121
|
});
|
|
122
122
|
test('should set label and highlight color on focus with stacked label placement', async ({ page }) => {
|
|
123
123
|
await page.setContent(`
|
|
124
124
|
<ion-textarea fill="outline" class="has-focus" color="danger" label="Email" label-placement="stacked" value="hi@ionic.io"></ion-textarea>
|
|
125
125
|
`, config);
|
|
126
126
|
const textarea = page.locator('ion-textarea');
|
|
127
|
-
expect(
|
|
127
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-outline-color-stacked`));
|
|
128
128
|
});
|
|
129
129
|
});
|
|
130
130
|
});
|
|
@@ -0,0 +1,37 @@
|
|
|
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({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
7
|
+
test.describe(title('textarea: cols'), () => {
|
|
8
|
+
test('should respect cols when autogrow is not set', async ({ page }) => {
|
|
9
|
+
await page.setContent(`
|
|
10
|
+
<style>
|
|
11
|
+
ion-textarea {
|
|
12
|
+
border: 1px solid red;
|
|
13
|
+
}
|
|
14
|
+
</style>
|
|
15
|
+
<div id="container" style="width: 300px; margin: 20px;">
|
|
16
|
+
<ion-textarea label="Textarea" cols="5" value="Lorem Ipsum"></ion-textarea>
|
|
17
|
+
</div>
|
|
18
|
+
`, config);
|
|
19
|
+
const container = page.locator('#container');
|
|
20
|
+
await expect(container).toHaveScreenshot(screenshot('textarea-cols'));
|
|
21
|
+
});
|
|
22
|
+
test('should ignore cols when autogrow is set', async ({ page }) => {
|
|
23
|
+
await page.setContent(`
|
|
24
|
+
<style>
|
|
25
|
+
ion-textarea {
|
|
26
|
+
border: 1px solid red;
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
29
|
+
<div id="container" style="width: 300px; margin: 20px;">
|
|
30
|
+
<ion-textarea label="Textarea" cols="5" auto-grow="true" value="Lorem Ipsum"></ion-textarea>
|
|
31
|
+
</div>
|
|
32
|
+
`, config);
|
|
33
|
+
const container = page.locator('#container');
|
|
34
|
+
await expect(container).toHaveScreenshot(screenshot('textarea-cols-autogrow'));
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -21,7 +21,7 @@ configs({ modes: ['md'] }).forEach(({ title, screenshot, config }) => {
|
|
|
21
21
|
></ion-textarea>
|
|
22
22
|
`, config);
|
|
23
23
|
const textarea = page.locator('ion-textarea');
|
|
24
|
-
expect(
|
|
24
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-fill-solid`));
|
|
25
25
|
});
|
|
26
26
|
test('should render correctly with floating label', async ({ page }) => {
|
|
27
27
|
await page.setContent(`
|
|
@@ -36,7 +36,7 @@ configs({ modes: ['md'] }).forEach(({ title, screenshot, config }) => {
|
|
|
36
36
|
></ion-textarea>
|
|
37
37
|
`, config);
|
|
38
38
|
const textarea = page.locator('ion-textarea');
|
|
39
|
-
expect(
|
|
39
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-fill-solid-label-floating`));
|
|
40
40
|
});
|
|
41
41
|
test('should not have visual regressions with shaped solid', async ({ page }) => {
|
|
42
42
|
await page.setContent(`
|
|
@@ -51,7 +51,7 @@ configs({ modes: ['md'] }).forEach(({ title, screenshot, config }) => {
|
|
|
51
51
|
></ion-textarea>
|
|
52
52
|
`, config);
|
|
53
53
|
const textarea = page.locator('ion-textarea');
|
|
54
|
-
expect(
|
|
54
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-fill-shaped-solid`));
|
|
55
55
|
});
|
|
56
56
|
test('padding and border radius should be customizable', async ({ page }) => {
|
|
57
57
|
await page.setContent(`
|
|
@@ -75,7 +75,7 @@ configs({ modes: ['md'] }).forEach(({ title, screenshot, config }) => {
|
|
|
75
75
|
></ion-textarea>
|
|
76
76
|
`, config);
|
|
77
77
|
const textarea = page.locator('ion-textarea');
|
|
78
|
-
expect(
|
|
78
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-fill-shaped-solid-custom`));
|
|
79
79
|
});
|
|
80
80
|
});
|
|
81
81
|
test.describe('textarea: fill outline', () => {
|
|
@@ -91,7 +91,7 @@ configs({ modes: ['md'] }).forEach(({ title, screenshot, config }) => {
|
|
|
91
91
|
></ion-textarea>
|
|
92
92
|
`, config);
|
|
93
93
|
const textarea = page.locator('ion-textarea');
|
|
94
|
-
expect(
|
|
94
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-fill-outline`));
|
|
95
95
|
});
|
|
96
96
|
test('should render correctly with floating label', async ({ page }) => {
|
|
97
97
|
await page.setContent(`
|
|
@@ -106,7 +106,7 @@ configs({ modes: ['md'] }).forEach(({ title, screenshot, config }) => {
|
|
|
106
106
|
></ion-textarea>
|
|
107
107
|
`, config);
|
|
108
108
|
const textarea = page.locator('ion-textarea');
|
|
109
|
-
expect(
|
|
109
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-fill-outline-label-floating`));
|
|
110
110
|
});
|
|
111
111
|
test('should not have visual regressions with shaped outline', async ({ page }) => {
|
|
112
112
|
await page.setContent(`
|
|
@@ -121,7 +121,7 @@ configs({ modes: ['md'] }).forEach(({ title, screenshot, config }) => {
|
|
|
121
121
|
></ion-textarea>
|
|
122
122
|
`, config);
|
|
123
123
|
const textarea = page.locator('ion-textarea');
|
|
124
|
-
expect(
|
|
124
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-fill-shaped-outline`));
|
|
125
125
|
});
|
|
126
126
|
test('padding and border radius should be customizable', async ({ page }) => {
|
|
127
127
|
await page.setContent(`
|
|
@@ -145,7 +145,7 @@ configs({ modes: ['md'] }).forEach(({ title, screenshot, config }) => {
|
|
|
145
145
|
></ion-textarea>
|
|
146
146
|
`, config);
|
|
147
147
|
const textarea = page.locator('ion-textarea');
|
|
148
|
-
expect(
|
|
148
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-fill-shaped-outline-custom`));
|
|
149
149
|
});
|
|
150
150
|
});
|
|
151
151
|
});
|
|
@@ -179,7 +179,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
|
|
|
179
179
|
</ion-textarea>
|
|
180
180
|
`, config);
|
|
181
181
|
const textarea = page.locator('ion-textarea');
|
|
182
|
-
expect(
|
|
182
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-fill-outline-slotted-label`));
|
|
183
183
|
});
|
|
184
184
|
test('should render the notch correctly with a slotted label after the textarea was originally hidden', async ({ page, }) => {
|
|
185
185
|
await page.setContent(`
|
|
@@ -199,7 +199,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
|
|
|
199
199
|
`, config);
|
|
200
200
|
const textarea = page.locator('ion-textarea');
|
|
201
201
|
await textarea.evaluate((el) => el.style.removeProperty('display'));
|
|
202
|
-
expect(
|
|
202
|
+
await expect(textarea).toHaveScreenshot(screenshot(`textarea-fill-outline-hidden-slotted-label`));
|
|
203
203
|
});
|
|
204
204
|
});
|
|
205
205
|
});
|