merge release-6.2.2
Release 6.2.2
4
.github/workflows/release.yml
vendored
@ -74,8 +74,8 @@ jobs:
|
||||
"path": [
|
||||
"/npm/@ionic/core@6/dist/ionic/ionic.esm.js",
|
||||
"/npm/@ionic/core@latest/dist/ionic/ionic.esm.js",
|
||||
"/npm/@ionic/core@6/css/ionic.bundle.css,
|
||||
"/npm/@ionic/core@latest/css/ionic.bundle.css
|
||||
"/npm/@ionic/core@6/css/ionic.bundle.css",
|
||||
"/npm/@ionic/core@latest/css/ionic.bundle.css"
|
||||
]}'
|
||||
|
||||
|
||||
|
15
CHANGELOG.md
@ -3,6 +3,21 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.2.2](https://github.com/ionic-team/ionic-framework/compare/v6.2.1...v6.2.2) (2022-08-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** DatetimeButton is declared on IonicModule ([#25727](https://github.com/ionic-team/ionic-framework/issues/25727)) ([76ad1d1](https://github.com/ionic-team/ionic-framework/commit/76ad1d18c81272435db1994977aa9dd5d880504a))
|
||||
* **datetime:** add correct null check when value changes ([#25716](https://github.com/ionic-team/ionic-framework/issues/25716)) ([36bea1c](https://github.com/ionic-team/ionic-framework/commit/36bea1ca2520c9eb9ee7705abb046607a52d198d)), closes [#25714](https://github.com/ionic-team/ionic-framework/issues/25714)
|
||||
* **datetime:** preferWheel respects column ordering by locale ([#25726](https://github.com/ionic-team/ionic-framework/issues/25726)) ([dee0f51](https://github.com/ionic-team/ionic-framework/commit/dee0f513ee443c0c69ea8e38a292c900e9c70221)), closes [#25722](https://github.com/ionic-team/ionic-framework/issues/25722)
|
||||
* **react:** outlet will not clear in react 18 with hot reload ([#25703](https://github.com/ionic-team/ionic-framework/issues/25703)) ([3878bf7](https://github.com/ionic-team/ionic-framework/commit/3878bf76523f2e1c26c147473fd7c07ee4d0e820)), closes [#25507](https://github.com/ionic-team/ionic-framework/issues/25507)
|
||||
* **vue:** go back to correct view with memory history ([#25732](https://github.com/ionic-team/ionic-framework/issues/25732)) ([8327889](https://github.com/ionic-team/ionic-framework/commit/832788971a7098e52812f66563cbc0a63d3e5df7)), closes [#25705](https://github.com/ionic-team/ionic-framework/issues/25705)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.2.1](https://github.com/ionic-team/ionic-framework/compare/v6.2.0...v6.2.1) (2022-08-03)
|
||||
|
||||
|
||||
|
@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.2.2](https://github.com/ionic-team/ionic/compare/v6.2.1...v6.2.2) (2022-08-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** DatetimeButton is declared on IonicModule ([#25727](https://github.com/ionic-team/ionic/issues/25727)) ([76ad1d1](https://github.com/ionic-team/ionic/commit/76ad1d18c81272435db1994977aa9dd5d880504a))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.2.1](https://github.com/ionic-team/ionic/compare/v6.2.0...v6.2.1) (2022-08-03)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
18
angular/package-lock.json
generated
@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.2.1",
|
||||
"@ionic/core": "^6.2.2",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
@ -1023,9 +1023,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.1.tgz",
|
||||
"integrity": "sha512-bWlE2ZMR7tMyqcBhncc21zZPMZfCEoyGQP2bdu/ft1uov0ozw/wfETygd07C+0DOkbU6x1OYncIvo+1bzK4alA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.2.tgz",
|
||||
"integrity": "sha512-neE+JhtQ7Kb4nGoKR3e55edHQot5BZTw+woV9+pbyCXP1jGeyFeWWPYBYYOkm05TSEkHgh0v6NkV9y31k8GTNw==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
@ -7939,9 +7939,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.1.tgz",
|
||||
"integrity": "sha512-bWlE2ZMR7tMyqcBhncc21zZPMZfCEoyGQP2bdu/ft1uov0ozw/wfETygd07C+0DOkbU6x1OYncIvo+1bzK4alA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.2.tgz",
|
||||
"integrity": "sha512-neE+JhtQ7Kb4nGoKR3e55edHQot5BZTw+woV9+pbyCXP1jGeyFeWWPYBYYOkm05TSEkHgh0v6NkV9y31k8GTNw==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"description": "Angular specific wrappers for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@ -44,7 +44,7 @@
|
||||
"validate": "npm i && npm run lint && npm run test && npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.2.1",
|
||||
"@ionic/core": "^6.2.2",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
|
@ -40,6 +40,7 @@ import {
|
||||
IonCol,
|
||||
IonContent,
|
||||
IonDatetime,
|
||||
IonDatetimeButton,
|
||||
IonFab,
|
||||
IonFabButton,
|
||||
IonFabList,
|
||||
@ -127,6 +128,7 @@ const DECLARATIONS = [
|
||||
IonCol,
|
||||
IonContent,
|
||||
IonDatetime,
|
||||
IonDatetimeButton,
|
||||
IonFab,
|
||||
IonFabButton,
|
||||
IonFabList,
|
||||
|
@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.2.2](https://github.com/ionic-team/ionic/compare/v6.2.1...v6.2.2) (2022-08-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** add correct null check when value changes ([#25716](https://github.com/ionic-team/ionic/issues/25716)) ([36bea1c](https://github.com/ionic-team/ionic/commit/36bea1ca2520c9eb9ee7705abb046607a52d198d)), closes [#25714](https://github.com/ionic-team/ionic/issues/25714)
|
||||
* **datetime:** preferWheel respects column ordering by locale ([#25726](https://github.com/ionic-team/ionic/issues/25726)) ([dee0f51](https://github.com/ionic-team/ionic/commit/dee0f513ee443c0c69ea8e38a292c900e9c70221)), closes [#25722](https://github.com/ionic-team/ionic/issues/25722)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.2.1](https://github.com/ionic-team/ionic/compare/v6.2.0...v6.2.1) (2022-08-03)
|
||||
|
||||
|
||||
|
4
core/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/core",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"description": "Base components for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
|
@ -353,7 +353,7 @@ export class Datetime implements ComponentInterface {
|
||||
this.activePartsClone = [...valueDateParts];
|
||||
} else {
|
||||
const { month, day, year, hour, minute } = valueDateParts;
|
||||
const ampm = hour ? (hour >= 12 ? 'pm' : 'am') : undefined;
|
||||
const ampm = hour != null ? (hour >= 12 ? 'pm' : 'am') : undefined;
|
||||
|
||||
this.activePartsClone = {
|
||||
...this.activeParts,
|
||||
@ -1522,7 +1522,27 @@ export class Datetime implements ComponentInterface {
|
||||
? getYearColumnData(this.todayParts, this.minParts, this.maxParts, this.parsedYearValues)
|
||||
: [];
|
||||
|
||||
return [this.renderMonthPickerColumn(months), this.renderDayPickerColumn(days), this.renderYearPickerColumn(years)];
|
||||
/**
|
||||
* Certain locales show the day before the month.
|
||||
*/
|
||||
const showMonthFirst = isMonthFirstLocale(this.locale, { month: 'numeric', day: 'numeric' });
|
||||
|
||||
let renderArray = [];
|
||||
if (showMonthFirst) {
|
||||
renderArray = [
|
||||
this.renderMonthPickerColumn(months),
|
||||
this.renderDayPickerColumn(days),
|
||||
this.renderYearPickerColumn(years),
|
||||
];
|
||||
} else {
|
||||
renderArray = [
|
||||
this.renderDayPickerColumn(days),
|
||||
this.renderMonthPickerColumn(months),
|
||||
this.renderYearPickerColumn(years),
|
||||
];
|
||||
}
|
||||
|
||||
return renderArray;
|
||||
}
|
||||
|
||||
private renderDayPickerColumn(days: PickerColumnItem[]) {
|
||||
|
@ -89,6 +89,7 @@ test.describe('datetime: prefer wheel', () => {
|
||||
expect(await yearValues.count()).toBe(3);
|
||||
expect(await dayValues.count()).toBe(5);
|
||||
});
|
||||
test.describe('datetime: date wheel localization', () => {
|
||||
test('should correctly localize the date data', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime
|
||||
@ -110,6 +111,43 @@ test.describe('datetime: prefer wheel', () => {
|
||||
expect(monthValues).toHaveText(['1月', '2月', '3月']);
|
||||
expect(dayValues).toHaveText(['1日', '2日', '3日']);
|
||||
});
|
||||
test('should render the columns according to locale - en-US', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime
|
||||
presentation="date"
|
||||
prefer-wheel="true"
|
||||
locale="en-US"
|
||||
value="2022-01-01"
|
||||
></ion-datetime>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const columns = page.locator('ion-picker-column-internal');
|
||||
|
||||
await expect(columns.nth(0)).toHaveClass(/month-column/);
|
||||
await expect(columns.nth(1)).toHaveClass(/day-column/);
|
||||
await expect(columns.nth(2)).toHaveClass(/year-column/);
|
||||
});
|
||||
test('should render the columns according to locale - en-GB', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime
|
||||
presentation="date"
|
||||
prefer-wheel="true"
|
||||
locale="en-GB"
|
||||
value="2022-01-01"
|
||||
></ion-datetime>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const columns = page.locator('ion-picker-column-internal');
|
||||
|
||||
await expect(columns.nth(0)).toHaveClass(/day-column/);
|
||||
await expect(columns.nth(1)).toHaveClass(/month-column/);
|
||||
await expect(columns.nth(2)).toHaveClass(/year-column/);
|
||||
});
|
||||
});
|
||||
});
|
||||
test.describe('datetime: date-time wheel rendering', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
|
@ -74,8 +74,19 @@ export const getNumDaysInMonth = (month: number, year: number) => {
|
||||
* others display year then month.
|
||||
* We can use Intl.DateTimeFormat to determine
|
||||
* the ordering for each locale.
|
||||
* The formatOptions param can be used to customize
|
||||
* which pieces of a date to compare against the month
|
||||
* with. For example, some locales render dd/mm/yyyy
|
||||
* while others render mm/dd/yyyy. This function can be
|
||||
* used for variations of the same "month first" check.
|
||||
*/
|
||||
export const isMonthFirstLocale = (locale: string) => {
|
||||
export const isMonthFirstLocale = (
|
||||
locale: string,
|
||||
formatOptions: Intl.DateTimeFormatOptions = {
|
||||
month: 'numeric',
|
||||
year: 'numeric',
|
||||
}
|
||||
) => {
|
||||
/**
|
||||
* By setting month and year we guarantee that only
|
||||
* month, year, and literal (slashes '/', for example)
|
||||
@ -88,7 +99,7 @@ export const isMonthFirstLocale = (locale: string) => {
|
||||
*
|
||||
* This ordering can be controlled by customizing the locale property.
|
||||
*/
|
||||
const parts = new Intl.DateTimeFormat(locale, { month: 'numeric', year: 'numeric' }).formatToParts(new Date());
|
||||
const parts = new Intl.DateTimeFormat(locale, formatOptions).formatToParts(new Date());
|
||||
|
||||
return parts[0].type === 'month';
|
||||
};
|
||||
|
@ -22,161 +22,35 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="outer-content">
|
||||
<p class="ion-text-center">
|
||||
<ion-button onClick="addRadio()">Add Radio</ion-button>
|
||||
<ion-button onClick="addChecked()">Add Checked</ion-button>
|
||||
<ion-button id="removeButton" onClick="removeRadio()">Remove Radio</ion-button>
|
||||
</p>
|
||||
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-radio-group id="dynamicDisabled" disabled name="tannen" id="group" value="biff">
|
||||
<ion-radio-group name="items" id="group" value="1">
|
||||
<ion-list-header>
|
||||
<ion-label>Luckiest Man On Earth <span id="group-value"></span></ion-label>
|
||||
<ion-label>Radio Group Header</ion-label>
|
||||
</ion-list-header>
|
||||
|
||||
<ion-item>
|
||||
<ion-label
|
||||
>Biff
|
||||
<span id="biff"></span>
|
||||
</ion-label>
|
||||
<ion-radio value="biff" slot="start"></ion-radio>
|
||||
<ion-label>Item 1</ion-label>
|
||||
<ion-radio value="1" slot="start"></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label
|
||||
>Griff
|
||||
<span id="griff"></span>
|
||||
</ion-label>
|
||||
<ion-radio value="griff" slot="start"></ion-radio>
|
||||
<ion-label>Item 2</ion-label>
|
||||
<ion-radio value="2" slot="start"></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label
|
||||
>Buford
|
||||
<span id="buford"></span>
|
||||
</ion-label>
|
||||
<ion-radio value="buford" slot="start"></ion-radio>
|
||||
<ion-label>Item 3</ion-label>
|
||||
<ion-radio value="3" slot="start"></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>George</ion-label>
|
||||
<ion-radio value="george" slot="start"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
</ion-list>
|
||||
|
||||
<ion-list>
|
||||
<ion-radio-group value="huey">
|
||||
<ion-item>
|
||||
<ion-label>Huey</ion-label>
|
||||
<ion-radio slot="start" value="huey"></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Dewey</ion-label>
|
||||
<ion-radio slot="start" value="dewey"></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Louie</ion-label>
|
||||
<ion-radio slot="start" value="louie"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
</ion-list>
|
||||
|
||||
<ion-list>
|
||||
<ion-radio-group value="huey">
|
||||
<ion-item-divider>
|
||||
<ion-label> Maintenance Drone </ion-label>
|
||||
</ion-item-divider>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Huey</ion-label>
|
||||
<ion-radio slot="start" value="huey"></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Dewey</ion-label>
|
||||
<ion-radio slot="start" value="dewey"></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Louie</ion-label>
|
||||
<ion-radio slot="start" value="louie"></ion-radio>
|
||||
<ion-label>Item 4</ion-label>
|
||||
<ion-radio value="4" slot="start"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
|
||||
<style>
|
||||
.outer-content {
|
||||
--background: #f2f2f2;
|
||||
}
|
||||
|
||||
ion-list {
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
let count = 0;
|
||||
const removeButton = document.querySelector('#removeButton');
|
||||
|
||||
const valueEl = document.querySelector('#group-value');
|
||||
const group = document.querySelector('ion-radio-group');
|
||||
|
||||
group.addEventListener('ionChange', (ev) => {
|
||||
valueEl.textContent = group.value;
|
||||
});
|
||||
|
||||
customElements
|
||||
.whenDefined('ion-radio-group')
|
||||
.then(() => group.componentOnReady && group.componentOnReady())
|
||||
.then(() => {
|
||||
valueEl.textContent = group.value;
|
||||
});
|
||||
|
||||
function addRadio() {
|
||||
const item = document.createElement('ion-item');
|
||||
|
||||
item.innerHTML = `
|
||||
<ion-label>Item ${count}</ion-label>
|
||||
<ion-radio value="item-${count}" slot="start"></ion-radio>
|
||||
`;
|
||||
group.appendChild(item);
|
||||
count++;
|
||||
|
||||
removeButton.disabled = false;
|
||||
}
|
||||
|
||||
function addChecked() {
|
||||
const item = document.createElement('ion-item');
|
||||
item.innerHTML = `
|
||||
<ion-label>Item ${count}</ion-label>
|
||||
<ion-radio value="item-${count}" slot="start"></ion-radio>
|
||||
`;
|
||||
group.appendChild(item);
|
||||
|
||||
group.value = `item-${count}`;
|
||||
count++;
|
||||
|
||||
removeButton.disabled = false;
|
||||
}
|
||||
|
||||
function removeRadio() {
|
||||
const removeEl = group.children[group.children.length - 1];
|
||||
|
||||
if (removeEl && removeEl.tagName === 'ION-ITEM') {
|
||||
removeEl.remove();
|
||||
|
||||
// No more radios to remove, disable button
|
||||
if (!group.querySelector('ion-item')) {
|
||||
removeButton.disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</ion-app>
|
||||
</body>
|
||||
</html>
|
||||
|
110
core/src/components/radio-group/test/basic/radio-group.e2e.ts
Normal file
@ -0,0 +1,110 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import type { Locator } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
import type { E2EPage } from '@utils/test/playwright';
|
||||
|
||||
test.describe('radio-group: basic', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.goto(`/src/components/radio-group/test/basic`);
|
||||
|
||||
const list = page.locator('ion-list');
|
||||
|
||||
expect(await list.screenshot()).toMatchSnapshot(`radio-group-diff-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('radio-group: interaction', () => {
|
||||
let radioFixture: RadioFixture;
|
||||
|
||||
test.beforeEach(({ page }, testInfo) => {
|
||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs RTL logic.');
|
||||
radioFixture = new RadioFixture(page);
|
||||
});
|
||||
|
||||
test('spacebar should not deselect without allowEmptySelection', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-radio-group value="one" allow-empty-selection="false">
|
||||
<ion-item>
|
||||
<ion-label>One</ion-label>
|
||||
<ion-radio id="one" value="one"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
`);
|
||||
|
||||
await radioFixture.checkRadio('keyboard');
|
||||
await radioFixture.expectChecked(true);
|
||||
});
|
||||
|
||||
test('spacebar should deselect with allowEmptySelection', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-radio-group value="one" allow-empty-selection="true">
|
||||
<ion-item>
|
||||
<ion-label>One</ion-label>
|
||||
<ion-radio id="one" value="one"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
`);
|
||||
|
||||
await radioFixture.checkRadio('keyboard');
|
||||
await radioFixture.expectChecked(false);
|
||||
});
|
||||
|
||||
test('click should not deselect without allowEmptySelection', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-radio-group value="one" allow-empty-selection="false">
|
||||
<ion-item>
|
||||
<ion-label>One</ion-label>
|
||||
<ion-radio id="one" value="one"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
`);
|
||||
|
||||
await radioFixture.checkRadio('mouse');
|
||||
await radioFixture.expectChecked(true);
|
||||
});
|
||||
|
||||
test('click should deselect with allowEmptySelection', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-radio-group value="one" allow-empty-selection="true">
|
||||
<ion-item>
|
||||
<ion-label>One</ion-label>
|
||||
<ion-radio id="one" value="one"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
`);
|
||||
|
||||
await radioFixture.checkRadio('mouse');
|
||||
await radioFixture.expectChecked(false);
|
||||
});
|
||||
});
|
||||
|
||||
class RadioFixture {
|
||||
readonly page: E2EPage;
|
||||
|
||||
private radio!: Locator;
|
||||
|
||||
constructor(page: E2EPage) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
async checkRadio(method: 'keyboard' | 'mouse', selector = 'ion-radio') {
|
||||
const { page } = this;
|
||||
const radio = (this.radio = page.locator(selector));
|
||||
|
||||
if (method === 'keyboard') {
|
||||
await radio.focus();
|
||||
await page.keyboard.press('Space');
|
||||
} else {
|
||||
await radio.click();
|
||||
}
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
return radio;
|
||||
}
|
||||
|
||||
async expectChecked(state: boolean) {
|
||||
const { radio } = this;
|
||||
await expect(radio.locator('input')).toHaveJSProperty('checked', state);
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 28 KiB |
34
core/src/components/radio-group/test/form/radio-group.e2e.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('radio-group: form', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/radio-group/test/form');
|
||||
});
|
||||
|
||||
test('selecting an option should update the value', async ({ page }) => {
|
||||
const radioGroup = page.locator('ion-radio-group');
|
||||
const ionChange = await page.spyOnEvent('ionChange');
|
||||
const griffRadio = page.locator('ion-radio[value="griff"]');
|
||||
|
||||
await expect(radioGroup).toHaveAttribute('value', 'biff');
|
||||
|
||||
await griffRadio.click();
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(ionChange).toHaveReceivedEventDetail({ value: 'griff' });
|
||||
});
|
||||
|
||||
test('selecting a disabled option should not update the value', async ({ page }) => {
|
||||
const value = page.locator('#value');
|
||||
const disabledRadio = page.locator('ion-radio[value="george"]');
|
||||
|
||||
await expect(value).toHaveText('');
|
||||
await expect(disabledRadio).toHaveAttribute('disabled', '');
|
||||
|
||||
await disabledRadio.click({ force: true });
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(value).toHaveText('');
|
||||
});
|
||||
});
|
@ -1,133 +0,0 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import type { Locator } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
import type { E2EPage } from '@utils/test/playwright';
|
||||
|
||||
test.describe('radio-group', () => {
|
||||
// eslint-disable-next-line no-empty-pattern
|
||||
test.beforeEach(({}, testInfo) => {
|
||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs RTL logic.');
|
||||
});
|
||||
|
||||
test.describe('radio-group: interaction', () => {
|
||||
let radioFixture: RadioFixture;
|
||||
|
||||
test.beforeEach(({ page }) => {
|
||||
radioFixture = new RadioFixture(page);
|
||||
});
|
||||
|
||||
test('spacebar should not deselect without allowEmptySelection', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-radio-group value="one" allow-empty-selection="false">
|
||||
<ion-item>
|
||||
<ion-label>One</ion-label>
|
||||
<ion-radio id="one" value="one"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
`);
|
||||
|
||||
await radioFixture.checkRadio('keyboard');
|
||||
await radioFixture.expectChecked(true);
|
||||
});
|
||||
|
||||
test('spacebar should deselect with allowEmptySelection', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-radio-group value="one" allow-empty-selection="true">
|
||||
<ion-item>
|
||||
<ion-label>One</ion-label>
|
||||
<ion-radio id="one" value="one"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
`);
|
||||
|
||||
await radioFixture.checkRadio('keyboard');
|
||||
await radioFixture.expectChecked(false);
|
||||
});
|
||||
|
||||
test('click should not deselect without allowEmptySelection', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-radio-group value="one" allow-empty-selection="false">
|
||||
<ion-item>
|
||||
<ion-label>One</ion-label>
|
||||
<ion-radio id="one" value="one"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
`);
|
||||
|
||||
await radioFixture.checkRadio('mouse');
|
||||
await radioFixture.expectChecked(true);
|
||||
});
|
||||
|
||||
test('click should deselect with allowEmptySelection', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-radio-group value="one" allow-empty-selection="true">
|
||||
<ion-item>
|
||||
<ion-label>One</ion-label>
|
||||
<ion-radio id="one" value="one"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
`);
|
||||
|
||||
await radioFixture.checkRadio('mouse');
|
||||
await radioFixture.expectChecked(false);
|
||||
});
|
||||
});
|
||||
test.describe('radio-group: state', () => {
|
||||
test('radio should remain checked after being removed/readded to the dom', async ({ page }) => {
|
||||
await page.goto('/src/components/radio-group/test/search');
|
||||
|
||||
const radioGroup = page.locator('ion-radio-group');
|
||||
const radio = page.locator('ion-radio[value=two]');
|
||||
|
||||
// select radio
|
||||
await radio.click();
|
||||
await expect(radio.locator('input')).toHaveJSProperty('checked', true);
|
||||
|
||||
// filter radio so it is not in DOM
|
||||
await page.fill('ion-searchbar input', 'zero');
|
||||
await page.waitForChanges();
|
||||
expect(radio).toBeHidden();
|
||||
|
||||
// ensure radio group has the same value
|
||||
expect(radioGroup).toHaveJSProperty('value', 'two');
|
||||
|
||||
// clear the search so the radio appears
|
||||
await page.fill('ion-searchbar input', '');
|
||||
await page.waitForChanges();
|
||||
|
||||
// ensure that the new radio instance is still checked
|
||||
await expect(radio.locator('input')).toHaveJSProperty('checked', true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
class RadioFixture {
|
||||
readonly page: E2EPage;
|
||||
|
||||
private radio!: Locator;
|
||||
|
||||
constructor(page: E2EPage) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
async checkRadio(method: 'keyboard' | 'mouse', selector = 'ion-radio') {
|
||||
const { page } = this;
|
||||
const radio = (this.radio = page.locator(selector));
|
||||
|
||||
if (method === 'keyboard') {
|
||||
await radio.focus();
|
||||
await page.keyboard.press('Space');
|
||||
} else {
|
||||
await radio.click();
|
||||
}
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
return radio;
|
||||
}
|
||||
|
||||
async expectChecked(state: boolean) {
|
||||
const { radio } = this;
|
||||
await expect(radio.locator('input')).toHaveJSProperty('checked', state);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('radio-group', () => {
|
||||
test.beforeEach(async ({ page }, testInfo) => {
|
||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs RTL logic.');
|
||||
await page.goto('/src/components/radio-group/test/search');
|
||||
});
|
||||
|
||||
test.describe('radio-group: state', () => {
|
||||
test('radio should remain checked after being removed/readded to the dom', async ({ page }) => {
|
||||
const radioGroup = page.locator('ion-radio-group');
|
||||
const radio = page.locator('ion-radio[value=two]');
|
||||
|
||||
// select radio
|
||||
await radio.click();
|
||||
await expect(radio.locator('input')).toHaveJSProperty('checked', true);
|
||||
|
||||
// filter radio so it is not in DOM
|
||||
await page.fill('ion-searchbar input', 'zero');
|
||||
await page.waitForChanges();
|
||||
expect(radio).toBeHidden();
|
||||
|
||||
// ensure radio group has the same value
|
||||
expect(radioGroup).toHaveJSProperty('value', 'two');
|
||||
|
||||
// clear the search so the radio appears
|
||||
await page.fill('ion-searchbar input', '');
|
||||
await page.waitForChanges();
|
||||
|
||||
// ensure that the new radio instance is still checked
|
||||
await expect(radio.locator('input')).toHaveJSProperty('checked', true);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,65 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('searchbar: basic', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/searchbar/test/basic?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const compares = [];
|
||||
compares.push(await page.compareScreenshot());
|
||||
|
||||
let searchbar = await page.find('#basic');
|
||||
await searchbar.callMethod('setFocus');
|
||||
|
||||
await page.waitForTimeout(250);
|
||||
searchbar = await page.find('#basic');
|
||||
expect(searchbar).toHaveClass('searchbar-has-focus');
|
||||
|
||||
compares.push(await page.compareScreenshot('focused'));
|
||||
|
||||
// No Cancel Button Searchbar
|
||||
searchbar = await page.find('#noCancel');
|
||||
await searchbar.callMethod('setFocus');
|
||||
|
||||
await page.waitForTimeout(250);
|
||||
searchbar = await page.find('#noCancel');
|
||||
expect(searchbar).toHaveClass('searchbar-has-focus');
|
||||
|
||||
compares.push(await page.compareScreenshot('no cancel button, focused'));
|
||||
|
||||
for (const compare of compares) {
|
||||
expect(compare).toMatchScreenshot();
|
||||
}
|
||||
});
|
||||
|
||||
test('searchbar:rtl: basic', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/searchbar/test/basic?ionic:_testing=true&rtl=true',
|
||||
});
|
||||
|
||||
const compares = [];
|
||||
compares.push(await page.compareScreenshot());
|
||||
|
||||
let searchbar = await page.find('#basic');
|
||||
await searchbar.callMethod('setFocus');
|
||||
|
||||
await page.waitForTimeout(250);
|
||||
searchbar = await page.find('#basic');
|
||||
expect(searchbar).toHaveClass('searchbar-has-focus');
|
||||
|
||||
compares.push(await page.compareScreenshot('focused'));
|
||||
|
||||
// No Cancel Button Searchbar
|
||||
searchbar = await page.find('#noCancel');
|
||||
await searchbar.callMethod('setFocus');
|
||||
|
||||
await page.waitForTimeout(250);
|
||||
searchbar = await page.find('#noCancel');
|
||||
expect(searchbar).toHaveClass('searchbar-has-focus');
|
||||
|
||||
compares.push(await page.compareScreenshot('no cancel button, focused'));
|
||||
|
||||
for (const compare of compares) {
|
||||
expect(compare).toMatchScreenshot();
|
||||
}
|
||||
});
|
@ -26,61 +26,25 @@
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Default</h5>
|
||||
<ion-searchbar id="basic" value="test" type="tel" show-cancel-button="focus" debounce="500"> </ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - No Cancel Button</h5>
|
||||
<ion-searchbar
|
||||
class="red-box"
|
||||
id="noCancel"
|
||||
value="after view"
|
||||
autocorrect="off"
|
||||
autocomplete="off"
|
||||
spellcheck="true"
|
||||
type="text"
|
||||
show-cancel-button="never"
|
||||
>
|
||||
</ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Always Show Cancel Button</h5>
|
||||
<ion-searchbar id="noCancel" value="after view" animated="true" show-cancel-button="always"> </ion-searchbar>
|
||||
<ion-searchbar id="alwaysCancel" value="after view" animated="true" show-cancel-button="always">
|
||||
</ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Never Show Cancel Button</h5>
|
||||
<ion-searchbar id="noCancel" value="after view" animated="true" show-cancel-button="never"> </ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Show Cancel Button on Focus</h5>
|
||||
<ion-searchbar id="noCancel" value="after view" animated="true" show-cancel-button="focus"> </ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Cancel Button set to false</h5>
|
||||
<ion-searchbar
|
||||
id="noCancel"
|
||||
value="after view"
|
||||
autocorrect="off"
|
||||
autocomplete="off"
|
||||
spellcheck="true"
|
||||
type="text"
|
||||
show-cancel-button="never"
|
||||
>
|
||||
</ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Cancel Button set to true</h5>
|
||||
<ion-searchbar
|
||||
id="noCancel"
|
||||
value="after view"
|
||||
autocorrect="off"
|
||||
autocomplete="off"
|
||||
spellcheck="true"
|
||||
type="text"
|
||||
show-cancel-button="focus"
|
||||
>
|
||||
</ion-searchbar>
|
||||
<ion-searchbar id="focusCancel" value="after view" animated="true" show-cancel-button="focus"> </ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - No Clear Button</h5>
|
||||
<ion-searchbar id="noCancel" value="after view" type="text" show-clear-button="never"> </ion-searchbar>
|
||||
<ion-searchbar id="noClear" value="after view" type="text" show-clear-button="never"> </ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Always Show Clear Button</h5>
|
||||
<ion-searchbar id="noCancel" value="after view" type="text" show-clear-button="always"> </ion-searchbar>
|
||||
<ion-searchbar id="alwaysClear" value="after view" type="text" show-clear-button="always"> </ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Input mode set to numeric</h5>
|
||||
<ion-searchbar
|
||||
id="noCancel"
|
||||
id="numericMode"
|
||||
value="after view"
|
||||
inputmode="numeric"
|
||||
autocorrect="off"
|
||||
@ -100,38 +64,22 @@
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Custom Search Icon</h5>
|
||||
<ion-searchbar search-icon="home" show-cancel-button="focus" debounce="500"> </ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Animated</h5>
|
||||
<ion-searchbar animated="true" show-cancel-button="focus" debounce="500"> </ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Custom Placeholder</h5>
|
||||
<ion-searchbar
|
||||
id="dynamicProp"
|
||||
value="33"
|
||||
autocorrect="on"
|
||||
show-cancel-button="focus"
|
||||
autocomplete="on"
|
||||
spellcheck="false"
|
||||
type="number"
|
||||
placeholder="Filter Schedules"
|
||||
>
|
||||
</ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Custom Cancel Button Danger</h5>
|
||||
<ion-searchbar show-cancel-button="focus" cancel-button-text="Really Long Cancel" color="danger">
|
||||
</ion-searchbar>
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Custom Cancel Button</h5>
|
||||
<ion-searchbar show-cancel-button="always" cancel-button-text="Really Long Cancel"> </ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Custom Cancel Button Icon through property</h5>
|
||||
<ion-searchbar show-cancel-button="focus" cancel-button-icon="rewind"> </ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Value passed</h5>
|
||||
<ion-searchbar value="mysearch" cancel-button-text="Really Long Cancel" color="dark" show-cancel-button="focus">
|
||||
</ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Mode iOS</h5>
|
||||
<ion-searchbar mode="ios" animated="true" show-cancel-button="focus" placeholder="Search"> </ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Mode MD</h5>
|
||||
<ion-searchbar mode="md" animated="true" show-cancel-button="focus" placeholder="Search"> </ion-searchbar>
|
||||
<ion-searchbar show-cancel-button="always" cancel-button-icon="play-back"> </ion-searchbar>
|
||||
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - DebounceTime</h5>
|
||||
<ion-searchbar
|
||||
@ -158,10 +106,6 @@
|
||||
>
|
||||
</ion-searchbar>
|
||||
|
||||
<p class="ion-padding">
|
||||
<ion-button expand="block" (click)="changeValue()">Change Value</ion-button>
|
||||
</p>
|
||||
|
||||
<div class="ion-padding-horizontal">
|
||||
<ion-button expand="block" onClick="toggleProp()">Toggle Property</ion-button>
|
||||
</div>
|
||||
@ -173,13 +117,6 @@
|
||||
<ion-button expand="block" color="secondary" onClick="toggleDisabled()">Toggle disabled</ion-button>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.red-box {
|
||||
--box-shadow: 0 2px 2px 0 rgba(255, 0, 0, 0.14), 0 3px 1px -2px rgba(255, 0, 0, 0.2),
|
||||
0 1px 5px 0 rgba(255, 0, 0, 0.12);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function toggleAttr() {
|
||||
var dynamicAttr = document.getElementById('dynamicAttr');
|
||||
@ -245,17 +182,6 @@
|
||||
const propIsSpellcheck = dynamicProp.spellcheck === true ? false : true;
|
||||
dynamicProp.spellcheck = propIsSpellcheck;
|
||||
}
|
||||
|
||||
const content = document.querySelector('#content');
|
||||
content.addEventListener('ionChange', (ev) => {
|
||||
console.log(ev);
|
||||
});
|
||||
content.addEventListener('ionCancel', (ev) => {
|
||||
console.log(ev);
|
||||
});
|
||||
content.addEventListener('ionClear', (ev) => {
|
||||
console.log(ev);
|
||||
});
|
||||
</script>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
|
35
core/src/components/searchbar/test/basic/searchbar.e2e.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('searchbar: basic', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(`/src/components/searchbar/test/basic`);
|
||||
});
|
||||
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setIonViewport();
|
||||
expect(await page.screenshot()).toMatchSnapshot(`searchbar-diff-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
|
||||
test('should show cancel button on focus if show-cancel-button=focus', async ({ page }) => {
|
||||
const searchbar = page.locator('#basic');
|
||||
const cancelButton = searchbar.locator('.searchbar-cancel-button');
|
||||
|
||||
await searchbar.evaluate((el: HTMLIonSearchbarElement) => el.setFocus());
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(searchbar).toHaveClass(/searchbar-has-focus/);
|
||||
await expect(cancelButton).toBeVisible();
|
||||
});
|
||||
|
||||
test('should not show cancel button on focus if show-cancel-button=never', async ({ page }) => {
|
||||
const searchbar = page.locator('#noCancel');
|
||||
const cancelButton = searchbar.locator('.searchbar-cancel-button');
|
||||
|
||||
await searchbar.evaluate((el: HTMLIonSearchbarElement) => el.setFocus());
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(searchbar).toHaveClass(/searchbar-has-focus/);
|
||||
await expect(cancelButton).toHaveCount(0);
|
||||
});
|
||||
});
|
After Width: | Height: | Size: 364 KiB |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 362 KiB |
After Width: | Height: | Size: 362 KiB |
After Width: | Height: | Size: 135 KiB |
After Width: | Height: | Size: 360 KiB |
After Width: | Height: | Size: 334 KiB |
After Width: | Height: | Size: 127 KiB |
After Width: | Height: | Size: 329 KiB |
After Width: | Height: | Size: 334 KiB |
After Width: | Height: | Size: 127 KiB |
After Width: | Height: | Size: 328 KiB |
@ -1,10 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('searchbar: rtl', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/searchbar/test/rtl?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
@ -1,31 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Searchbar - RTL</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
||||
/>
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Searchbar - RTL</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content id="content">
|
||||
<h5 class="ion-padding-start ion-padding-top">Search - Default</h5>
|
||||
<ion-searchbar dir="rtl" value="test" type="tel" show-cancel-button="focus" debounce="500"> </ion-searchbar>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
</body>
|
||||
</html>
|
@ -1,14 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('searchbar: standalone', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/searchbar/test/standalone?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
|
||||
const searchbar = await page.find('ion-searchbar');
|
||||
await searchbar.callMethod('setFocus');
|
||||
expect(await page.compareScreenshot('focused')).toMatchScreenshot();
|
||||
});
|
@ -43,26 +43,9 @@
|
||||
|
||||
<ion-searchbar show-cancel-button="focus" cancel-button-text="Really Long Cancel" color="danger"> </ion-searchbar>
|
||||
|
||||
<ion-searchbar value="mysearch" cancel-button-text="Really Long Cancel" color="dark" show-cancel-button="focus">
|
||||
<ion-searchbar value="mysearch" cancel-button-text="Really Long Cancel" color="dark" show-cancel-button="always">
|
||||
</ion-searchbar>
|
||||
|
||||
<ion-searchbar mode="ios" animated="true" show-cancel-button="focus" placeholder="Search"> </ion-searchbar>
|
||||
|
||||
<ion-searchbar mode="md" animated="true" show-cancel-button="focus" placeholder="Search"> </ion-searchbar>
|
||||
|
||||
<ion-searchbar
|
||||
autocorrect="on"
|
||||
show-cancel-button="focus"
|
||||
autocomplete="on"
|
||||
spellcheck="true"
|
||||
type="text"
|
||||
debounce="5000"
|
||||
placeholder="Check the log"
|
||||
>
|
||||
</ion-searchbar>
|
||||
|
||||
<ion-searchbar id="dynamicAttr" placeholder="Search" animated="true" show-cancel-button="never"> </ion-searchbar>
|
||||
|
||||
<ion-searchbar class="custom" show-cancel-button="focus"> </ion-searchbar>
|
||||
|
||||
<style>
|
||||
|
@ -0,0 +1,12 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('searchbar: standalone', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.goto(`/src/components/searchbar/test/standalone`);
|
||||
|
||||
expect(await page.screenshot({ fullPage: true })).toMatchSnapshot(
|
||||
`searchbar-standalone-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
});
|
||||
});
|
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 61 KiB |
After Width: | Height: | Size: 61 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 61 KiB |
@ -1,10 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('searchbar: toolbar', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/searchbar/test/toolbar?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
@ -1,162 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Ionic Searchbar Toolbar</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header translucent>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-button>Undo</ion-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Searchbar - Toolbar</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button>Clear</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-button>Undo</ion-button>
|
||||
</ion-buttons>
|
||||
<ion-searchbar translucent></ion-searchbar>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button>Clear</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
<ion-toolbar>
|
||||
<ion-back-button default-href="#" slot="start"></ion-back-button>
|
||||
<ion-searchbar translucent></ion-searchbar>
|
||||
<ion-chip slot="end" outline>Chip</ion-chip>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content id="content" fullscreen>
|
||||
<h5 class="ion-padding-start">Search - Transparent Toolbar</h5>
|
||||
<ion-toolbar transparent>
|
||||
<ion-searchbar show-cancel-button="focus"></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<h5 class="ion-padding-start">Search - Default Toolbar</h5>
|
||||
<ion-toolbar>
|
||||
<ion-searchbar show-cancel-button="focus"></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<h5 class="ion-padding-start">Search - Primary Toolbar</h5>
|
||||
<ion-toolbar color="primary">
|
||||
<ion-searchbar show-cancel-button="focus"></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<h5 class="ion-padding-start">Search - Secondary Toolbar</h5>
|
||||
<ion-toolbar color="secondary">
|
||||
<ion-searchbar show-cancel-button="focus"></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<h5 class="ion-padding-start">Search - Tertiary Toolbar</h5>
|
||||
<ion-toolbar color="tertiary">
|
||||
<ion-searchbar show-cancel-button="focus"></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<h5 class="ion-padding-start">Search - Success Toolbar</h5>
|
||||
<ion-toolbar color="success">
|
||||
<ion-searchbar show-cancel-button="focus"></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<h5 class="ion-padding-start">Search - Warning Toolbar</h5>
|
||||
<ion-toolbar color="warning">
|
||||
<ion-searchbar show-cancel-button="focus"></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<h5 class="ion-padding-start">Search - Danger Toolbar</h5>
|
||||
<ion-toolbar color="danger">
|
||||
<ion-searchbar show-cancel-button="focus"></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<h5 class="ion-padding-start">Search - Light Toolbar</h5>
|
||||
<ion-toolbar color="light">
|
||||
<ion-searchbar show-cancel-button="focus"></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<h5 class="ion-padding-start">Search - Medium Toolbar</h5>
|
||||
<ion-toolbar color="medium">
|
||||
<ion-searchbar show-cancel-button="focus"></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<h5 class="ion-padding-start">Search - Dark Toolbar</h5>
|
||||
<ion-toolbar color="dark">
|
||||
<ion-searchbar show-cancel-button="focus" placeholder="Filter Schedules"></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<h5 class="ion-padding-start">Search - Dark Toolbar, Primary Search</h5>
|
||||
<ion-toolbar color="dark">
|
||||
<ion-searchbar show-cancel-button="focus" color="primary" placeholder="Filter Schedules"></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col size="6"><f class="red"></f></ion-col>
|
||||
<ion-col size="6"><f class="green"></f></ion-col>
|
||||
<ion-col size="6"><f class="blue"></f></ion-col>
|
||||
<ion-col size="6"><f class="yellow"></f></ion-col>
|
||||
<ion-col size="6"><f class="pink"></f></ion-col>
|
||||
<ion-col size="6"><f class="purple"></f></ion-col>
|
||||
<ion-col size="6"><f class="black"></f></ion-col>
|
||||
<ion-col size="6"><f class="orange"></f></ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
|
||||
<style>
|
||||
f {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.red {
|
||||
background-color: #ea445a;
|
||||
}
|
||||
|
||||
.green {
|
||||
background-color: #76d672;
|
||||
}
|
||||
|
||||
.blue {
|
||||
background-color: #3478f6;
|
||||
}
|
||||
|
||||
.yellow {
|
||||
background-color: #ffff80;
|
||||
}
|
||||
|
||||
.pink {
|
||||
background-color: #ff6b86;
|
||||
}
|
||||
|
||||
.purple {
|
||||
background-color: #7e34f6;
|
||||
}
|
||||
|
||||
.black {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.orange {
|
||||
background-color: #f69234;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.2.2](https://github.com/ionic-team/ionic-docs/compare/v6.2.1...v6.2.2) (2022-08-10)
|
||||
|
||||
**Note:** Version bump only for package @ionic/docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.2.1](https://github.com/ionic-team/ionic-docs/compare/v6.2.0...v6.2.1) (2022-08-03)
|
||||
|
||||
**Note:** Version bump only for package @ionic/docs
|
||||
|
4
docs/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ionic/docs",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/docs",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/docs",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"description": "Pre-packaged API documentation for the Ionic docs.",
|
||||
"main": "core.json",
|
||||
"types": "core.d.ts",
|
||||
|
@ -5,5 +5,5 @@
|
||||
"angular",
|
||||
"packages/*"
|
||||
],
|
||||
"version": "6.2.1"
|
||||
"version": "6.2.2"
|
||||
}
|
||||
|
@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.2.2](https://github.com/ionic-team/ionic/compare/v6.2.1...v6.2.2) (2022-08-10)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular-server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.2.1](https://github.com/ionic-team/ionic/compare/v6.2.0...v6.2.1) (2022-08-03)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular-server
|
||||
|
18
packages/angular-server/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@angular-eslint/eslint-plugin": "^12.6.1",
|
||||
@ -18,7 +18,7 @@
|
||||
"@angular/platform-browser": "^12.0.0",
|
||||
"@angular/platform-browser-dynamic": "^12.2.10",
|
||||
"@angular/platform-server": "^12.0.0",
|
||||
"@ionic/core": "^6.2.1",
|
||||
"@ionic/core": "^6.2.2",
|
||||
"@ionic/eslint-config": "^0.3.0",
|
||||
"@ionic/prettier-config": "^2.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.2.0",
|
||||
@ -786,9 +786,9 @@
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.1.tgz",
|
||||
"integrity": "sha512-bWlE2ZMR7tMyqcBhncc21zZPMZfCEoyGQP2bdu/ft1uov0ozw/wfETygd07C+0DOkbU6x1OYncIvo+1bzK4alA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.2.tgz",
|
||||
"integrity": "sha512-neE+JhtQ7Kb4nGoKR3e55edHQot5BZTw+woV9+pbyCXP1jGeyFeWWPYBYYOkm05TSEkHgh0v6NkV9y31k8GTNw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
@ -7103,9 +7103,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.1.tgz",
|
||||
"integrity": "sha512-bWlE2ZMR7tMyqcBhncc21zZPMZfCEoyGQP2bdu/ft1uov0ozw/wfETygd07C+0DOkbU6x1OYncIvo+1bzK4alA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.2.tgz",
|
||||
"integrity": "sha512-neE+JhtQ7Kb4nGoKR3e55edHQot5BZTw+woV9+pbyCXP1jGeyFeWWPYBYYOkm05TSEkHgh0v6NkV9y31k8GTNw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"description": "Angular SSR Module for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@ -56,7 +56,7 @@
|
||||
"@angular/platform-browser": "^12.0.0",
|
||||
"@angular/platform-browser-dynamic": "^12.2.10",
|
||||
"@angular/platform-server": "^12.0.0",
|
||||
"@ionic/core": "^6.2.1",
|
||||
"@ionic/core": "^6.2.2",
|
||||
"@ionic/eslint-config": "^0.3.0",
|
||||
"@ionic/prettier-config": "^2.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.2.0",
|
||||
|
@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.2.2](https://github.com/ionic-team/ionic/compare/v6.2.1...v6.2.2) (2022-08-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react:** outlet will not clear in react 18 with hot reload ([#25703](https://github.com/ionic-team/ionic/issues/25703)) ([3878bf7](https://github.com/ionic-team/ionic/commit/3878bf76523f2e1c26c147473fd7c07ee4d0e820)), closes [#25507](https://github.com/ionic-team/ionic/issues/25507)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.2.1](https://github.com/ionic-team/ionic/compare/v6.2.0...v6.2.1) (2022-08-03)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react-router
|
||||
|
34
packages/react-router/package-lock.json
generated
@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/react-router",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/react-router",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/react": "^6.2.1",
|
||||
"@ionic/react": "^6.2.2",
|
||||
"tslib": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -147,9 +147,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.1.tgz",
|
||||
"integrity": "sha512-bWlE2ZMR7tMyqcBhncc21zZPMZfCEoyGQP2bdu/ft1uov0ozw/wfETygd07C+0DOkbU6x1OYncIvo+1bzK4alA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.2.tgz",
|
||||
"integrity": "sha512-neE+JhtQ7Kb4nGoKR3e55edHQot5BZTw+woV9+pbyCXP1jGeyFeWWPYBYYOkm05TSEkHgh0v6NkV9y31k8GTNw==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
@ -157,11 +157,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/react": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-6.2.1.tgz",
|
||||
"integrity": "sha512-zHqoGeEm4QwzCijBvcYZQifrCvFXSRChh8ey5lsYUixxKwgl2j9y3kKLckLiipR/g+mbC5lVjno0UlIlBvsulQ==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-6.2.2.tgz",
|
||||
"integrity": "sha512-CRuDJbNDn9bbDba37/5v9aZ2gd450XGklGqXmsxEfadh1iq7iWmqcgw14S0ZDAXQt0aE/J+TeKhTyjyutjsAww==",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.2.1",
|
||||
"@ionic/core": "^6.2.2",
|
||||
"ionicons": "^6.0.2",
|
||||
"tslib": "*"
|
||||
},
|
||||
@ -1157,9 +1157,9 @@
|
||||
}
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.1.tgz",
|
||||
"integrity": "sha512-bWlE2ZMR7tMyqcBhncc21zZPMZfCEoyGQP2bdu/ft1uov0ozw/wfETygd07C+0DOkbU6x1OYncIvo+1bzK4alA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.2.tgz",
|
||||
"integrity": "sha512-neE+JhtQ7Kb4nGoKR3e55edHQot5BZTw+woV9+pbyCXP1jGeyFeWWPYBYYOkm05TSEkHgh0v6NkV9y31k8GTNw==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
@ -1167,11 +1167,11 @@
|
||||
}
|
||||
},
|
||||
"@ionic/react": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-6.2.1.tgz",
|
||||
"integrity": "sha512-zHqoGeEm4QwzCijBvcYZQifrCvFXSRChh8ey5lsYUixxKwgl2j9y3kKLckLiipR/g+mbC5lVjno0UlIlBvsulQ==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-6.2.2.tgz",
|
||||
"integrity": "sha512-CRuDJbNDn9bbDba37/5v9aZ2gd450XGklGqXmsxEfadh1iq7iWmqcgw14S0ZDAXQt0aE/J+TeKhTyjyutjsAww==",
|
||||
"requires": {
|
||||
"@ionic/core": "^6.2.1",
|
||||
"@ionic/core": "^6.2.2",
|
||||
"ionicons": "^6.0.2",
|
||||
"tslib": "*"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/react-router",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"description": "React Router wrapper for @ionic/react",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@ -37,7 +37,7 @@
|
||||
"dist/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ionic/react": "^6.2.1",
|
||||
"@ionic/react": "^6.2.2",
|
||||
"tslib": "*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
@ -18,7 +18,8 @@ interface StackManagerProps {
|
||||
|
||||
interface StackManagerState {}
|
||||
|
||||
const isViewVisible = (el: HTMLElement) => !el.classList.contains('ion-page-invisible') && !el.classList.contains('ion-page-hidden');
|
||||
const isViewVisible = (el: HTMLElement) =>
|
||||
!el.classList.contains('ion-page-invisible') && !el.classList.contains('ion-page-hidden');
|
||||
|
||||
export class StackManager extends React.PureComponent<StackManagerProps, StackManagerState> {
|
||||
id: string;
|
||||
@ -33,6 +34,7 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
isInOutlet: () => true,
|
||||
};
|
||||
|
||||
private clearOutletTimeout: any;
|
||||
private pendingPageTransition = false;
|
||||
|
||||
constructor(props: StackManagerProps) {
|
||||
@ -46,9 +48,20 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.clearOutletTimeout) {
|
||||
/**
|
||||
* The clearOutlet integration with React Router is a bit hacky.
|
||||
* It uses a timeout to clear the outlet after a transition.
|
||||
* In React v18, components are mounted and unmounted in development mode
|
||||
* to check for side effects.
|
||||
*
|
||||
* This clearTimeout prevents the outlet from being cleared when the component is re-mounted,
|
||||
* which should only happen in development mode and as a result of a hot reload.
|
||||
*/
|
||||
clearTimeout(this.clearOutletTimeout);
|
||||
}
|
||||
if (this.routerOutletElement) {
|
||||
this.setupRouterOutlet(this.routerOutletElement);
|
||||
// console.log(`SM Mount - ${this.routerOutletElement.id} (${this.id})`);
|
||||
this.handlePageTransition(this.props.routeInfo);
|
||||
}
|
||||
}
|
||||
@ -67,8 +80,7 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
// console.log(`SM UNMount - ${(this.routerOutletElement?.id as any).id} (${this.id})`);
|
||||
this.context.clearOutlet(this.id);
|
||||
this.clearOutletTimeout = this.context.clearOutlet(this.id);
|
||||
}
|
||||
|
||||
async handlePageTransition(routeInfo: RouteInfo) {
|
||||
@ -142,13 +154,20 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
* to find the leaving view item to transition between.
|
||||
*/
|
||||
if (!leavingViewItem && this.props.routeInfo.prevRouteLastPathname) {
|
||||
leavingViewItem = this.context.findViewItemByPathname(this.props.routeInfo.prevRouteLastPathname, this.id);
|
||||
leavingViewItem = this.context.findViewItemByPathname(
|
||||
this.props.routeInfo.prevRouteLastPathname,
|
||||
this.id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the entering view is already visible and the leaving view is not, the transition does not need to occur.
|
||||
*/
|
||||
if (isViewVisible(enteringViewItem.ionPageElement) && leavingViewItem !== undefined && !isViewVisible(leavingViewItem.ionPageElement!)) {
|
||||
if (
|
||||
isViewVisible(enteringViewItem.ionPageElement) &&
|
||||
leavingViewItem !== undefined &&
|
||||
!isViewVisible(leavingViewItem.ionPageElement!)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -197,11 +216,16 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
const canStart = () => {
|
||||
const config = getConfig();
|
||||
const swipeEnabled = config && config.get('swipeBackEnabled', routerOutlet.mode === 'ios');
|
||||
if (!swipeEnabled) { return false; }
|
||||
if (!swipeEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { routeInfo } = this.props;
|
||||
|
||||
const propsToUse = (this.prevProps && this.prevProps.routeInfo.pathname === routeInfo.pushedByRoute) ? this.prevProps.routeInfo : { pathname: routeInfo.pushedByRoute || '' } as any;
|
||||
const propsToUse =
|
||||
this.prevProps && this.prevProps.routeInfo.pathname === routeInfo.pushedByRoute
|
||||
? this.prevProps.routeInfo
|
||||
: ({ pathname: routeInfo.pushedByRoute || '' } as any);
|
||||
const enteringViewItem = this.context.findViewItemByRouteInfo(propsToUse, this.id, false);
|
||||
|
||||
return (
|
||||
@ -213,7 +237,6 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
* root url.
|
||||
*/
|
||||
enteringViewItem.mount &&
|
||||
|
||||
/**
|
||||
* When on the first page (whatever view
|
||||
* you land on after the root url) it
|
||||
@ -229,7 +252,10 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
const onStart = async () => {
|
||||
const { routeInfo } = this.props;
|
||||
|
||||
const propsToUse = (this.prevProps && this.prevProps.routeInfo.pathname === routeInfo.pushedByRoute) ? this.prevProps.routeInfo : { pathname: routeInfo.pushedByRoute || '' } as any;
|
||||
const propsToUse =
|
||||
this.prevProps && this.prevProps.routeInfo.pathname === routeInfo.pushedByRoute
|
||||
? this.prevProps.routeInfo
|
||||
: ({ pathname: routeInfo.pushedByRoute || '' } as any);
|
||||
const enteringViewItem = this.context.findViewItemByRouteInfo(propsToUse, this.id, false);
|
||||
const leavingViewItem = this.context.findViewItemByRouteInfo(routeInfo, this.id, false);
|
||||
|
||||
@ -257,7 +283,10 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
*/
|
||||
const { routeInfo } = this.props;
|
||||
|
||||
const propsToUse = (this.prevProps && this.prevProps.routeInfo.pathname === routeInfo.pushedByRoute) ? this.prevProps.routeInfo : { pathname: routeInfo.pushedByRoute || '' } as any;
|
||||
const propsToUse =
|
||||
this.prevProps && this.prevProps.routeInfo.pathname === routeInfo.pushedByRoute
|
||||
? this.prevProps.routeInfo
|
||||
: ({ pathname: routeInfo.pushedByRoute || '' } as any);
|
||||
const enteringViewItem = this.context.findViewItemByRouteInfo(propsToUse, this.id, false);
|
||||
const leavingViewItem = this.context.findViewItemByRouteInfo(routeInfo, this.id, false);
|
||||
|
||||
@ -279,12 +308,12 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
ionPageElement.classList.add('ion-page-hidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
routerOutlet.swipeHandler = {
|
||||
canStart,
|
||||
onStart,
|
||||
onEnd
|
||||
onEnd,
|
||||
};
|
||||
}
|
||||
|
||||
@ -333,7 +362,7 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
progressAnimation,
|
||||
animationBuilder: routeInfo.routeAnimation,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const routerOutlet = this.routerOutletElement!;
|
||||
|
||||
|
@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.2.2](https://github.com/ionic-team/ionic/compare/v6.2.1...v6.2.2) (2022-08-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react:** outlet will not clear in react 18 with hot reload ([#25703](https://github.com/ionic-team/ionic/issues/25703)) ([3878bf7](https://github.com/ionic-team/ionic/commit/3878bf76523f2e1c26c147473fd7c07ee4d0e820)), closes [#25507](https://github.com/ionic-team/ionic/issues/25507)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.2.1](https://github.com/ionic-team/ionic/compare/v6.2.0...v6.2.1) (2022-08-03)
|
||||
|
||||
|
||||
|
18
packages/react/package-lock.json
generated
@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/react",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/react",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.2.1",
|
||||
"@ionic/core": "^6.2.2",
|
||||
"ionicons": "^6.0.2",
|
||||
"tslib": "*"
|
||||
},
|
||||
@ -607,9 +607,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.1.tgz",
|
||||
"integrity": "sha512-bWlE2ZMR7tMyqcBhncc21zZPMZfCEoyGQP2bdu/ft1uov0ozw/wfETygd07C+0DOkbU6x1OYncIvo+1bzK4alA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.2.tgz",
|
||||
"integrity": "sha512-neE+JhtQ7Kb4nGoKR3e55edHQot5BZTw+woV9+pbyCXP1jGeyFeWWPYBYYOkm05TSEkHgh0v6NkV9y31k8GTNw==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
@ -9522,9 +9522,9 @@
|
||||
}
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.1.tgz",
|
||||
"integrity": "sha512-bWlE2ZMR7tMyqcBhncc21zZPMZfCEoyGQP2bdu/ft1uov0ozw/wfETygd07C+0DOkbU6x1OYncIvo+1bzK4alA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.2.tgz",
|
||||
"integrity": "sha512-neE+JhtQ7Kb4nGoKR3e55edHQot5BZTw+woV9+pbyCXP1jGeyFeWWPYBYYOkm05TSEkHgh0v6NkV9y31k8GTNw==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/react",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"description": "React specific wrapper for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@ -41,7 +41,7 @@
|
||||
"css/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.2.1",
|
||||
"@ionic/core": "^6.2.2",
|
||||
"ionicons": "^6.0.2",
|
||||
"tslib": "*"
|
||||
},
|
||||
|
@ -23,8 +23,7 @@ export abstract class ViewStacks {
|
||||
|
||||
clear(outletId: string) {
|
||||
// Give some time for the leaving views to transition before removing
|
||||
setTimeout(() => {
|
||||
// console.log('Removing viewstack for outletID ' + outletId);
|
||||
return setTimeout(() => {
|
||||
delete this.viewStacks[outletId];
|
||||
}, 500);
|
||||
}
|
||||
|
@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.2.2](https://github.com/ionic-team/ionic/compare/v6.2.1...v6.2.2) (2022-08-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **vue:** go back to correct view with memory history ([#25732](https://github.com/ionic-team/ionic/issues/25732)) ([8327889](https://github.com/ionic-team/ionic/commit/832788971a7098e52812f66563cbc0a63d3e5df7)), closes [#25705](https://github.com/ionic-team/ionic/issues/25705)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.2.1](https://github.com/ionic-team/ionic/compare/v6.2.0...v6.2.1) (2022-08-03)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue-router
|
||||
|
34
packages/vue-router/package-lock.json
generated
@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/vue-router",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/vue-router",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/vue": "^6.2.1"
|
||||
"@ionic/vue": "^6.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^28.1.1",
|
||||
@ -578,9 +578,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.1.tgz",
|
||||
"integrity": "sha512-bWlE2ZMR7tMyqcBhncc21zZPMZfCEoyGQP2bdu/ft1uov0ozw/wfETygd07C+0DOkbU6x1OYncIvo+1bzK4alA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.2.tgz",
|
||||
"integrity": "sha512-neE+JhtQ7Kb4nGoKR3e55edHQot5BZTw+woV9+pbyCXP1jGeyFeWWPYBYYOkm05TSEkHgh0v6NkV9y31k8GTNw==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
@ -588,11 +588,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/vue": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-6.2.1.tgz",
|
||||
"integrity": "sha512-buVKw5ZAeNCBa1PmSZWkUDaNJgRSjp2iBzYH6/8MQC/bniTRb1QV6LebTAw3xt+6QhHqCeiBedZtwYCSlr510Q==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-6.2.2.tgz",
|
||||
"integrity": "sha512-jxFW/FFCW6PB5daOGrBlHzZiabS+1A2MUExLQmBoVvw8Dt5gypv1J6oMWKqdVlBDOU7wqozkFjqioeK3c5sPSA==",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.2.1",
|
||||
"@ionic/core": "^6.2.2",
|
||||
"ionicons": "^6.0.2"
|
||||
}
|
||||
},
|
||||
@ -5233,9 +5233,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.1.tgz",
|
||||
"integrity": "sha512-bWlE2ZMR7tMyqcBhncc21zZPMZfCEoyGQP2bdu/ft1uov0ozw/wfETygd07C+0DOkbU6x1OYncIvo+1bzK4alA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.2.tgz",
|
||||
"integrity": "sha512-neE+JhtQ7Kb4nGoKR3e55edHQot5BZTw+woV9+pbyCXP1jGeyFeWWPYBYYOkm05TSEkHgh0v6NkV9y31k8GTNw==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
@ -5243,11 +5243,11 @@
|
||||
}
|
||||
},
|
||||
"@ionic/vue": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-6.2.1.tgz",
|
||||
"integrity": "sha512-buVKw5ZAeNCBa1PmSZWkUDaNJgRSjp2iBzYH6/8MQC/bniTRb1QV6LebTAw3xt+6QhHqCeiBedZtwYCSlr510Q==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-6.2.2.tgz",
|
||||
"integrity": "sha512-jxFW/FFCW6PB5daOGrBlHzZiabS+1A2MUExLQmBoVvw8Dt5gypv1J6oMWKqdVlBDOU7wqozkFjqioeK3c5sPSA==",
|
||||
"requires": {
|
||||
"@ionic/core": "^6.2.1",
|
||||
"@ionic/core": "^6.2.2",
|
||||
"ionicons": "^6.0.2"
|
||||
}
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/vue-router",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"description": "Vue Router integration for @ionic/vue",
|
||||
"scripts": {
|
||||
"prepublishOnly": "npm run build",
|
||||
@ -44,7 +44,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/ionic-team/ionic#readme",
|
||||
"dependencies": {
|
||||
"@ionic/vue": "^6.2.1"
|
||||
"@ionic/vue": "^6.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^28.1.1",
|
||||
|
@ -120,7 +120,12 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
||||
* will go back in a linear fashion.
|
||||
*/
|
||||
prevInfo.pathname === routeInfo.pushedByRoute &&
|
||||
routeInfo.tab === '' && prevInfo.tab === ''
|
||||
|
||||
/**
|
||||
* Tab info can be undefined or '' (empty string)
|
||||
* both are false-y values, so we can just use !.
|
||||
*/
|
||||
!routeInfo.tab && !prevInfo.tab
|
||||
)
|
||||
) {
|
||||
router.back();
|
||||
|
@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.2.2](https://github.com/ionic-team/ionic/compare/v6.2.1...v6.2.2) (2022-08-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **vue:** go back to correct view with memory history ([#25732](https://github.com/ionic-team/ionic/issues/25732)) ([8327889](https://github.com/ionic-team/ionic/commit/832788971a7098e52812f66563cbc0a63d3e5df7)), closes [#25705](https://github.com/ionic-team/ionic/issues/25705)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.2.1](https://github.com/ionic-team/ionic/compare/v6.2.0...v6.2.1) (2022-08-03)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue
|
||||
|
18
packages/vue/package-lock.json
generated
@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/vue",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/vue",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.2.1",
|
||||
"@ionic/core": "^6.2.2",
|
||||
"ionicons": "^6.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -59,9 +59,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.1.tgz",
|
||||
"integrity": "sha512-bWlE2ZMR7tMyqcBhncc21zZPMZfCEoyGQP2bdu/ft1uov0ozw/wfETygd07C+0DOkbU6x1OYncIvo+1bzK4alA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.2.tgz",
|
||||
"integrity": "sha512-neE+JhtQ7Kb4nGoKR3e55edHQot5BZTw+woV9+pbyCXP1jGeyFeWWPYBYYOkm05TSEkHgh0v6NkV9y31k8GTNw==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
@ -768,9 +768,9 @@
|
||||
}
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.1.tgz",
|
||||
"integrity": "sha512-bWlE2ZMR7tMyqcBhncc21zZPMZfCEoyGQP2bdu/ft1uov0ozw/wfETygd07C+0DOkbU6x1OYncIvo+1bzK4alA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.2.tgz",
|
||||
"integrity": "sha512-neE+JhtQ7Kb4nGoKR3e55edHQot5BZTw+woV9+pbyCXP1jGeyFeWWPYBYYOkm05TSEkHgh0v6NkV9y31k8GTNw==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/vue",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"description": "Vue specific wrapper for @ionic/core",
|
||||
"scripts": {
|
||||
"prepublishOnly": "npm run build",
|
||||
@ -61,7 +61,7 @@
|
||||
"vue-router": "^4.0.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.2.1",
|
||||
"@ionic/core": "^6.2.2",
|
||||
"ionicons": "^6.0.2"
|
||||
},
|
||||
"vetur": {
|
||||
|
76
packages/vue/test-app/tests/unit/memory.spec.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import { mount } from '@vue/test-utils';
|
||||
import { createRouter, createMemoryHistory } from '@ionic/vue-router';
|
||||
import {
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonToolbar,
|
||||
IonBackButton,
|
||||
IonicVue,
|
||||
IonApp,
|
||||
IonRouterOutlet,
|
||||
IonPage,
|
||||
} from '@ionic/vue';
|
||||
import { waitForRouter } from './utils';
|
||||
|
||||
const App = {
|
||||
components: { IonApp, IonRouterOutlet },
|
||||
template: '<ion-app><ion-router-outlet /></ion-app>',
|
||||
}
|
||||
|
||||
describe('createMemoryHistory', () => {
|
||||
beforeAll(() => {
|
||||
(HTMLElement.prototype as HTMLIonRouterOutletElement).commit = jest.fn();
|
||||
});
|
||||
it('should not error when going back with memory router', async () => {
|
||||
const PageTemplate = {
|
||||
template: `
|
||||
<ion-page>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-back-button></ion-back-button>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content></ion-content>
|
||||
</ion-page>
|
||||
`,
|
||||
components: { IonPage, IonContent, IonHeader, IonToolbar, IonBackButton }
|
||||
}
|
||||
|
||||
const router = createRouter({
|
||||
history: createMemoryHistory(process.env.BASE_URL),
|
||||
routes: [
|
||||
{ path: '/', component: PageTemplate },
|
||||
{ path: '/page2', component: PageTemplate },
|
||||
{ path: '/page3', component: PageTemplate }
|
||||
]
|
||||
});
|
||||
const push = jest.spyOn(router, 'back')
|
||||
|
||||
router.push('/');
|
||||
await router.isReady();
|
||||
const wrapper = mount(App, {
|
||||
global: {
|
||||
plugins: [router, IonicVue]
|
||||
}
|
||||
});
|
||||
|
||||
router.push('/page2');
|
||||
await waitForRouter();
|
||||
|
||||
router.push('/page3');
|
||||
await waitForRouter();
|
||||
|
||||
|
||||
const backButtons = wrapper.findAllComponents(IonBackButton);
|
||||
const pageTwoButton = backButtons[1];
|
||||
const pageThreeButton = backButtons[2];
|
||||
|
||||
await pageThreeButton.trigger('click');
|
||||
await waitForRouter();
|
||||
|
||||
await pageTwoButton.trigger('click');
|
||||
await waitForRouter();
|
||||
|
||||
expect(push).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
})
|