diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9c913dccf9..6f45c1c078 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -15,9 +15,9 @@ ## Angular -/packages/angular/ @sean-perkins -/packages/angular-server @sean-perkins -/packages/angular/test +/packages/angular/ @sean-perkins @thetaPC +/packages/angular-server @sean-perkins @thetaPC +/packages/angular/test @thetaPC ## React @@ -28,19 +28,23 @@ ## Vue -/packages/vue/ @liamdebeasi -/packages/vue-router/ @liamdebeasi -/packages/vue/test/ -/packages/vue-router/__tests__ +/packages/vue/ @liamdebeasi @thetaPC +/packages/vue-router/ @liamdebeasi @thetaPC +/packages/vue/test/ @thetaPC +/packages/vue-router/__tests__ @thetaPC # Components /core/src/components/accordion/ @liamdebeasi /core/src/components/accordion-group/ @liamdebeasi +/core/src/components/checkbox/ @amandaejohnston + /core/src/components/datetime/ @liamdebeasi @amandaejohnston @sean-perkins /core/src/components/datetime-button/ @liamdebeasi +/core/src/components/item/ @brandyscarney + /core/src/components/menu/ @amandaejohnston /core/src/components/menu-toggle/ @amandaejohnston @@ -50,9 +54,19 @@ /core/src/components/picker-internal/ @liamdebeasi /core/src/components/picker-column-internal/ @liamdebeasi +/core/src/components/radio/ @amandaejohnston +/core/src/components/radio-group/ @amandaejohnston + /core/src/components/refresher/ @liamdebeasi /core/src/components/refresher-content/ @liamdebeasi +/core/src/components/searchbar/ @brandyscarney + +/core/src/components/segment/ @brandyscarney +/core/src/components/segment-button/ @brandyscarney + +/core/src/components/skeleton-text/ @brandyscarney + # Utilities /core/src/utils/animation/ @liamdebeasi @@ -64,3 +78,13 @@ /core/src/utils/sanitization/ @liamdebeasi /core/src/utils/tap-click/ @liamdebeasi /core/src/utils/transition/ @liamdebeasi + +/core/src/css/ @brandyscarney +/core/src/themes/ @brandyscarney + +# Tests + +**/datetime.e2e.ts @mapsandapps +**/datetime-button.e2e.ts @mapsandapps +**/icon.e2e.ts @mapsandapps +**/loading.e2e.ts @mapsandapps diff --git a/.github/workflows/actions/test-core-clean-build/action.yml b/.github/workflows/actions/test-core-clean-build/action.yml index f7b55d7465..ae41a8924f 100644 --- a/.github/workflows/actions/test-core-clean-build/action.yml +++ b/.github/workflows/actions/test-core-clean-build/action.yml @@ -13,6 +13,15 @@ runs: path: ./core filename: CoreBuild.zip - name: Check Diff - run: git diff --exit-code + run: | + git diff --exit-code || { + echo -e "\033[1;31m⚠️ Error: Differences Detected ⚠️\033[0m" + echo -e "\033[1;31mThere are uncommitted changes between the build outputs from CI and your branch.\033[0m" + echo -e "\033[1;31mPlease ensure you have followed these steps:\033[0m" + echo -e "\033[1;31m1. Run 'npm run build' locally to generate the latest build output.\033[0m" + echo -e "\033[1;31m2. Commit and push all necessary changes to your branch.\033[0m" + echo -e "\033[1;31m3. Compare and validate the differences before proceeding.\033[0m" + exit 1 + } shell: bash working-directory: ./core diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c440cb5a2..1849a4c122 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23) + + +### Bug Fixes + +* **angular:** ionTabsWillChange is fired before tab activation ([#27991](https://github.com/ionic-team/ionic-framework/issues/27991)) ([bbfb8f8](https://github.com/ionic-team/ionic-framework/commit/bbfb8f81a61475d7e73b63743db5d6a0cd979d21)), closes [#27212](https://github.com/ionic-team/ionic-framework/issues/27212) +* **input, textarea:** clearOnEdit does not clear when pressing Tab ([#28005](https://github.com/ionic-team/ionic-framework/issues/28005)) ([444acc1](https://github.com/ionic-team/ionic-framework/commit/444acc1f1bca348b62dfb398067cc087529f67f1)), closes [#27746](https://github.com/ionic-team/ionic-framework/issues/27746) +* **react:** avoid multiple invocations of onDidDismiss and onWillPresent ([#28020](https://github.com/ionic-team/ionic-framework/issues/28020)) ([0ac3df3](https://github.com/ionic-team/ionic-framework/commit/0ac3df3f378bdefc3a927adc798ebd9ec7a54fee)), closes [#28010](https://github.com/ionic-team/ionic-framework/issues/28010) + + + + + # [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16) diff --git a/README.md b/README.md index c3790ca495..3ca6f6ca97 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ | Project | Package | Version | Downloads| Links | | ------- | ------- | ------- | -------- |:-----:| | **Core** | [`@ionic/core`](https://www.npmjs.com/package/@ionic/core) | [![version](https://img.shields.io/npm/v/@ionic/core/latest.svg)](https://www.npmjs.com/package/@ionic/core) | NPM Downloads | [`README.md`](core/README.md) -| **Angular** | [`@ionic/angular`](https://www.npmjs.com/package/@ionic/angular) | [![version](https://img.shields.io/npm/v/@ionic/angular/latest.svg)](https://www.npmjs.com/package/@ionic/angular) | NPM Downloads | [`README.md`](angular/README.md) +| **Angular** | [`@ionic/angular`](https://www.npmjs.com/package/@ionic/angular) | [![version](https://img.shields.io/npm/v/@ionic/angular/latest.svg)](https://www.npmjs.com/package/@ionic/angular) | NPM Downloads | [`README.md`](packages/angular/README.md) | **Vue** | [`@ionic/vue`](https://www.npmjs.com/package/@ionic/vue) | [![version](https://img.shields.io/npm/v/@ionic/vue/latest.svg)](https://www.npmjs.com/package/@ionic/vue) | NPM Downloads | [`README.md`](packages/vue/README.md) | **React** | [`@ionic/react`](https://www.npmjs.com/package/@ionic/react) | [![version](https://img.shields.io/npm/v/@ionic/react/latest.svg)](https://www.npmjs.com/package/@ionic/react) | NPM Downloads |[`README.md`](packages/react/README.md) diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 39ff4c7296..47f747d30a 100644 --- a/core/CHANGELOG.md +++ b/core/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. +## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23) + + +### Bug Fixes + +* **input, textarea:** clearOnEdit does not clear when pressing Tab ([#28005](https://github.com/ionic-team/ionic-framework/issues/28005)) ([444acc1](https://github.com/ionic-team/ionic-framework/commit/444acc1f1bca348b62dfb398067cc087529f67f1)), closes [#27746](https://github.com/ionic-team/ionic-framework/issues/27746) + + + + + # [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16) diff --git a/core/package-lock.json b/core/package-lock.json index c8fa61a450..9aed29cc88 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -1,28 +1,28 @@ { "name": "@ionic/core", - "version": "7.3.0", + "version": "7.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/core", - "version": "7.3.0", + "version": "7.3.1", "license": "MIT", "dependencies": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" }, "devDependencies": { "@axe-core/playwright": "^4.7.3", - "@capacitor/core": "^5.2.3", + "@capacitor/core": "^5.3.0", "@capacitor/haptics": "^5.0.6", "@capacitor/keyboard": "^5.0.6", "@capacitor/status-bar": "^5.0.6", "@ionic/eslint-config": "^0.3.0", "@ionic/prettier-config": "^2.0.0", "@jest/core": "^27.5.1", - "@playwright/test": "^1.37.0", + "@playwright/test": "^1.37.1", "@rollup/plugin-node-resolve": "^8.4.0", "@rollup/plugin-virtual": "^2.0.3", "@stencil/angular-output-target": "^0.7.1", @@ -607,9 +607,9 @@ "dev": true }, "node_modules/@capacitor/core": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.2.3.tgz", - "integrity": "sha512-Q1zbgt3Mvldy7six2/GX54kTL0ozgnR37jeDUAXL/fOJBF4Iorr/8A0OjGEAnwEjpR1la7uFZUunESMFyMLhEQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.3.0.tgz", + "integrity": "sha512-mvhh1yJtcUTZ0hUUriBKKpxq47hn75bjxH3tYPRgAFu1z3gowCg+OtG4Rce3W5gr5fSfCjQgOSL0Vp7k9hPUWw==", "dev": true, "dependencies": { "tslib": "^2.1.0" @@ -1541,13 +1541,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.0.tgz", - "integrity": "sha512-181WBLk4SRUyH1Q96VZl7BP6HcK0b7lbdeKisn3N/vnjitk+9HbdlFz/L5fey05vxaAhldIDnzo8KUoy8S3mmQ==", + "version": "1.37.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz", + "integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==", "dev": true, "dependencies": { "@types/node": "*", - "playwright-core": "1.37.0" + "playwright-core": "1.37.1" }, "bin": { "playwright": "cli.js" @@ -1634,9 +1634,9 @@ } }, "node_modules/@stencil/core": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.3.tgz", - "integrity": "sha512-uWaH4tQ16So1feRu4tD0gupDEnzhRatS3Jp9uYkYlqjhx5BQ/ox5CTP+lxboochqkLlvkmXvhH9SsEV+UTsYTA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==", "bin": { "stencil": "bin/stencil" }, @@ -8194,9 +8194,9 @@ } }, "node_modules/playwright-core": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.0.tgz", - "integrity": "sha512-1c46jhTH/myQw6sesrcuHVtLoSNfJv8Pfy9t3rs6subY7kARv0HRw5PpyfPYPpPtQvBOmgbE6K+qgYUpj81LAA==", + "version": "1.37.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz", + "integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -10788,9 +10788,9 @@ "dev": true }, "@capacitor/core": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.2.3.tgz", - "integrity": "sha512-Q1zbgt3Mvldy7six2/GX54kTL0ozgnR37jeDUAXL/fOJBF4Iorr/8A0OjGEAnwEjpR1la7uFZUunESMFyMLhEQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.3.0.tgz", + "integrity": "sha512-mvhh1yJtcUTZ0hUUriBKKpxq47hn75bjxH3tYPRgAFu1z3gowCg+OtG4Rce3W5gr5fSfCjQgOSL0Vp7k9hPUWw==", "dev": true, "requires": { "tslib": "^2.1.0" @@ -11455,14 +11455,14 @@ } }, "@playwright/test": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.0.tgz", - "integrity": "sha512-181WBLk4SRUyH1Q96VZl7BP6HcK0b7lbdeKisn3N/vnjitk+9HbdlFz/L5fey05vxaAhldIDnzo8KUoy8S3mmQ==", + "version": "1.37.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz", + "integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==", "dev": true, "requires": { "@types/node": "*", "fsevents": "2.3.2", - "playwright-core": "1.37.0" + "playwright-core": "1.37.1" } }, "@rollup/plugin-node-resolve": { @@ -11524,9 +11524,9 @@ "requires": {} }, "@stencil/core": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.3.tgz", - "integrity": "sha512-uWaH4tQ16So1feRu4tD0gupDEnzhRatS3Jp9uYkYlqjhx5BQ/ox5CTP+lxboochqkLlvkmXvhH9SsEV+UTsYTA==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==" }, "@stencil/react-output-target": { "version": "0.5.3", @@ -16332,9 +16332,9 @@ } }, "playwright-core": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.0.tgz", - "integrity": "sha512-1c46jhTH/myQw6sesrcuHVtLoSNfJv8Pfy9t3rs6subY7kARv0HRw5PpyfPYPpPtQvBOmgbE6K+qgYUpj81LAA==", + "version": "1.37.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz", + "integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==", "dev": true }, "postcss": { diff --git a/core/package.json b/core/package.json index db3d0394c0..fd46ff517c 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/core", - "version": "7.3.0", + "version": "7.3.1", "description": "Base components for Ionic", "keywords": [ "ionic", @@ -31,20 +31,20 @@ "loader/" ], "dependencies": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" }, "devDependencies": { "@axe-core/playwright": "^4.7.3", - "@capacitor/core": "^5.2.3", + "@capacitor/core": "^5.3.0", "@capacitor/haptics": "^5.0.6", "@capacitor/keyboard": "^5.0.6", "@capacitor/status-bar": "^5.0.6", "@ionic/eslint-config": "^0.3.0", "@ionic/prettier-config": "^2.0.0", "@jest/core": "^27.5.1", - "@playwright/test": "^1.37.0", + "@playwright/test": "^1.37.1", "@rollup/plugin-node-resolve": "^8.4.0", "@rollup/plugin-virtual": "^2.0.3", "@stencil/angular-output-target": "^0.7.1", diff --git a/core/src/components/button/button.tsx b/core/src/components/button/button.tsx index 73fe417fca..a0c3c4570f 100644 --- a/core/src/components/button/button.tsx +++ b/core/src/components/button/button.tsx @@ -153,6 +153,15 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf */ @Event() ionBlur!: EventEmitter; + /** + * This is responsible for rendering a hidden native + * button element inside the associated form. This allows + * users to submit a form by pressing "Enter" when a text + * field inside of the form is focused. The native button + * rendered inside of `ion-button` is in the Shadow DOM + * and therefore does not participate in form submission + * which is why the following code is necessary. + */ private renderHiddenButton() { const formEl = (this.formEl = this.findForm()); if (formEl) { @@ -323,6 +332,13 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf fill = this.inToolbar || this.inListHeader ? 'clear' : 'solid'; } + /** + * We call renderHiddenButton in the render function to account + * for any properties being set async. For example, changing the + * "type" prop from "button" to "submit" after the component has + * loaded would warrant the hidden button being added to the + * associated form. + */ { type !== 'button' && this.renderHiddenButton(); } diff --git a/core/src/components/datetime/test/parse.spec.ts b/core/src/components/datetime/test/parse.spec.ts index 282ec75a42..ea2e5132b0 100644 --- a/core/src/components/datetime/test/parse.spec.ts +++ b/core/src/components/datetime/test/parse.spec.ts @@ -154,6 +154,18 @@ describe('parseMinParts()', () => { minute: 30, }); }); + it('should return undefined when given invalid info', () => { + const today = { + day: 14, + month: 3, + year: 2022, + minute: 4, + hour: 2, + }; + expect(parseMinParts(undefined, today)).toEqual(undefined); + expect(parseMinParts(null, today)).toEqual(undefined); + expect(parseMinParts('foo', today)).toEqual(undefined); + }); }); describe('parseMaxParts()', () => { @@ -205,4 +217,16 @@ describe('parseMaxParts()', () => { minute: 59, }); }); + it('should return undefined when given invalid info', () => { + const today = { + day: 14, + month: 3, + year: 2022, + minute: 4, + hour: 2, + }; + expect(parseMaxParts(undefined, today)).toEqual(undefined); + expect(parseMaxParts(null, today)).toEqual(undefined); + expect(parseMaxParts('foo', today)).toEqual(undefined); + }); }); diff --git a/core/src/components/datetime/utils/parse.ts b/core/src/components/datetime/utils/parse.ts index 6904462f84..efda69f655 100644 --- a/core/src/components/datetime/utils/parse.ts +++ b/core/src/components/datetime/utils/parse.ts @@ -154,9 +154,16 @@ export const parseAmPm = (hour: number) => { * month, day, hour, and minute information. */ export const parseMaxParts = (max: string, todayParts: DatetimeParts): DatetimeParts | undefined => { - const parsedMax = parseDate(max); - if (!parsedMax) return; - const { month, day, year, hour, minute } = parsedMax; + const result = parseDate(max); + + /** + * If min was not a valid date then return undefined. + */ + if (result === undefined) { + return; + } + + const { month, day, year, hour, minute } = result; /** * When passing in `max` or `min`, developers @@ -192,9 +199,16 @@ export const parseMaxParts = (max: string, todayParts: DatetimeParts): DatetimeP * month, day, hour, and minute information. */ export const parseMinParts = (min: string, todayParts: DatetimeParts): DatetimeParts | undefined => { - const parsedMin = parseDate(min); - if (!parsedMin) return; - const { month, day, year, hour, minute } = parsedMin; + const result = parseDate(min); + + /** + * If min was not a valid date then return undefined. + */ + if (result === undefined) { + return; + } + + const { month, day, year, hour, minute } = result; /** * When passing in `max` or `min`, developers diff --git a/core/src/components/input/input.tsx b/core/src/components/input/input.tsx index 44dec367e4..6498eeffa4 100644 --- a/core/src/components/input/input.tsx +++ b/core/src/components/input/input.tsx @@ -532,7 +532,7 @@ export class Input implements ComponentInterface { * Clear the input if the control has not been previously cleared during focus. * Do not clear if the user hitting enter to submit a form. */ - if (!this.didInputClearOnEdit && this.hasValue() && ev.key !== 'Enter') { + if (!this.didInputClearOnEdit && this.hasValue() && ev.key !== 'Enter' && ev.key !== 'Tab') { this.value = ''; this.emitInputChange(ev); } diff --git a/core/src/components/input/test/basic/index.html b/core/src/components/input/test/basic/index.html new file mode 100644 index 0000000000..9ab5c6ecab --- /dev/null +++ b/core/src/components/input/test/basic/index.html @@ -0,0 +1,57 @@ + + + + + Input - Basic + + + + + + + + + + + + + + Input - Basic + + + + +
+
+

