diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6df95c181d..b80e2ff094 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,7 +65,7 @@ jobs: # component playgrounds always load # the latest version of Ionic. - name: Purge JSDelivr Cache - run: | + run: | curl -X POST \ https://purge.jsdelivr.net/ \ -H 'cache-control: no-cache' \ @@ -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" ]}' diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bc764a392..f112d97a3f 100644 --- a/CHANGELOG.md +++ b/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) diff --git a/angular/CHANGELOG.md b/angular/CHANGELOG.md index 1901c0dbc7..19f4b29b55 100644 --- a/angular/CHANGELOG.md +++ b/angular/CHANGELOG.md @@ -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 diff --git a/angular/package-lock.json b/angular/package-lock.json index 3229b72ed8..875cfff038 100644 --- a/angular/package-lock.json +++ b/angular/package-lock.json @@ -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", diff --git a/angular/package.json b/angular/package.json index d55be60c44..3505221f0e 100644 --- a/angular/package.json +++ b/angular/package.json @@ -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" }, diff --git a/angular/src/ionic-module.ts b/angular/src/ionic-module.ts index 2e58b0ba1c..64c5cd9003 100644 --- a/angular/src/ionic-module.ts +++ b/angular/src/ionic-module.ts @@ -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, diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 42cdffd6c9..afd7d99085 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -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) diff --git a/core/package-lock.json b/core/package-lock.json index ca8afc2734..b3042479c8 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -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", diff --git a/core/package.json b/core/package.json index 805df7892f..f3789692c3 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/core", - "version": "6.2.1", + "version": "6.2.2", "description": "Base components for Ionic", "keywords": [ "ionic", diff --git a/core/src/components/datetime/datetime.tsx b/core/src/components/datetime/datetime.tsx index ced53c64bb..2d2c354068 100644 --- a/core/src/components/datetime/datetime.tsx +++ b/core/src/components/datetime/datetime.tsx @@ -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[]) { diff --git a/core/src/components/datetime/test/prefer-wheel/datetime.e2e.ts b/core/src/components/datetime/test/prefer-wheel/datetime.e2e.ts index 3072c7fc03..7ae1f3ca3c 100644 --- a/core/src/components/datetime/test/prefer-wheel/datetime.e2e.ts +++ b/core/src/components/datetime/test/prefer-wheel/datetime.e2e.ts @@ -89,26 +89,64 @@ test.describe('datetime: prefer wheel', () => { expect(await yearValues.count()).toBe(3); expect(await dayValues.count()).toBe(5); }); - test('should correctly localize the date data', async ({ page }) => { - await page.setContent(` - - `); + test.describe('datetime: date wheel localization', () => { + test('should correctly localize the date data', async ({ page }) => { + await page.setContent(` + + `); - await page.waitForSelector('.datetime-ready'); + await page.waitForSelector('.datetime-ready'); - const monthValues = page.locator('.month-column .picker-item:not(.picker-item-empty)'); - const dayValues = page.locator('.day-column .picker-item:not(.picker-item-empty)'); + const monthValues = page.locator('.month-column .picker-item:not(.picker-item-empty)'); + const dayValues = page.locator('.day-column .picker-item:not(.picker-item-empty)'); - expect(monthValues).toHaveText(['1月', '2月', '3月']); - expect(dayValues).toHaveText(['1日', '2日', '3日']); + 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(` + + `); + + 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(` + + `); + + 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', () => { diff --git a/core/src/components/datetime/utils/helpers.ts b/core/src/components/datetime/utils/helpers.ts index 141b965502..370de63b42 100644 --- a/core/src/components/datetime/utils/helpers.ts +++ b/core/src/components/datetime/utils/helpers.ts @@ -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'; }; diff --git a/core/src/components/radio-group/test/basic/index.html b/core/src/components/radio-group/test/basic/index.html index 53e68659f6..5b690307e3 100644 --- a/core/src/components/radio-group/test/basic/index.html +++ b/core/src/components/radio-group/test/basic/index.html @@ -22,161 +22,35 @@ - -

- Add Radio - Add Checked - Remove Radio -