Default

+ +
+
+
+
+ + diff --git a/core/src/components/input/test/clear-on-edit/input.e2e.ts b/core/src/components/input/test/clear-on-edit/input.e2e.ts new file mode 100644 index 0000000000..e668690278 --- /dev/null +++ b/core/src/components/input/test/clear-on-edit/input.e2e.ts @@ -0,0 +1,43 @@ +import { expect } from '@playwright/test'; +import { test, configs } from '@utils/test/playwright'; + +configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('input: clearOnEdit'), () => { + test('should clear when typed into', async ({ page }) => { + await page.setContent(``, config); + + const ionInput = await page.spyOnEvent('ionInput'); + + const input = page.locator('ion-input'); + await input.locator('input').type('h'); + + await ionInput.next(); + + await expect(input).toHaveJSProperty('value', 'h'); + }); + + test('should not clear when enter is pressed', async ({ page }) => { + await page.setContent(``, config); + + const input = page.locator('ion-input'); + await input.locator('input').focus(); + + await page.keyboard.press('Enter'); + await page.waitForChanges(); + + await expect(input).toHaveJSProperty('value', 'abc'); + }); + + test('should not clear when tab is pressed', async ({ page }) => { + await page.setContent(``, config); + + const input = page.locator('ion-input'); + await input.locator('input').focus(); + + await page.keyboard.press('Tab'); + await page.waitForChanges(); + + await expect(input).toHaveJSProperty('value', 'abc'); + }); + }); +}); diff --git a/core/src/components/menu-button/test/async/index.html b/core/src/components/menu-button/test/async/index.html new file mode 100644 index 0000000000..105b9a3b87 --- /dev/null +++ b/core/src/components/menu-button/test/async/index.html @@ -0,0 +1,64 @@ + + + + + Menu - Async + + + + + + + + + + + + + +
+ + + Menu - Async + + + + + Main Content + + +
+
+ + + + diff --git a/core/src/components/menu-button/test/async/menu-button.e2e.ts b/core/src/components/menu-button/test/async/menu-button.e2e.ts new file mode 100644 index 0000000000..9d06238b19 --- /dev/null +++ b/core/src/components/menu-button/test/async/menu-button.e2e.ts @@ -0,0 +1,25 @@ +import { expect } from '@playwright/test'; +import { configs, test } from '@utils/test/playwright'; + +/** + * This behavior does not vary across modes/directions + */ +configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('menu button: async'), () => { + test('menu button should be visible if menu is moved', async ({ page }) => { + await page.goto(`/src/components/menu-button/test/async`, config); + + const menu = page.locator('ion-menu'); + const menuButton = page.locator('ion-menu-button'); + const triggerButton = page.locator('#trigger'); + + await expect(menu).not.toBeAttached(); + await expect(menuButton).toBeHidden(); + + await triggerButton.click(); + + await expect(menu).toBeAttached(); + await expect(menuButton).toBeVisible(); + }); + }); +}); diff --git a/core/src/components/menu/menu.tsx b/core/src/components/menu/menu.tsx index c010e72d2d..5072bb74cd 100644 --- a/core/src/components/menu/menu.tsx +++ b/core/src/components/menu/menu.tsx @@ -38,6 +38,7 @@ export class Menu implements ComponentInterface, MenuI { private lastOnEnd = 0; private gesture?: Gesture; private blocker = GESTURE_CONTROLLER.createBlocker({ disableScroll: true }); + private didLoad = false; isAnimating = false; width!: number; @@ -216,6 +217,7 @@ export class Menu implements ComponentInterface, MenuI { // register this menu with the app's menu controller menuController._register(this); + this.menuChanged(); this.gesture = (await import('../../utils/gesture')).createGesture({ el: document, @@ -237,10 +239,22 @@ export class Menu implements ComponentInterface, MenuI { } async componentDidLoad() { - this.ionMenuChange.emit({ disabled: this.disabled, open: this._isOpen }); + this.didLoad = true; + this.menuChanged(); this.updateState(); } + private menuChanged() { + /** + * Inform dependent components such as ion-menu-button + * that the menu is ready. Note that we only want to do this + * once the menu has been rendered which is why we check for didLoad. + */ + if (this.didLoad) { + this.ionMenuChange.emit({ disabled: this.disabled, open: this._isOpen }); + } + } + async disconnectedCallback() { /** * The menu should be closed when it is diff --git a/core/src/components/picker/picker-interface.ts b/core/src/components/picker/picker-interface.ts index 4ddb18c326..6a01a8d437 100644 --- a/core/src/components/picker/picker-interface.ts +++ b/core/src/components/picker/picker-interface.ts @@ -27,6 +27,9 @@ export interface PickerButton { export interface PickerColumn { name: string; align?: string; + /** + * Changing this value allows the initial value of a picker column to be set. + */ selectedIndex?: number; prevSelected?: number; prefix?: string; diff --git a/core/src/components/textarea/test/clear-on-edit/textarea.e2e.ts b/core/src/components/textarea/test/clear-on-edit/textarea.e2e.ts new file mode 100644 index 0000000000..f085f46ee8 --- /dev/null +++ b/core/src/components/textarea/test/clear-on-edit/textarea.e2e.ts @@ -0,0 +1,37 @@ +import { expect } from '@playwright/test'; +import { test, configs } from '@utils/test/playwright'; + +configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('textarea: clearOnEdit'), () => { + test('should clear when typed into', async ({ page }) => { + await page.setContent( + ``, + config + ); + + const ionInput = await page.spyOnEvent('ionInput'); + + const textarea = page.locator('ion-textarea'); + await textarea.locator('textarea').type('h'); + + await ionInput.next(); + + await expect(textarea).toHaveJSProperty('value', 'h'); + }); + + test('should not clear when tab is pressed', async ({ page }) => { + await page.setContent( + ``, + config + ); + + const textarea = page.locator('ion-textarea'); + await textarea.locator('textarea').focus(); + + await page.keyboard.press('Tab'); + await page.waitForChanges(); + + await expect(textarea).toHaveJSProperty('value', 'abc'); + }); + }); +}); diff --git a/core/src/components/textarea/textarea.tsx b/core/src/components/textarea/textarea.tsx index b49ad7cb9d..e2bb7e1a57 100644 --- a/core/src/components/textarea/textarea.tsx +++ b/core/src/components/textarea/textarea.tsx @@ -434,7 +434,7 @@ export class Textarea implements ComponentInterface { /** * Check if we need to clear the text input if clearOnEdit is enabled */ - private checkClearOnEdit(ev: Event) { + private checkClearOnEdit(ev: KeyboardEvent) { if (!this.clearOnEdit) { return; } @@ -442,7 +442,7 @@ export class Textarea implements ComponentInterface { * Clear the textarea if the control has not been previously cleared * during focus. */ - if (!this.didTextareaClearOnEdit && this.hasValue()) { + if (!this.didTextareaClearOnEdit && this.hasValue() && ev.key !== 'Tab') { this.value = ''; this.emitInputChange(ev); } @@ -501,7 +501,7 @@ export class Textarea implements ComponentInterface { this.ionBlur.emit(ev); }; - private onKeyDown = (ev: Event) => { + private onKeyDown = (ev: KeyboardEvent) => { this.checkClearOnEdit(ev); }; diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index ea824c5914..6e839b9d0a 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. +## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23) + +**Note:** Version bump only for package @ionic/docs + + + + + # [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16) **Note:** Version bump only for package @ionic/docs diff --git a/docs/package-lock.json b/docs/package-lock.json index 9aa4b113f6..368464d68f 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ionic/docs", - "version": "7.3.0", + "version": "7.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/docs", - "version": "7.3.0", + "version": "7.3.1", "license": "MIT" } } diff --git a/docs/package.json b/docs/package.json index a0f04f52b4..f8ba02d5a5 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/docs", - "version": "7.3.0", + "version": "7.3.1", "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 1585c6ac92..7e0e1026f2 100644 --- a/lerna.json +++ b/lerna.json @@ -4,5 +4,5 @@ "docs", "packages/*" ], - "version": "7.3.0" + "version": "7.3.1" } diff --git a/packages/angular-server/CHANGELOG.md b/packages/angular-server/CHANGELOG.md index ec13f8471d..e03e1b4a7a 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. +## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23) + +**Note:** Version bump only for package @ionic/angular-server + + + + + # [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16) **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 a3b4df6bc0..8a33a755d7 100644 --- a/packages/angular-server/package-lock.json +++ b/packages/angular-server/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/angular-server", - "version": "7.3.0", + "version": "7.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/angular-server", - "version": "7.3.0", + "version": "7.3.1", "license": "MIT", "dependencies": { - "@ionic/core": "^7.3.0" + "@ionic/core": "^7.3.1" }, "devDependencies": { "@angular-eslint/eslint-plugin": "^14.0.0", @@ -1060,19 +1060,19 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.0.tgz", - "integrity": "sha512-DPHG0U44O4WcknXa+x3JR/G/5ySxqCS5S8w65PZUQBYA657L4zkaGOvZpObP1MtiBLj9kG7c6Ae6xgJjrU7tyQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz", + "integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==", "dependencies": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" } }, "node_modules/@ionic/core/node_modules/@stencil/core": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.5.tgz", - "integrity": "sha512-0nZRvvhjjOKsQFGX0pKiDtOS/5IiL7HRxtLqpIxHAxXKLs9ZcomTsdOwl12m/qjx2AtQReOfP8+x8jLOBNMOIQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==", "bin": { "stencil": "bin/stencil" }, @@ -7342,19 +7342,19 @@ "dev": true }, "@ionic/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.0.tgz", - "integrity": "sha512-DPHG0U44O4WcknXa+x3JR/G/5ySxqCS5S8w65PZUQBYA657L4zkaGOvZpObP1MtiBLj9kG7c6Ae6xgJjrU7tyQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz", + "integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==", "requires": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" }, "dependencies": { "@stencil/core": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.5.tgz", - "integrity": "sha512-0nZRvvhjjOKsQFGX0pKiDtOS/5IiL7HRxtLqpIxHAxXKLs9ZcomTsdOwl12m/qjx2AtQReOfP8+x8jLOBNMOIQ==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==" } } }, diff --git a/packages/angular-server/package.json b/packages/angular-server/package.json index f1bc3d1203..b3be622d8f 100644 --- a/packages/angular-server/package.json +++ b/packages/angular-server/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular-server", - "version": "7.3.0", + "version": "7.3.1", "description": "Angular SSR Module for Ionic", "keywords": [ "ionic", @@ -61,6 +61,6 @@ }, "prettier": "@ionic/prettier-config", "dependencies": { - "@ionic/core": "^7.3.0" + "@ionic/core": "^7.3.1" } } diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index fa82b32572..aa820675a7 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/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. +## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23) + + +### Bug Fixes + +* **angular:** ionTabsWillChange is fired before tab activation ([#27991](https://github.com/ionic-team/ionic-framework/issues/27991)) ([bbfb8f8](https://github.com/ionic-team/ionic-framework/commit/bbfb8f81a61475d7e73b63743db5d6a0cd979d21)), closes [#27212](https://github.com/ionic-team/ionic-framework/issues/27212) + + + + + # [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16) **Note:** Version bump only for package @ionic/angular diff --git a/packages/angular/package-lock.json b/packages/angular/package-lock.json index 76bfb1895e..0770143aeb 100644 --- a/packages/angular/package-lock.json +++ b/packages/angular/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/angular", - "version": "7.3.0", + "version": "7.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/angular", - "version": "7.3.0", + "version": "7.3.1", "license": "MIT", "dependencies": { - "@ionic/core": "^7.3.0", + "@ionic/core": "^7.3.1", "ionicons": "^7.0.0", "jsonc-parser": "^3.0.0", "tslib": "^2.3.0" @@ -1227,19 +1227,19 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.0.tgz", - "integrity": "sha512-DPHG0U44O4WcknXa+x3JR/G/5ySxqCS5S8w65PZUQBYA657L4zkaGOvZpObP1MtiBLj9kG7c6Ae6xgJjrU7tyQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz", + "integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==", "dependencies": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" } }, "node_modules/@ionic/core/node_modules/@stencil/core": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.5.tgz", - "integrity": "sha512-0nZRvvhjjOKsQFGX0pKiDtOS/5IiL7HRxtLqpIxHAxXKLs9ZcomTsdOwl12m/qjx2AtQReOfP8+x8jLOBNMOIQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==", "bin": { "stencil": "bin/stencil" }, @@ -8104,19 +8104,19 @@ "dev": true }, "@ionic/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.0.tgz", - "integrity": "sha512-DPHG0U44O4WcknXa+x3JR/G/5ySxqCS5S8w65PZUQBYA657L4zkaGOvZpObP1MtiBLj9kG7c6Ae6xgJjrU7tyQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz", + "integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==", "requires": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" }, "dependencies": { "@stencil/core": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.5.tgz", - "integrity": "sha512-0nZRvvhjjOKsQFGX0pKiDtOS/5IiL7HRxtLqpIxHAxXKLs9ZcomTsdOwl12m/qjx2AtQReOfP8+x8jLOBNMOIQ==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==" } } }, diff --git a/packages/angular/package.json b/packages/angular/package.json index ec8c10144f..7841d9e124 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular", - "version": "7.3.0", + "version": "7.3.1", "description": "Angular specific wrappers for @ionic/core", "keywords": [ "ionic", @@ -47,7 +47,7 @@ } }, "dependencies": { - "@ionic/core": "^7.3.0", + "@ionic/core": "^7.3.1", "ionicons": "^7.0.0", "jsonc-parser": "^3.0.0", "tslib": "^2.3.0" diff --git a/packages/angular/src/directives/navigation/ion-router-outlet.ts b/packages/angular/src/directives/navigation/ion-router-outlet.ts index c54eaa17f3..118c2fd7b6 100644 --- a/packages/angular/src/directives/navigation/ion-router-outlet.ts +++ b/packages/angular/src/directives/navigation/ion-router-outlet.ts @@ -30,7 +30,7 @@ import { Config } from '../../providers/config'; import { NavController } from '../../providers/nav-controller'; import { StackController } from './stack-controller'; -import { RouteView, getUrl } from './stack-utils'; +import { RouteView, StackDidChangeEvent, StackWillChangeEvent, getUrl, isTabSwitch } from './stack-utils'; // TODO(FW-2827): types @@ -66,7 +66,11 @@ export class IonRouterOutlet implements OnDestroy, OnInit { */ @Input() name = PRIMARY_OUTLET; - @Output() stackEvents = new EventEmitter(); + /** @internal */ + @Output() stackWillChange = new EventEmitter(); + /** @internal */ + @Output() stackDidChange = new EventEmitter(); + // eslint-disable-next-line @angular-eslint/no-output-rename @Output('activate') activateEvents = new EventEmitter(); // eslint-disable-next-line @angular-eslint/no-output-rename @@ -304,9 +308,16 @@ export class IonRouterOutlet implements OnDestroy, OnInit { */ this.navCtrl.setTopOutlet(this); + const leavingView = this.stackCtrl.getActiveView(); + + this.stackWillChange.emit({ + enteringView, + tabSwitch: isTabSwitch(enteringView, leavingView), + }); + this.stackCtrl.setActive(enteringView).then((data) => { this.activateEvents.emit(cmpRef.instance); - this.stackEvents.emit(data); + this.stackDidChange.emit(data); }); } diff --git a/packages/angular/src/directives/navigation/ion-tabs.ts b/packages/angular/src/directives/navigation/ion-tabs.ts index 1fa8965218..08ce66d36f 100644 --- a/packages/angular/src/directives/navigation/ion-tabs.ts +++ b/packages/angular/src/directives/navigation/ion-tabs.ts @@ -16,14 +16,19 @@ import { NavController } from '../../providers/nav-controller'; import { IonTabBar } from '../proxies'; import { IonRouterOutlet } from './ion-router-outlet'; -import { StackEvent } from './stack-utils'; +import { StackDidChangeEvent, StackWillChangeEvent } from './stack-utils'; @Component({ selector: 'ion-tabs', template: `
- +
`, @@ -62,7 +67,13 @@ export class IonTabs implements AfterContentInit, AfterContentChecked { @ContentChild(IonTabBar, { static: false }) tabBar: IonTabBar | undefined; @ContentChildren(IonTabBar) tabBars: QueryList; + /** + * Emitted before the tab view is changed. + */ @Output() ionTabsWillChange = new EventEmitter<{ tab: string }>(); + /** + * Emitted after the tab view is changed. + */ @Output() ionTabsDidChange = new EventEmitter<{ tab: string }>(); private tabBarSlot = 'bottom'; @@ -80,10 +91,19 @@ export class IonTabs implements AfterContentInit, AfterContentChecked { /** * @internal */ - onPageSelected(detail: StackEvent): void { - const stackId = detail.enteringView.stackId; - if (detail.tabSwitch && stackId !== undefined) { + onStackWillChange({ enteringView, tabSwitch }: StackWillChangeEvent): void { + const stackId = enteringView.stackId; + if (tabSwitch && stackId !== undefined) { this.ionTabsWillChange.emit({ tab: stackId }); + } + } + + /** + * @internal + */ + onStackDidChange({ enteringView, tabSwitch }: StackDidChangeEvent): void { + const stackId = enteringView.stackId; + if (tabSwitch && stackId !== undefined) { if (this.tabBar) { this.tabBar.selectedTab = stackId; } diff --git a/packages/angular/src/directives/navigation/stack-controller.ts b/packages/angular/src/directives/navigation/stack-controller.ts index 93520c0a66..673ff34d02 100644 --- a/packages/angular/src/directives/navigation/stack-controller.ts +++ b/packages/angular/src/directives/navigation/stack-controller.ts @@ -8,7 +8,7 @@ import { NavController } from '../../providers/nav-controller'; import { RouteView, - StackEvent, + StackDidChangeEvent, computeStackId, destroyView, getUrl, @@ -61,7 +61,7 @@ export class StackController { return view; } - setActive(enteringView: RouteView): Promise { + setActive(enteringView: RouteView): Promise { const consumeResult = this.navCtrl.consumeTransition(); let { direction, animation, animationBuilder } = consumeResult; const leavingView = this.activeView; @@ -224,6 +224,13 @@ export class StackController { return this.activeView ? this.activeView.stackId : undefined; } + /** + * @internal + */ + getActiveView(): RouteView | undefined { + return this.activeView; + } + hasRunningTask(): boolean { return this.runningTask !== undefined; } diff --git a/packages/angular/src/directives/navigation/stack-utils.ts b/packages/angular/src/directives/navigation/stack-utils.ts index ae33e03ce7..dda4ecac7b 100644 --- a/packages/angular/src/directives/navigation/stack-utils.ts +++ b/packages/angular/src/directives/navigation/stack-utils.ts @@ -79,10 +79,23 @@ export const destroyView = (view: RouteView | undefined): void => { } }; -export interface StackEvent { +export interface StackWillChangeEvent { + enteringView: RouteView; + /** + * `true` if the event is trigged as a result of a switch + * between tab navigation stacks. + */ + tabSwitch: boolean; +} + +export interface StackDidChangeEvent { enteringView: RouteView; direction: RouterDirection; animation: NavDirection | undefined; + /** + * `true` if the event is trigged as a result of a switch + * between tab navigation stacks. + */ tabSwitch: boolean; } diff --git a/packages/angular/src/directives/validators/index.ts b/packages/angular/src/directives/validators/index.ts new file mode 100644 index 0000000000..50edda4ec5 --- /dev/null +++ b/packages/angular/src/directives/validators/index.ts @@ -0,0 +1,2 @@ +export * from './max-validator'; +export * from './min-validator'; diff --git a/packages/angular/src/directives/validators/max-validator.ts b/packages/angular/src/directives/validators/max-validator.ts new file mode 100644 index 0000000000..be316f3dca --- /dev/null +++ b/packages/angular/src/directives/validators/max-validator.ts @@ -0,0 +1,22 @@ +import { Directive, forwardRef, Provider } from '@angular/core'; +import { MaxValidator, NG_VALIDATORS } from '@angular/forms'; + +/** + * @description + * Provider which adds `MaxValidator` to the `NG_VALIDATORS` multi-provider list. + */ +export const ION_MAX_VALIDATOR: Provider = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => IonMaxValidator), + multi: true, +}; + +@Directive({ + selector: + 'ion-input[type=number][max][formControlName],ion-input[type=number][max][formControl],ion-input[type=number][max][ngModel]', + providers: [ION_MAX_VALIDATOR], + // eslint-disable-next-line @angular-eslint/no-host-metadata-property + host: { '[attr.max]': '_enabled ? max : null' }, +}) +// eslint-disable-next-line @angular-eslint/directive-class-suffix +export class IonMaxValidator extends MaxValidator {} diff --git a/packages/angular/src/directives/validators/min-validator.ts b/packages/angular/src/directives/validators/min-validator.ts new file mode 100644 index 0000000000..bce1f0b066 --- /dev/null +++ b/packages/angular/src/directives/validators/min-validator.ts @@ -0,0 +1,22 @@ +import { Directive, forwardRef, Provider } from '@angular/core'; +import { MinValidator, NG_VALIDATORS } from '@angular/forms'; + +/** + * @description + * Provider which adds `MinValidator` to the `NG_VALIDATORS` multi-provider list. + */ +export const ION_MIN_VALIDATOR: Provider = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => IonMinValidator), + multi: true, +}; + +@Directive({ + selector: + 'ion-input[type=number][min][formControlName],ion-input[type=number][min][formControl],ion-input[type=number][min][ngModel]', + providers: [ION_MIN_VALIDATOR], + // eslint-disable-next-line @angular-eslint/no-host-metadata-property + host: { '[attr.min]': '_enabled ? min : null' }, +}) +// eslint-disable-next-line @angular-eslint/directive-class-suffix +export class IonMinValidator extends MinValidator {} diff --git a/packages/angular/src/index.ts b/packages/angular/src/index.ts index b92167e481..fb0daa2a4d 100644 --- a/packages/angular/src/index.ts +++ b/packages/angular/src/index.ts @@ -17,6 +17,7 @@ export { NavParams } from './directives/navigation/nav-params'; export { IonModal } from './directives/overlays/modal'; export { IonPopover } from './directives/overlays/popover'; export * from './directives/proxies'; +export * from './directives/validators'; // PROVIDERS export { AngularDelegate } from './providers/angular-delegate'; diff --git a/packages/angular/src/ionic-module.ts b/packages/angular/src/ionic-module.ts index 32ad4eaa4d..b8c7f5c227 100644 --- a/packages/angular/src/ionic-module.ts +++ b/packages/angular/src/ionic-module.ts @@ -22,6 +22,7 @@ import { import { IonModal } from './directives/overlays/modal'; import { IonPopover } from './directives/overlays/popover'; import { DIRECTIVES } from './directives/proxies-list'; +import { IonMaxValidator, IonMinValidator } from './directives/validators'; import { AngularDelegate } from './providers/angular-delegate'; import { ConfigToken } from './providers/config'; import { ModalController } from './providers/modal-controller'; @@ -49,6 +50,10 @@ const DECLARATIONS = [ NavDelegate, RouterLinkDelegateDirective, RouterLinkWithHrefDelegateDirective, + + // validators + IonMinValidator, + IonMaxValidator, ]; @NgModule({ diff --git a/packages/angular/test/base/e2e/src/form.spec.ts b/packages/angular/test/base/e2e/src/form.spec.ts index 39995f2f5a..10d5be7132 100644 --- a/packages/angular/test/base/e2e/src/form.spec.ts +++ b/packages/angular/test/base/e2e/src/form.spec.ts @@ -30,6 +30,8 @@ describe('Form', () => { toggle: false, input: '', input2: 'Default Value', + inputMin: 1, + inputMax: 1, checkbox: false }); }); @@ -55,6 +57,8 @@ describe('Form', () => { toggle: false, input: 'Some value', input2: 'Default Value', + inputMin: 1, + inputMax: 1, checkbox: false }); }); @@ -67,6 +71,8 @@ describe('Form', () => { toggle: true, input: '', input2: 'Default Value', + inputMin: 1, + inputMax: 1, checkbox: false }); }); @@ -79,6 +85,8 @@ describe('Form', () => { toggle: false, input: '', input2: 'Default Value', + inputMin: 1, + inputMax: 1, checkbox: true }); }); @@ -99,6 +107,8 @@ describe('Form', () => { toggle: true, input: '', input2: 'Default Value', + inputMin: 1, + inputMax: 1, checkbox: false }); cy.get('ion-checkbox').click(); @@ -108,10 +118,39 @@ describe('Form', () => { toggle: true, input: '', input2: 'Default Value', + inputMin: 1, + inputMax: 1, checkbox: true }); }); }); + + describe('validators', () => { + + it('ion-input should error with min set', () => { + const control = cy.get('form ion-input[formControlName="inputMin"]'); + + control.should('have.class', 'ng-valid'); + + control.type('{backspace}0'); + + control.within(() => cy.get('input').blur()); + + control.should('have.class', 'ng-invalid'); + }); + + it('ion-input should error with max set', () => { + const control = cy.get('form ion-input[formControlName="inputMax"]'); + + control.should('have.class', 'ng-valid'); + + control.type('2'); + control.within(() => cy.get('input').blur()); + + control.should('have.class', 'ng-invalid'); + }); + + }); }); function testStatus(status) { diff --git a/packages/angular/test/base/src/app/form/form.component.html b/packages/angular/test/base/src/app/form/form.component.html index 4ba9b9621f..f5891cb19f 100644 --- a/packages/angular/test/base/src/app/form/form.component.html +++ b/packages/angular/test/base/src/app/form/form.component.html @@ -1,15 +1,12 @@ - - Forms test - + Forms test
- DateTime @@ -29,13 +26,16 @@ - - Toggle - + Toggle - + Set Input Touched @@ -45,11 +45,20 @@ - - Checkbox - + Checkbox + + + + Min + +
errors: {{ profileForm.controls['inputMin'].errors | json }}
+ + Max + +
errors: {{ profileForm.controls['inputMax'].errors | json }}
+

Form Status: {{ profileForm.status }} @@ -58,18 +67,15 @@ Form value: {{ profileForm.value | json }}

- Form Submit: {{submitted}} + Form Submit: {{ submitted }}

Mark all as touched Submit -
- - Outside form - - {{outsideToggle.value}} + Outside form + {{ outsideToggle.value }}

diff --git a/packages/angular/test/base/src/app/form/form.component.ts b/packages/angular/test/base/src/app/form/form.component.ts index ec10f31cbb..131237632c 100644 --- a/packages/angular/test/base/src/app/form/form.component.ts +++ b/packages/angular/test/base/src/app/form/form.component.ts @@ -18,6 +18,8 @@ export class FormComponent { toggle: [false], input: ['', Validators.required], input2: ['Default Value'], + inputMin: [1, Validators.min(1)], + inputMax: [1, Validators.max(1)], checkbox: [false] }, { updateOn: typeof (window as any) !== 'undefined' && window.location.hash === '#blur' ? 'blur' : 'change' diff --git a/packages/react-router/CHANGELOG.md b/packages/react-router/CHANGELOG.md index de6131b325..d64e47ef42 100644 --- a/packages/react-router/CHANGELOG.md +++ b/packages/react-router/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. +## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23) + +**Note:** Version bump only for package @ionic/react-router + + + + + # [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16) **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 e48d53a46f..12b7a184ad 100644 --- a/packages/react-router/package-lock.json +++ b/packages/react-router/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/react-router", - "version": "7.3.0", + "version": "7.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/react-router", - "version": "7.3.0", + "version": "7.3.1", "license": "MIT", "dependencies": { - "@ionic/react": "^7.3.0", + "@ionic/react": "^7.3.1", "tslib": "*" }, "devDependencies": { @@ -205,11 +205,11 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.0.tgz", - "integrity": "sha512-DPHG0U44O4WcknXa+x3JR/G/5ySxqCS5S8w65PZUQBYA657L4zkaGOvZpObP1MtiBLj9kG7c6Ae6xgJjrU7tyQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz", + "integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==", "dependencies": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" } @@ -401,11 +401,11 @@ } }, "node_modules/@ionic/react": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.3.0.tgz", - "integrity": "sha512-7fBlCpCX1QT18v1BwSh41d1KQpMLLWtUTr7RmxbQi1QhGxWbqkMNPK9a6Dr4Z1sYQI7J75o6biWtNmAqCF370g==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.3.1.tgz", + "integrity": "sha512-X1n81R85mprFqwqNiISiqrzYWbMJm0chPxJZkVOzFwuWG7fKDKY1vigNvm5eI/lOTbfC2xjJZOYwuHAxHi3BoQ==", "dependencies": { - "@ionic/core": "7.3.0", + "@ionic/core": "7.3.1", "ionicons": "^7.0.0", "tslib": "*" }, @@ -486,9 +486,9 @@ } }, "node_modules/@stencil/core": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.5.tgz", - "integrity": "sha512-0nZRvvhjjOKsQFGX0pKiDtOS/5IiL7HRxtLqpIxHAxXKLs9ZcomTsdOwl12m/qjx2AtQReOfP8+x8jLOBNMOIQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==", "bin": { "stencil": "bin/stencil" }, @@ -3663,11 +3663,11 @@ "dev": true }, "@ionic/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.0.tgz", - "integrity": "sha512-DPHG0U44O4WcknXa+x3JR/G/5ySxqCS5S8w65PZUQBYA657L4zkaGOvZpObP1MtiBLj9kG7c6Ae6xgJjrU7tyQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz", + "integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==", "requires": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" }, @@ -3786,11 +3786,11 @@ "requires": {} }, "@ionic/react": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.3.0.tgz", - "integrity": "sha512-7fBlCpCX1QT18v1BwSh41d1KQpMLLWtUTr7RmxbQi1QhGxWbqkMNPK9a6Dr4Z1sYQI7J75o6biWtNmAqCF370g==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.3.1.tgz", + "integrity": "sha512-X1n81R85mprFqwqNiISiqrzYWbMJm0chPxJZkVOzFwuWG7fKDKY1vigNvm5eI/lOTbfC2xjJZOYwuHAxHi3BoQ==", "requires": { - "@ionic/core": "7.3.0", + "@ionic/core": "7.3.1", "ionicons": "^7.0.0", "tslib": "*" } @@ -3844,9 +3844,9 @@ } }, "@stencil/core": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.5.tgz", - "integrity": "sha512-0nZRvvhjjOKsQFGX0pKiDtOS/5IiL7HRxtLqpIxHAxXKLs9ZcomTsdOwl12m/qjx2AtQReOfP8+x8jLOBNMOIQ==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==" }, "@types/estree": { "version": "0.0.39", diff --git a/packages/react-router/package.json b/packages/react-router/package.json index 789a353ea4..a77ca009bc 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/react-router", - "version": "7.3.0", + "version": "7.3.1", "description": "React Router wrapper for @ionic/react", "keywords": [ "ionic", @@ -37,7 +37,7 @@ "dist/" ], "dependencies": { - "@ionic/react": "^7.3.0", + "@ionic/react": "^7.3.1", "tslib": "*" }, "peerDependencies": { diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 369f40dfbc..22d6d0360b 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/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. +## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23) + + +### Bug Fixes + +* **react:** avoid multiple invocations of onDidDismiss and onWillPresent ([#28020](https://github.com/ionic-team/ionic-framework/issues/28020)) ([0ac3df3](https://github.com/ionic-team/ionic-framework/commit/0ac3df3f378bdefc3a927adc798ebd9ec7a54fee)), closes [#28010](https://github.com/ionic-team/ionic-framework/issues/28010) + + + + + # [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16) **Note:** Version bump only for package @ionic/react diff --git a/packages/react/package-lock.json b/packages/react/package-lock.json index 52088dc730..66c48107a2 100644 --- a/packages/react/package-lock.json +++ b/packages/react/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/react", - "version": "7.3.0", + "version": "7.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/react", - "version": "7.3.0", + "version": "7.3.1", "license": "MIT", "dependencies": { - "@ionic/core": "^7.3.0", + "@ionic/core": "^7.3.1", "ionicons": "^7.0.0", "tslib": "*" }, @@ -697,19 +697,19 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.0.tgz", - "integrity": "sha512-DPHG0U44O4WcknXa+x3JR/G/5ySxqCS5S8w65PZUQBYA657L4zkaGOvZpObP1MtiBLj9kG7c6Ae6xgJjrU7tyQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz", + "integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==", "dependencies": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" } }, "node_modules/@ionic/core/node_modules/@stencil/core": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.5.tgz", - "integrity": "sha512-0nZRvvhjjOKsQFGX0pKiDtOS/5IiL7HRxtLqpIxHAxXKLs9ZcomTsdOwl12m/qjx2AtQReOfP8+x8jLOBNMOIQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==", "bin": { "stencil": "bin/stencil" }, @@ -11778,19 +11778,19 @@ "dev": true }, "@ionic/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.0.tgz", - "integrity": "sha512-DPHG0U44O4WcknXa+x3JR/G/5ySxqCS5S8w65PZUQBYA657L4zkaGOvZpObP1MtiBLj9kG7c6Ae6xgJjrU7tyQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz", + "integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==", "requires": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" }, "dependencies": { "@stencil/core": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.5.tgz", - "integrity": "sha512-0nZRvvhjjOKsQFGX0pKiDtOS/5IiL7HRxtLqpIxHAxXKLs9ZcomTsdOwl12m/qjx2AtQReOfP8+x8jLOBNMOIQ==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==" } } }, diff --git a/packages/react/package.json b/packages/react/package.json index de7ead19b2..90edc60d4e 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/react", - "version": "7.3.0", + "version": "7.3.1", "description": "React specific wrapper for @ionic/core", "keywords": [ "ionic", @@ -41,7 +41,7 @@ "css/" ], "dependencies": { - "@ionic/core": "^7.3.0", + "@ionic/core": "^7.3.1", "ionicons": "^7.0.0", "tslib": "*" }, diff --git a/packages/react/scripts/sync.sh b/packages/react/scripts/sync.sh index 1675071ac0..2c2e4a5817 100644 --- a/packages/react/scripts/sync.sh +++ b/packages/react/scripts/sync.sh @@ -2,8 +2,11 @@ set -e -# Copy core dist -rm -rf node_modules/@ionic/core/dist node_modules/@ionic/core/components -cp -a ../../core/dist node_modules/@ionic/core/dist -cp -a ../../core/components node_modules/@ionic/core/components -cp -a ../../core/package.json node_modules/@ionic/core/package.json +# Delete old packages +rm -f *.tgz + +# Pack @ionic/core +npm pack ../../core + +# Install Dependencies +npm install *.tgz --no-save diff --git a/packages/react/src/components/createInlineOverlayComponent.tsx b/packages/react/src/components/createInlineOverlayComponent.tsx index 38679e8515..65f1711cbb 100644 --- a/packages/react/src/components/createInlineOverlayComponent.tsx +++ b/packages/react/src/components/createInlineOverlayComponent.tsx @@ -63,7 +63,14 @@ export const createInlineOverlayComponent = ( componentDidUpdate(prevProps: IonicReactInternalProps) { const node = this.ref.current! as HTMLElement; - attachProps(node, this.props, prevProps); + /** + * onDidDismiss and onWillPresent have manual implementations that + * will invoke the original handler. We need to filter those out + * so they don't get attached twice and called twice. + */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { onDidDismiss, onWillPresent, ...cProps } = this.props; + attachProps(node, cProps, prevProps); } componentWillUnmount() { diff --git a/packages/react/test/base/src/pages/overlay-components/ActionSheetComponent.tsx b/packages/react/test/base/src/pages/overlay-components/ActionSheetComponent.tsx index 0c67f13e59..b7efc95b6f 100644 --- a/packages/react/test/base/src/pages/overlay-components/ActionSheetComponent.tsx +++ b/packages/react/test/base/src/pages/overlay-components/ActionSheetComponent.tsx @@ -1,10 +1,11 @@ -import React from 'react'; import { IonButton, IonContent, IonPage, IonActionSheet } from '@ionic/react'; -import { useState } from 'react'; +import React, { useState } from 'react'; const ActionSheetComponent: React.FC = () => { const [message, setMessage] = useState(''); const [show, setShow] = useState(false); + const [willPresentCount, setWillPresentCount] = useState(0); + const [didDismissCount, setDidDismissCount] = useState(0); return ( @@ -26,7 +27,13 @@ const ActionSheetComponent: React.FC = () => { }, ]} header="Action Sheet" - onDidDismiss={() => setShow(false)} + onWillPresent={() => { + setWillPresentCount(willPresentCount + 1); + }} + onDidDismiss={() => { + setDidDismissCount(didDismissCount + 1); + setShow(false); + }} /> setShow(true)}> Show ActionSheet @@ -41,6 +48,8 @@ const ActionSheetComponent: React.FC = () => { Show ActionSheet, hide after 250 mss

{message}
+
onWillPresent count: {willPresentCount}
+
onDidDismiss count: {didDismissCount}
); diff --git a/packages/react/test/base/tests/e2e/specs/overlay-components/IonActionSheet.cy.ts b/packages/react/test/base/tests/e2e/specs/overlay-components/IonActionSheet.cy.ts index 07a91f4e45..bb5bf41208 100644 --- a/packages/react/test/base/tests/e2e/specs/overlay-components/IonActionSheet.cy.ts +++ b/packages/react/test/base/tests/e2e/specs/overlay-components/IonActionSheet.cy.ts @@ -17,11 +17,19 @@ describe('IonActionSheet', () => { }); it('display action and call dismiss to close it', () => { - //show action sheet + cy.get('ion-content').contains('onWillPresent count: 0'); + cy.get('ion-content').contains('onDidDismiss count: 0'); + + // show action sheet cy.get('ion-button').contains('Show ActionSheet, hide after 250 ms').click(); cy.get('ion-action-sheet').contains('Action Sheet'); - //verify action sheet is hidden + // verify action sheet is hidden cy.get('ion-action-sheet').should('not.be.visible'); + + // verify lifecycle events are called once + cy.get('ion-content').contains('onWillPresent count: 1'); + cy.get('ion-content').contains('onDidDismiss count: 0'); }); + }); diff --git a/packages/vue-router/CHANGELOG.md b/packages/vue-router/CHANGELOG.md index 4b1c3916c1..119369d972 100644 --- a/packages/vue-router/CHANGELOG.md +++ b/packages/vue-router/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. +## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23) + +**Note:** Version bump only for package @ionic/vue-router + + + + + # [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16) **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 9cd308af35..59701de5cd 100644 --- a/packages/vue-router/package-lock.json +++ b/packages/vue-router/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/vue-router", - "version": "7.3.0", + "version": "7.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/vue-router", - "version": "7.3.0", + "version": "7.3.1", "license": "MIT", "dependencies": { - "@ionic/vue": "^7.3.0" + "@ionic/vue": "^7.3.1" }, "devDependencies": { "@ionic/eslint-config": "^0.3.0", @@ -660,11 +660,11 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.0.tgz", - "integrity": "sha512-DPHG0U44O4WcknXa+x3JR/G/5ySxqCS5S8w65PZUQBYA657L4zkaGOvZpObP1MtiBLj9kG7c6Ae6xgJjrU7tyQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz", + "integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==", "dependencies": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" } @@ -871,11 +871,11 @@ } }, "node_modules/@ionic/vue": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.3.0.tgz", - "integrity": "sha512-fbWcwGBFvH+04gFWdVoENqr2DiFAXucSdbDotI93wjmdAvg/H1RQEAMuJAVccCpb9fTKVkpZQwpKwS4z6IoQIw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.3.1.tgz", + "integrity": "sha512-URxNXLYo4gh0riQlHiCoGDo7GqEqbVJi/1gMamM3tGBQHCMNZdm9IDfIDYjHY4L3dVi5pF+szl/b4p2lsIV3hw==", "dependencies": { - "@ionic/core": "7.3.0", + "@ionic/core": "7.3.1", "ionicons": "^7.0.0" } }, @@ -1323,9 +1323,9 @@ } }, "node_modules/@stencil/core": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.5.tgz", - "integrity": "sha512-0nZRvvhjjOKsQFGX0pKiDtOS/5IiL7HRxtLqpIxHAxXKLs9ZcomTsdOwl12m/qjx2AtQReOfP8+x8jLOBNMOIQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==", "bin": { "stencil": "bin/stencil" }, @@ -6807,9 +6807,9 @@ } }, "node_modules/tslib": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", - "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -7697,11 +7697,11 @@ "dev": true }, "@ionic/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.0.tgz", - "integrity": "sha512-DPHG0U44O4WcknXa+x3JR/G/5ySxqCS5S8w65PZUQBYA657L4zkaGOvZpObP1MtiBLj9kG7c6Ae6xgJjrU7tyQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz", + "integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==", "requires": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" }, @@ -7829,11 +7829,11 @@ "requires": {} }, "@ionic/vue": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.3.0.tgz", - "integrity": "sha512-fbWcwGBFvH+04gFWdVoENqr2DiFAXucSdbDotI93wjmdAvg/H1RQEAMuJAVccCpb9fTKVkpZQwpKwS4z6IoQIw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.3.1.tgz", + "integrity": "sha512-URxNXLYo4gh0riQlHiCoGDo7GqEqbVJi/1gMamM3tGBQHCMNZdm9IDfIDYjHY4L3dVi5pF+szl/b4p2lsIV3hw==", "requires": { - "@ionic/core": "7.3.0", + "@ionic/core": "7.3.1", "ionicons": "^7.0.0" } }, @@ -8192,9 +8192,9 @@ } }, "@stencil/core": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.5.tgz", - "integrity": "sha512-0nZRvvhjjOKsQFGX0pKiDtOS/5IiL7HRxtLqpIxHAxXKLs9ZcomTsdOwl12m/qjx2AtQReOfP8+x8jLOBNMOIQ==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==" }, "@tootallnate/once": { "version": "2.0.0", @@ -12220,9 +12220,9 @@ } }, "tslib": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", - "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "tsutils": { "version": "3.21.0", diff --git a/packages/vue-router/package.json b/packages/vue-router/package.json index 5a0ae72286..9c1900bfd7 100644 --- a/packages/vue-router/package.json +++ b/packages/vue-router/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/vue-router", - "version": "7.3.0", + "version": "7.3.1", "description": "Vue Router integration for @ionic/vue", "scripts": { "test.spec": "jest", @@ -45,7 +45,7 @@ }, "homepage": "https://github.com/ionic-team/ionic#readme", "dependencies": { - "@ionic/vue": "^7.3.0" + "@ionic/vue": "^7.3.1" }, "devDependencies": { "@ionic/eslint-config": "^0.3.0", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 9c056b0a37..f07feffbcb 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/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. +## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23) + +**Note:** Version bump only for package @ionic/vue + + + + + # [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16) **Note:** Version bump only for package @ionic/vue diff --git a/packages/vue/package-lock.json b/packages/vue/package-lock.json index 6579db25e4..783079332c 100644 --- a/packages/vue/package-lock.json +++ b/packages/vue/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/vue", - "version": "7.3.0", + "version": "7.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/vue", - "version": "7.3.0", + "version": "7.3.1", "license": "MIT", "dependencies": { - "@ionic/core": "^7.3.0", + "@ionic/core": "^7.3.1", "ionicons": "^7.0.0" }, "devDependencies": { @@ -207,11 +207,11 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.0.tgz", - "integrity": "sha512-DPHG0U44O4WcknXa+x3JR/G/5ySxqCS5S8w65PZUQBYA657L4zkaGOvZpObP1MtiBLj9kG7c6Ae6xgJjrU7tyQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz", + "integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==", "dependencies": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" } @@ -423,9 +423,9 @@ } }, "node_modules/@stencil/core": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.5.tgz", - "integrity": "sha512-0nZRvvhjjOKsQFGX0pKiDtOS/5IiL7HRxtLqpIxHAxXKLs9ZcomTsdOwl12m/qjx2AtQReOfP8+x8jLOBNMOIQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==", "bin": { "stencil": "bin/stencil" }, @@ -3746,11 +3746,11 @@ "dev": true }, "@ionic/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.0.tgz", - "integrity": "sha512-DPHG0U44O4WcknXa+x3JR/G/5ySxqCS5S8w65PZUQBYA657L4zkaGOvZpObP1MtiBLj9kG7c6Ae6xgJjrU7tyQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz", + "integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==", "requires": { - "@stencil/core": "^4.0.3", + "@stencil/core": "^4.1.0", "ionicons": "7.1.0", "tslib": "^2.1.0" }, @@ -3885,9 +3885,9 @@ } }, "@stencil/core": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.0.5.tgz", - "integrity": "sha512-0nZRvvhjjOKsQFGX0pKiDtOS/5IiL7HRxtLqpIxHAxXKLs9ZcomTsdOwl12m/qjx2AtQReOfP8+x8jLOBNMOIQ==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz", + "integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==" }, "@types/json-schema": { "version": "7.0.11", diff --git a/packages/vue/package.json b/packages/vue/package.json index d2ab6c7519..55d02a3302 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/vue", - "version": "7.3.0", + "version": "7.3.1", "description": "Vue specific wrapper for @ionic/core", "scripts": { "eslint": "eslint src", @@ -66,7 +66,7 @@ "vue-router": "^4.0.16" }, "dependencies": { - "@ionic/core": "^7.3.0", + "@ionic/core": "^7.3.1", "ionicons": "^7.0.0" }, "vetur": {