- + - + - Luckiest Man On Earth + Radio Group Header - Biff - - - + Item 1 + - Griff - - - + Item 2 + - Buford - - - + Item 3 + - George - - - - - - - - - Huey - - - - - Dewey - - - - - Louie - - - - - - - - - Maintenance Drone - - - - Huey - - - - - Dewey - - - - - Louie - + Item 4 + - - - - diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts b/core/src/components/radio-group/test/basic/radio-group.e2e.ts new file mode 100644 index 0000000000..3916a5e280 --- /dev/null +++ b/core/src/components/radio-group/test/basic/radio-group.e2e.ts @@ -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(` + + + One + + + + `); + + await radioFixture.checkRadio('keyboard'); + await radioFixture.expectChecked(true); + }); + + test('spacebar should deselect with allowEmptySelection', async ({ page }) => { + await page.setContent(` + + + One + + + + `); + + await radioFixture.checkRadio('keyboard'); + await radioFixture.expectChecked(false); + }); + + test('click should not deselect without allowEmptySelection', async ({ page }) => { + await page.setContent(` + + + One + + + + `); + + await radioFixture.checkRadio('mouse'); + await radioFixture.expectChecked(true); + }); + + test('click should deselect with allowEmptySelection', async ({ page }) => { + await page.setContent(` + + + One + + + + `); + + 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); + } +} diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..10526e13ec Binary files /dev/null and b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-ltr-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..530024862e Binary files /dev/null and b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-ltr-Mobile-Safari-linux.png b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-ltr-Mobile-Safari-linux.png new file mode 100644 index 0000000000..a25993629a Binary files /dev/null and b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-rtl-Mobile-Chrome-linux.png b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-rtl-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..e1c94c7fd0 Binary files /dev/null and b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-rtl-Mobile-Chrome-linux.png differ diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-rtl-Mobile-Firefox-linux.png b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-rtl-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..986c40f8ff Binary files /dev/null and b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-rtl-Mobile-Safari-linux.png b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-rtl-Mobile-Safari-linux.png new file mode 100644 index 0000000000..4663fa1e04 Binary files /dev/null and b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-ios-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-ltr-Mobile-Chrome-linux.png b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..d3e1bdc629 Binary files /dev/null and b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-ltr-Mobile-Firefox-linux.png b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-ltr-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..85fa71cf2a Binary files /dev/null and b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-ltr-Mobile-Safari-linux.png b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-ltr-Mobile-Safari-linux.png new file mode 100644 index 0000000000..64bd3fc737 Binary files /dev/null and b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-rtl-Mobile-Chrome-linux.png b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-rtl-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..f40e0710aa Binary files /dev/null and b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-rtl-Mobile-Chrome-linux.png differ diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-rtl-Mobile-Firefox-linux.png b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-rtl-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..6f574063ce Binary files /dev/null and b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-rtl-Mobile-Safari-linux.png b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-rtl-Mobile-Safari-linux.png new file mode 100644 index 0000000000..b798475214 Binary files /dev/null and b/core/src/components/radio-group/test/basic/radio-group.e2e.ts-snapshots/radio-group-diff-md-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/radio-group/test/form/radio-group.e2e.ts b/core/src/components/radio-group/test/form/radio-group.e2e.ts new file mode 100644 index 0000000000..d6a833e6e6 --- /dev/null +++ b/core/src/components/radio-group/test/form/radio-group.e2e.ts @@ -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(''); + }); +}); diff --git a/core/src/components/radio-group/test/radio-group.e2e.ts b/core/src/components/radio-group/test/radio-group.e2e.ts deleted file mode 100644 index 9a6aa2f80a..0000000000 --- a/core/src/components/radio-group/test/radio-group.e2e.ts +++ /dev/null @@ -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(` - - - One - - - - `); - - await radioFixture.checkRadio('keyboard'); - await radioFixture.expectChecked(true); - }); - - test('spacebar should deselect with allowEmptySelection', async ({ page }) => { - await page.setContent(` - - - One - - - - `); - - await radioFixture.checkRadio('keyboard'); - await radioFixture.expectChecked(false); - }); - - test('click should not deselect without allowEmptySelection', async ({ page }) => { - await page.setContent(` - - - One - - - - `); - - await radioFixture.checkRadio('mouse'); - await radioFixture.expectChecked(true); - }); - - test('click should deselect with allowEmptySelection', async ({ page }) => { - await page.setContent(` - - - One - - - - `); - - 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); - } -} diff --git a/core/src/components/radio-group/test/search/radio-group.e2e.ts b/core/src/components/radio-group/test/search/radio-group.e2e.ts new file mode 100644 index 0000000000..ef031bb4a4 --- /dev/null +++ b/core/src/components/radio-group/test/search/radio-group.e2e.ts @@ -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); + }); + }); +}); diff --git a/core/src/components/searchbar/test/basic/e2e.ts b/core/src/components/searchbar/test/basic/e2e.ts deleted file mode 100644 index 72fbd73204..0000000000 --- a/core/src/components/searchbar/test/basic/e2e.ts +++ /dev/null @@ -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(); - } -}); diff --git a/core/src/components/searchbar/test/basic/index.html b/core/src/components/searchbar/test/basic/index.html index a2074b4ae5..3ec031120d 100644 --- a/core/src/components/searchbar/test/basic/index.html +++ b/core/src/components/searchbar/test/basic/index.html @@ -26,61 +26,25 @@
Search - Default
-
Search - No Cancel Button
- - -
Search - Always Show Cancel Button
- + +
Search - Never Show Cancel Button
Search - Show Cancel Button on Focus
- - -
Search - Cancel Button set to false
- - - -
Search - Cancel Button set to true
- - +
Search - No Clear Button
- +
Search - Always Show Clear Button
- +
Search - Input mode set to numeric
Search - Custom Search Icon -
Search - Animated
- -
Search - Custom Placeholder
-
Search - Custom Cancel Button Danger
- - +
Search - Custom Cancel Button
+
Search - Custom Cancel Button Icon through property
- - -
Search - Value passed
- - - -
Search - Mode iOS
- - -
Search - Mode MD
- +
Search - DebounceTime
-

- Change Value -

-
Toggle Property
@@ -173,13 +117,6 @@ Toggle disabled - -
diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts b/core/src/components/searchbar/test/basic/searchbar.e2e.ts new file mode 100644 index 0000000000..b387954480 --- /dev/null +++ b/core/src/components/searchbar/test/basic/searchbar.e2e.ts @@ -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); + }); +}); diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..bc5004bf08 Binary files /dev/null and b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-ltr-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..71a0f64a80 Binary files /dev/null and b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-ltr-Mobile-Safari-linux.png b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-ltr-Mobile-Safari-linux.png new file mode 100644 index 0000000000..d3d4c7e2e5 Binary files /dev/null and b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-rtl-Mobile-Chrome-linux.png b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-rtl-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..e5b5567c74 Binary files /dev/null and b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-rtl-Mobile-Chrome-linux.png differ diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-rtl-Mobile-Firefox-linux.png b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-rtl-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..a41e7b1f5f Binary files /dev/null and b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-rtl-Mobile-Safari-linux.png b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-rtl-Mobile-Safari-linux.png new file mode 100644 index 0000000000..3f634b2763 Binary files /dev/null and b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-ios-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-ltr-Mobile-Chrome-linux.png b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..0ef1948c88 Binary files /dev/null and b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-ltr-Mobile-Firefox-linux.png b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-ltr-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..7a1d6db328 Binary files /dev/null and b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-ltr-Mobile-Safari-linux.png b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-ltr-Mobile-Safari-linux.png new file mode 100644 index 0000000000..4f65097bf6 Binary files /dev/null and b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-rtl-Mobile-Chrome-linux.png b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-rtl-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..3e62d6c3e3 Binary files /dev/null and b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-rtl-Mobile-Chrome-linux.png differ diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-rtl-Mobile-Firefox-linux.png b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-rtl-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..2a892ec32d Binary files /dev/null and b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-rtl-Mobile-Safari-linux.png b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-rtl-Mobile-Safari-linux.png new file mode 100644 index 0000000000..d58afe15f3 Binary files /dev/null and b/core/src/components/searchbar/test/basic/searchbar.e2e.ts-snapshots/searchbar-diff-md-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/searchbar/test/rtl/e2e.ts b/core/src/components/searchbar/test/rtl/e2e.ts deleted file mode 100644 index dc221a2abd..0000000000 --- a/core/src/components/searchbar/test/rtl/e2e.ts +++ /dev/null @@ -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(); -}); diff --git a/core/src/components/searchbar/test/rtl/index.html b/core/src/components/searchbar/test/rtl/index.html deleted file mode 100644 index 899d814773..0000000000 --- a/core/src/components/searchbar/test/rtl/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - Searchbar - RTL - - - - - - - - - - - - - Searchbar - RTL - - - - -
Search - Default
- -
-
- - diff --git a/core/src/components/searchbar/test/standalone/e2e.ts b/core/src/components/searchbar/test/standalone/e2e.ts deleted file mode 100644 index 2477fd8b72..0000000000 --- a/core/src/components/searchbar/test/standalone/e2e.ts +++ /dev/null @@ -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(); -}); diff --git a/core/src/components/searchbar/test/standalone/index.html b/core/src/components/searchbar/test/standalone/index.html index 9e1e7808ca..2cebe90391 100644 --- a/core/src/components/searchbar/test/standalone/index.html +++ b/core/src/components/searchbar/test/standalone/index.html @@ -43,26 +43,9 @@ - + - - - - - - - - - - - diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 1ac11774de..7a7f8d26da 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -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 diff --git a/docs/package-lock.json b/docs/package-lock.json index a1be69eb3e..1a86f901eb 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -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" } } diff --git a/docs/package.json b/docs/package.json index 053966a0b0..a41188dde5 100644 --- a/docs/package.json +++ b/docs/package.json @@ -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", diff --git a/lerna.json b/lerna.json index 4a4befb45f..baf9961b81 100644 --- a/lerna.json +++ b/lerna.json @@ -5,5 +5,5 @@ "angular", "packages/*" ], - "version": "6.2.1" + "version": "6.2.2" } diff --git a/packages/angular-server/CHANGELOG.md b/packages/angular-server/CHANGELOG.md index a14afa1d69..96135f0b27 100644 --- a/packages/angular-server/CHANGELOG.md +++ b/packages/angular-server/CHANGELOG.md @@ -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 diff --git a/packages/angular-server/package-lock.json b/packages/angular-server/package-lock.json index 6373f22549..03954e9359 100644 --- a/packages/angular-server/package-lock.json +++ b/packages/angular-server/package-lock.json @@ -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", diff --git a/packages/angular-server/package.json b/packages/angular-server/package.json index fe52f511d0..77e9361b60 100644 --- a/packages/angular-server/package.json +++ b/packages/angular-server/package.json @@ -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", diff --git a/packages/react-router/CHANGELOG.md b/packages/react-router/CHANGELOG.md index 2b27268e3b..4c2f5f37ee 100644 --- a/packages/react-router/CHANGELOG.md +++ b/packages/react-router/CHANGELOG.md @@ -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 diff --git a/packages/react-router/package-lock.json b/packages/react-router/package-lock.json index aa137c3afa..faec7e5ff0 100644 --- a/packages/react-router/package-lock.json +++ b/packages/react-router/package-lock.json @@ -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": "*" } diff --git a/packages/react-router/package.json b/packages/react-router/package.json index 62b95dd742..795cbe9785 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -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": { diff --git a/packages/react-router/src/ReactRouter/StackManager.tsx b/packages/react-router/src/ReactRouter/StackManager.tsx index 01c2b3641c..e000008aef 100644 --- a/packages/react-router/src/ReactRouter/StackManager.tsx +++ b/packages/react-router/src/ReactRouter/StackManager.tsx @@ -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 { id: string; @@ -33,6 +34,7 @@ export class StackManager extends React.PureComponent true, }; + private clearOutletTimeout: any; private pendingPageTransition = false; constructor(props: StackManagerProps) { @@ -46,9 +48,20 @@ export class StackManager extends React.PureComponent { 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 { 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 { - // console.log('Removing viewstack for outletID ' + outletId); + return setTimeout(() => { delete this.viewStacks[outletId]; }, 500); } diff --git a/packages/vue-router/CHANGELOG.md b/packages/vue-router/CHANGELOG.md index ecb26785d1..6a96734905 100644 --- a/packages/vue-router/CHANGELOG.md +++ b/packages/vue-router/CHANGELOG.md @@ -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 diff --git a/packages/vue-router/package-lock.json b/packages/vue-router/package-lock.json index 636b44ade1..643405a704 100644 --- a/packages/vue-router/package-lock.json +++ b/packages/vue-router/package-lock.json @@ -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" } }, diff --git a/packages/vue-router/package.json b/packages/vue-router/package.json index f2add95b2a..739e5dce2f 100644 --- a/packages/vue-router/package.json +++ b/packages/vue-router/package.json @@ -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", diff --git a/packages/vue-router/src/router.ts b/packages/vue-router/src/router.ts index 71fc08c248..755820f214 100644 --- a/packages/vue-router/src/router.ts +++ b/packages/vue-router/src/router.ts @@ -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(); diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 6702428b88..c07b070406 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -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 diff --git a/packages/vue/package-lock.json b/packages/vue/package-lock.json index 8399155d17..6f5f9e9de2 100644 --- a/packages/vue/package-lock.json +++ b/packages/vue/package-lock.json @@ -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", diff --git a/packages/vue/package.json b/packages/vue/package.json index c7e8dde876..8be351c4ae 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -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": { diff --git a/packages/vue/test-app/tests/unit/memory.spec.ts b/packages/vue/test-app/tests/unit/memory.spec.ts new file mode 100644 index 0000000000..8a6ce3dd7d --- /dev/null +++ b/packages/vue/test-app/tests/unit/memory.spec.ts @@ -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: '', +} + +describe('createMemoryHistory', () => { + beforeAll(() => { + (HTMLElement.prototype as HTMLIonRouterOutletElement).commit = jest.fn(); + }); + it('should not error when going back with memory router', async () => { + const PageTemplate = { + template: ` + + + + + + + + + `, + 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); + }); +})