diff --git a/.github/workflows/actions/build-core/action.yml b/.github/workflows/actions/build-core/action.yml index 17e92a01db..b2b9fd75ed 100644 --- a/.github/workflows/actions/build-core/action.yml +++ b/.github/workflows/actions/build-core/action.yml @@ -1,5 +1,10 @@ name: 'Build Ionic Core' description: 'Build Ionic Core' +inputs: + ionicons-version: + description: 'The NPM tag of ionicons to install.' + type: string + required: false runs: using: 'composite' steps: @@ -11,6 +16,13 @@ runs: run: npm install working-directory: ./core shell: bash + # If an Ionicons version was specified install that. + # Otherwise just use the version defined in the package.json. + - name: Install Ionicons Version + if: inputs.ionicons-version != '' + run: npm install ionicons@${{ inputs.ionicons-version }} + working-directory: ./core + shell: bash - name: Build Core run: npm run build -- --ci working-directory: ./core diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fe8f9f2e2d..c026db383d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,6 +4,12 @@ on: pull_request: branches: [ '**' ] merge_group: + workflow_dispatch: + inputs: + ionicons_npm_release_tag: + required: false + type: string + description: What version of ionicons should be pulled from NPM? Use this if you want to test a custom version of Ionicons with Ionic. # When pushing a new commit we should # cancel the previous test run to not @@ -18,6 +24,8 @@ jobs: steps: - uses: actions/checkout@v3 - uses: ./.github/workflows/actions/build-core + with: + ionicons-version: ${{ inputs.ionicons_npm_release_tag }} test-core-clean-build: needs: [build-core] diff --git a/CHANGELOG.md b/CHANGELOG.md index c73e6e2657..2d8b395348 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. +## [7.5.1](https://github.com/ionic-team/ionic-framework/compare/v7.5.0...v7.5.1) (2023-10-18) + + +### Bug Fixes + +* **angular:** do not create duplicate menuController instances ([#28343](https://github.com/ionic-team/ionic-framework/issues/28343)) ([fa78676](https://github.com/ionic-team/ionic-framework/commit/fa78676d57eb80655ee9447ffa07dcfdae0c6b2a)), closes [#28337](https://github.com/ionic-team/ionic-framework/issues/28337) +* **angular:** export missing lifecycle interfaces for standalone package ([#28346](https://github.com/ionic-team/ionic-framework/issues/28346)) ([dd93e0b](https://github.com/ionic-team/ionic-framework/commit/dd93e0b2689511f3145606f4dbb2c30dcf4c2950)), closes [/github.com/ionic-team/ionic-angular-standalone-codemods/pull/13/files/baa37ef1e3e8ba773b693db280542efba815482a#r1356414362](https://github.com//github.com/ionic-team/ionic-angular-standalone-codemods/pull/13/files/baa37ef1e3e8ba773b693db280542efba815482a/issues/r1356414362) +* **react:** cleanup functions are execute for lifecycle hooks ([#28319](https://github.com/ionic-team/ionic-framework/issues/28319)) ([1ba9973](https://github.com/ionic-team/ionic-framework/commit/1ba9973857503c6e47cb225b77a5b89e0a9d2718)), closes [#28186](https://github.com/ionic-team/ionic-framework/issues/28186) +* **react:** lifecycle events are removed on page unmount ([#28316](https://github.com/ionic-team/ionic-framework/issues/28316)) ([f14a59c](https://github.com/ionic-team/ionic-framework/commit/f14a59c5e0670ed7cc9ce1a73a087a5af13266e2)) +* **title:** large title transition supports dynamic font scaling ([#28290](https://github.com/ionic-team/ionic-framework/issues/28290)) ([fe47594](https://github.com/ionic-team/ionic-framework/commit/fe47594dc0bbb047f0bade144cf07b084fbeef5e)), closes [#28351](https://github.com/ionic-team/ionic-framework/issues/28351) + + + + + # [7.5.0](https://github.com/ionic-team/ionic-framework/compare/v7.4.4...v7.5.0) (2023-10-11) diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 23b707f233..549dfd06c1 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. +## [7.5.1](https://github.com/ionic-team/ionic-framework/compare/v7.5.0...v7.5.1) (2023-10-18) + + +### Bug Fixes + +* **angular:** do not create duplicate menuController instances ([#28343](https://github.com/ionic-team/ionic-framework/issues/28343)) ([fa78676](https://github.com/ionic-team/ionic-framework/commit/fa78676d57eb80655ee9447ffa07dcfdae0c6b2a)), closes [#28337](https://github.com/ionic-team/ionic-framework/issues/28337) +* **title:** large title transition supports dynamic font scaling ([#28290](https://github.com/ionic-team/ionic-framework/issues/28290)) ([fe47594](https://github.com/ionic-team/ionic-framework/commit/fe47594dc0bbb047f0bade144cf07b084fbeef5e)), closes [#28351](https://github.com/ionic-team/ionic-framework/issues/28351) + + + + + # [7.5.0](https://github.com/ionic-team/ionic-framework/compare/v7.4.4...v7.5.0) (2023-10-11) diff --git a/core/package-lock.json b/core/package-lock.json index 98f808b8c2..70ffa72805 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -1,28 +1,28 @@ { "name": "@ionic/core", - "version": "7.5.0", + "version": "7.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/core", - "version": "7.5.0", + "version": "7.5.1", "license": "MIT", "dependencies": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" }, "devDependencies": { - "@axe-core/playwright": "^4.7.3", - "@capacitor/core": "^5.4.2", + "@axe-core/playwright": "^4.8.1", + "@capacitor/core": "^5.5.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.38.1", + "@playwright/test": "^1.39.0", "@rollup/plugin-node-resolve": "^8.4.0", "@rollup/plugin-virtual": "^2.0.3", "@stencil/angular-output-target": "^0.8.2", @@ -56,12 +56,12 @@ "dev": true }, "node_modules/@axe-core/playwright": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.7.3.tgz", - "integrity": "sha512-v2PRgAyGvop7bamrTpNJtc5b1R7giAPnMzZXrS/VDZBCY5+uwVYtCNgDvBsqp5P1QMZxUMoBN+CERJUTMjFN0A==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.8.1.tgz", + "integrity": "sha512-KC1X++UdRAwMLRvB+BIKFheyLHUnbJTL0t0Wbv6TJMozn2V2QyEtAcN6jyUiudtGiLUGhHCtj/eWorBnVZ4dAA==", "dev": true, "dependencies": { - "axe-core": "^4.7.0" + "axe-core": "~4.8.2" }, "peerDependencies": { "playwright-core": ">= 1.0.0" @@ -606,9 +606,9 @@ "dev": true }, "node_modules/@capacitor/core": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.4.2.tgz", - "integrity": "sha512-XbR1vldJFzBWHeoGPpgfNy3Zhjf0NxXdHEaGNANWVBg0ZWG2gwFr1dcRALUUQtbwrEEkCCNiLYg4YiQPRk7SEQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.5.0.tgz", + "integrity": "sha512-w59io0ctwnb7JRng7yO2H0YLHG8uz7XARUugRfp5aYTNiG55FqdSmSMOOqGCMPRg4sEnKjJTvAa4ImCYh3Kk1w==", "dev": true, "dependencies": { "tslib": "^2.1.0" @@ -1564,12 +1564,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.1.tgz", - "integrity": "sha512-NqRp8XMwj3AK+zKLbZShl0r/9wKgzqI/527bkptKXomtuo+dOjU9NdMASQ8DNC9z9zLOMbG53T4eihYr3XR+BQ==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz", + "integrity": "sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==", "dev": true, "dependencies": { - "playwright": "1.38.1" + "playwright": "1.39.0" }, "bin": { "playwright": "cli.js" @@ -1653,9 +1653,9 @@ } }, "node_modules/@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==", "bin": { "stencil": "bin/stencil" }, @@ -2636,9 +2636,9 @@ } }, "node_modules/axe-core": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.1.tgz", - "integrity": "sha512-sCXXUhA+cljomZ3ZAwb8i1p3oOlkABzPy08ZDAoGcYuvtBPlQ1Ytde129ArXyHWDhfeewq7rlx9F+cUx2SSlkg==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.8.2.tgz", + "integrity": "sha512-/dlp0fxyM3R8YW7MFzaHWXrf4zzbr0vaYb23VBFCl83R7nWNPg/yaQw2Dc8jzCMmDVLhSdzH8MjrsuIUuvX+6g==", "dev": true, "engines": { "node": ">=4" @@ -8212,12 +8212,12 @@ } }, "node_modules/playwright": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.38.1.tgz", - "integrity": "sha512-oRMSJmZrOu1FP5iu3UrCx8JEFRIMxLDM0c/3o4bpzU5Tz97BypefWf7TuTNPWeCe279TPal5RtPPZ+9lW/Qkow==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz", + "integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==", "dev": true, "dependencies": { - "playwright-core": "1.38.1" + "playwright-core": "1.39.0" }, "bin": { "playwright": "cli.js" @@ -8230,9 +8230,9 @@ } }, "node_modules/playwright-core": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.38.1.tgz", - "integrity": "sha512-tQqNFUKa3OfMf4b2jQ7aGLB8o9bS3bOY0yMEtldtC2+spf8QXG9zvXLTXUeRsoNuxEYMgLYR+NXfAa1rjKRcrg==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.39.0.tgz", + "integrity": "sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -10428,12 +10428,12 @@ }, "dependencies": { "@axe-core/playwright": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.7.3.tgz", - "integrity": "sha512-v2PRgAyGvop7bamrTpNJtc5b1R7giAPnMzZXrS/VDZBCY5+uwVYtCNgDvBsqp5P1QMZxUMoBN+CERJUTMjFN0A==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.8.1.tgz", + "integrity": "sha512-KC1X++UdRAwMLRvB+BIKFheyLHUnbJTL0t0Wbv6TJMozn2V2QyEtAcN6jyUiudtGiLUGhHCtj/eWorBnVZ4dAA==", "dev": true, "requires": { - "axe-core": "^4.7.0" + "axe-core": "~4.8.2" } }, "@babel/code-frame": { @@ -10837,9 +10837,9 @@ "dev": true }, "@capacitor/core": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.4.2.tgz", - "integrity": "sha512-XbR1vldJFzBWHeoGPpgfNy3Zhjf0NxXdHEaGNANWVBg0ZWG2gwFr1dcRALUUQtbwrEEkCCNiLYg4YiQPRk7SEQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.5.0.tgz", + "integrity": "sha512-w59io0ctwnb7JRng7yO2H0YLHG8uz7XARUugRfp5aYTNiG55FqdSmSMOOqGCMPRg4sEnKjJTvAa4ImCYh3Kk1w==", "dev": true, "requires": { "tslib": "^2.1.0" @@ -11519,12 +11519,12 @@ } }, "@playwright/test": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.1.tgz", - "integrity": "sha512-NqRp8XMwj3AK+zKLbZShl0r/9wKgzqI/527bkptKXomtuo+dOjU9NdMASQ8DNC9z9zLOMbG53T4eihYr3XR+BQ==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz", + "integrity": "sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==", "dev": true, "requires": { - "playwright": "1.38.1" + "playwright": "1.39.0" } }, "@rollup/plugin-node-resolve": { @@ -11586,9 +11586,9 @@ "requires": {} }, "@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==" }, "@stencil/react-output-target": { "version": "0.5.3", @@ -12271,9 +12271,9 @@ } }, "axe-core": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.1.tgz", - "integrity": "sha512-sCXXUhA+cljomZ3ZAwb8i1p3oOlkABzPy08ZDAoGcYuvtBPlQ1Ytde129ArXyHWDhfeewq7rlx9F+cUx2SSlkg==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.8.2.tgz", + "integrity": "sha512-/dlp0fxyM3R8YW7MFzaHWXrf4zzbr0vaYb23VBFCl83R7nWNPg/yaQw2Dc8jzCMmDVLhSdzH8MjrsuIUuvX+6g==", "dev": true }, "babel-jest": { @@ -16401,19 +16401,19 @@ } }, "playwright": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.38.1.tgz", - "integrity": "sha512-oRMSJmZrOu1FP5iu3UrCx8JEFRIMxLDM0c/3o4bpzU5Tz97BypefWf7TuTNPWeCe279TPal5RtPPZ+9lW/Qkow==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz", + "integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==", "dev": true, "requires": { "fsevents": "2.3.2", - "playwright-core": "1.38.1" + "playwright-core": "1.39.0" } }, "playwright-core": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.38.1.tgz", - "integrity": "sha512-tQqNFUKa3OfMf4b2jQ7aGLB8o9bS3bOY0yMEtldtC2+spf8QXG9zvXLTXUeRsoNuxEYMgLYR+NXfAa1rjKRcrg==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.39.0.tgz", + "integrity": "sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==", "dev": true }, "postcss": { diff --git a/core/package.json b/core/package.json index 92a540a713..8c8c38d77a 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/core", - "version": "7.5.0", + "version": "7.5.1", "description": "Base components for Ionic", "keywords": [ "ionic", @@ -31,20 +31,20 @@ "loader/" ], "dependencies": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" }, "devDependencies": { - "@axe-core/playwright": "^4.7.3", - "@capacitor/core": "^5.4.2", + "@axe-core/playwright": "^4.8.1", + "@capacitor/core": "^5.5.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.38.1", + "@playwright/test": "^1.39.0", "@rollup/plugin-node-resolve": "^8.4.0", "@rollup/plugin-virtual": "^2.0.3", "@stencil/angular-output-target": "^0.8.2", diff --git a/core/src/components/datetime/test/a11y/datetime.e2e.ts-snapshots/datetime-scale-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/datetime/test/a11y/datetime.e2e.ts-snapshots/datetime-scale-ios-ltr-Mobile-Firefox-linux.png index d4876cf09b..f165eeca07 100644 Binary files a/core/src/components/datetime/test/a11y/datetime.e2e.ts-snapshots/datetime-scale-ios-ltr-Mobile-Firefox-linux.png and b/core/src/components/datetime/test/a11y/datetime.e2e.ts-snapshots/datetime-scale-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/header/test/condense/header.e2e.ts-snapshots/header-condense-large-title-collapsed-diff-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/header/test/condense/header.e2e.ts-snapshots/header-condense-large-title-collapsed-diff-ios-ltr-Mobile-Chrome-linux.png index d10003306a..39c8b4e1c8 100644 Binary files a/core/src/components/header/test/condense/header.e2e.ts-snapshots/header-condense-large-title-collapsed-diff-ios-ltr-Mobile-Chrome-linux.png and b/core/src/components/header/test/condense/header.e2e.ts-snapshots/header-condense-large-title-collapsed-diff-ios-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/item-option/item-option.scss b/core/src/components/item-option/item-option.scss index b01024e6ec..56cb1138ab 100644 --- a/core/src/components/item-option/item-option.scss +++ b/core/src/components/item-option/item-option.scss @@ -17,18 +17,6 @@ font-family: $font-family-base; } -:host(.in-list.item-options-end:last-child) { - @include padding-horizontal( - null, calc(.7em + var(--ion-safe-area-right)) - ); -} - -:host(.in-list.item-options-start:first-child) { - @include padding-horizontal( - calc(.7em + var(--ion-safe-area-left)), null - ); -} - :host(.ion-color) { background: current-color(base); color: current-color(contrast); diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts index 3d31279b40..908155f0ea 100644 --- a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts +++ b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts @@ -99,3 +99,94 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co }); }); }); + +/** + * This behavior needs to be tested in both modes and directions to + * make sure the safe area padding is applied only to that side + * regardless of direction + */ +configs().forEach(({ title, screenshot, config }) => { + test.describe(title('item-sliding: basic'), () => { + test.describe('safe area left', () => { + test('should have padding on the left only', async ({ page }) => { + await page.setContent( + ` + + + + + + Archive + + + Delete + + + + + + Sliding Item + + + + `, + config + ); + + const direction = config.direction; + const item = page.locator('ion-item-sliding'); + + const dragByX = direction == 'rtl' ? -150 : 150; + await dragElementBy(item, page, dragByX); + await page.waitForChanges(); + + await expect(item).toHaveScreenshot(screenshot(`item-sliding-safe-area-left`)); + }); + }); + + test.describe('safe area right', () => { + test('should have padding on the right only', async ({ page }) => { + await page.setContent( + ` + + + + + + Sliding Item + + + + + + Archive + + + Delete + + + + `, + config + ); + + const direction = config.direction; + const item = page.locator('ion-item-sliding'); + + const dragByX = direction == 'rtl' ? 150 : -150; + await dragElementBy(item, page, dragByX); + await page.waitForChanges(); + + await expect(item).toHaveScreenshot(screenshot(`item-sliding-safe-area-right`)); + }); + }); + }); +}); diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..60b83137e0 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-ltr-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..b7ca18c5e7 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-ltr-Mobile-Safari-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-ltr-Mobile-Safari-linux.png new file mode 100644 index 0000000000..52beeeb7a9 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-rtl-Mobile-Chrome-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-rtl-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..c9f7034c52 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-rtl-Mobile-Chrome-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-rtl-Mobile-Firefox-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-rtl-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..edb97fa14a Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-rtl-Mobile-Safari-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-rtl-Mobile-Safari-linux.png new file mode 100644 index 0000000000..7a0b3c04ca Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-ios-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-ltr-Mobile-Chrome-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..873f68641e Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-ltr-Mobile-Firefox-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-ltr-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..5ef8f2fdf3 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-ltr-Mobile-Safari-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-ltr-Mobile-Safari-linux.png new file mode 100644 index 0000000000..671a9d901e Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-rtl-Mobile-Chrome-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-rtl-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..4fdf0ad75a Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-rtl-Mobile-Chrome-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-rtl-Mobile-Firefox-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-rtl-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..9473f2c20c Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-rtl-Mobile-Safari-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-rtl-Mobile-Safari-linux.png new file mode 100644 index 0000000000..59ca54af36 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-left-md-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..ac79bcf0a4 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-ltr-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..d52744a855 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-ltr-Mobile-Safari-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-ltr-Mobile-Safari-linux.png new file mode 100644 index 0000000000..aff99e31d9 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-rtl-Mobile-Chrome-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-rtl-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..e0ac027181 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-rtl-Mobile-Chrome-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-rtl-Mobile-Firefox-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-rtl-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..104548e503 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-rtl-Mobile-Safari-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-rtl-Mobile-Safari-linux.png new file mode 100644 index 0000000000..1871af7cb1 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-ios-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-ltr-Mobile-Chrome-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..4bdb163297 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-ltr-Mobile-Firefox-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-ltr-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..176c185cfb Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-ltr-Mobile-Safari-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-ltr-Mobile-Safari-linux.png new file mode 100644 index 0000000000..682e019648 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-rtl-Mobile-Chrome-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-rtl-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..a2767263a0 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-rtl-Mobile-Chrome-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-rtl-Mobile-Firefox-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-rtl-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..e532cf2302 Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-rtl-Mobile-Safari-linux.png b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-rtl-Mobile-Safari-linux.png new file mode 100644 index 0000000000..80312a26af Binary files /dev/null and b/core/src/components/item-sliding/test/basic/item-sliding.e2e.ts-snapshots/item-sliding-safe-area-right-md-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-disabled-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-disabled-ios-ltr-Mobile-Firefox-linux.png index ebca29ab21..f379936b30 100644 Binary files a/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-disabled-ios-ltr-Mobile-Firefox-linux.png and b/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-disabled-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-disabled-md-ltr-Mobile-Firefox-linux.png b/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-disabled-md-ltr-Mobile-Firefox-linux.png index c3146ad9af..44175208bd 100644 Binary files a/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-disabled-md-ltr-Mobile-Firefox-linux.png and b/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-disabled-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-ios-ltr-Mobile-Firefox-linux.png index 21350c51b2..880e336696 100644 Binary files a/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-ios-ltr-Mobile-Firefox-linux.png and b/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-ios-rtl-Mobile-Firefox-linux.png b/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-ios-rtl-Mobile-Firefox-linux.png index 6bc4b4a14e..473ed40edd 100644 Binary files a/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-ios-rtl-Mobile-Firefox-linux.png and b/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-ios-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-md-ltr-Mobile-Firefox-linux.png b/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-md-ltr-Mobile-Firefox-linux.png index 240bbeb605..96d4a99df3 100644 Binary files a/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-md-ltr-Mobile-Firefox-linux.png and b/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-md-rtl-Mobile-Firefox-linux.png b/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-md-rtl-Mobile-Firefox-linux.png index f9c4cd274e..a48d9a8197 100644 Binary files a/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-md-rtl-Mobile-Firefox-linux.png and b/core/src/components/item/test/inputs/item.e2e.ts-snapshots/item-inputs-md-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-ios-ltr-Mobile-Firefox-linux.png index 51501d2b3f..d63616a88c 100644 Binary files a/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-ios-ltr-Mobile-Firefox-linux.png and b/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-ios-rtl-Mobile-Firefox-linux.png b/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-ios-rtl-Mobile-Firefox-linux.png index 43949a22a2..8248d9a00c 100644 Binary files a/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-ios-rtl-Mobile-Firefox-linux.png and b/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-ios-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-md-ltr-Mobile-Firefox-linux.png b/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-md-ltr-Mobile-Firefox-linux.png index 827c5c4288..f7c656908d 100644 Binary files a/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-md-ltr-Mobile-Firefox-linux.png and b/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-md-rtl-Mobile-Firefox-linux.png b/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-md-rtl-Mobile-Firefox-linux.png index f1e8eeeb05..5b33ad807e 100644 Binary files a/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-md-rtl-Mobile-Firefox-linux.png and b/core/src/components/item/test/legacy/disabled/item.e2e.ts-snapshots/item-disabled-diff-md-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/menu/menu-interface.ts b/core/src/components/menu/menu-interface.ts index 0361f207fb..9f1c4f3e8c 100644 --- a/core/src/components/menu/menu-interface.ts +++ b/core/src/components/menu/menu-interface.ts @@ -1,4 +1,4 @@ -import type { Animation } from '../../interface'; +import type { Animation, AnimationBuilder } from '@utils/animation/animation-interface'; export type Side = 'start' | 'end'; @@ -26,13 +26,23 @@ export interface MenuI { } export interface MenuControllerI { + registerAnimation(name: string, animation: AnimationBuilder): void; + get(menu?: string | null, logOnMultipleSideMenus?: boolean): Promise; + getMenus(): Promise; + getOpen(): Promise; + isEnabled(menu?: string | null): Promise; + swipeGesture(shouldEnable: boolean, menu?: string | null): Promise; + isAnimating(): Promise; + isOpen(menu?: string | null): Promise; + enable(shouldEnable: boolean, menu?: string | null): Promise; + toggle(menu?: string | null): Promise; + close(menu?: string | null): Promise; + open(menu?: string | null): Promise; + _getOpenSync(): HTMLIonMenuElement | undefined; _createAnimation(type: string, menuCmp: MenuI): Promise; - _setOpen(menu: MenuI, shouldOpen: boolean, animated: boolean): Promise; _register(menu: MenuI): void; _unregister(menu: MenuI): void; - - getMenus(): Promise; - getOpenSync(): HTMLIonMenuElement | undefined; + _setOpen(menu: MenuI, shouldOpen: boolean, animated: boolean): Promise; } export interface MenuChangeEventDetail { diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Firefox-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Firefox-linux.png index 509fc18de6..5911fa5e1c 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Firefox-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Safari-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Safari-linux.png index 655f4423bc..b1843a2b09 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Safari-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-ios-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Firefox-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Firefox-linux.png index 76b19a0830..9a1cb20106 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Firefox-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Safari-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Safari-linux.png index 7d64c60606..5f9f0e9aaa 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Safari-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-md-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Firefox-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Firefox-linux.png index 3a3b396e0e..937d38ec8c 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Firefox-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Safari-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Safari-linux.png index f23b06ab64..29cc9bcb0f 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Safari-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-ios-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Firefox-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Firefox-linux.png index b9147d78ad..9a60e5f2b0 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Firefox-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Safari-linux.png b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Safari-linux.png index 1a6d83bfad..875a045fff 100644 Binary files a/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Safari-linux.png and b/core/src/components/popover/test/nested/popover.e2e.ts-snapshots/popover-nested-multiple-md-rtl-Mobile-Safari-linux.png differ diff --git a/core/src/components/textarea/test/legacy/autogrow/textarea.e2e.ts-snapshots/textarea-autogrow-diff-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/textarea/test/legacy/autogrow/textarea.e2e.ts-snapshots/textarea-autogrow-diff-ios-ltr-Mobile-Firefox-linux.png index d62e18c29a..f1a59c1e70 100644 Binary files a/core/src/components/textarea/test/legacy/autogrow/textarea.e2e.ts-snapshots/textarea-autogrow-diff-ios-ltr-Mobile-Firefox-linux.png and b/core/src/components/textarea/test/legacy/autogrow/textarea.e2e.ts-snapshots/textarea-autogrow-diff-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/textarea/test/legacy/autogrow/textarea.e2e.ts-snapshots/textarea-autogrow-diff-md-ltr-Mobile-Firefox-linux.png b/core/src/components/textarea/test/legacy/autogrow/textarea.e2e.ts-snapshots/textarea-autogrow-diff-md-ltr-Mobile-Firefox-linux.png index 15328f12a2..0624c13a5c 100644 Binary files a/core/src/components/textarea/test/legacy/autogrow/textarea.e2e.ts-snapshots/textarea-autogrow-diff-md-ltr-Mobile-Firefox-linux.png and b/core/src/components/textarea/test/legacy/autogrow/textarea.e2e.ts-snapshots/textarea-autogrow-diff-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-ios-ltr-Mobile-Firefox-linux.png index abc2078432..6eb736cbed 100644 Binary files a/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-ios-ltr-Mobile-Firefox-linux.png and b/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-ios-rtl-Mobile-Firefox-linux.png b/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-ios-rtl-Mobile-Firefox-linux.png index ba8a710b35..710a9dc3ac 100644 Binary files a/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-ios-rtl-Mobile-Firefox-linux.png and b/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-ios-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-md-ltr-Mobile-Firefox-linux.png b/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-md-ltr-Mobile-Firefox-linux.png index 967580eb8f..f526fbd6f6 100644 Binary files a/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-md-ltr-Mobile-Firefox-linux.png and b/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-md-rtl-Mobile-Firefox-linux.png b/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-md-rtl-Mobile-Firefox-linux.png index 68172f49f8..7dfac785e0 100644 Binary files a/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-md-rtl-Mobile-Firefox-linux.png and b/core/src/components/textarea/test/legacy/basic/textarea.e2e.ts-snapshots/textarea-diff-md-rtl-Mobile-Firefox-linux.png differ diff --git a/core/src/components/title/title.ios.scss b/core/src/components/title/title.ios.scss index 973ff98c58..f83ece1874 100644 --- a/core/src/components/title/title.ios.scss +++ b/core/src/components/title/title.ios.scss @@ -67,4 +67,14 @@ :host(.title-large) .toolbar-title { @include transform-origin(inherit); + + /** + * During a page transition + * if the large title and the back button + * texts match up, the back button should be + * scaled to roughly match the dimensions of + * the large title text. The following line + * ensures that the scale values are accurate. + */ + width: auto; } diff --git a/core/src/themes/ionic.functions.string.scss b/core/src/themes/ionic.functions.string.scss index 098a2e9f73..ea3da90c5e 100644 --- a/core/src/themes/ionic.functions.string.scss +++ b/core/src/themes/ionic.functions.string.scss @@ -85,9 +85,15 @@ // Add Root Selector // -------------------------------------------------------------------------------- // Adds a root selector using host based on the selector passed +// $root: The selector that needs to be updated to include the $addHostSelector. +// - Example: ion-button +// $addHostSelector: The selector that is used to add the host to the $root selector. +// - Example: [dir=rtl] +// $useHostContext: Whether to use host-context or not. Defaults to true. // -------------------------------------------------------------------------------- -@function add-root-selector($root, $addHostSelector) { + +@function add-root-selector($root, $addHostSelector, $useHostContext: true) { $selectors: str-split($root, ","); $list: (); @@ -95,14 +101,21 @@ @each $selector in $selectors { // If the selector contains :host( it means it is targeting a class on the host // element so we need to change how we target it: + // Example with `useHostContext=true` // @include add-root-selector(":host(.fixed)", "[dir=rtl]") // --> :host-context([dir=rtl]):host(.fixed) // --> :host-context([dir=rtl]).fixed + // --- + // Example with `useHostContext=false` + // @include add-root(":host(.fixed)", ":dir(rtl)", false) + // --> :host(.fixed:dir(rtl)) @if str-contains($selector, ":host(") { - // @include add-root-selector(":host(.fixed)", "[dir=rtl]") - // --> :host-context([dir=rtl]):host(.fixed) - $shadow-element: str-replace($selector, ":host(", ":host-context(#{$addHostSelector}):host("); - $list: append($list, $shadow-element, comma); + @if $useHostContext { + // @include add-root-selector(":host(.fixed)", "[dir=rtl]") + // --> :host-context([dir=rtl]):host(.fixed) + $shadow-element: str-replace($selector, ":host(", ":host-context(#{$addHostSelector}):host("); + $list: append($list, $shadow-element, comma); + } $new-element: (); $elements: str-split($selector, " "); @@ -117,19 +130,28 @@ $scoped-element: str-replace($scoped-element, ")", ""); $scoped-element: str-replace($scoped-element, ":host(", ""); - // Add the class back inside of host with the rtl selector: - // .fixed -> :host-context([dir=rtl]).fixed - $scoped-element: str-replace($scoped-element, $scoped-element, ":host-context(#{$addHostSelector})#{$scoped-element}"); - + // Add the class back inside of host with the addHostSelector: + @if $useHostContext { + // .fixed -> :host-context([dir=rtl]).fixed + $scoped-element: str-replace($scoped-element, $scoped-element, ":host-context(#{$addHostSelector})#{$scoped-element}"); + } @else { + // .fixed -> :host(.fixed:dir(rtl)) + $scoped-element: str-replace($scoped-element, $scoped-element, ":host(#{$scoped-element}#{$addHostSelector})"); + } + // @include add-root-selector(":host(.fixed)", "[dir=rtl]") // --> :host-context([dir=rtl]).fixed + // @include add-root(":host(.fixed)", ":dir(rtl)", false) + // --> :host(.fixed:dir(rtl)) $new-element: append($new-element, $scoped-element, space); } @else { - // Add back any selectors that followed the host after transforming the - // first selector: - // :host(.fixed) ::slotted(ion-icon) + // Add back any selectors that followed the host + // after transforming the first selector: + // @include add-root-selector(":host(.fixed) ::slotted(ion-icon)", "[dir=rtl]") // --> :host-context([dir=rtl]):host(.fixed) ::slotted(ion-icon) // --> :host-context([dir=rtl]).fixed ::slotted(ion-icon) + // @include add-root(":host(.fixed) ::slotted(ion-icon)", ":dir(rtl)", false) + // --> :host(.fixed:dir(rtl)) ::slotted(ion-icon) $new-element: append($new-element, $element, space); } } @@ -140,24 +162,38 @@ // element so we can change it to look for host-context // @include add-root-selector(":host", "[dir=rtl]") // --> :host-context([dir=rtl]) - // --> :host:dir(rtl) + // @include add-root(":host", ":dir(rtl)", false) + // --> :host(:dir(rtl)) } @else if str-contains($selector, ":host") { $new-element: (); $elements: str-split($selector, " "); @each $element in $elements { @if str-contains($element, ":host") { + $updated-element: ''; + // Replace the :host with the addHostSelector: - // :host -> :host-context([dir=rtl]) - $updated-element: str-replace($element, ":host", ":host-context(#{$addHostSelector})"); + @if $useHostContext { + // :host -> :host-context([dir=rtl]) + $updated-element: str-replace($element, ":host", ":host-context(#{$addHostSelector})"); + } @else { + // :host -> :host(:dir(rtl)) + $updated-element: str-replace($element, ":host", ":host(#{$addHostSelector})"); + } // Add the final selector after all transformations: - // :host -> :host-context([dir=rtl]) + // @include add-root-selector(":host", "[dir=rtl]") + // --> :host-context([dir=rtl]) + // @include add-root(":host", ":dir(rtl)", false) + // --> :host(:dir(rtl)) $new-element: append($new-element, $updated-element, space); } @else { - // Add back any selectors that followed the host after transforming the - // first selector: - // :host ::slotted(ion-icon) -> :host-context([dir=rtl]) ::slotted(ion-icon) + // Add back any selectors that followed the host + // after transforming the first selector: + // @include add-root-selector(":host ::slotted(ion-icon)", "[dir=rtl]") + // --> :host-context([dir=rtl]) ::slotted(ion-icon) + // @include add-root(":host ::slotted(ion-icon)", ":dir(rtl)", false) + // --> :host(:dir(rtl)) ::slotted(ion-icon) $new-element: append($new-element, $element, space); } } @@ -168,9 +204,15 @@ // @include add-root-selector("ion-component", "[dir=rtl]") // --> :host-context([dir=rtl]) ion-component // --> [dir=rtl] ion-component + // @include add-root("ion-component", ":dir(rtl)", false) + // --> ion-component:dir(rtl) } @else { - $list: append($list, "#{$addHostSelector} #{$selector}", comma); - $list: append($list, ":host-context(#{$addHostSelector}) #{$selector}", comma); + @if ($useHostContext) { + $list: append($list, ":host-context(#{$addHostSelector}) #{$selector}", comma); + $list: append($list, "#{$addHostSelector} #{$selector}", comma); + } @else { + $list: append($list, "#{$selector}#{$addHostSelector}", comma); + } } } diff --git a/core/src/themes/ionic.mixins.scss b/core/src/themes/ionic.mixins.scss index 053a4627c6..0c8cdad9b7 100644 --- a/core/src/themes/ionic.mixins.scss +++ b/core/src/themes/ionic.mixins.scss @@ -242,17 +242,13 @@ // - Firefox doesn't support `:host-context()`, but does support `:dir()`. // - Safari doesn't support `:host-context()`, but Safari 16.4+ supports `:dir()` // @link https://webkit.org/blog/13966/webkit-features-in-safari-16-4/ - @each $selector in $rootSplit { - $dirSelector: "#{$selector}:dir(rtl)"; - // Group the selectors back into a single selector to optimize the output. - $dirSelectors: append($dirSelectors, $dirSelector, comma); - } + // -- However, there is a Webkit bug on v16 that prevents `:dir()` from working when + // -- the app direction is changed dynamically. v17+ works fine. + // -- @link https://bugs.webkit.org/show_bug.cgi?id=257133 // Supported by Firefox. - @if length($dirSelectors) > 0 { - @at-root #{$dirSelectors} { - @content; - } + @at-root #{add-root-selector($root, ":dir(rtl)", false)} { + @content; } } } diff --git a/core/src/utils/menu-controller/index.ts b/core/src/utils/menu-controller/index.ts index a0e6cf25f7..ab5a1ffc01 100644 --- a/core/src/utils/menu-controller/index.ts +++ b/core/src/utils/menu-controller/index.ts @@ -1,6 +1,6 @@ import { printIonWarning } from '@utils/logging'; -import type { MenuI } from '../../components/menu/menu-interface'; +import type { MenuI, MenuControllerI } from '../../components/menu/menu-interface'; import type { AnimationBuilder, BackButtonEvent } from '../../interface'; import { MENU_BACK_BUTTON_PRIORITY } from '../hardware-back-button'; import { componentOnReady } from '../helpers'; @@ -9,7 +9,7 @@ import { menuOverlayAnimation } from './animations/overlay'; import { menuPushAnimation } from './animations/push'; import { menuRevealAnimation } from './animations/reveal'; -const createMenuController = () => { +const createMenuController = (): MenuControllerI => { const menuAnimations = new Map(); const menus: MenuI[] = []; diff --git a/core/src/utils/transition/ios.transition.ts b/core/src/utils/transition/ios.transition.ts index ab3d7132e3..107e305334 100644 --- a/core/src/utils/transition/ios.transition.ts +++ b/core/src/utils/transition/ios.transition.ts @@ -75,41 +75,63 @@ const createLargeTitleTransition = ( const leavingLargeTitleBox = leavingLargeTitle.getBoundingClientRect(); const enteringBackButtonBox = enteringBackButton.getBoundingClientRect(); + const enteringBackButtonTextEl = shadow(enteringBackButton).querySelector('.button-text')!; + const enteringBackButtonTextBox = enteringBackButtonTextEl.getBoundingClientRect(); + + const leavingLargeTitleTextEl = shadow(leavingLargeTitle).querySelector('.toolbar-title')!; + const leavingLargeTitleTextBox = leavingLargeTitleTextEl.getBoundingClientRect(); + animateLargeTitle( rootAnimation, rtl, backDirection, leavingLargeTitle, leavingLargeTitleBox, - enteringBackButtonBox + leavingLargeTitleTextBox, + enteringBackButtonTextEl, + enteringBackButtonTextBox ); animateBackButton( rootAnimation, rtl, backDirection, enteringBackButton, - leavingLargeTitleBox, - enteringBackButtonBox + enteringBackButtonBox, + enteringBackButtonTextEl, + enteringBackButtonTextBox, + leavingLargeTitle, + leavingLargeTitleTextBox ); } else if (shouldAnimationBackward) { const enteringLargeTitleBox = enteringLargeTitle.getBoundingClientRect(); const leavingBackButtonBox = leavingBackButton.getBoundingClientRect(); + const leavingBackButtonTextEl = shadow(leavingBackButton).querySelector('.button-text')!; + const leavingBackButtonTextBox = leavingBackButtonTextEl.getBoundingClientRect(); + + const enteringLargeTitleTextEl = shadow(enteringLargeTitle).querySelector('.toolbar-title')!; + const enteringLargeTitleTextBox = enteringLargeTitleTextEl.getBoundingClientRect(); + animateLargeTitle( rootAnimation, rtl, backDirection, enteringLargeTitle, enteringLargeTitleBox, - leavingBackButtonBox + enteringLargeTitleTextBox, + leavingBackButtonTextEl, + leavingBackButtonTextBox ); animateBackButton( rootAnimation, rtl, backDirection, leavingBackButton, - enteringLargeTitleBox, - leavingBackButtonBox + leavingBackButtonBox, + leavingBackButtonTextEl, + leavingBackButtonTextBox, + enteringLargeTitle, + enteringLargeTitleTextBox ); } @@ -123,56 +145,133 @@ const animateBackButton = ( rootAnimation: Animation, rtl: boolean, backDirection: boolean, - backButtonEl: any, - largeTitleBox: DOMRect, - backButtonBox: DOMRect + backButtonEl: HTMLIonBackButtonElement, + backButtonBox: DOMRect, + backButtonTextEl: HTMLElement, + backButtonTextBox: DOMRect, + largeTitleEl: HTMLIonTitleElement, + largeTitleTextBox: DOMRect ) => { const BACK_BUTTON_START_OFFSET = rtl ? `calc(100% - ${backButtonBox.right + 4}px)` : `${backButtonBox.left - 4}px`; - const START_TEXT_TRANSLATE = rtl ? '7px' : '-7px'; - const END_TEXT_TRANSLATE = rtl ? '-4px' : '4px'; - - const ICON_TRANSLATE = rtl ? '-4px' : '4px'; const TEXT_ORIGIN_X = rtl ? 'right' : 'left'; const ICON_ORIGIN_X = rtl ? 'left' : 'right'; + const CONTAINER_ORIGIN_X = rtl ? 'right' : 'left'; + + /** + * When the title and back button texts match + * then they should overlap during the page transition. + * If the texts do not match up then the back button text scale adjusts + * to not perfectly match the large title text otherwise the + * proportions will be incorrect. + * When the texts match we scale both the width and height to account for + * font weight differences between the title and back button. + */ + const doTitleAndButtonTextsMatch = backButtonTextEl.textContent?.trim() === largeTitleEl.textContent?.trim(); + + const WIDTH_SCALE = largeTitleTextBox.width / backButtonTextBox.width; + + /** + * We subtract an offset to account for slight sizing/padding + * differences between the title and the back button. + */ + const HEIGHT_SCALE = (largeTitleTextBox.height - LARGE_TITLE_SIZE_OFFSET) / backButtonTextBox.height; + + const TEXT_START_SCALE = doTitleAndButtonTextsMatch + ? `scale(${WIDTH_SCALE}, ${HEIGHT_SCALE})` + : `scale(${HEIGHT_SCALE})`; + const TEXT_END_SCALE = 'scale(1)'; + + const backButtonIconEl = shadow(backButtonEl).querySelector('ion-icon')!; + const backButtonIconBox = backButtonIconEl.getBoundingClientRect(); + + /** + * We need to offset the container by the icon dimensions + * so that the back button text aligns with the large title + * text. Otherwise, the back button icon will align with the + * large title text but the back button text will not. + */ + const CONTAINER_START_TRANSLATE_X = rtl + ? `${backButtonIconBox.width / 2 - (backButtonIconBox.right - backButtonBox.right)}px` + : `${backButtonBox.left - backButtonIconBox.width / 2}px`; + const CONTAINER_END_TRANSLATE_X = rtl ? `-${window.innerWidth - backButtonBox.right}px` : `${backButtonBox.left}px`; + + /** + * Back button container should be + * aligned to the top of the title container + * so the texts overlap as the back button + * text begins to fade in. + */ + const CONTAINER_START_TRANSLATE_Y = `${largeTitleTextBox.top}px`; + + /** + * The cloned back button should align exactly with the + * real back button on the entering page otherwise there will + * be a layout shift. + */ + const CONTAINER_END_TRANSLATE_Y = `${backButtonBox.top}px`; + + /** + * In the forward direction, the cloned back button + * container should translate from over the large title + * to over the back button. In the backward direction, + * it should translate from over the back button to over + * the large title. + */ + const FORWARD_CONTAINER_KEYFRAMES = [ + { offset: 0, transform: `translate3d(${CONTAINER_START_TRANSLATE_X}, ${CONTAINER_START_TRANSLATE_Y}, 0)` }, + { offset: 1, transform: `translate3d(${CONTAINER_END_TRANSLATE_X}, ${CONTAINER_END_TRANSLATE_Y}, 0)` }, + ]; + const BACKWARD_CONTAINER_KEYFRAMES = [ + { offset: 0, transform: `translate3d(${CONTAINER_END_TRANSLATE_X}, ${CONTAINER_END_TRANSLATE_Y}, 0)` }, + { offset: 1, transform: `translate3d(${CONTAINER_START_TRANSLATE_X}, ${CONTAINER_START_TRANSLATE_Y}, 0)` }, + ]; + const CONTAINER_KEYFRAMES = backDirection ? BACKWARD_CONTAINER_KEYFRAMES : FORWARD_CONTAINER_KEYFRAMES; + + /** + * In the forward direction, the text in the cloned back button + * should start to be (roughly) the size of the large title + * and then scale down to be the size of the actual back button. + * The text should also translate, but that translate is handled + * by the container keyframes. + */ const FORWARD_TEXT_KEYFRAMES = [ - { - offset: 0, - opacity: 0, - transform: `translate3d(${START_TEXT_TRANSLATE}, ${largeTitleBox.top - 40}px, 0) scale(2.1)`, - }, - { offset: 1, opacity: 1, transform: `translate3d(${END_TEXT_TRANSLATE}, ${backButtonBox.top - 46}px, 0) scale(1)` }, + { offset: 0, opacity: 0, transform: TEXT_START_SCALE }, + { offset: 1, opacity: 1, transform: TEXT_END_SCALE }, ]; const BACKWARD_TEXT_KEYFRAMES = [ - { offset: 0, opacity: 1, transform: `translate3d(${END_TEXT_TRANSLATE}, ${backButtonBox.top - 46}px, 0) scale(1)` }, - { offset: 0.6, opacity: 0 }, - { - offset: 1, - opacity: 0, - transform: `translate3d(${START_TEXT_TRANSLATE}, ${largeTitleBox.top - 40}px, 0) scale(2.1)`, - }, + { offset: 0, opacity: 1, transform: TEXT_END_SCALE }, + { offset: 1, opacity: 0, transform: TEXT_START_SCALE }, ]; const TEXT_KEYFRAMES = backDirection ? BACKWARD_TEXT_KEYFRAMES : FORWARD_TEXT_KEYFRAMES; + /** + * The icon should scale in/out in the second + * half of the animation. The icon should also + * translate, but that translate is handled by the + * container keyframes. + */ const FORWARD_ICON_KEYFRAMES = [ - { offset: 0, opacity: 0, transform: `translate3d(${ICON_TRANSLATE}, ${backButtonBox.top - 41}px, 0) scale(0.6)` }, - { offset: 1, opacity: 1, transform: `translate3d(${ICON_TRANSLATE}, ${backButtonBox.top - 46}px, 0) scale(1)` }, + { offset: 0, opacity: 0, transform: 'scale(0.6)' }, + { offset: 0.6, opacity: 0, transform: 'scale(0.6)' }, + { offset: 1, opacity: 1, transform: 'scale(1)' }, ]; const BACKWARD_ICON_KEYFRAMES = [ - { offset: 0, opacity: 1, transform: `translate3d(${ICON_TRANSLATE}, ${backButtonBox.top - 46}px, 0) scale(1)` }, - { offset: 0.2, opacity: 0, transform: `translate3d(${ICON_TRANSLATE}, ${backButtonBox.top - 41}px, 0) scale(0.6)` }, - { offset: 1, opacity: 0, transform: `translate3d(${ICON_TRANSLATE}, ${backButtonBox.top - 41}px, 0) scale(0.6)` }, + { offset: 0, opacity: 1, transform: 'scale(1)' }, + { offset: 0.2, opacity: 0, transform: 'scale(0.6)' }, + { offset: 1, opacity: 0, transform: 'scale(0.6)' }, ]; const ICON_KEYFRAMES = backDirection ? BACKWARD_ICON_KEYFRAMES : FORWARD_ICON_KEYFRAMES; const enteringBackButtonTextAnimation = createAnimation(); const enteringBackButtonIconAnimation = createAnimation(); + const enteringBackButtonAnimation = createAnimation(); const clonedBackButtonEl = getClonedElement('ion-back-button'); - const backButtonTextEl = shadow(clonedBackButtonEl).querySelector('.button-text'); - const backButtonIconEl = shadow(clonedBackButtonEl).querySelector('ion-icon'); + const clonedBackButtonTextEl = shadow(clonedBackButtonEl).querySelector('.button-text'); + const clonedBackButtonIconEl = shadow(clonedBackButtonEl).querySelector('ion-icon'); clonedBackButtonEl.text = backButtonEl.text; clonedBackButtonEl.mode = backButtonEl.mode; @@ -183,12 +282,21 @@ const animateBackButton = ( clonedBackButtonEl.style.setProperty('display', 'block'); clonedBackButtonEl.style.setProperty('position', 'fixed'); - enteringBackButtonIconAnimation.addElement(backButtonIconEl); - enteringBackButtonTextAnimation.addElement(backButtonTextEl); + enteringBackButtonIconAnimation.addElement(clonedBackButtonIconEl); + enteringBackButtonTextAnimation.addElement(clonedBackButtonTextEl); + enteringBackButtonAnimation.addElement(clonedBackButtonEl); + + enteringBackButtonAnimation + .beforeStyles({ + position: 'absolute', + top: '0px', + [CONTAINER_ORIGIN_X]: '0px', + }) + .keyframes(CONTAINER_KEYFRAMES); enteringBackButtonTextAnimation .beforeStyles({ - 'transform-origin': `${TEXT_ORIGIN_X} center`, + 'transform-origin': `${TEXT_ORIGIN_X} top`, }) .beforeAddWrite(() => { backButtonEl.style.setProperty('display', 'none'); @@ -207,30 +315,111 @@ const animateBackButton = ( }) .keyframes(ICON_KEYFRAMES); - rootAnimation.addAnimation([enteringBackButtonTextAnimation, enteringBackButtonIconAnimation]); + rootAnimation.addAnimation([ + enteringBackButtonTextAnimation, + enteringBackButtonIconAnimation, + enteringBackButtonAnimation, + ]); }; const animateLargeTitle = ( rootAnimation: Animation, rtl: boolean, backDirection: boolean, - largeTitleEl: any, + largeTitleEl: HTMLIonTitleElement, largeTitleBox: DOMRect, - backButtonBox: DOMRect + largeTitleTextBox: DOMRect, + backButtonTextEl: HTMLElement, + backButtonTextBox: DOMRect ) => { - const TITLE_START_OFFSET = rtl ? `calc(100% - ${largeTitleBox.right}px)` : `${largeTitleBox.left}px`; - const START_TRANSLATE = rtl ? '-18px' : '18px'; + /** + * The horizontal transform origin for the large title + */ const ORIGIN_X = rtl ? 'right' : 'left'; + const TITLE_START_OFFSET = rtl ? `calc(100% - ${largeTitleBox.right}px)` : `${largeTitleBox.left}px`; + + /** + * The cloned large should align exactly with the + * real large title on the leaving page otherwise there will + * be a layout shift. + */ + const START_TRANSLATE_X = '0px'; + const START_TRANSLATE_Y = `${largeTitleBox.top}px`; + + /** + * How much to offset the large title translation by. + * This accounts for differences in sizing between the large + * title and the back button due to padding and font weight. + */ + const LARGE_TITLE_TRANSLATION_OFFSET = 8; + + /** + * The scaled title should (roughly) overlap the back button. + * This ensures that the back button and title overlap during + * the animation. Note that since both elements either fade in + * or fade out over the course of the animation, neither element + * will be fully visible on top of the other. As a result, the overlap + * does not need to be perfect, so approximate values are acceptable here. + */ + const END_TRANSLATE_X = rtl + ? `-${window.innerWidth - backButtonTextBox.right - LARGE_TITLE_TRANSLATION_OFFSET}px` + : `${backButtonTextBox.x - LARGE_TITLE_TRANSLATION_OFFSET}px`; + + /** + * The top of the scaled large title + * should match with the top of the + * back button text element. + * We subtract 2px to account for the top padding + * on the large title element. + */ + const LARGE_TITLE_TOP_PADDING = 2; + const END_TRANSLATE_Y = `${backButtonTextBox.y - LARGE_TITLE_TOP_PADDING}px`; + + /** + * In the forward direction, the large title should start at its + * normal size and then scale down to be (roughly) the size of the + * back button on the other view. In the backward direction, the + * large title should start at (roughly) the size of the back button + * and then scale up to its original size. + * + * Note that since both elements either fade in + * or fade out over the course of the animation, neither element + * will be fully visible on top of the other. As a result, the overlap + * does not need to be perfect, so approximate values are acceptable here. + */ + + /** + * When the title and back button texts match + * then they should overlap during the page transition. + * If the texts do not match up then the large title text scale adjusts + * to not perfectly match the back button text otherwise the + * proportions will be incorrect. + * When the texts match we scale both the width and height to account for + * font weight differences between the title and back button. + */ + const doTitleAndButtonTextsMatch = backButtonTextEl.textContent?.trim() === largeTitleEl.textContent?.trim(); + + const WIDTH_SCALE = backButtonTextBox.width / largeTitleTextBox.width; + const HEIGHT_SCALE = backButtonTextBox.height / (largeTitleTextBox.height - LARGE_TITLE_SIZE_OFFSET); + + const START_SCALE = 'scale(1)'; + + const END_SCALE = doTitleAndButtonTextsMatch ? `scale(${WIDTH_SCALE}, ${HEIGHT_SCALE})` : `scale(${HEIGHT_SCALE})`; + const BACKWARDS_KEYFRAMES = [ - { offset: 0, opacity: 0, transform: `translate3d(${START_TRANSLATE}, ${backButtonBox.top - 4}px, 0) scale(0.49)` }, + { offset: 0, opacity: 0, transform: `translate3d(${END_TRANSLATE_X}, ${END_TRANSLATE_Y}, 0) ${END_SCALE}` }, { offset: 0.1, opacity: 0 }, - { offset: 1, opacity: 1, transform: `translate3d(0, ${largeTitleBox.top + 2}px, 0) scale(1)` }, + { offset: 1, opacity: 1, transform: `translate3d(${START_TRANSLATE_X}, ${START_TRANSLATE_Y}, 0) ${START_SCALE}` }, ]; const FORWARDS_KEYFRAMES = [ - { offset: 0, opacity: 0.99, transform: `translate3d(0, ${largeTitleBox.top + 2}px, 0) scale(1)` }, + { + offset: 0, + opacity: 0.99, + transform: `translate3d(${START_TRANSLATE_X}, ${START_TRANSLATE_Y}, 0) ${START_SCALE}`, + }, { offset: 0.6, opacity: 0 }, - { offset: 1, opacity: 0, transform: `translate3d(${START_TRANSLATE}, ${backButtonBox.top - 4}px, 0) scale(0.5)` }, + { offset: 1, opacity: 0, transform: `translate3d(${END_TRANSLATE_X}, ${END_TRANSLATE_Y}, 0) ${END_SCALE}` }, ]; const KEYFRAMES = backDirection ? BACKWARDS_KEYFRAMES : FORWARDS_KEYFRAMES; @@ -246,8 +435,15 @@ const animateLargeTitle = ( clonedLargeTitleAnimation .beforeStyles({ - 'transform-origin': `${ORIGIN_X} center`, - height: '46px', + 'transform-origin': `${ORIGIN_X} top`, + + /** + * Since font size changes will cause + * the dimension of the large title to change + * we need to set the cloned title height + * equal to that of the original large title height. + */ + height: `${largeTitleBox.height}px`, display: '', position: 'relative', [ORIGIN_X]: TITLE_START_OFFSET, @@ -634,3 +830,14 @@ export const iosTransitionAnimation = (navEl: HTMLElement, opts: TransitionOptio throw err; } }; + +/** + * The scale of the back button during the animation + * is computed based on the scale of the large title + * and vice versa. However, we need to account for slight + * variations in the size of the large title due to + * padding and font weight. This value should be used to subtract + * a small amount from the large title height when computing scales + * to get more accurate scale results. + */ +const LARGE_TITLE_SIZE_OFFSET = 10; diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index ff2aefca94..696fe92ae1 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.5.1](https://github.com/ionic-team/ionic-framework/compare/v7.5.0...v7.5.1) (2023-10-18) + +**Note:** Version bump only for package @ionic/docs + + + + + # [7.5.0](https://github.com/ionic-team/ionic-framework/compare/v7.4.4...v7.5.0) (2023-10-11) **Note:** Version bump only for package @ionic/docs diff --git a/docs/package-lock.json b/docs/package-lock.json index e6ea2c2ec6..0e3dbfc6bd 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ionic/docs", - "version": "7.5.0", + "version": "7.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/docs", - "version": "7.5.0", + "version": "7.5.1", "license": "MIT" } } diff --git a/docs/package.json b/docs/package.json index bedabdf29b..a3d8326dfa 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/docs", - "version": "7.5.0", + "version": "7.5.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 a730d7dcec..2e878a4b85 100644 --- a/lerna.json +++ b/lerna.json @@ -4,5 +4,5 @@ "docs", "packages/*" ], - "version": "7.5.0" + "version": "7.5.1" } diff --git a/packages/angular-server/CHANGELOG.md b/packages/angular-server/CHANGELOG.md index 04952ee14d..bd9f704cce 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.5.1](https://github.com/ionic-team/ionic-framework/compare/v7.5.0...v7.5.1) (2023-10-18) + +**Note:** Version bump only for package @ionic/angular-server + + + + + # [7.5.0](https://github.com/ionic-team/ionic-framework/compare/v7.4.4...v7.5.0) (2023-10-11) **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 fcad7a667d..ea54bbd588 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.5.0", + "version": "7.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/angular-server", - "version": "7.5.0", + "version": "7.5.1", "license": "MIT", "dependencies": { - "@ionic/core": "^7.5.0" + "@ionic/core": "^7.5.1" }, "devDependencies": { "@angular-eslint/eslint-plugin": "^14.0.0", @@ -1060,11 +1060,11 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.0.tgz", - "integrity": "sha512-oreRvbKj8VqqO9JraxR/n56GC6MHQtnJEmZf/EFuw5ZvDV8My91uNIzLkb4P9SvPL5NRr/Z0TFem28cgRf5YVA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.1.tgz", + "integrity": "sha512-BnWehjZ3IVGPFLdOZV151VhLsyXzr8d2mIVULqUXil5NHgQf039ScppI0kfrCS+M3zMdqeTmlIK/nq6M+kcQaQ==", "dependencies": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" } @@ -1462,9 +1462,9 @@ "license": "MIT" }, "node_modules/@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==", "bin": { "stencil": "bin/stencil" }, @@ -7330,11 +7330,11 @@ "dev": true }, "@ionic/core": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.0.tgz", - "integrity": "sha512-oreRvbKj8VqqO9JraxR/n56GC6MHQtnJEmZf/EFuw5ZvDV8My91uNIzLkb4P9SvPL5NRr/Z0TFem28cgRf5YVA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.1.tgz", + "integrity": "sha512-BnWehjZ3IVGPFLdOZV151VhLsyXzr8d2mIVULqUXil5NHgQf039ScppI0kfrCS+M3zMdqeTmlIK/nq6M+kcQaQ==", "requires": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" } @@ -7581,9 +7581,9 @@ } }, "@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==" }, "@types/estree": { "version": "0.0.39", diff --git a/packages/angular-server/package.json b/packages/angular-server/package.json index e1456d40ef..108ca98ad2 100644 --- a/packages/angular-server/package.json +++ b/packages/angular-server/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular-server", - "version": "7.5.0", + "version": "7.5.1", "description": "Angular SSR Module for Ionic", "keywords": [ "ionic", @@ -61,6 +61,6 @@ }, "prettier": "@ionic/prettier-config", "dependencies": { - "@ionic/core": "^7.5.0" + "@ionic/core": "^7.5.1" } } diff --git a/packages/angular/.prettierignore b/packages/angular/.prettierignore index 9ac0616858..a69cde511b 100644 --- a/packages/angular/.prettierignore +++ b/packages/angular/.prettierignore @@ -1,6 +1,6 @@ dist scripts test -src/directives/proxies.ts +proxies.ts src/directives/proxies-list.ts src/directives/angular-component-lib/utils.ts diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index 08f714ee37..a7028183f3 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/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. +## [7.5.1](https://github.com/ionic-team/ionic-framework/compare/v7.5.0...v7.5.1) (2023-10-18) + + +### Bug Fixes + +* **angular:** do not create duplicate menuController instances ([#28343](https://github.com/ionic-team/ionic-framework/issues/28343)) ([fa78676](https://github.com/ionic-team/ionic-framework/commit/fa78676d57eb80655ee9447ffa07dcfdae0c6b2a)), closes [#28337](https://github.com/ionic-team/ionic-framework/issues/28337) +* **angular:** export missing lifecycle interfaces for standalone package ([#28346](https://github.com/ionic-team/ionic-framework/issues/28346)) ([dd93e0b](https://github.com/ionic-team/ionic-framework/commit/dd93e0b2689511f3145606f4dbb2c30dcf4c2950)), closes [/github.com/ionic-team/ionic-angular-standalone-codemods/pull/13/files/baa37ef1e3e8ba773b693db280542efba815482a#r1356414362](https://github.com//github.com/ionic-team/ionic-angular-standalone-codemods/pull/13/files/baa37ef1e3e8ba773b693db280542efba815482a/issues/r1356414362) + + + + + # [7.5.0](https://github.com/ionic-team/ionic-framework/compare/v7.4.4...v7.5.0) (2023-10-11) diff --git a/packages/angular/common/src/index.ts b/packages/angular/common/src/index.ts index 7b834ffe14..bd432ea3ba 100644 --- a/packages/angular/common/src/index.ts +++ b/packages/angular/common/src/index.ts @@ -18,6 +18,7 @@ export { Platform } from './providers/platform'; export { bindLifecycleEvents, AngularDelegate } from './providers/angular-delegate'; export type { IonicWindow } from './types/interfaces'; +export type { ViewWillEnter, ViewWillLeave, ViewDidEnter, ViewDidLeave } from './types/ionic-lifecycle-hooks'; export { NavParams } from './directives/navigation/nav-params'; diff --git a/packages/angular/common/src/providers/menu-controller.ts b/packages/angular/common/src/providers/menu-controller.ts index ba1876e23b..0a197b1f5b 100644 --- a/packages/angular/common/src/providers/menu-controller.ts +++ b/packages/angular/common/src/providers/menu-controller.ts @@ -1,17 +1,15 @@ -import { Injectable } from '@angular/core'; -import { menuController } from '@ionic/core/components'; +import type { MenuControllerI } from '@ionic/core/components'; -@Injectable({ - providedIn: 'root', -}) export class MenuController { + constructor(private menuController: MenuControllerI) {} + /** * Programmatically open the Menu. * @param [menuId] Optionally get the menu by its id, or side. * @return returns a promise when the menu is fully opened */ open(menuId?: string): Promise { - return menuController.open(menuId); + return this.menuController.open(menuId); } /** @@ -22,7 +20,7 @@ export class MenuController { * @return returns a promise when the menu is fully closed */ close(menuId?: string): Promise { - return menuController.close(menuId); + return this.menuController.close(menuId); } /** @@ -32,7 +30,7 @@ export class MenuController { * @return returns a promise when the menu has been toggled */ toggle(menuId?: string): Promise { - return menuController.toggle(menuId); + return this.menuController.toggle(menuId); } /** @@ -44,7 +42,7 @@ export class MenuController { * @return Returns the instance of the menu, which is useful for chaining. */ enable(shouldEnable: boolean, menuId?: string): Promise { - return menuController.enable(shouldEnable, menuId); + return this.menuController.enable(shouldEnable, menuId); } /** @@ -54,7 +52,7 @@ export class MenuController { * @return Returns the instance of the menu, which is useful for chaining. */ swipeGesture(shouldEnable: boolean, menuId?: string): Promise { - return menuController.swipeGesture(shouldEnable, menuId); + return this.menuController.swipeGesture(shouldEnable, menuId); } /** @@ -63,7 +61,7 @@ export class MenuController { * If the menuId is not specified, it returns true if ANY menu is currenly open. */ isOpen(menuId?: string): Promise { - return menuController.isOpen(menuId); + return this.menuController.isOpen(menuId); } /** @@ -71,7 +69,7 @@ export class MenuController { * @return Returns true if the menu is currently enabled, otherwise false. */ isEnabled(menuId?: string): Promise { - return menuController.isEnabled(menuId); + return this.menuController.isEnabled(menuId); } /** @@ -84,20 +82,20 @@ export class MenuController { * @return Returns the instance of the menu if found, otherwise `null`. */ get(menuId?: string): Promise { - return menuController.get(menuId); + return this.menuController.get(menuId); } /** * @return Returns the instance of the menu already opened, otherwise `null`. */ getOpen(): Promise { - return menuController.getOpen(); + return this.menuController.getOpen(); } /** * @return Returns an array of all menu instances. */ getMenus(): Promise { - return menuController.getMenus(); + return this.menuController.getMenus(); } } diff --git a/packages/angular/src/types/ionic-lifecycle-hooks.ts b/packages/angular/common/src/types/ionic-lifecycle-hooks.ts similarity index 100% rename from packages/angular/src/types/ionic-lifecycle-hooks.ts rename to packages/angular/common/src/types/ionic-lifecycle-hooks.ts diff --git a/packages/angular/package-lock.json b/packages/angular/package-lock.json index fd3e95f9aa..87b6185a7a 100644 --- a/packages/angular/package-lock.json +++ b/packages/angular/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/angular", - "version": "7.5.0", + "version": "7.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/angular", - "version": "7.5.0", + "version": "7.5.1", "license": "MIT", "dependencies": { - "@ionic/core": "^7.5.0", + "@ionic/core": "^7.5.1", "ionicons": "^7.0.0", "jsonc-parser": "^3.0.0", "tslib": "^2.3.0" @@ -1227,11 +1227,11 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.0.tgz", - "integrity": "sha512-oreRvbKj8VqqO9JraxR/n56GC6MHQtnJEmZf/EFuw5ZvDV8My91uNIzLkb4P9SvPL5NRr/Z0TFem28cgRf5YVA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.1.tgz", + "integrity": "sha512-BnWehjZ3IVGPFLdOZV151VhLsyXzr8d2mIVULqUXil5NHgQf039ScppI0kfrCS+M3zMdqeTmlIK/nq6M+kcQaQ==", "dependencies": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" } @@ -1583,9 +1583,9 @@ } }, "node_modules/@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==", "bin": { "stencil": "bin/stencil" }, @@ -8093,11 +8093,11 @@ "dev": true }, "@ionic/core": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.0.tgz", - "integrity": "sha512-oreRvbKj8VqqO9JraxR/n56GC6MHQtnJEmZf/EFuw5ZvDV8My91uNIzLkb4P9SvPL5NRr/Z0TFem28cgRf5YVA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.1.tgz", + "integrity": "sha512-BnWehjZ3IVGPFLdOZV151VhLsyXzr8d2mIVULqUXil5NHgQf039ScppI0kfrCS+M3zMdqeTmlIK/nq6M+kcQaQ==", "requires": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" } @@ -8327,9 +8327,9 @@ } }, "@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==" }, "@types/estree": { "version": "0.0.39", diff --git a/packages/angular/package.json b/packages/angular/package.json index 725ff4332b..0db698c6fc 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular", - "version": "7.5.0", + "version": "7.5.1", "description": "Angular specific wrappers for @ionic/core", "keywords": [ "ionic", @@ -47,7 +47,7 @@ } }, "dependencies": { - "@ionic/core": "^7.5.0", + "@ionic/core": "^7.5.1", "ionicons": "^7.0.0", "jsonc-parser": "^3.0.0", "tslib": "^2.3.0" diff --git a/packages/angular/src/index.ts b/packages/angular/src/index.ts index 3ebea61c44..6db8e3d7d2 100644 --- a/packages/angular/src/index.ts +++ b/packages/angular/src/index.ts @@ -23,7 +23,6 @@ export { ActionSheetController, AlertController, LoadingController, - MenuController, ModalController, PickerController, PopoverController, @@ -37,10 +36,12 @@ export { AngularDelegate, NavParams, IonicRouteStrategy, + ViewWillEnter, + ViewWillLeave, + ViewDidEnter, + ViewDidLeave, } from '@ionic/angular/common'; - -// TYPES -export * from './types/ionic-lifecycle-hooks'; +export { MenuController } from './providers/menu-controller'; // PACKAGE MODULE export { IonicModule } from './ionic-module'; diff --git a/packages/angular/src/providers/menu-controller.ts b/packages/angular/src/providers/menu-controller.ts new file mode 100644 index 0000000000..04f9c6ddc5 --- /dev/null +++ b/packages/angular/src/providers/menu-controller.ts @@ -0,0 +1,12 @@ +import { Injectable } from '@angular/core'; +import { MenuController as MenuControllerBase } from '@ionic/angular/common'; +import { menuController } from '@ionic/core'; + +@Injectable({ + providedIn: 'root', +}) +export class MenuController extends MenuControllerBase { + constructor() { + super(menuController); + } +} diff --git a/packages/angular/standalone/src/directives/checkbox.ts b/packages/angular/standalone/src/directives/checkbox.ts index 26f139f379..218c0483ee 100644 --- a/packages/angular/standalone/src/directives/checkbox.ts +++ b/packages/angular/standalone/src/directives/checkbox.ts @@ -8,12 +8,25 @@ import { Injector, NgZone, } from '@angular/core'; +import type { OnInit } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ValueAccessor, setIonicClasses } from '@ionic/angular/common'; import type { CheckboxChangeEventDetail, Components } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-checkbox.js'; -import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils'; +/** + * Value accessor components should not use ProxyCmp + * and should call defineCustomElement and proxyInputs + * manually instead. Using both the @ProxyCmp and @Component + * decorators and useExisting (where useExisting refers to the + * class) causes ng-packagr to output multiple component variables + * which breaks treeshaking. + * For example, the following would be generated: + * let IonCheckbox = IonCheckbox_1 = class IonCheckbox extends ValueAccessor { + * Instead, we want only want the class generated: + * class IonCheckbox extends ValueAccessor { + */ +import { proxyInputs, proxyOutputs } from './angular-component-lib/utils'; const CHECKBOX_INPUTS = [ 'checked', @@ -28,10 +41,6 @@ const CHECKBOX_INPUTS = [ 'value', ]; -@ProxyCmp({ - defineCustomElementFn: defineCustomElement, - inputs: CHECKBOX_INPUTS, -}) @Component({ selector: 'ion-checkbox', changeDetection: ChangeDetectionStrategy.OnPush, @@ -47,15 +56,25 @@ const CHECKBOX_INPUTS = [ ], standalone: true, }) -export class IonCheckbox extends ValueAccessor { +export class IonCheckbox extends ValueAccessor implements OnInit { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone, injector: Injector) { super(injector, r); + defineCustomElement(); c.detach(); this.el = r.nativeElement; proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur']); } + ngOnInit(): void { + /** + * Data-bound input properties are set + * by Angular after the constructor, so + * we need to run the proxy in ngOnInit. + */ + proxyInputs(IonCheckbox, CHECKBOX_INPUTS); + } + writeValue(value: boolean): void { this.elementRef.nativeElement.checked = this.lastValue = value; setIonicClasses(this.elementRef); diff --git a/packages/angular/standalone/src/directives/datetime.ts b/packages/angular/standalone/src/directives/datetime.ts index 57068f71b9..4f476d7b4e 100644 --- a/packages/angular/standalone/src/directives/datetime.ts +++ b/packages/angular/standalone/src/directives/datetime.ts @@ -8,12 +8,25 @@ import { Injector, NgZone, } from '@angular/core'; +import type { OnInit } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ValueAccessor } from '@ionic/angular/common'; import type { DatetimeChangeEventDetail, Components } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-datetime.js'; -import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils'; +/** + * Value accessor components should not use ProxyCmp + * and should call defineCustomElement and proxyInputs + * manually instead. Using both the @ProxyCmp and @Component + * decorators and useExisting (where useExisting refers to the + * class) causes ng-packagr to output multiple component variables + * which breaks treeshaking. + * For example, the following would be generated: + * let IonDatetime = IonDatetime_1 = class IonDatetime extends ValueAccessor { + * Instead, we want only want the class generated: + * class IonDatetime extends ValueAccessor { + */ +import { proxyInputs, proxyMethods, proxyOutputs } from './angular-component-lib/utils'; const DATETIME_INPUTS = [ 'cancelText', @@ -48,11 +61,8 @@ const DATETIME_INPUTS = [ 'yearValues', ]; -@ProxyCmp({ - defineCustomElementFn: defineCustomElement, - inputs: DATETIME_INPUTS, - methods: ['confirm', 'reset', 'cancel'], -}) +const DATETIME_METHODS = ['confirm', 'reset', 'cancel']; + @Component({ selector: 'ion-datetime', changeDetection: ChangeDetectionStrategy.OnPush, @@ -68,15 +78,26 @@ const DATETIME_INPUTS = [ ], standalone: true, }) -export class IonDatetime extends ValueAccessor { +export class IonDatetime extends ValueAccessor implements OnInit { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone, injector: Injector) { super(injector, r); + defineCustomElement(); c.detach(); this.el = r.nativeElement; proxyOutputs(this, this.el, ['ionCancel', 'ionChange', 'ionFocus', 'ionBlur']); } + ngOnInit(): void { + /** + * Data-bound input properties are set + * by Angular after the constructor, so + * we need to run the proxy in ngOnInit. + */ + proxyInputs(IonDatetime, DATETIME_INPUTS); + proxyMethods(IonDatetime, DATETIME_METHODS); + } + @HostListener('ionChange', ['$event.target']) handleIonChange(el: HTMLIonDatetimeElement): void { this.handleValueChange(el, el.value); diff --git a/packages/angular/standalone/src/directives/input.ts b/packages/angular/standalone/src/directives/input.ts index 1fb55006f7..8fb920eddb 100644 --- a/packages/angular/standalone/src/directives/input.ts +++ b/packages/angular/standalone/src/directives/input.ts @@ -8,6 +8,7 @@ import { Injector, NgZone, } from '@angular/core'; +import type { OnInit } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ValueAccessor } from '@ionic/angular/common'; import type { @@ -17,7 +18,19 @@ import type { } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-input.js'; -import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils'; +/** + * Value accessor components should not use ProxyCmp + * and should call defineCustomElement and proxyInputs + * manually instead. Using both the @ProxyCmp and @Component + * decorators and useExisting (where useExisting refers to the + * class) causes ng-packagr to output multiple component variables + * which breaks treeshaking. + * For example, the following would be generated: + * let IonInput = IonInput_1 = class IonInput extends ValueAccessor { + * Instead, we want only want the class generated: + * class IonInput extends ValueAccessor { + */ +import { proxyInputs, proxyMethods, proxyOutputs } from './angular-component-lib/utils'; const INPUT_INPUTS = [ 'accept', @@ -59,11 +72,8 @@ const INPUT_INPUTS = [ 'value', ]; -@ProxyCmp({ - defineCustomElementFn: defineCustomElement, - inputs: INPUT_INPUTS, - methods: ['setFocus', 'getInputElement'], -}) +const INPUT_METHODS = ['setFocus', 'getInputElement']; + @Component({ selector: 'ion-input', changeDetection: ChangeDetectionStrategy.OnPush, @@ -79,15 +89,26 @@ const INPUT_INPUTS = [ ], standalone: true, }) -export class IonInput extends ValueAccessor { +export class IonInput extends ValueAccessor implements OnInit { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone, injector: Injector) { super(injector, r); + defineCustomElement(); c.detach(); this.el = r.nativeElement; proxyOutputs(this, this.el, ['ionInput', 'ionChange', 'ionBlur', 'ionFocus']); } + ngOnInit(): void { + /** + * Data-bound input properties are set + * by Angular after the constructor, so + * we need to run the proxy in ngOnInit. + */ + proxyInputs(IonInput, INPUT_INPUTS); + proxyMethods(IonInput, INPUT_METHODS); + } + @HostListener('ionInput', ['$event.target']) handleIonInput(el: HTMLIonInputElement): void { this.handleValueChange(el, el.value); diff --git a/packages/angular/standalone/src/directives/proxies.ts b/packages/angular/standalone/src/directives/proxies.ts index d112c3b93c..022535606a 100644 --- a/packages/angular/standalone/src/directives/proxies.ts +++ b/packages/angular/standalone/src/directives/proxies.ts @@ -73,7 +73,7 @@ import { defineCustomElement as defineIonToast } from '@ionic/core/components/io import { defineCustomElement as defineIonToolbar } from '@ionic/core/components/ion-toolbar.js'; @ProxyCmp({ defineCustomElementFn: defineIonAccordion, - inputs: ['disabled', 'mode', 'readonly', 'toggleIcon', 'toggleIconSlot', 'value'], + inputs: ['disabled', 'mode', 'readonly', 'toggleIcon', 'toggleIconSlot', 'value'] }) @Component({ selector: 'ion-accordion', @@ -81,7 +81,7 @@ import { defineCustomElement as defineIonToolbar } from '@ionic/core/components/ template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['disabled', 'mode', 'readonly', 'toggleIcon', 'toggleIconSlot', 'value'], - standalone: true, + standalone: true }) export class IonAccordion { protected el: HTMLElement; @@ -91,11 +91,13 @@ export class IonAccordion { } } + export declare interface IonAccordion extends Components.IonAccordion {} + @ProxyCmp({ defineCustomElementFn: defineIonAccordionGroup, - inputs: ['animated', 'disabled', 'expand', 'mode', 'multiple', 'readonly', 'value'], + inputs: ['animated', 'disabled', 'expand', 'mode', 'multiple', 'readonly', 'value'] }) @Component({ selector: 'ion-accordion-group', @@ -103,7 +105,7 @@ export declare interface IonAccordion extends Components.IonAccordion {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['animated', 'disabled', 'expand', 'mode', 'multiple', 'readonly', 'value'], - standalone: true, + standalone: true }) export class IonAccordionGroup { protected el: HTMLElement; @@ -114,6 +116,7 @@ export class IonAccordionGroup { } } + import type { AccordionGroupChangeEventDetail as IIonAccordionGroupAccordionGroupChangeEventDetail } from '@ionic/core/components'; export declare interface IonAccordionGroup extends Components.IonAccordionGroup { @@ -126,67 +129,30 @@ the value property. ionChange: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonActionSheet, - inputs: [ - 'animated', - 'backdropDismiss', - 'buttons', - 'cssClass', - 'enterAnimation', - 'header', - 'htmlAttributes', - 'isOpen', - 'keyboardClose', - 'leaveAnimation', - 'mode', - 'subHeader', - 'translucent', - 'trigger', - ], - methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'], + inputs: ['animated', 'backdropDismiss', 'buttons', 'cssClass', 'enterAnimation', 'header', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'subHeader', 'translucent', 'trigger'], + methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'] }) @Component({ selector: 'ion-action-sheet', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: [ - 'animated', - 'backdropDismiss', - 'buttons', - 'cssClass', - 'enterAnimation', - 'header', - 'htmlAttributes', - 'isOpen', - 'keyboardClose', - 'leaveAnimation', - 'mode', - 'subHeader', - 'translucent', - 'trigger', - ], - standalone: true, + inputs: ['animated', 'backdropDismiss', 'buttons', 'cssClass', 'enterAnimation', 'header', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'subHeader', 'translucent', 'trigger'], + standalone: true }) export class IonActionSheet { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { c.detach(); this.el = r.nativeElement; - proxyOutputs(this, this.el, [ - 'ionActionSheetDidPresent', - 'ionActionSheetWillPresent', - 'ionActionSheetWillDismiss', - 'ionActionSheetDidDismiss', - 'didPresent', - 'willPresent', - 'willDismiss', - 'didDismiss', - ]); + proxyOutputs(this, this.el, ['ionActionSheetDidPresent', 'ionActionSheetWillPresent', 'ionActionSheetWillDismiss', 'ionActionSheetDidDismiss', 'didPresent', 'willPresent', 'willDismiss', 'didDismiss']); } } + import type { OverlayEventDetail as IIonActionSheetOverlayEventDetail } from '@ionic/core/components'; export declare interface IonActionSheet extends Components.IonActionSheet { @@ -228,71 +194,30 @@ Shorthand for ionActionSheetDidDismiss. didDismiss: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonAlert, - inputs: [ - 'animated', - 'backdropDismiss', - 'buttons', - 'cssClass', - 'enterAnimation', - 'header', - 'htmlAttributes', - 'inputs', - 'isOpen', - 'keyboardClose', - 'leaveAnimation', - 'message', - 'mode', - 'subHeader', - 'translucent', - 'trigger', - ], - methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'], + inputs: ['animated', 'backdropDismiss', 'buttons', 'cssClass', 'enterAnimation', 'header', 'htmlAttributes', 'inputs', 'isOpen', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'subHeader', 'translucent', 'trigger'], + methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'] }) @Component({ selector: 'ion-alert', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: [ - 'animated', - 'backdropDismiss', - 'buttons', - 'cssClass', - 'enterAnimation', - 'header', - 'htmlAttributes', - 'inputs', - 'isOpen', - 'keyboardClose', - 'leaveAnimation', - 'message', - 'mode', - 'subHeader', - 'translucent', - 'trigger', - ], - standalone: true, + inputs: ['animated', 'backdropDismiss', 'buttons', 'cssClass', 'enterAnimation', 'header', 'htmlAttributes', 'inputs', 'isOpen', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'subHeader', 'translucent', 'trigger'], + standalone: true }) export class IonAlert { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { c.detach(); this.el = r.nativeElement; - proxyOutputs(this, this.el, [ - 'ionAlertDidPresent', - 'ionAlertWillPresent', - 'ionAlertWillDismiss', - 'ionAlertDidDismiss', - 'didPresent', - 'willPresent', - 'willDismiss', - 'didDismiss', - ]); + proxyOutputs(this, this.el, ['ionAlertDidPresent', 'ionAlertWillPresent', 'ionAlertWillDismiss', 'ionAlertDidDismiss', 'didPresent', 'willPresent', 'willDismiss', 'didDismiss']); } } + import type { OverlayEventDetail as IIonAlertOverlayEventDetail } from '@ionic/core/components'; export declare interface IonAlert extends Components.IonAlert { @@ -334,8 +259,9 @@ Shorthand for ionAlertDidDismiss. didDismiss: EventEmitter>; } + @ProxyCmp({ - defineCustomElementFn: defineIonApp, + defineCustomElementFn: defineIonApp }) @Component({ selector: 'ion-app', @@ -343,7 +269,7 @@ Shorthand for ionAlertDidDismiss. template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: [], - standalone: true, + standalone: true }) export class IonApp { protected el: HTMLElement; @@ -353,10 +279,12 @@ export class IonApp { } } + export declare interface IonApp extends Components.IonApp {} + @ProxyCmp({ - defineCustomElementFn: defineIonAvatar, + defineCustomElementFn: defineIonAvatar }) @Component({ selector: 'ion-avatar', @@ -364,7 +292,7 @@ export declare interface IonApp extends Components.IonApp {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: [], - standalone: true, + standalone: true }) export class IonAvatar { protected el: HTMLElement; @@ -374,11 +302,13 @@ export class IonAvatar { } } + export declare interface IonAvatar extends Components.IonAvatar {} + @ProxyCmp({ defineCustomElementFn: defineIonBackdrop, - inputs: ['stopPropagation', 'tappable', 'visible'], + inputs: ['stopPropagation', 'tappable', 'visible'] }) @Component({ selector: 'ion-backdrop', @@ -386,7 +316,7 @@ export declare interface IonAvatar extends Components.IonAvatar {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['stopPropagation', 'tappable', 'visible'], - standalone: true, + standalone: true }) export class IonBackdrop { protected el: HTMLElement; @@ -397,6 +327,7 @@ export class IonBackdrop { } } + export declare interface IonBackdrop extends Components.IonBackdrop { /** * Emitted when the backdrop is tapped. @@ -404,9 +335,10 @@ export declare interface IonBackdrop extends Components.IonBackdrop { ionBackdropTap: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonBadge, - inputs: ['color', 'mode'], + inputs: ['color', 'mode'] }) @Component({ selector: 'ion-badge', @@ -414,7 +346,7 @@ export declare interface IonBackdrop extends Components.IonBackdrop { template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'mode'], - standalone: true, + standalone: true }) export class IonBadge { protected el: HTMLElement; @@ -424,43 +356,21 @@ export class IonBadge { } } + export declare interface IonBadge extends Components.IonBadge {} + @ProxyCmp({ defineCustomElementFn: defineIonBreadcrumb, - inputs: [ - 'active', - 'color', - 'disabled', - 'download', - 'href', - 'mode', - 'rel', - 'routerAnimation', - 'routerDirection', - 'separator', - 'target', - ], + inputs: ['active', 'color', 'disabled', 'download', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'separator', 'target'] }) @Component({ selector: 'ion-breadcrumb', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: [ - 'active', - 'color', - 'disabled', - 'download', - 'href', - 'mode', - 'rel', - 'routerAnimation', - 'routerDirection', - 'separator', - 'target', - ], - standalone: true, + inputs: ['active', 'color', 'disabled', 'download', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'separator', 'target'], + standalone: true }) export class IonBreadcrumb { protected el: HTMLElement; @@ -471,6 +381,7 @@ export class IonBreadcrumb { } } + export declare interface IonBreadcrumb extends Components.IonBreadcrumb { /** * Emitted when the breadcrumb has focus. @@ -482,9 +393,10 @@ export declare interface IonBreadcrumb extends Components.IonBreadcrumb { ionBlur: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonBreadcrumbs, - inputs: ['color', 'itemsAfterCollapse', 'itemsBeforeCollapse', 'maxItems', 'mode'], + inputs: ['color', 'itemsAfterCollapse', 'itemsBeforeCollapse', 'maxItems', 'mode'] }) @Component({ selector: 'ion-breadcrumbs', @@ -492,7 +404,7 @@ export declare interface IonBreadcrumb extends Components.IonBreadcrumb { template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'itemsAfterCollapse', 'itemsBeforeCollapse', 'maxItems', 'mode'], - standalone: true, + standalone: true }) export class IonBreadcrumbs { protected el: HTMLElement; @@ -503,6 +415,7 @@ export class IonBreadcrumbs { } } + import type { BreadcrumbCollapsedClickEventDetail as IIonBreadcrumbsBreadcrumbCollapsedClickEventDetail } from '@ionic/core/components'; export declare interface IonBreadcrumbs extends Components.IonBreadcrumbs { @@ -512,53 +425,18 @@ export declare interface IonBreadcrumbs extends Components.IonBreadcrumbs { ionCollapsedClick: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonButton, - inputs: [ - 'buttonType', - 'color', - 'disabled', - 'download', - 'expand', - 'fill', - 'form', - 'href', - 'mode', - 'rel', - 'routerAnimation', - 'routerDirection', - 'shape', - 'size', - 'strong', - 'target', - 'type', - ], + inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'type'] }) @Component({ selector: 'ion-button', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: [ - 'buttonType', - 'color', - 'disabled', - 'download', - 'expand', - 'fill', - 'form', - 'href', - 'mode', - 'rel', - 'routerAnimation', - 'routerDirection', - 'shape', - 'size', - 'strong', - 'target', - 'type', - ], - standalone: true, + inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'type'], + standalone: true }) export class IonButton { protected el: HTMLElement; @@ -569,6 +447,7 @@ export class IonButton { } } + export declare interface IonButton extends Components.IonButton { /** * Emitted when the button has focus. @@ -580,9 +459,10 @@ export declare interface IonButton extends Components.IonButton { ionBlur: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonButtons, - inputs: ['collapse'], + inputs: ['collapse'] }) @Component({ selector: 'ion-buttons', @@ -590,7 +470,7 @@ export declare interface IonButton extends Components.IonButton { template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['collapse'], - standalone: true, + standalone: true }) export class IonButtons { protected el: HTMLElement; @@ -600,43 +480,21 @@ export class IonButtons { } } + export declare interface IonButtons extends Components.IonButtons {} + @ProxyCmp({ defineCustomElementFn: defineIonCard, - inputs: [ - 'button', - 'color', - 'disabled', - 'download', - 'href', - 'mode', - 'rel', - 'routerAnimation', - 'routerDirection', - 'target', - 'type', - ], + inputs: ['button', 'color', 'disabled', 'download', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'target', 'type'] }) @Component({ selector: 'ion-card', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: [ - 'button', - 'color', - 'disabled', - 'download', - 'href', - 'mode', - 'rel', - 'routerAnimation', - 'routerDirection', - 'target', - 'type', - ], - standalone: true, + inputs: ['button', 'color', 'disabled', 'download', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'target', 'type'], + standalone: true }) export class IonCard { protected el: HTMLElement; @@ -646,11 +504,13 @@ export class IonCard { } } + export declare interface IonCard extends Components.IonCard {} + @ProxyCmp({ defineCustomElementFn: defineIonCardContent, - inputs: ['mode'], + inputs: ['mode'] }) @Component({ selector: 'ion-card-content', @@ -658,7 +518,7 @@ export declare interface IonCard extends Components.IonCard {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['mode'], - standalone: true, + standalone: true }) export class IonCardContent { protected el: HTMLElement; @@ -668,11 +528,13 @@ export class IonCardContent { } } + export declare interface IonCardContent extends Components.IonCardContent {} + @ProxyCmp({ defineCustomElementFn: defineIonCardHeader, - inputs: ['color', 'mode', 'translucent'], + inputs: ['color', 'mode', 'translucent'] }) @Component({ selector: 'ion-card-header', @@ -680,7 +542,7 @@ export declare interface IonCardContent extends Components.IonCardContent {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'mode', 'translucent'], - standalone: true, + standalone: true }) export class IonCardHeader { protected el: HTMLElement; @@ -690,11 +552,13 @@ export class IonCardHeader { } } + export declare interface IonCardHeader extends Components.IonCardHeader {} + @ProxyCmp({ defineCustomElementFn: defineIonCardSubtitle, - inputs: ['color', 'mode'], + inputs: ['color', 'mode'] }) @Component({ selector: 'ion-card-subtitle', @@ -702,7 +566,7 @@ export declare interface IonCardHeader extends Components.IonCardHeader {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'mode'], - standalone: true, + standalone: true }) export class IonCardSubtitle { protected el: HTMLElement; @@ -712,11 +576,13 @@ export class IonCardSubtitle { } } + export declare interface IonCardSubtitle extends Components.IonCardSubtitle {} + @ProxyCmp({ defineCustomElementFn: defineIonCardTitle, - inputs: ['color', 'mode'], + inputs: ['color', 'mode'] }) @Component({ selector: 'ion-card-title', @@ -724,7 +590,7 @@ export declare interface IonCardSubtitle extends Components.IonCardSubtitle {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'mode'], - standalone: true, + standalone: true }) export class IonCardTitle { protected el: HTMLElement; @@ -734,11 +600,13 @@ export class IonCardTitle { } } + export declare interface IonCardTitle extends Components.IonCardTitle {} + @ProxyCmp({ defineCustomElementFn: defineIonChip, - inputs: ['color', 'disabled', 'mode', 'outline'], + inputs: ['color', 'disabled', 'mode', 'outline'] }) @Component({ selector: 'ion-chip', @@ -746,7 +614,7 @@ export declare interface IonCardTitle extends Components.IonCardTitle {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'disabled', 'mode', 'outline'], - standalone: true, + standalone: true }) export class IonChip { protected el: HTMLElement; @@ -756,69 +624,21 @@ export class IonChip { } } + export declare interface IonChip extends Components.IonChip {} + @ProxyCmp({ defineCustomElementFn: defineIonCol, - inputs: [ - 'offset', - 'offsetLg', - 'offsetMd', - 'offsetSm', - 'offsetXl', - 'offsetXs', - 'pull', - 'pullLg', - 'pullMd', - 'pullSm', - 'pullXl', - 'pullXs', - 'push', - 'pushLg', - 'pushMd', - 'pushSm', - 'pushXl', - 'pushXs', - 'size', - 'sizeLg', - 'sizeMd', - 'sizeSm', - 'sizeXl', - 'sizeXs', - ], + inputs: ['offset', 'offsetLg', 'offsetMd', 'offsetSm', 'offsetXl', 'offsetXs', 'pull', 'pullLg', 'pullMd', 'pullSm', 'pullXl', 'pullXs', 'push', 'pushLg', 'pushMd', 'pushSm', 'pushXl', 'pushXs', 'size', 'sizeLg', 'sizeMd', 'sizeSm', 'sizeXl', 'sizeXs'] }) @Component({ selector: 'ion-col', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: [ - 'offset', - 'offsetLg', - 'offsetMd', - 'offsetSm', - 'offsetXl', - 'offsetXs', - 'pull', - 'pullLg', - 'pullMd', - 'pullSm', - 'pullXl', - 'pullXs', - 'push', - 'pushLg', - 'pushMd', - 'pushSm', - 'pushXl', - 'pushXs', - 'size', - 'sizeLg', - 'sizeMd', - 'sizeSm', - 'sizeXl', - 'sizeXs', - ], - standalone: true, + inputs: ['offset', 'offsetLg', 'offsetMd', 'offsetSm', 'offsetXl', 'offsetXs', 'pull', 'pullLg', 'pullMd', 'pullSm', 'pullXl', 'pullXs', 'push', 'pushLg', 'pushMd', 'pushSm', 'pushXl', 'pushXs', 'size', 'sizeLg', 'sizeMd', 'sizeSm', 'sizeXl', 'sizeXs'], + standalone: true }) export class IonCol { protected el: HTMLElement; @@ -828,12 +648,14 @@ export class IonCol { } } + export declare interface IonCol extends Components.IonCol {} + @ProxyCmp({ defineCustomElementFn: defineIonContent, inputs: ['color', 'forceOverscroll', 'fullscreen', 'scrollEvents', 'scrollX', 'scrollY'], - methods: ['getScrollElement', 'scrollToTop', 'scrollToBottom', 'scrollByPoint', 'scrollToPoint'], + methods: ['getScrollElement', 'scrollToTop', 'scrollToBottom', 'scrollByPoint', 'scrollToPoint'] }) @Component({ selector: 'ion-content', @@ -841,7 +663,7 @@ export declare interface IonCol extends Components.IonCol {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'forceOverscroll', 'fullscreen', 'scrollEvents', 'scrollX', 'scrollY'], - standalone: true, + standalone: true }) export class IonContent { protected el: HTMLElement; @@ -852,6 +674,7 @@ export class IonContent { } } + import type { ScrollBaseDetail as IIonContentScrollBaseDetail } from '@ionic/core/components'; import type { ScrollDetail as IIonContentScrollDetail } from '@ionic/core/components'; @@ -873,9 +696,10 @@ Set `scrollEvents` to `true` to enable. ionScrollEnd: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonDatetimeButton, - inputs: ['color', 'datetime', 'disabled', 'mode'], + inputs: ['color', 'datetime', 'disabled', 'mode'] }) @Component({ selector: 'ion-datetime-button', @@ -883,7 +707,7 @@ Set `scrollEvents` to `true` to enable. template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'datetime', 'disabled', 'mode'], - standalone: true, + standalone: true }) export class IonDatetimeButton { protected el: HTMLElement; @@ -893,12 +717,14 @@ export class IonDatetimeButton { } } + export declare interface IonDatetimeButton extends Components.IonDatetimeButton {} + @ProxyCmp({ defineCustomElementFn: defineIonFab, inputs: ['activated', 'edge', 'horizontal', 'vertical'], - methods: ['close'], + methods: ['close'] }) @Component({ selector: 'ion-fab', @@ -906,7 +732,7 @@ export declare interface IonDatetimeButton extends Components.IonDatetimeButton template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['activated', 'edge', 'horizontal', 'vertical'], - standalone: true, + standalone: true }) export class IonFab { protected el: HTMLElement; @@ -916,51 +742,21 @@ export class IonFab { } } + export declare interface IonFab extends Components.IonFab {} + @ProxyCmp({ defineCustomElementFn: defineIonFabButton, - inputs: [ - 'activated', - 'closeIcon', - 'color', - 'disabled', - 'download', - 'href', - 'mode', - 'rel', - 'routerAnimation', - 'routerDirection', - 'show', - 'size', - 'target', - 'translucent', - 'type', - ], + inputs: ['activated', 'closeIcon', 'color', 'disabled', 'download', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'show', 'size', 'target', 'translucent', 'type'] }) @Component({ selector: 'ion-fab-button', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: [ - 'activated', - 'closeIcon', - 'color', - 'disabled', - 'download', - 'href', - 'mode', - 'rel', - 'routerAnimation', - 'routerDirection', - 'show', - 'size', - 'target', - 'translucent', - 'type', - ], - standalone: true, + inputs: ['activated', 'closeIcon', 'color', 'disabled', 'download', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'show', 'size', 'target', 'translucent', 'type'], + standalone: true }) export class IonFabButton { protected el: HTMLElement; @@ -971,6 +767,7 @@ export class IonFabButton { } } + export declare interface IonFabButton extends Components.IonFabButton { /** * Emitted when the button has focus. @@ -982,9 +779,10 @@ export declare interface IonFabButton extends Components.IonFabButton { ionBlur: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonFabList, - inputs: ['activated', 'side'], + inputs: ['activated', 'side'] }) @Component({ selector: 'ion-fab-list', @@ -992,7 +790,7 @@ export declare interface IonFabButton extends Components.IonFabButton { template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['activated', 'side'], - standalone: true, + standalone: true }) export class IonFabList { protected el: HTMLElement; @@ -1002,11 +800,13 @@ export class IonFabList { } } + export declare interface IonFabList extends Components.IonFabList {} + @ProxyCmp({ defineCustomElementFn: defineIonFooter, - inputs: ['collapse', 'mode', 'translucent'], + inputs: ['collapse', 'mode', 'translucent'] }) @Component({ selector: 'ion-footer', @@ -1014,7 +814,7 @@ export declare interface IonFabList extends Components.IonFabList {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['collapse', 'mode', 'translucent'], - standalone: true, + standalone: true }) export class IonFooter { protected el: HTMLElement; @@ -1024,11 +824,13 @@ export class IonFooter { } } + export declare interface IonFooter extends Components.IonFooter {} + @ProxyCmp({ defineCustomElementFn: defineIonGrid, - inputs: ['fixed'], + inputs: ['fixed'] }) @Component({ selector: 'ion-grid', @@ -1036,7 +838,7 @@ export declare interface IonFooter extends Components.IonFooter {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['fixed'], - standalone: true, + standalone: true }) export class IonGrid { protected el: HTMLElement; @@ -1046,11 +848,13 @@ export class IonGrid { } } + export declare interface IonGrid extends Components.IonGrid {} + @ProxyCmp({ defineCustomElementFn: defineIonHeader, - inputs: ['collapse', 'mode', 'translucent'], + inputs: ['collapse', 'mode', 'translucent'] }) @Component({ selector: 'ion-header', @@ -1058,7 +862,7 @@ export declare interface IonGrid extends Components.IonGrid {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['collapse', 'mode', 'translucent'], - standalone: true, + standalone: true }) export class IonHeader { protected el: HTMLElement; @@ -1068,11 +872,13 @@ export class IonHeader { } } + export declare interface IonHeader extends Components.IonHeader {} + @ProxyCmp({ defineCustomElementFn: defineIonImg, - inputs: ['alt', 'src'], + inputs: ['alt', 'src'] }) @Component({ selector: 'ion-img', @@ -1080,7 +886,7 @@ export declare interface IonHeader extends Components.IonHeader {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['alt', 'src'], - standalone: true, + standalone: true }) export class IonImg { protected el: HTMLElement; @@ -1091,6 +897,7 @@ export class IonImg { } } + export declare interface IonImg extends Components.IonImg { /** * Emitted when the img src has been set @@ -1106,10 +913,11 @@ export declare interface IonImg extends Components.IonImg { ionError: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonInfiniteScroll, inputs: ['disabled', 'position', 'threshold'], - methods: ['complete'], + methods: ['complete'] }) @Component({ selector: 'ion-infinite-scroll', @@ -1117,7 +925,7 @@ export declare interface IonImg extends Components.IonImg { template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['disabled', 'position', 'threshold'], - standalone: true, + standalone: true }) export class IonInfiniteScroll { protected el: HTMLElement; @@ -1128,6 +936,7 @@ export class IonInfiniteScroll { } } + export declare interface IonInfiniteScroll extends Components.IonInfiniteScroll { /** * Emitted when the scroll reaches @@ -1138,9 +947,10 @@ your async operation has completed. ionInfinite: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonInfiniteScrollContent, - inputs: ['loadingSpinner', 'loadingText'], + inputs: ['loadingSpinner', 'loadingText'] }) @Component({ selector: 'ion-infinite-scroll-content', @@ -1148,7 +958,7 @@ your async operation has completed. template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['loadingSpinner', 'loadingText'], - standalone: true, + standalone: true }) export class IonInfiniteScrollContent { protected el: HTMLElement; @@ -1158,57 +968,21 @@ export class IonInfiniteScrollContent { } } + export declare interface IonInfiniteScrollContent extends Components.IonInfiniteScrollContent {} + @ProxyCmp({ defineCustomElementFn: defineIonItem, - inputs: [ - 'button', - 'color', - 'counter', - 'counterFormatter', - 'detail', - 'detailIcon', - 'disabled', - 'download', - 'fill', - 'href', - 'lines', - 'mode', - 'rel', - 'routerAnimation', - 'routerDirection', - 'shape', - 'target', - 'type', - ], + inputs: ['button', 'color', 'counter', 'counterFormatter', 'detail', 'detailIcon', 'disabled', 'download', 'fill', 'href', 'lines', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'target', 'type'] }) @Component({ selector: 'ion-item', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: [ - 'button', - 'color', - 'counter', - 'counterFormatter', - 'detail', - 'detailIcon', - 'disabled', - 'download', - 'fill', - 'href', - 'lines', - 'mode', - 'rel', - 'routerAnimation', - 'routerDirection', - 'shape', - 'target', - 'type', - ], - standalone: true, + inputs: ['button', 'color', 'counter', 'counterFormatter', 'detail', 'detailIcon', 'disabled', 'download', 'fill', 'href', 'lines', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'target', 'type'], + standalone: true }) export class IonItem { protected el: HTMLElement; @@ -1218,11 +992,13 @@ export class IonItem { } } + export declare interface IonItem extends Components.IonItem {} + @ProxyCmp({ defineCustomElementFn: defineIonItemDivider, - inputs: ['color', 'mode', 'sticky'], + inputs: ['color', 'mode', 'sticky'] }) @Component({ selector: 'ion-item-divider', @@ -1230,7 +1006,7 @@ export declare interface IonItem extends Components.IonItem {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'mode', 'sticky'], - standalone: true, + standalone: true }) export class IonItemDivider { protected el: HTMLElement; @@ -1240,10 +1016,12 @@ export class IonItemDivider { } } + export declare interface IonItemDivider extends Components.IonItemDivider {} + @ProxyCmp({ - defineCustomElementFn: defineIonItemGroup, + defineCustomElementFn: defineIonItemGroup }) @Component({ selector: 'ion-item-group', @@ -1251,7 +1029,7 @@ export declare interface IonItemDivider extends Components.IonItemDivider {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: [], - standalone: true, + standalone: true }) export class IonItemGroup { protected el: HTMLElement; @@ -1261,11 +1039,13 @@ export class IonItemGroup { } } + export declare interface IonItemGroup extends Components.IonItemGroup {} + @ProxyCmp({ defineCustomElementFn: defineIonItemOption, - inputs: ['color', 'disabled', 'download', 'expandable', 'href', 'mode', 'rel', 'target', 'type'], + inputs: ['color', 'disabled', 'download', 'expandable', 'href', 'mode', 'rel', 'target', 'type'] }) @Component({ selector: 'ion-item-option', @@ -1273,7 +1053,7 @@ export declare interface IonItemGroup extends Components.IonItemGroup {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'disabled', 'download', 'expandable', 'href', 'mode', 'rel', 'target', 'type'], - standalone: true, + standalone: true }) export class IonItemOption { protected el: HTMLElement; @@ -1283,11 +1063,13 @@ export class IonItemOption { } } + export declare interface IonItemOption extends Components.IonItemOption {} + @ProxyCmp({ defineCustomElementFn: defineIonItemOptions, - inputs: ['side'], + inputs: ['side'] }) @Component({ selector: 'ion-item-options', @@ -1295,7 +1077,7 @@ export declare interface IonItemOption extends Components.IonItemOption {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['side'], - standalone: true, + standalone: true }) export class IonItemOptions { protected el: HTMLElement; @@ -1306,6 +1088,7 @@ export class IonItemOptions { } } + export declare interface IonItemOptions extends Components.IonItemOptions { /** * Emitted when the item has been fully swiped. @@ -1313,10 +1096,11 @@ export declare interface IonItemOptions extends Components.IonItemOptions { ionSwipe: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonItemSliding, inputs: ['disabled'], - methods: ['getOpenAmount', 'getSlidingRatio', 'open', 'close', 'closeOpened'], + methods: ['getOpenAmount', 'getSlidingRatio', 'open', 'close', 'closeOpened'] }) @Component({ selector: 'ion-item-sliding', @@ -1324,7 +1108,7 @@ export declare interface IonItemOptions extends Components.IonItemOptions { template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['disabled'], - standalone: true, + standalone: true }) export class IonItemSliding { protected el: HTMLElement; @@ -1335,6 +1119,7 @@ export class IonItemSliding { } } + export declare interface IonItemSliding extends Components.IonItemSliding { /** * Emitted when the sliding position changes. @@ -1342,9 +1127,10 @@ export declare interface IonItemSliding extends Components.IonItemSliding { ionDrag: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonLabel, - inputs: ['color', 'mode', 'position'], + inputs: ['color', 'mode', 'position'] }) @Component({ selector: 'ion-label', @@ -1352,7 +1138,7 @@ export declare interface IonItemSliding extends Components.IonItemSliding { template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'mode', 'position'], - standalone: true, + standalone: true }) export class IonLabel { protected el: HTMLElement; @@ -1362,12 +1148,14 @@ export class IonLabel { } } + export declare interface IonLabel extends Components.IonLabel {} + @ProxyCmp({ defineCustomElementFn: defineIonList, inputs: ['inset', 'lines', 'mode'], - methods: ['closeSlidingItems'], + methods: ['closeSlidingItems'] }) @Component({ selector: 'ion-list', @@ -1375,7 +1163,7 @@ export declare interface IonLabel extends Components.IonLabel {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['inset', 'lines', 'mode'], - standalone: true, + standalone: true }) export class IonList { protected el: HTMLElement; @@ -1385,11 +1173,13 @@ export class IonList { } } + export declare interface IonList extends Components.IonList {} + @ProxyCmp({ defineCustomElementFn: defineIonListHeader, - inputs: ['color', 'lines', 'mode'], + inputs: ['color', 'lines', 'mode'] }) @Component({ selector: 'ion-list-header', @@ -1397,7 +1187,7 @@ export declare interface IonList extends Components.IonList {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'lines', 'mode'], - standalone: true, + standalone: true }) export class IonListHeader { protected el: HTMLElement; @@ -1407,71 +1197,33 @@ export class IonListHeader { } } + export declare interface IonListHeader extends Components.IonListHeader {} + @ProxyCmp({ defineCustomElementFn: defineIonLoading, - inputs: [ - 'animated', - 'backdropDismiss', - 'cssClass', - 'duration', - 'enterAnimation', - 'htmlAttributes', - 'isOpen', - 'keyboardClose', - 'leaveAnimation', - 'message', - 'mode', - 'showBackdrop', - 'spinner', - 'translucent', - 'trigger', - ], - methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'], + inputs: ['animated', 'backdropDismiss', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'showBackdrop', 'spinner', 'translucent', 'trigger'], + methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'] }) @Component({ selector: 'ion-loading', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: [ - 'animated', - 'backdropDismiss', - 'cssClass', - 'duration', - 'enterAnimation', - 'htmlAttributes', - 'isOpen', - 'keyboardClose', - 'leaveAnimation', - 'message', - 'mode', - 'showBackdrop', - 'spinner', - 'translucent', - 'trigger', - ], - standalone: true, + inputs: ['animated', 'backdropDismiss', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'showBackdrop', 'spinner', 'translucent', 'trigger'], + standalone: true }) export class IonLoading { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { c.detach(); this.el = r.nativeElement; - proxyOutputs(this, this.el, [ - 'ionLoadingDidPresent', - 'ionLoadingWillPresent', - 'ionLoadingWillDismiss', - 'ionLoadingDidDismiss', - 'didPresent', - 'willPresent', - 'willDismiss', - 'didDismiss', - ]); + proxyOutputs(this, this.el, ['ionLoadingDidPresent', 'ionLoadingWillPresent', 'ionLoadingWillDismiss', 'ionLoadingDidDismiss', 'didPresent', 'willPresent', 'willDismiss', 'didDismiss']); } } + import type { OverlayEventDetail as IIonLoadingOverlayEventDetail } from '@ionic/core/components'; export declare interface IonLoading extends Components.IonLoading { @@ -1513,10 +1265,11 @@ Shorthand for ionLoadingDidDismiss. didDismiss: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonMenu, inputs: ['contentId', 'disabled', 'maxEdgeStart', 'menuId', 'side', 'swipeGesture', 'type'], - methods: ['isOpen', 'isActive', 'open', 'close', 'toggle', 'setOpen'], + methods: ['isOpen', 'isActive', 'open', 'close', 'toggle', 'setOpen'] }) @Component({ selector: 'ion-menu', @@ -1524,7 +1277,7 @@ Shorthand for ionLoadingDidDismiss. template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['contentId', 'disabled', 'maxEdgeStart', 'menuId', 'side', 'swipeGesture', 'type'], - standalone: true, + standalone: true }) export class IonMenu { protected el: HTMLElement; @@ -1535,6 +1288,7 @@ export class IonMenu { } } + export declare interface IonMenu extends Components.IonMenu { /** * Emitted when the menu is about to be opened. @@ -1554,9 +1308,10 @@ export declare interface IonMenu extends Components.IonMenu { ionDidClose: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonMenuButton, - inputs: ['autoHide', 'color', 'disabled', 'menu', 'mode', 'type'], + inputs: ['autoHide', 'color', 'disabled', 'menu', 'mode', 'type'] }) @Component({ selector: 'ion-menu-button', @@ -1564,7 +1319,7 @@ export declare interface IonMenu extends Components.IonMenu { template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['autoHide', 'color', 'disabled', 'menu', 'mode', 'type'], - standalone: true, + standalone: true }) export class IonMenuButton { protected el: HTMLElement; @@ -1574,11 +1329,13 @@ export class IonMenuButton { } } + export declare interface IonMenuButton extends Components.IonMenuButton {} + @ProxyCmp({ defineCustomElementFn: defineIonMenuToggle, - inputs: ['autoHide', 'menu'], + inputs: ['autoHide', 'menu'] }) @Component({ selector: 'ion-menu-toggle', @@ -1586,7 +1343,7 @@ export declare interface IonMenuButton extends Components.IonMenuButton {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['autoHide', 'menu'], - standalone: true, + standalone: true }) export class IonMenuToggle { protected el: HTMLElement; @@ -1596,11 +1353,13 @@ export class IonMenuToggle { } } + export declare interface IonMenuToggle extends Components.IonMenuToggle {} + @ProxyCmp({ defineCustomElementFn: defineIonNavLink, - inputs: ['component', 'componentProps', 'routerAnimation', 'routerDirection'], + inputs: ['component', 'componentProps', 'routerAnimation', 'routerDirection'] }) @Component({ selector: 'ion-nav-link', @@ -1608,7 +1367,7 @@ export declare interface IonMenuToggle extends Components.IonMenuToggle {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['component', 'componentProps', 'routerAnimation', 'routerDirection'], - standalone: true, + standalone: true }) export class IonNavLink { protected el: HTMLElement; @@ -1618,11 +1377,13 @@ export class IonNavLink { } } + export declare interface IonNavLink extends Components.IonNavLink {} + @ProxyCmp({ defineCustomElementFn: defineIonNote, - inputs: ['color', 'mode'], + inputs: ['color', 'mode'] }) @Component({ selector: 'ion-note', @@ -1630,7 +1391,7 @@ export declare interface IonNavLink extends Components.IonNavLink {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'mode'], - standalone: true, + standalone: true }) export class IonNote { protected el: HTMLElement; @@ -1640,69 +1401,33 @@ export class IonNote { } } + export declare interface IonNote extends Components.IonNote {} + @ProxyCmp({ defineCustomElementFn: defineIonPicker, - inputs: [ - 'animated', - 'backdropDismiss', - 'buttons', - 'columns', - 'cssClass', - 'duration', - 'enterAnimation', - 'htmlAttributes', - 'isOpen', - 'keyboardClose', - 'leaveAnimation', - 'mode', - 'showBackdrop', - 'trigger', - ], - methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss', 'getColumn'], + inputs: ['animated', 'backdropDismiss', 'buttons', 'columns', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'showBackdrop', 'trigger'], + methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss', 'getColumn'] }) @Component({ selector: 'ion-picker', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: [ - 'animated', - 'backdropDismiss', - 'buttons', - 'columns', - 'cssClass', - 'duration', - 'enterAnimation', - 'htmlAttributes', - 'isOpen', - 'keyboardClose', - 'leaveAnimation', - 'mode', - 'showBackdrop', - 'trigger', - ], - standalone: true, + inputs: ['animated', 'backdropDismiss', 'buttons', 'columns', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'showBackdrop', 'trigger'], + standalone: true }) export class IonPicker { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { c.detach(); this.el = r.nativeElement; - proxyOutputs(this, this.el, [ - 'ionPickerDidPresent', - 'ionPickerWillPresent', - 'ionPickerWillDismiss', - 'ionPickerDidDismiss', - 'didPresent', - 'willPresent', - 'willDismiss', - 'didDismiss', - ]); + proxyOutputs(this, this.el, ['ionPickerDidPresent', 'ionPickerWillPresent', 'ionPickerWillDismiss', 'ionPickerDidDismiss', 'didPresent', 'willPresent', 'willDismiss', 'didDismiss']); } } + import type { OverlayEventDetail as IIonPickerOverlayEventDetail } from '@ionic/core/components'; export declare interface IonPicker extends Components.IonPicker { @@ -1744,9 +1469,10 @@ Shorthand for ionPickerDidDismiss. didDismiss: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonProgressBar, - inputs: ['buffer', 'color', 'mode', 'reversed', 'type', 'value'], + inputs: ['buffer', 'color', 'mode', 'reversed', 'type', 'value'] }) @Component({ selector: 'ion-progress-bar', @@ -1754,7 +1480,7 @@ Shorthand for ionPickerDidDismiss. template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['buffer', 'color', 'mode', 'reversed', 'type', 'value'], - standalone: true, + standalone: true }) export class IonProgressBar { protected el: HTMLElement; @@ -1764,12 +1490,14 @@ export class IonProgressBar { } } + export declare interface IonProgressBar extends Components.IonProgressBar {} + @ProxyCmp({ defineCustomElementFn: defineIonRefresher, inputs: ['closeDuration', 'disabled', 'pullFactor', 'pullMax', 'pullMin', 'snapbackDuration'], - methods: ['complete', 'cancel', 'getProgress'], + methods: ['complete', 'cancel', 'getProgress'] }) @Component({ selector: 'ion-refresher', @@ -1777,7 +1505,7 @@ export declare interface IonProgressBar extends Components.IonProgressBar {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['closeDuration', 'disabled', 'pullFactor', 'pullMax', 'pullMin', 'snapbackDuration'], - standalone: true, + standalone: true }) export class IonRefresher { protected el: HTMLElement; @@ -1788,6 +1516,7 @@ export class IonRefresher { } } + import type { RefresherEventDetail as IIonRefresherRefresherEventDetail } from '@ionic/core/components'; export declare interface IonRefresher extends Components.IonRefresher { @@ -1808,9 +1537,10 @@ called when the async operation has completed. ionStart: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonRefresherContent, - inputs: ['pullingIcon', 'pullingText', 'refreshingSpinner', 'refreshingText'], + inputs: ['pullingIcon', 'pullingText', 'refreshingSpinner', 'refreshingText'] }) @Component({ selector: 'ion-refresher-content', @@ -1818,7 +1548,7 @@ called when the async operation has completed. template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['pullingIcon', 'pullingText', 'refreshingSpinner', 'refreshingText'], - standalone: true, + standalone: true }) export class IonRefresherContent { protected el: HTMLElement; @@ -1828,10 +1558,12 @@ export class IonRefresherContent { } } + export declare interface IonRefresherContent extends Components.IonRefresherContent {} + @ProxyCmp({ - defineCustomElementFn: defineIonReorder, + defineCustomElementFn: defineIonReorder }) @Component({ selector: 'ion-reorder', @@ -1839,7 +1571,7 @@ export declare interface IonRefresherContent extends Components.IonRefresherCont template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: [], - standalone: true, + standalone: true }) export class IonReorder { protected el: HTMLElement; @@ -1849,12 +1581,14 @@ export class IonReorder { } } + export declare interface IonReorder extends Components.IonReorder {} + @ProxyCmp({ defineCustomElementFn: defineIonReorderGroup, inputs: ['disabled'], - methods: ['complete'], + methods: ['complete'] }) @Component({ selector: 'ion-reorder-group', @@ -1862,7 +1596,7 @@ export declare interface IonReorder extends Components.IonReorder {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['disabled'], - standalone: true, + standalone: true }) export class IonReorderGroup { protected el: HTMLElement; @@ -1873,6 +1607,7 @@ export class IonReorderGroup { } } + import type { ItemReorderEventDetail as IIonReorderGroupItemReorderEventDetail } from '@ionic/core/components'; export declare interface IonReorderGroup extends Components.IonReorderGroup { @@ -1884,10 +1619,11 @@ to be called in order to finalize the reorder action. ionItemReorder: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonRippleEffect, inputs: ['type'], - methods: ['addRipple'], + methods: ['addRipple'] }) @Component({ selector: 'ion-ripple-effect', @@ -1895,7 +1631,7 @@ to be called in order to finalize the reorder action. template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['type'], - standalone: true, + standalone: true }) export class IonRippleEffect { protected el: HTMLElement; @@ -1905,10 +1641,12 @@ export class IonRippleEffect { } } + export declare interface IonRippleEffect extends Components.IonRippleEffect {} + @ProxyCmp({ - defineCustomElementFn: defineIonRow, + defineCustomElementFn: defineIonRow }) @Component({ selector: 'ion-row', @@ -1916,7 +1654,7 @@ export declare interface IonRippleEffect extends Components.IonRippleEffect {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: [], - standalone: true, + standalone: true }) export class IonRow { protected el: HTMLElement; @@ -1926,11 +1664,13 @@ export class IonRow { } } + export declare interface IonRow extends Components.IonRow {} + @ProxyCmp({ defineCustomElementFn: defineIonSegmentButton, - inputs: ['disabled', 'layout', 'mode', 'type', 'value'], + inputs: ['disabled', 'layout', 'mode', 'type', 'value'] }) @Component({ selector: 'ion-segment-button', @@ -1938,7 +1678,7 @@ export declare interface IonRow extends Components.IonRow {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['disabled', 'layout', 'mode', 'type', 'value'], - standalone: true, + standalone: true }) export class IonSegmentButton { protected el: HTMLElement; @@ -1948,11 +1688,13 @@ export class IonSegmentButton { } } + export declare interface IonSegmentButton extends Components.IonSegmentButton {} + @ProxyCmp({ defineCustomElementFn: defineIonSelectOption, - inputs: ['disabled', 'value'], + inputs: ['disabled', 'value'] }) @Component({ selector: 'ion-select-option', @@ -1960,7 +1702,7 @@ export declare interface IonSegmentButton extends Components.IonSegmentButton {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['disabled', 'value'], - standalone: true, + standalone: true }) export class IonSelectOption { protected el: HTMLElement; @@ -1970,11 +1712,13 @@ export class IonSelectOption { } } + export declare interface IonSelectOption extends Components.IonSelectOption {} + @ProxyCmp({ defineCustomElementFn: defineIonSkeletonText, - inputs: ['animated'], + inputs: ['animated'] }) @Component({ selector: 'ion-skeleton-text', @@ -1982,7 +1726,7 @@ export declare interface IonSelectOption extends Components.IonSelectOption {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['animated'], - standalone: true, + standalone: true }) export class IonSkeletonText { protected el: HTMLElement; @@ -1992,11 +1736,13 @@ export class IonSkeletonText { } } + export declare interface IonSkeletonText extends Components.IonSkeletonText {} + @ProxyCmp({ defineCustomElementFn: defineIonSpinner, - inputs: ['color', 'duration', 'name', 'paused'], + inputs: ['color', 'duration', 'name', 'paused'] }) @Component({ selector: 'ion-spinner', @@ -2004,7 +1750,7 @@ export declare interface IonSkeletonText extends Components.IonSkeletonText {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'duration', 'name', 'paused'], - standalone: true, + standalone: true }) export class IonSpinner { protected el: HTMLElement; @@ -2014,11 +1760,13 @@ export class IonSpinner { } } + export declare interface IonSpinner extends Components.IonSpinner {} + @ProxyCmp({ defineCustomElementFn: defineIonSplitPane, - inputs: ['contentId', 'disabled', 'when'], + inputs: ['contentId', 'disabled', 'when'] }) @Component({ selector: 'ion-split-pane', @@ -2026,7 +1774,7 @@ export declare interface IonSpinner extends Components.IonSpinner {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['contentId', 'disabled', 'when'], - standalone: true, + standalone: true }) export class IonSplitPane { protected el: HTMLElement; @@ -2037,6 +1785,7 @@ export class IonSplitPane { } } + export declare interface IonSplitPane extends Components.IonSplitPane { /** * Expression to be called when the split-pane visibility has changed @@ -2044,9 +1793,10 @@ export declare interface IonSplitPane extends Components.IonSplitPane { ionSplitPaneVisible: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonTabBar, - inputs: ['color', 'mode', 'selectedTab', 'translucent'], + inputs: ['color', 'mode', 'selectedTab', 'translucent'] }) @Component({ selector: 'ion-tab-bar', @@ -2054,7 +1804,7 @@ export declare interface IonSplitPane extends Components.IonSplitPane { template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'mode', 'selectedTab', 'translucent'], - standalone: true, + standalone: true }) export class IonTabBar { protected el: HTMLElement; @@ -2064,11 +1814,13 @@ export class IonTabBar { } } + export declare interface IonTabBar extends Components.IonTabBar {} + @ProxyCmp({ defineCustomElementFn: defineIonTabButton, - inputs: ['disabled', 'download', 'href', 'layout', 'mode', 'rel', 'selected', 'tab', 'target'], + inputs: ['disabled', 'download', 'href', 'layout', 'mode', 'rel', 'selected', 'tab', 'target'] }) @Component({ selector: 'ion-tab-button', @@ -2076,7 +1828,7 @@ export declare interface IonTabBar extends Components.IonTabBar {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['disabled', 'download', 'href', 'layout', 'mode', 'rel', 'selected', 'tab', 'target'], - standalone: true, + standalone: true }) export class IonTabButton { protected el: HTMLElement; @@ -2086,11 +1838,13 @@ export class IonTabButton { } } + export declare interface IonTabButton extends Components.IonTabButton {} + @ProxyCmp({ defineCustomElementFn: defineIonText, - inputs: ['color', 'mode'], + inputs: ['color', 'mode'] }) @Component({ selector: 'ion-text', @@ -2098,7 +1852,7 @@ export declare interface IonTabButton extends Components.IonTabButton {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'mode'], - standalone: true, + standalone: true }) export class IonText { protected el: HTMLElement; @@ -2108,10 +1862,12 @@ export class IonText { } } + export declare interface IonText extends Components.IonText {} + @ProxyCmp({ - defineCustomElementFn: defineIonThumbnail, + defineCustomElementFn: defineIonThumbnail }) @Component({ selector: 'ion-thumbnail', @@ -2119,7 +1875,7 @@ export declare interface IonText extends Components.IonText {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: [], - standalone: true, + standalone: true }) export class IonThumbnail { protected el: HTMLElement; @@ -2129,11 +1885,13 @@ export class IonThumbnail { } } + export declare interface IonThumbnail extends Components.IonThumbnail {} + @ProxyCmp({ defineCustomElementFn: defineIonTitle, - inputs: ['color', 'size'], + inputs: ['color', 'size'] }) @Component({ selector: 'ion-title', @@ -2141,7 +1899,7 @@ export declare interface IonThumbnail extends Components.IonThumbnail {} template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'size'], - standalone: true, + standalone: true }) export class IonTitle { protected el: HTMLElement; @@ -2151,77 +1909,33 @@ export class IonTitle { } } + export declare interface IonTitle extends Components.IonTitle {} + @ProxyCmp({ defineCustomElementFn: defineIonToast, - inputs: [ - 'animated', - 'buttons', - 'color', - 'cssClass', - 'duration', - 'enterAnimation', - 'header', - 'htmlAttributes', - 'icon', - 'isOpen', - 'keyboardClose', - 'layout', - 'leaveAnimation', - 'message', - 'mode', - 'position', - 'translucent', - 'trigger', - ], - methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'], + inputs: ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'isOpen', 'keyboardClose', 'layout', 'leaveAnimation', 'message', 'mode', 'position', 'positionAnchor', 'translucent', 'trigger'], + methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'] }) @Component({ selector: 'ion-toast', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: [ - 'animated', - 'buttons', - 'color', - 'cssClass', - 'duration', - 'enterAnimation', - 'header', - 'htmlAttributes', - 'icon', - 'isOpen', - 'keyboardClose', - 'layout', - 'leaveAnimation', - 'message', - 'mode', - 'position', - 'translucent', - 'trigger', - ], - standalone: true, + inputs: ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'isOpen', 'keyboardClose', 'layout', 'leaveAnimation', 'message', 'mode', 'position', 'positionAnchor', 'translucent', 'trigger'], + standalone: true }) export class IonToast { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { c.detach(); this.el = r.nativeElement; - proxyOutputs(this, this.el, [ - 'ionToastDidPresent', - 'ionToastWillPresent', - 'ionToastWillDismiss', - 'ionToastDidDismiss', - 'didPresent', - 'willPresent', - 'willDismiss', - 'didDismiss', - ]); + proxyOutputs(this, this.el, ['ionToastDidPresent', 'ionToastWillPresent', 'ionToastWillDismiss', 'ionToastDidDismiss', 'didPresent', 'willPresent', 'willDismiss', 'didDismiss']); } } + import type { OverlayEventDetail as IIonToastOverlayEventDetail } from '@ionic/core/components'; export declare interface IonToast extends Components.IonToast { @@ -2263,9 +1977,10 @@ Shorthand for ionToastDidDismiss. didDismiss: EventEmitter>; } + @ProxyCmp({ defineCustomElementFn: defineIonToolbar, - inputs: ['color', 'mode'], + inputs: ['color', 'mode'] }) @Component({ selector: 'ion-toolbar', @@ -2273,7 +1988,7 @@ Shorthand for ionToastDidDismiss. template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['color', 'mode'], - standalone: true, + standalone: true }) export class IonToolbar { protected el: HTMLElement; @@ -2283,4 +1998,7 @@ export class IonToolbar { } } + export declare interface IonToolbar extends Components.IonToolbar {} + + diff --git a/packages/angular/standalone/src/directives/radio-group.ts b/packages/angular/standalone/src/directives/radio-group.ts index 998057a5e3..2c6870aa16 100644 --- a/packages/angular/standalone/src/directives/radio-group.ts +++ b/packages/angular/standalone/src/directives/radio-group.ts @@ -8,19 +8,28 @@ import { Injector, NgZone, } from '@angular/core'; +import type { OnInit } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ValueAccessor } from '@ionic/angular/common'; import type { RadioGroupChangeEventDetail, Components } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-radio-group.js'; -import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils'; +/** + * Value accessor components should not use ProxyCmp + * and should call defineCustomElement and proxyInputs + * manually instead. Using both the @ProxyCmp and @Component + * decorators and useExisting (where useExisting refers to the + * class) causes ng-packagr to output multiple component variables + * which breaks treeshaking. + * For example, the following would be generated: + * let IonRadioGroup = IonRadioGroup_1 = class IonRadioGroup extends ValueAccessor { + * Instead, we want only want the class generated: + * class IonRadioGroup extends ValueAccessor { + */ +import { proxyInputs, proxyOutputs } from './angular-component-lib/utils'; const RADIO_GROUP_INPUTS = ['allowEmptySelection', 'name', 'value']; -@ProxyCmp({ - defineCustomElementFn: defineCustomElement, - inputs: RADIO_GROUP_INPUTS, -}) @Component({ selector: 'ion-radio-group', changeDetection: ChangeDetectionStrategy.OnPush, @@ -36,15 +45,25 @@ const RADIO_GROUP_INPUTS = ['allowEmptySelection', 'name', 'value']; ], standalone: true, }) -export class IonRadioGroup extends ValueAccessor { +export class IonRadioGroup extends ValueAccessor implements OnInit { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone, injector: Injector) { super(injector, r); + defineCustomElement(); c.detach(); this.el = r.nativeElement; proxyOutputs(this, this.el, ['ionChange']); } + ngOnInit(): void { + /** + * Data-bound input properties are set + * by Angular after the constructor, so + * we need to run the proxy in ngOnInit. + */ + proxyInputs(IonRadioGroup, RADIO_GROUP_INPUTS); + } + @HostListener('ionChange', ['$event.target']) handleIonChange(el: HTMLIonRadioGroupElement): void { this.handleValueChange(el, el.value); diff --git a/packages/angular/standalone/src/directives/radio.ts b/packages/angular/standalone/src/directives/radio.ts index 9ad32fadf8..d70ea8d01d 100644 --- a/packages/angular/standalone/src/directives/radio.ts +++ b/packages/angular/standalone/src/directives/radio.ts @@ -8,19 +8,28 @@ import { Injector, NgZone, } from '@angular/core'; +import type { OnInit } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ValueAccessor } from '@ionic/angular/common'; import type { Components } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-radio.js'; -import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils'; +/** + * Value accessor components should not use ProxyCmp + * and should call defineCustomElement and proxyInputs + * manually instead. Using both the @ProxyCmp and @Component + * decorators and useExisting (where useExisting refers to the + * class) causes ng-packagr to output multiple component variables + * which breaks treeshaking. + * For example, the following would be generated: + * let IonRadio = IonRadio_1 = class IonRadio extends ValueAccessor { + * Instead, we want only want the class generated: + * class IonRadio extends ValueAccessor { + */ +import { proxyInputs, proxyOutputs } from './angular-component-lib/utils'; const RADIO_INPUTS = ['color', 'disabled', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value']; -@ProxyCmp({ - defineCustomElementFn: defineCustomElement, - inputs: RADIO_INPUTS, -}) @Component({ selector: 'ion-radio', changeDetection: ChangeDetectionStrategy.OnPush, @@ -36,15 +45,25 @@ const RADIO_INPUTS = ['color', 'disabled', 'justify', 'labelPlacement', 'legacy' ], standalone: true, }) -export class IonRadio extends ValueAccessor { +export class IonRadio extends ValueAccessor implements OnInit { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone, injector: Injector) { super(injector, r); + defineCustomElement(); c.detach(); this.el = r.nativeElement; proxyOutputs(this, this.el, ['ionFocus', 'ionBlur']); } + ngOnInit(): void { + /** + * Data-bound input properties are set + * by Angular after the constructor, so + * we need to run the proxy in ngOnInit. + */ + proxyInputs(IonRadio, RADIO_INPUTS); + } + @HostListener('ionSelect', ['$event.target']) handleIonSelect(el: any): void { /** diff --git a/packages/angular/standalone/src/directives/range.ts b/packages/angular/standalone/src/directives/range.ts index 36aa4c93fc..f77beecbe4 100644 --- a/packages/angular/standalone/src/directives/range.ts +++ b/packages/angular/standalone/src/directives/range.ts @@ -8,6 +8,7 @@ import { Injector, NgZone, } from '@angular/core'; +import type { OnInit } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ValueAccessor } from '@ionic/angular/common'; import type { @@ -18,7 +19,19 @@ import type { } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-range.js'; -import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils'; +/** + * Value accessor components should not use ProxyCmp + * and should call defineCustomElement and proxyInputs + * manually instead. Using both the @ProxyCmp and @Component + * decorators and useExisting (where useExisting refers to the + * class) causes ng-packagr to output multiple component variables + * which breaks treeshaking. + * For example, the following would be generated: + * let IonRange = IonRange_1 = class IonRange extends ValueAccessor { + * Instead, we want only want the class generated: + * class IonRange extends ValueAccessor { + */ +import { proxyInputs, proxyOutputs } from './angular-component-lib/utils'; const RANGE_INPUTS = [ 'activeBarStart', @@ -41,10 +54,6 @@ const RANGE_INPUTS = [ 'value', ]; -@ProxyCmp({ - defineCustomElementFn: defineCustomElement, - inputs: RANGE_INPUTS, -}) @Component({ selector: 'ion-range', changeDetection: ChangeDetectionStrategy.OnPush, @@ -60,15 +69,25 @@ const RANGE_INPUTS = [ ], standalone: true, }) -export class IonRange extends ValueAccessor { +export class IonRange extends ValueAccessor implements OnInit { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone, injector: Injector) { super(injector, r); + defineCustomElement(); c.detach(); this.el = r.nativeElement; proxyOutputs(this, this.el, ['ionChange', 'ionInput', 'ionFocus', 'ionBlur', 'ionKnobMoveStart', 'ionKnobMoveEnd']); } + ngOnInit(): void { + /** + * Data-bound input properties are set + * by Angular after the constructor, so + * we need to run the proxy in ngOnInit. + */ + proxyInputs(IonRange, RANGE_INPUTS); + } + @HostListener('ionChange', ['$event.target']) handleIonChange(el: HTMLIonRangeElement): void { this.handleValueChange(el, el.value); diff --git a/packages/angular/standalone/src/directives/searchbar.ts b/packages/angular/standalone/src/directives/searchbar.ts index 5a4abd6d31..75f1d7da67 100644 --- a/packages/angular/standalone/src/directives/searchbar.ts +++ b/packages/angular/standalone/src/directives/searchbar.ts @@ -8,12 +8,25 @@ import { Injector, NgZone, } from '@angular/core'; +import type { OnInit } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ValueAccessor } from '@ionic/angular/common'; import type { SearchbarInputEventDetail, SearchbarChangeEventDetail, Components } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-searchbar.js'; -import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils'; +/** + * Value accessor components should not use ProxyCmp + * and should call defineCustomElement and proxyInputs + * manually instead. Using both the @ProxyCmp and @Component + * decorators and useExisting (where useExisting refers to the + * class) causes ng-packagr to output multiple component variables + * which breaks treeshaking. + * For example, the following would be generated: + * let IonSearchbar = IonSearchbar_1 = class IonSearchbar extends ValueAccessor { + * Instead, we want only want the class generated: + * class IonSearchbar extends ValueAccessor { + */ +import { proxyInputs, proxyMethods, proxyOutputs } from './angular-component-lib/utils'; const SEARCHBAR_INPUTS = [ 'animated', @@ -38,11 +51,8 @@ const SEARCHBAR_INPUTS = [ 'value', ]; -@ProxyCmp({ - defineCustomElementFn: defineCustomElement, - inputs: SEARCHBAR_INPUTS, - methods: ['setFocus', 'getInputElement'], -}) +const SEARCHBAR_METHODS = ['setFocus', 'getInputElement']; + @Component({ selector: 'ion-searchbar', changeDetection: ChangeDetectionStrategy.OnPush, @@ -58,15 +68,26 @@ const SEARCHBAR_INPUTS = [ ], standalone: true, }) -export class IonSearchbar extends ValueAccessor { +export class IonSearchbar extends ValueAccessor implements OnInit { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone, injector: Injector) { super(injector, r); + defineCustomElement(); c.detach(); this.el = r.nativeElement; proxyOutputs(this, this.el, ['ionInput', 'ionChange', 'ionCancel', 'ionClear', 'ionBlur', 'ionFocus']); } + ngOnInit(): void { + /** + * Data-bound input properties are set + * by Angular after the constructor, so + * we need to run the proxy in ngOnInit. + */ + proxyInputs(IonSearchbar, SEARCHBAR_INPUTS); + proxyMethods(IonSearchbar, SEARCHBAR_METHODS); + } + @HostListener('ionInput', ['$event.target']) handleIonInput(el: HTMLIonSearchbarElement): void { this.handleValueChange(el, el.value); diff --git a/packages/angular/standalone/src/directives/segment.ts b/packages/angular/standalone/src/directives/segment.ts index 760b990d5e..5d6a16f77c 100644 --- a/packages/angular/standalone/src/directives/segment.ts +++ b/packages/angular/standalone/src/directives/segment.ts @@ -8,19 +8,28 @@ import { Injector, NgZone, } from '@angular/core'; +import type { OnInit } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ValueAccessor } from '@ionic/angular/common'; import type { SegmentChangeEventDetail, Components } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-segment.js'; -import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils'; +/** + * Value accessor components should not use ProxyCmp + * and should call defineCustomElement and proxyInputs + * manually instead. Using both the @ProxyCmp and @Component + * decorators and useExisting (where useExisting refers to the + * class) causes ng-packagr to output multiple component variables + * which breaks treeshaking. + * For example, the following would be generated: + * let IonSegment = IonSegment_1 = class IonSegment extends ValueAccessor { + * Instead, we want only want the class generated: + * class IonSegment extends ValueAccessor { + */ +import { proxyInputs, proxyOutputs } from './angular-component-lib/utils'; const SEGMENT_INPUTS = ['color', 'disabled', 'mode', 'scrollable', 'selectOnFocus', 'swipeGesture', 'value']; -@ProxyCmp({ - defineCustomElementFn: defineCustomElement, - inputs: SEGMENT_INPUTS, -}) @Component({ selector: 'ion-segment', changeDetection: ChangeDetectionStrategy.OnPush, @@ -36,15 +45,25 @@ const SEGMENT_INPUTS = ['color', 'disabled', 'mode', 'scrollable', 'selectOnFocu ], standalone: true, }) -export class IonSegment extends ValueAccessor { +export class IonSegment extends ValueAccessor implements OnInit { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone, injector: Injector) { super(injector, r); + defineCustomElement(); c.detach(); this.el = r.nativeElement; proxyOutputs(this, this.el, ['ionChange']); } + ngOnInit(): void { + /** + * Data-bound input properties are set + * by Angular after the constructor, so + * we need to run the proxy in ngOnInit. + */ + proxyInputs(IonSegment, SEGMENT_INPUTS); + } + @HostListener('ionChange', ['$event.target']) handleIonChange(el: HTMLIonSegmentElement): void { this.handleValueChange(el, el.value); diff --git a/packages/angular/standalone/src/directives/select.ts b/packages/angular/standalone/src/directives/select.ts index f0d19ce078..0041f91d86 100644 --- a/packages/angular/standalone/src/directives/select.ts +++ b/packages/angular/standalone/src/directives/select.ts @@ -8,12 +8,25 @@ import { Injector, NgZone, } from '@angular/core'; +import type { OnInit } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ValueAccessor } from '@ionic/angular/common'; import type { SelectChangeEventDetail, Components } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-select.js'; -import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils'; +/** + * Value accessor components should not use ProxyCmp + * and should call defineCustomElement and proxyInputs + * manually instead. Using both the @ProxyCmp and @Component + * decorators and useExisting (where useExisting refers to the + * class) causes ng-packagr to output multiple component variables + * which breaks treeshaking. + * For example, the following would be generated: + * let IonSelect = IonSelect_1 = class IonSelect extends ValueAccessor { + * Instead, we want only want the class generated: + * class IonSelect extends ValueAccessor { + */ +import { proxyInputs, proxyMethods, proxyOutputs } from './angular-component-lib/utils'; const SELECT_INPUTS = [ 'cancelText', @@ -39,11 +52,8 @@ const SELECT_INPUTS = [ 'value', ]; -@ProxyCmp({ - defineCustomElementFn: defineCustomElement, - inputs: SELECT_INPUTS, - methods: ['open'], -}) +const SELECT_METHODS = ['open']; + @Component({ selector: 'ion-select', changeDetection: ChangeDetectionStrategy.OnPush, @@ -59,15 +69,26 @@ const SELECT_INPUTS = [ ], standalone: true, }) -export class IonSelect extends ValueAccessor { +export class IonSelect extends ValueAccessor implements OnInit { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone, injector: Injector) { super(injector, r); + defineCustomElement(); c.detach(); this.el = r.nativeElement; proxyOutputs(this, this.el, ['ionChange', 'ionCancel', 'ionDismiss', 'ionFocus', 'ionBlur']); } + ngOnInit(): void { + /** + * Data-bound input properties are set + * by Angular after the constructor, so + * we need to run the proxy in ngOnInit. + */ + proxyInputs(IonSelect, SELECT_INPUTS); + proxyMethods(IonSelect, SELECT_METHODS); + } + @HostListener('ionChange', ['$event.target']) handleIonChange(el: HTMLIonSelectElement): void { this.handleValueChange(el, el.value); diff --git a/packages/angular/standalone/src/directives/textarea.ts b/packages/angular/standalone/src/directives/textarea.ts index 7523963232..af5d8b4996 100644 --- a/packages/angular/standalone/src/directives/textarea.ts +++ b/packages/angular/standalone/src/directives/textarea.ts @@ -8,12 +8,25 @@ import { Injector, NgZone, } from '@angular/core'; +import type { OnInit } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ValueAccessor } from '@ionic/angular/common'; import type { TextareaChangeEventDetail, TextareaInputEventDetail, Components } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-textarea.js'; -import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils'; +/** + * Value accessor components should not use ProxyCmp + * and should call defineCustomElement and proxyInputs + * manually instead. Using both the @ProxyCmp and @Component + * decorators and useExisting (where useExisting refers to the + * class) causes ng-packagr to output multiple component variables + * which breaks treeshaking. + * For example, the following would be generated: + * let IonTextarea = IonTextarea_1 = class IonTextarea extends ValueAccessor { + * Instead, we want only want the class generated: + * class IonTextarea extends ValueAccessor { + */ +import { proxyInputs, proxyMethods, proxyOutputs } from './angular-component-lib/utils'; const TEXTAREA_INPUTS = [ 'autoGrow', @@ -48,11 +61,8 @@ const TEXTAREA_INPUTS = [ 'wrap', ]; -@ProxyCmp({ - defineCustomElementFn: defineCustomElement, - inputs: TEXTAREA_INPUTS, - methods: ['setFocus', 'getInputElement'], -}) +const TEXTAREA_METHODS = ['setFocus', 'getInputElement']; + @Component({ selector: 'ion-textarea', changeDetection: ChangeDetectionStrategy.OnPush, @@ -68,15 +78,26 @@ const TEXTAREA_INPUTS = [ ], standalone: true, }) -export class IonTextarea extends ValueAccessor { +export class IonTextarea extends ValueAccessor implements OnInit { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone, injector: Injector) { super(injector, r); + defineCustomElement(); c.detach(); this.el = r.nativeElement; proxyOutputs(this, this.el, ['ionChange', 'ionInput', 'ionBlur', 'ionFocus']); } + ngOnInit(): void { + /** + * Data-bound input properties are set + * by Angular after the constructor, so + * we need to run the proxy in ngOnInit. + */ + proxyInputs(IonTextarea, TEXTAREA_INPUTS); + proxyMethods(IonTextarea, TEXTAREA_METHODS); + } + @HostListener('ionInput', ['$event.target']) handleIonInput(el: HTMLIonTextareaElement): void { this.handleValueChange(el, el.value); diff --git a/packages/angular/standalone/src/directives/toggle.ts b/packages/angular/standalone/src/directives/toggle.ts index e1ece5f856..1736200650 100644 --- a/packages/angular/standalone/src/directives/toggle.ts +++ b/packages/angular/standalone/src/directives/toggle.ts @@ -8,12 +8,25 @@ import { Injector, NgZone, } from '@angular/core'; +import type { OnInit } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ValueAccessor, setIonicClasses } from '@ionic/angular/common'; import type { ToggleChangeEventDetail, Components } from '@ionic/core/components'; import { defineCustomElement } from '@ionic/core/components/ion-toggle.js'; -import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils'; +/** + * Value accessor components should not use ProxyCmp + * and should call defineCustomElement and proxyInputs + * manually instead. Using both the @ProxyCmp and @Component + * decorators and useExisting (where useExisting refers to the + * class) causes ng-packagr to output multiple component variables + * which breaks treeshaking. + * For example, the following would be generated: + * let IonToggle = IonToggle_1 = class IonToggle extends ValueAccessor { + * Instead, we want only want the class generated: + * class IonToggle extends ValueAccessor { + */ +import { proxyInputs, proxyOutputs } from './angular-component-lib/utils'; const TOGGLE_INPUTS = [ 'checked', @@ -28,10 +41,6 @@ const TOGGLE_INPUTS = [ 'value', ]; -@ProxyCmp({ - defineCustomElementFn: defineCustomElement, - inputs: TOGGLE_INPUTS, -}) @Component({ selector: 'ion-toggle', changeDetection: ChangeDetectionStrategy.OnPush, @@ -47,15 +56,25 @@ const TOGGLE_INPUTS = [ ], standalone: true, }) -export class IonToggle extends ValueAccessor { +export class IonToggle extends ValueAccessor implements OnInit { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone, injector: Injector) { super(injector, r); + defineCustomElement(); c.detach(); this.el = r.nativeElement; proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur']); } + ngOnInit(): void { + /** + * Data-bound input properties are set + * by Angular after the constructor, so + * we need to run the proxy in ngOnInit. + */ + proxyInputs(IonToggle, TOGGLE_INPUTS); + } + writeValue(value: boolean): void { this.elementRef.nativeElement.checked = this.lastValue = value; setIonicClasses(this.elementRef); diff --git a/packages/angular/standalone/src/index.ts b/packages/angular/standalone/src/index.ts index 209fa25d77..36d8c2bf27 100644 --- a/packages/angular/standalone/src/index.ts +++ b/packages/angular/standalone/src/index.ts @@ -5,11 +5,11 @@ export { IonRouterOutlet } from './navigation/router-outlet'; export { IonRouterLink, IonRouterLinkWithHref } from './navigation/router-link-delegate'; export { IonTabs } from './navigation/tabs'; export { provideIonicAngular } from './providers/ionic-angular'; +export { MenuController } from './providers/menu-controller'; export { ActionSheetController, AlertController, LoadingController, - MenuController, ModalController, PickerController, PopoverController, @@ -22,6 +22,10 @@ export { Platform, NavParams, IonicRouteStrategy, + ViewWillEnter, + ViewDidEnter, + ViewWillLeave, + ViewDidLeave, } from '@ionic/angular/common'; export { IonNav } from './navigation/nav'; export { diff --git a/packages/angular/standalone/src/providers/menu-controller.ts b/packages/angular/standalone/src/providers/menu-controller.ts new file mode 100644 index 0000000000..fa1f50f0d4 --- /dev/null +++ b/packages/angular/standalone/src/providers/menu-controller.ts @@ -0,0 +1,12 @@ +import { Injectable } from '@angular/core'; +import { MenuController as MenuControllerBase } from '@ionic/angular/common'; +import { menuController } from '@ionic/core/components'; + +@Injectable({ + providedIn: 'root', +}) +export class MenuController extends MenuControllerBase { + constructor() { + super(menuController); + } +} diff --git a/packages/angular/test/base/e2e/src/lazy/providers.spec.ts b/packages/angular/test/base/e2e/src/lazy/providers.spec.ts index 215aa13cb4..0920ed35cd 100644 --- a/packages/angular/test/base/e2e/src/lazy/providers.spec.ts +++ b/packages/angular/test/base/e2e/src/lazy/providers.spec.ts @@ -27,5 +27,11 @@ describe('Providers', () => { cy.get('#query-params').should('have.text', 'firstParam: abc, firstParam: true'); }) + + // https://github.com/ionic-team/ionic-framework/issues/28337 + it('should register menus correctly', () => { + cy.get('#set-menu-count').click(); + cy.get('#registered-menu-count').should('have.text', '1'); + }); }); diff --git a/packages/angular/test/base/e2e/src/standalone/menu-controller.spec.ts b/packages/angular/test/base/e2e/src/standalone/menu-controller.spec.ts new file mode 100644 index 0000000000..b4dfd7245b --- /dev/null +++ b/packages/angular/test/base/e2e/src/standalone/menu-controller.spec.ts @@ -0,0 +1,11 @@ +describe('Menu Controller', () => { + beforeEach(() => { + cy.visit('/standalone/menu-controller'); + }) + + // https://github.com/ionic-team/ionic-framework/issues/28337 + it('should register menus correctly', () => { + cy.get('#set-menu-count').click(); + cy.get('#registered-menu-count').should('have.text', '1'); + }); +}) diff --git a/packages/angular/test/base/e2e/src/standalone/value-accessors.spec.ts b/packages/angular/test/base/e2e/src/standalone/value-accessors.spec.ts index a8e1c36e90..1e82274c80 100644 --- a/packages/angular/test/base/e2e/src/standalone/value-accessors.spec.ts +++ b/packages/angular/test/base/e2e/src/standalone/value-accessors.spec.ts @@ -14,6 +14,18 @@ describe('Value Accessors', () => { cy.get('ion-checkbox').should('have.class', 'ion-dirty'); cy.get('ion-checkbox').should('have.class', 'ion-valid'); }); + + it('should proxy inputs on load', () => { + cy.get('ion-checkbox').should('have.prop', 'color', 'danger'); + }); + }); + + describe('Datetime', () => { + beforeEach(() => cy.visit('/standalone/value-accessors/datetime')); + + it('should proxy inputs on load', () => { + cy.get('ion-datetime').should('have.prop', 'color', 'danger'); + }); }); describe('Input', () => { @@ -48,6 +60,10 @@ describe('Value Accessors', () => { cy.get('ion-input[formControlName="inputNumber"]').should('have.class', 'ion-valid'); }); + + it('should proxy inputs on load', () => { + cy.get('ion-input').first().should('have.prop', 'color', 'danger'); + }); }); describe('Radio Group', () => { @@ -63,8 +79,21 @@ describe('Value Accessors', () => { cy.get('ion-radio-group').should('have.class', 'ion-dirty'); cy.get('ion-radio-group').should('have.class', 'ion-valid'); }); + + it('should proxy inputs on load', () => { + cy.get('ion-radio').first().should('have.prop', 'color', 'danger'); + }); }); + describe('Range', () => { + beforeEach(() => cy.visit('/standalone/value-accessors/range')); + + it('should proxy inputs on load', () => { + cy.get('ion-range').should('have.prop', 'color', 'danger'); + }); + }); + + describe('Searchbar', () => { beforeEach(() => cy.visit('/standalone/value-accessors/searchbar')); @@ -80,6 +109,10 @@ describe('Value Accessors', () => { cy.get('ion-searchbar').should('have.class', 'ion-dirty'); cy.get('ion-searchbar').should('have.class', 'ion-valid'); }); + + it('should proxy inputs on load', () => { + cy.get('ion-searchbar').should('have.prop', 'color', 'danger'); + }); }); describe('Segment', () => { @@ -95,6 +128,32 @@ describe('Value Accessors', () => { cy.get('ion-segment').should('have.class', 'ion-dirty'); cy.get('ion-segment').should('have.class', 'ion-valid'); }); + + it('should proxy inputs on load', () => { + cy.get('ion-segment').should('have.prop', 'color', 'danger'); + }); + }); + + describe('Select', () => { + beforeEach(() => cy.visit('/standalone/value-accessors/select')); + + it('should update the form value', () => { + cy.get('#formValue').should('have.text', JSON.stringify({ select: 'bananas' }, null, 2)); + cy.get('ion-select').should('have.class', 'ion-pristine'); + + cy.get('ion-select').click(); + cy.get('ion-popover').should('be.visible'); + + cy.get('ion-popover ion-radio-group ion-radio').first().click(); + + cy.get('#formValue').should('have.text', JSON.stringify({ select: 'apples' }, null, 2)); + cy.get('ion-select').should('have.class', 'ion-dirty'); + cy.get('ion-select').should('have.class', 'ion-valid'); + }); + + it('should proxy inputs on load', () => { + cy.get('ion-select').should('have.prop', 'color', 'danger'); + }); }); describe('Textarea', () => { @@ -112,6 +171,10 @@ describe('Value Accessors', () => { cy.get('ion-textarea').should('have.class', 'ion-dirty'); cy.get('ion-textarea').should('have.class', 'ion-valid'); }); + + it('should proxy inputs on load', () => { + cy.get('ion-textarea').should('have.prop', 'color', 'danger'); + }); }); describe('Toggle', () => { @@ -127,6 +190,10 @@ describe('Value Accessors', () => { cy.get('ion-toggle').should('have.class', 'ion-dirty'); cy.get('ion-toggle').should('have.class', 'ion-valid'); }); + + it('should proxy inputs on load', () => { + cy.get('ion-toggle').should('have.prop', 'color', 'danger'); + }); }); }); diff --git a/packages/angular/test/base/src/app/lazy/providers/providers.component.html b/packages/angular/test/base/src/app/lazy/providers/providers.component.html index f198ba6518..981847ac24 100644 --- a/packages/angular/test/base/src/app/lazy/providers/providers.component.html +++ b/packages/angular/test/base/src/app/lazy/providers/providers.component.html @@ -1,39 +1,48 @@ + + Menu Content + + - - - Providers Test - - - - -

- isLoaded: {{isLoaded}} -

-

- isReady: {{isReady}} -

-

- isResumed: {{isResumed}} -

-

- isPaused: {{isPaused}} -

-

- isResized: {{isResized}} -

-

- isTesting: {{isTesting}} -

-

- isDesktop: {{isDesktop}} -

-

- isMobile: {{isMobile}} -

-

- keyboardHeight: {{keyboardHeight}} -

-

- queryParams: {{queryParams}} -

-
+ + + Providers Test + + + + +

+ isLoaded: {{isLoaded}} +

+

+ isReady: {{isReady}} +

+

+ isResumed: {{isResumed}} +

+

+ isPaused: {{isPaused}} +

+

+ isResized: {{isResized}} +

+

+ isTesting: {{isTesting}} +

+

+ isDesktop: {{isDesktop}} +

+

+ isMobile: {{isMobile}} +

+

+ keyboardHeight: {{keyboardHeight}} +

+

+ queryParams: {{queryParams}} +

+

+ Registered Menu Count: {{registeredMenuCount}} +

+ + +
diff --git a/packages/angular/test/base/src/app/lazy/providers/providers.component.ts b/packages/angular/test/base/src/app/lazy/providers/providers.component.ts index 3ef12a0eee..c65a85600f 100644 --- a/packages/angular/test/base/src/app/lazy/providers/providers.component.ts +++ b/packages/angular/test/base/src/app/lazy/providers/providers.component.ts @@ -21,12 +21,13 @@ export class ProvidersComponent { isMobile?: boolean = undefined; keyboardHeight = 0; queryParams = ''; + registeredMenuCount = 0; constructor( actionSheetCtrl: ActionSheetController, alertCtrl: AlertController, loadingCtrl: LoadingController, - menuCtrl: MenuController, + private menuCtrl: MenuController, pickerCtrl: PickerController, modalCtrl: ModalController, platform: Platform, @@ -82,4 +83,9 @@ export class ProvidersComponent { window.dispatchEvent(new CustomEvent('resize')); }); } + + async setMenuCount() { + const menus = await this.menuCtrl.getMenus(); + this.registeredMenuCount = menus.length; + } } diff --git a/packages/angular/test/base/src/app/standalone/app-standalone/app.routes.ts b/packages/angular/test/base/src/app/standalone/app-standalone/app.routes.ts index 93e869651a..3e2499ca11 100644 --- a/packages/angular/test/base/src/app/standalone/app-standalone/app.routes.ts +++ b/packages/angular/test/base/src/app/standalone/app-standalone/app.routes.ts @@ -6,6 +6,7 @@ export const routes: Routes = [ path: '', component: AppComponent, children: [ + { path: 'menu-controller', loadComponent: () => import('../menu-controller/menu-controller.component').then(c => c.MenuControllerComponent) }, { path: 'popover', loadComponent: () => import('../popover/popover.component').then(c => c.PopoverComponent) }, { path: 'modal', loadComponent: () => import('../modal/modal.component').then(c => c.ModalComponent) }, { path: 'router-outlet', loadComponent: () => import('../router-outlet/router-outlet.component').then(c => c.RouterOutletComponent) }, @@ -36,6 +37,7 @@ export const routes: Routes = [ { path: 'range', loadComponent: () => import('../value-accessors/range/range.component').then(c => c.RangeComponent) }, { path: 'searchbar', loadComponent: () => import('../value-accessors/searchbar/searchbar.component').then(c => c.SearchbarComponent) }, { path: 'segment', loadComponent: () => import('../value-accessors/segment/segment.component').then(c => c.SegmentComponent) }, + { path: 'select', loadComponent: () => import('../value-accessors/select/select.component').then(c => c.SelectComponent) }, { path: 'textarea', loadComponent: () => import('../value-accessors/textarea/textarea.component').then(c => c.TextareaComponent) }, { path: 'toggle', loadComponent: () => import('../value-accessors/toggle/toggle.component').then(c => c.ToggleComponent) }, { path: '**', redirectTo: 'checkbox' } diff --git a/packages/angular/test/base/src/app/standalone/menu-controller/menu-controller.component.html b/packages/angular/test/base/src/app/standalone/menu-controller/menu-controller.component.html new file mode 100644 index 0000000000..0d9df71538 --- /dev/null +++ b/packages/angular/test/base/src/app/standalone/menu-controller/menu-controller.component.html @@ -0,0 +1,10 @@ + + Menu Content + + +
    +
  • Registered Menu Count: {{registeredMenuCount}}
  • + + +
+ diff --git a/packages/angular/test/base/src/app/standalone/menu-controller/menu-controller.component.ts b/packages/angular/test/base/src/app/standalone/menu-controller/menu-controller.component.ts new file mode 100644 index 0000000000..d99944f5ad --- /dev/null +++ b/packages/angular/test/base/src/app/standalone/menu-controller/menu-controller.component.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; +import { MenuController, IonMenu } from '@ionic/angular/standalone'; + +@Component({ + selector: 'app-menu-controller', + templateUrl: './menu-controller.component.html', + standalone: true, + imports: [IonMenu] +}) +export class MenuControllerComponent { + registeredMenuCount = 0; + + constructor(private menuCtrl: MenuController) {} + + async setMenuCount() { + const menus = await this.menuCtrl.getMenus(); + this.registeredMenuCount = menus.length; + } +} diff --git a/packages/angular/test/base/src/app/standalone/value-accessors/checkbox/checkbox.component.html b/packages/angular/test/base/src/app/standalone/value-accessors/checkbox/checkbox.component.html index 2921e06b91..b3d621b0ae 100644 --- a/packages/angular/test/base/src/app/standalone/value-accessors/checkbox/checkbox.component.html +++ b/packages/angular/test/base/src/app/standalone/value-accessors/checkbox/checkbox.component.html @@ -6,6 +6,6 @@

- + diff --git a/packages/angular/test/base/src/app/standalone/value-accessors/datetime/datetime.component.html b/packages/angular/test/base/src/app/standalone/value-accessors/datetime/datetime.component.html index 22c3633971..6d682257c8 100644 --- a/packages/angular/test/base/src/app/standalone/value-accessors/datetime/datetime.component.html +++ b/packages/angular/test/base/src/app/standalone/value-accessors/datetime/datetime.component.html @@ -6,6 +6,6 @@

- + diff --git a/packages/angular/test/base/src/app/standalone/value-accessors/input/input.component.html b/packages/angular/test/base/src/app/standalone/value-accessors/input/input.component.html index e63235cea5..aa9a2feeff 100644 --- a/packages/angular/test/base/src/app/standalone/value-accessors/input/input.component.html +++ b/packages/angular/test/base/src/app/standalone/value-accessors/input/input.component.html @@ -5,7 +5,7 @@

- + diff --git a/packages/angular/test/base/src/app/standalone/value-accessors/radio-group/radio-group.component.html b/packages/angular/test/base/src/app/standalone/value-accessors/radio-group/radio-group.component.html index a511dbbbe5..274dfd2478 100644 --- a/packages/angular/test/base/src/app/standalone/value-accessors/radio-group/radio-group.component.html +++ b/packages/angular/test/base/src/app/standalone/value-accessors/radio-group/radio-group.component.html @@ -7,7 +7,7 @@ - One + One Two diff --git a/packages/angular/test/base/src/app/standalone/value-accessors/range/range.component.html b/packages/angular/test/base/src/app/standalone/value-accessors/range/range.component.html index 9a496fbcd3..969f4b13c7 100644 --- a/packages/angular/test/base/src/app/standalone/value-accessors/range/range.component.html +++ b/packages/angular/test/base/src/app/standalone/value-accessors/range/range.component.html @@ -4,6 +4,6 @@ This test checks the form integrations with ion-range to make sure values are correctly assigned to the form group.

- + diff --git a/packages/angular/test/base/src/app/standalone/value-accessors/searchbar/searchbar.component.html b/packages/angular/test/base/src/app/standalone/value-accessors/searchbar/searchbar.component.html index 9a6137c65b..c667a787d2 100644 --- a/packages/angular/test/base/src/app/standalone/value-accessors/searchbar/searchbar.component.html +++ b/packages/angular/test/base/src/app/standalone/value-accessors/searchbar/searchbar.component.html @@ -5,6 +5,6 @@ group.

- + diff --git a/packages/angular/test/base/src/app/standalone/value-accessors/segment/segment.component.html b/packages/angular/test/base/src/app/standalone/value-accessors/segment/segment.component.html index 98016fcde6..fca9dba8bc 100644 --- a/packages/angular/test/base/src/app/standalone/value-accessors/segment/segment.component.html +++ b/packages/angular/test/base/src/app/standalone/value-accessors/segment/segment.component.html @@ -6,7 +6,7 @@

- + Paid diff --git a/packages/angular/test/base/src/app/standalone/value-accessors/select/select.component.html b/packages/angular/test/base/src/app/standalone/value-accessors/select/select.component.html new file mode 100644 index 0000000000..28dbda038d --- /dev/null +++ b/packages/angular/test/base/src/app/standalone/value-accessors/select/select.component.html @@ -0,0 +1,14 @@ +
+

IonSelect Value Accessors

+

+ This test checks the form integrations with ion-select to make sure values are correctly assigned to the form + group. +

+ + + + Apples + Bananas + + +
diff --git a/packages/angular/test/base/src/app/standalone/value-accessors/select/select.component.ts b/packages/angular/test/base/src/app/standalone/value-accessors/select/select.component.ts new file mode 100644 index 0000000000..35246438f5 --- /dev/null +++ b/packages/angular/test/base/src/app/standalone/value-accessors/select/select.component.ts @@ -0,0 +1,26 @@ +import { Component } from "@angular/core"; +import { FormBuilder, FormsModule, ReactiveFormsModule, Validators } from "@angular/forms"; +import { IonSelect, IonSelectOption } from "@ionic/angular/standalone"; +import { ValueAccessorTestComponent } from "../value-accessor-test/value-accessor-test.component"; + +@Component({ + selector: 'app-select', + templateUrl: 'select.component.html', + standalone: true, + imports: [ + IonSelect, + IonSelectOption, + ReactiveFormsModule, + FormsModule, + ValueAccessorTestComponent + ] +}) +export class SelectComponent { + + form = this.fb.group({ + select: ['bananas', Validators.required], + }); + + constructor(private fb: FormBuilder) { } + +} diff --git a/packages/angular/test/base/src/app/standalone/value-accessors/textarea/textarea.component.html b/packages/angular/test/base/src/app/standalone/value-accessors/textarea/textarea.component.html index 678d42d391..05ab51817a 100644 --- a/packages/angular/test/base/src/app/standalone/value-accessors/textarea/textarea.component.html +++ b/packages/angular/test/base/src/app/standalone/value-accessors/textarea/textarea.component.html @@ -6,6 +6,6 @@

- + diff --git a/packages/angular/test/base/src/app/standalone/value-accessors/toggle/toggle.component.html b/packages/angular/test/base/src/app/standalone/value-accessors/toggle/toggle.component.html index 08888059f9..b7d74781c5 100644 --- a/packages/angular/test/base/src/app/standalone/value-accessors/toggle/toggle.component.html +++ b/packages/angular/test/base/src/app/standalone/value-accessors/toggle/toggle.component.html @@ -5,6 +5,6 @@

- + diff --git a/packages/react-router/CHANGELOG.md b/packages/react-router/CHANGELOG.md index a653d24806..432298ae0f 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.5.1](https://github.com/ionic-team/ionic-framework/compare/v7.5.0...v7.5.1) (2023-10-18) + +**Note:** Version bump only for package @ionic/react-router + + + + + # [7.5.0](https://github.com/ionic-team/ionic-framework/compare/v7.4.4...v7.5.0) (2023-10-11) **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 47f767e74d..fe140e1b76 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.5.0", + "version": "7.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/react-router", - "version": "7.5.0", + "version": "7.5.1", "license": "MIT", "dependencies": { - "@ionic/react": "^7.5.0", + "@ionic/react": "^7.5.1", "tslib": "*" }, "devDependencies": { @@ -205,11 +205,11 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.0.tgz", - "integrity": "sha512-oreRvbKj8VqqO9JraxR/n56GC6MHQtnJEmZf/EFuw5ZvDV8My91uNIzLkb4P9SvPL5NRr/Z0TFem28cgRf5YVA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.1.tgz", + "integrity": "sha512-BnWehjZ3IVGPFLdOZV151VhLsyXzr8d2mIVULqUXil5NHgQf039ScppI0kfrCS+M3zMdqeTmlIK/nq6M+kcQaQ==", "dependencies": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" } @@ -381,11 +381,11 @@ } }, "node_modules/@ionic/react": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.5.0.tgz", - "integrity": "sha512-hNpaKHrEtCKKbobV8Caf6aQB1rECNz7VBeCvfyH45UXkiP3EGjtZO8rkG43ej5KT+tNA8y4iJOw43A0C3sfB6Q==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.5.1.tgz", + "integrity": "sha512-1Hd0SPC9uYV1QR2VSKcXy945UWqUBTkHlmed/CU3B3pSIT3MNnZct5Nj9Ekat9UgXBC7NRrqv6yhfkzPekvilg==", "dependencies": { - "@ionic/core": "7.5.0", + "@ionic/core": "7.5.1", "ionicons": "^7.0.0", "tslib": "*" }, @@ -466,9 +466,9 @@ } }, "node_modules/@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==", "bin": { "stencil": "bin/stencil" }, @@ -3631,11 +3631,11 @@ "dev": true }, "@ionic/core": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.0.tgz", - "integrity": "sha512-oreRvbKj8VqqO9JraxR/n56GC6MHQtnJEmZf/EFuw5ZvDV8My91uNIzLkb4P9SvPL5NRr/Z0TFem28cgRf5YVA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.1.tgz", + "integrity": "sha512-BnWehjZ3IVGPFLdOZV151VhLsyXzr8d2mIVULqUXil5NHgQf039ScppI0kfrCS+M3zMdqeTmlIK/nq6M+kcQaQ==", "requires": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" } @@ -3737,11 +3737,11 @@ "requires": {} }, "@ionic/react": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.5.0.tgz", - "integrity": "sha512-hNpaKHrEtCKKbobV8Caf6aQB1rECNz7VBeCvfyH45UXkiP3EGjtZO8rkG43ej5KT+tNA8y4iJOw43A0C3sfB6Q==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.5.1.tgz", + "integrity": "sha512-1Hd0SPC9uYV1QR2VSKcXy945UWqUBTkHlmed/CU3B3pSIT3MNnZct5Nj9Ekat9UgXBC7NRrqv6yhfkzPekvilg==", "requires": { - "@ionic/core": "7.5.0", + "@ionic/core": "7.5.1", "ionicons": "^7.0.0", "tslib": "*" } @@ -3795,9 +3795,9 @@ } }, "@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==" }, "@types/estree": { "version": "0.0.39", diff --git a/packages/react-router/package.json b/packages/react-router/package.json index 5623447c4b..3362a90fe5 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/react-router", - "version": "7.5.0", + "version": "7.5.1", "description": "React Router wrapper for @ionic/react", "keywords": [ "ionic", @@ -37,7 +37,7 @@ "dist/" ], "dependencies": { - "@ionic/react": "^7.5.0", + "@ionic/react": "^7.5.1", "tslib": "*" }, "peerDependencies": { diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 543d8856c7..d64fb19f6d 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/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. +## [7.5.1](https://github.com/ionic-team/ionic-framework/compare/v7.5.0...v7.5.1) (2023-10-18) + + +### Bug Fixes + +* **react:** cleanup functions are execute for lifecycle hooks ([#28319](https://github.com/ionic-team/ionic-framework/issues/28319)) ([1ba9973](https://github.com/ionic-team/ionic-framework/commit/1ba9973857503c6e47cb225b77a5b89e0a9d2718)), closes [#28186](https://github.com/ionic-team/ionic-framework/issues/28186) +* **react:** lifecycle events are removed on page unmount ([#28316](https://github.com/ionic-team/ionic-framework/issues/28316)) ([f14a59c](https://github.com/ionic-team/ionic-framework/commit/f14a59c5e0670ed7cc9ce1a73a087a5af13266e2)) + + + + + # [7.5.0](https://github.com/ionic-team/ionic-framework/compare/v7.4.4...v7.5.0) (2023-10-11) diff --git a/packages/react/package-lock.json b/packages/react/package-lock.json index d3cfce81b1..3fb0b16a26 100644 --- a/packages/react/package-lock.json +++ b/packages/react/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/react", - "version": "7.5.0", + "version": "7.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/react", - "version": "7.5.0", + "version": "7.5.1", "license": "MIT", "dependencies": { - "@ionic/core": "^7.5.0", + "@ionic/core": "^7.5.1", "ionicons": "^7.0.0", "tslib": "*" }, @@ -697,11 +697,11 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.0.tgz", - "integrity": "sha512-oreRvbKj8VqqO9JraxR/n56GC6MHQtnJEmZf/EFuw5ZvDV8My91uNIzLkb4P9SvPL5NRr/Z0TFem28cgRf5YVA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.1.tgz", + "integrity": "sha512-BnWehjZ3IVGPFLdOZV151VhLsyXzr8d2mIVULqUXil5NHgQf039ScppI0kfrCS+M3zMdqeTmlIK/nq6M+kcQaQ==", "dependencies": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" } @@ -1364,9 +1364,9 @@ } }, "node_modules/@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==", "bin": { "stencil": "bin/stencil" }, @@ -11766,11 +11766,11 @@ "dev": true }, "@ionic/core": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.0.tgz", - "integrity": "sha512-oreRvbKj8VqqO9JraxR/n56GC6MHQtnJEmZf/EFuw5ZvDV8My91uNIzLkb4P9SvPL5NRr/Z0TFem28cgRf5YVA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.1.tgz", + "integrity": "sha512-BnWehjZ3IVGPFLdOZV151VhLsyXzr8d2mIVULqUXil5NHgQf039ScppI0kfrCS+M3zMdqeTmlIK/nq6M+kcQaQ==", "requires": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" } @@ -12220,9 +12220,9 @@ } }, "@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==" }, "@szmarczak/http-timer": { "version": "4.0.6", diff --git a/packages/react/package.json b/packages/react/package.json index d8fcb5f0f0..9652403ad1 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/react", - "version": "7.5.0", + "version": "7.5.1", "description": "React specific wrapper for @ionic/core", "keywords": [ "ionic", @@ -41,7 +41,7 @@ "css/" ], "dependencies": { - "@ionic/core": "^7.5.0", + "@ionic/core": "^7.5.1", "ionicons": "^7.0.0", "tslib": "*" }, diff --git a/packages/react/src/contexts/IonLifeCycleContext.tsx b/packages/react/src/contexts/IonLifeCycleContext.tsx index 6dc9d82550..c9343bf5b6 100644 --- a/packages/react/src/contexts/IonLifeCycleContext.tsx +++ b/packages/react/src/contexts/IonLifeCycleContext.tsx @@ -9,6 +9,10 @@ export interface IonLifeCycleContextInterface { ionViewWillLeave: () => void; onIonViewDidLeave: (callback: () => void) => void; ionViewDidLeave: () => void; + cleanupIonViewWillEnter: (callback: () => void) => void; + cleanupIonViewDidEnter: (callback: () => void) => void; + cleanupIonViewWillLeave: (callback: () => void) => void; + cleanupIonViewDidLeave: (callback: () => void) => void; } export const IonLifeCycleContext = /*@__PURE__*/ React.createContext({ @@ -36,19 +40,40 @@ export const IonLifeCycleContext = /*@__PURE__*/ React.createContext { return; }, + cleanupIonViewWillEnter: () => { + return; + }, + cleanupIonViewDidEnter: () => { + return; + }, + cleanupIonViewWillLeave: () => { + return; + }, + cleanupIonViewDidLeave: () => { + return; + }, }); export interface LifeCycleCallback { - (): void; + (): void | (() => void | undefined); id?: number; } +export interface LifeCycleDestructor { + id: number; + destructor: ReturnType; +} + export const DefaultIonLifeCycleContext = class implements IonLifeCycleContextInterface { ionViewWillEnterCallbacks: LifeCycleCallback[] = []; ionViewDidEnterCallbacks: LifeCycleCallback[] = []; ionViewWillLeaveCallbacks: LifeCycleCallback[] = []; ionViewDidLeaveCallbacks: LifeCycleCallback[] = []; componentCanBeDestroyedCallback?: () => void; + ionViewWillEnterDestructorCallbacks: LifeCycleDestructor[] = []; + ionViewDidEnterDestructorCallbacks: LifeCycleDestructor[] = []; + ionViewWillLeaveDestructorCallbacks: LifeCycleDestructor[] = []; + ionViewDidLeaveDestructorCallbacks: LifeCycleDestructor[] = []; onIonViewWillEnter(callback: LifeCycleCallback) { if (callback.id) { @@ -63,8 +88,64 @@ export const DefaultIonLifeCycleContext = class implements IonLifeCycleContextIn } } + teardownCallback(callback: LifeCycleCallback, callbacks: any[]) { + // Find any destructors that have been registered for the callback + const matches = callbacks.filter((x) => x.id === callback.id); + if (matches.length !== 0) { + // Execute the destructor for each matching item + matches.forEach((match) => { + if (match && typeof match.destructor === 'function') { + match.destructor(); + } + }); + // Remove all matching items from the array + callbacks = callbacks.filter((x) => x.id !== callback.id); + } + } + + /** + * Tears down the user-provided ionViewWillEnter lifecycle callback. + * This is the same behavior as React's useEffect hook. The callback + * is invoked when the component is unmounted. + */ + cleanupIonViewWillEnter(callback: LifeCycleCallback) { + this.teardownCallback(callback, this.ionViewWillEnterDestructorCallbacks); + } + + /** + * Tears down the user-provided ionViewDidEnter lifecycle callback. + * This is the same behavior as React's useEffect hook. The callback + * is invoked when the component is unmounted. + */ + cleanupIonViewDidEnter(callback: LifeCycleCallback) { + this.teardownCallback(callback, this.ionViewDidEnterDestructorCallbacks); + } + + /** + * Tears down the user-provided ionViewWillLeave lifecycle callback. + * This is the same behavior as React's useEffect hook. The callback + * is invoked when the component is unmounted. + */ + cleanupIonViewWillLeave(callback: LifeCycleCallback) { + this.teardownCallback(callback, this.ionViewWillLeaveDestructorCallbacks); + } + + /** + * Tears down the user-provided ionViewDidLeave lifecycle callback. + * This is the same behavior as React's useEffect hook. The callback + * is invoked when the component is unmounted. + */ + cleanupIonViewDidLeave(callback: LifeCycleCallback) { + this.teardownCallback(callback, this.ionViewDidLeaveDestructorCallbacks); + } + ionViewWillEnter() { - this.ionViewWillEnterCallbacks.forEach((cb) => cb()); + this.ionViewWillEnterCallbacks.forEach((cb) => { + const destructor = cb(); + if (cb.id) { + this.ionViewWillEnterDestructorCallbacks.push({ id: cb.id, destructor }); + } + }); } onIonViewDidEnter(callback: LifeCycleCallback) { @@ -81,7 +162,12 @@ export const DefaultIonLifeCycleContext = class implements IonLifeCycleContextIn } ionViewDidEnter() { - this.ionViewDidEnterCallbacks.forEach((cb) => cb()); + this.ionViewDidEnterCallbacks.forEach((cb) => { + const destructor = cb(); + if (cb.id) { + this.ionViewDidEnterDestructorCallbacks.push({ id: cb.id, destructor }); + } + }); } onIonViewWillLeave(callback: LifeCycleCallback) { @@ -98,7 +184,12 @@ export const DefaultIonLifeCycleContext = class implements IonLifeCycleContextIn } ionViewWillLeave() { - this.ionViewWillLeaveCallbacks.forEach((cb) => cb()); + this.ionViewWillLeaveCallbacks.forEach((cb) => { + const destructor = cb(); + if (cb.id) { + this.ionViewWillLeaveDestructorCallbacks.push({ id: cb.id, destructor }); + } + }); } onIonViewDidLeave(callback: LifeCycleCallback) { @@ -115,7 +206,12 @@ export const DefaultIonLifeCycleContext = class implements IonLifeCycleContextIn } ionViewDidLeave() { - this.ionViewDidLeaveCallbacks.forEach((cb) => cb()); + this.ionViewDidLeaveCallbacks.forEach((cb) => { + const destructor = cb(); + if (cb.id) { + this.ionViewDidLeaveDestructorCallbacks.push({ id: cb.id, destructor }); + } + }); this.componentCanBeDestroyed(); } diff --git a/packages/react/src/lifecycle/hooks.ts b/packages/react/src/lifecycle/hooks.ts index edc97280e9..3adc039d8e 100644 --- a/packages/react/src/lifecycle/hooks.ts +++ b/packages/react/src/lifecycle/hooks.ts @@ -10,6 +10,9 @@ export const useIonViewWillEnter = (callback: LifeCycleCallback, deps: any[] = [ useEffect(() => { callback.id = id.current!; context.onIonViewWillEnter(callback); + return () => { + context.cleanupIonViewWillEnter(callback); + }; }, deps); }; @@ -20,6 +23,9 @@ export const useIonViewDidEnter = (callback: LifeCycleCallback, deps: any[] = [] useEffect(() => { callback.id = id.current!; context.onIonViewDidEnter(callback); + return () => { + context.cleanupIonViewDidEnter(callback); + }; }, deps); }; @@ -30,6 +36,9 @@ export const useIonViewWillLeave = (callback: LifeCycleCallback, deps: any[] = [ useEffect(() => { callback.id = id.current!; context.onIonViewWillLeave(callback); + return () => { + context.cleanupIonViewWillLeave(callback); + }; }, deps); }; @@ -40,5 +49,8 @@ export const useIonViewDidLeave = (callback: LifeCycleCallback, deps: any[] = [] useEffect(() => { callback.id = id.current!; context.onIonViewDidLeave(callback); + return () => { + context.cleanupIonViewDidLeave(callback); + }; }, deps); }; diff --git a/packages/vue-router/CHANGELOG.md b/packages/vue-router/CHANGELOG.md index fc4c4e5710..8ef9429983 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.5.1](https://github.com/ionic-team/ionic-framework/compare/v7.5.0...v7.5.1) (2023-10-18) + +**Note:** Version bump only for package @ionic/vue-router + + + + + # [7.5.0](https://github.com/ionic-team/ionic-framework/compare/v7.4.4...v7.5.0) (2023-10-11) **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 ec367efb4f..2b28533666 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.5.0", + "version": "7.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/vue-router", - "version": "7.5.0", + "version": "7.5.1", "license": "MIT", "dependencies": { - "@ionic/vue": "^7.5.0" + "@ionic/vue": "^7.5.1" }, "devDependencies": { "@ionic/eslint-config": "^0.3.0", @@ -660,11 +660,11 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.0.tgz", - "integrity": "sha512-oreRvbKj8VqqO9JraxR/n56GC6MHQtnJEmZf/EFuw5ZvDV8My91uNIzLkb4P9SvPL5NRr/Z0TFem28cgRf5YVA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.1.tgz", + "integrity": "sha512-BnWehjZ3IVGPFLdOZV151VhLsyXzr8d2mIVULqUXil5NHgQf039ScppI0kfrCS+M3zMdqeTmlIK/nq6M+kcQaQ==", "dependencies": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" } @@ -851,11 +851,11 @@ } }, "node_modules/@ionic/vue": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.5.0.tgz", - "integrity": "sha512-sf/0qZrarZbBBLWk3YPVYikjopF6Qx+x8ChGIqiokpRJziD6mP4fjm4HPTzIQL/BYQ7XlEhTQ7tbkQXLBeW0tQ==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.5.1.tgz", + "integrity": "sha512-nA32DFFOJV5vF60xiz6Df/aE7iPEfCZXMAt+pSJYSYQuoMN6qD9eJUM4g37DZIWtRJdzlRBSZQvGEdPR41CyYg==", "dependencies": { - "@ionic/core": "7.5.0", + "@ionic/core": "7.5.1", "ionicons": "^7.0.0" } }, @@ -1303,9 +1303,9 @@ } }, "node_modules/@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==", "bin": { "stencil": "bin/stencil" }, @@ -7665,11 +7665,11 @@ "dev": true }, "@ionic/core": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.0.tgz", - "integrity": "sha512-oreRvbKj8VqqO9JraxR/n56GC6MHQtnJEmZf/EFuw5ZvDV8My91uNIzLkb4P9SvPL5NRr/Z0TFem28cgRf5YVA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.1.tgz", + "integrity": "sha512-BnWehjZ3IVGPFLdOZV151VhLsyXzr8d2mIVULqUXil5NHgQf039ScppI0kfrCS+M3zMdqeTmlIK/nq6M+kcQaQ==", "requires": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" } @@ -7780,11 +7780,11 @@ "requires": {} }, "@ionic/vue": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.5.0.tgz", - "integrity": "sha512-sf/0qZrarZbBBLWk3YPVYikjopF6Qx+x8ChGIqiokpRJziD6mP4fjm4HPTzIQL/BYQ7XlEhTQ7tbkQXLBeW0tQ==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.5.1.tgz", + "integrity": "sha512-nA32DFFOJV5vF60xiz6Df/aE7iPEfCZXMAt+pSJYSYQuoMN6qD9eJUM4g37DZIWtRJdzlRBSZQvGEdPR41CyYg==", "requires": { - "@ionic/core": "7.5.0", + "@ionic/core": "7.5.1", "ionicons": "^7.0.0" } }, @@ -8143,9 +8143,9 @@ } }, "@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==" }, "@tootallnate/once": { "version": "2.0.0", diff --git a/packages/vue-router/package.json b/packages/vue-router/package.json index 21066b9c24..1d1aba4ce0 100644 --- a/packages/vue-router/package.json +++ b/packages/vue-router/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/vue-router", - "version": "7.5.0", + "version": "7.5.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.5.0" + "@ionic/vue": "^7.5.1" }, "devDependencies": { "@ionic/eslint-config": "^0.3.0", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index e36ef09aac..c952257b22 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.5.1](https://github.com/ionic-team/ionic-framework/compare/v7.5.0...v7.5.1) (2023-10-18) + +**Note:** Version bump only for package @ionic/vue + + + + + # [7.5.0](https://github.com/ionic-team/ionic-framework/compare/v7.4.4...v7.5.0) (2023-10-11) diff --git a/packages/vue/package-lock.json b/packages/vue/package-lock.json index f106eb7c9d..9f110b4b30 100644 --- a/packages/vue/package-lock.json +++ b/packages/vue/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/vue", - "version": "7.5.0", + "version": "7.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/vue", - "version": "7.5.0", + "version": "7.5.1", "license": "MIT", "dependencies": { - "@ionic/core": "^7.5.0", + "@ionic/core": "^7.5.1", "ionicons": "^7.0.0" }, "devDependencies": { @@ -207,11 +207,11 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.0.tgz", - "integrity": "sha512-oreRvbKj8VqqO9JraxR/n56GC6MHQtnJEmZf/EFuw5ZvDV8My91uNIzLkb4P9SvPL5NRr/Z0TFem28cgRf5YVA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.1.tgz", + "integrity": "sha512-BnWehjZ3IVGPFLdOZV151VhLsyXzr8d2mIVULqUXil5NHgQf039ScppI0kfrCS+M3zMdqeTmlIK/nq6M+kcQaQ==", "dependencies": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" } @@ -423,9 +423,9 @@ } }, "node_modules/@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==", "bin": { "stencil": "bin/stencil" }, @@ -3734,11 +3734,11 @@ "dev": true }, "@ionic/core": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.0.tgz", - "integrity": "sha512-oreRvbKj8VqqO9JraxR/n56GC6MHQtnJEmZf/EFuw5ZvDV8My91uNIzLkb4P9SvPL5NRr/Z0TFem28cgRf5YVA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.1.tgz", + "integrity": "sha512-BnWehjZ3IVGPFLdOZV151VhLsyXzr8d2mIVULqUXil5NHgQf039ScppI0kfrCS+M3zMdqeTmlIK/nq6M+kcQaQ==", "requires": { - "@stencil/core": "^4.4.1", + "@stencil/core": "^4.5.0", "ionicons": "^7.2.1", "tslib": "^2.1.0" }, @@ -3873,9 +3873,9 @@ } }, "@stencil/core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.4.1.tgz", - "integrity": "sha512-SirGcrb5yKHCn2BwdM7HGVXuvCdmwiXlVczEj8jJxQIm42CAUQCUECxtZidTzp+oZBZnWLnoAvfanchJsgkQzA==" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.5.0.tgz", + "integrity": "sha512-XRbHdb9t4SQzCCbF9qsh0dexvnlArEzCDJl19BJzxzazVBM398SeJUKCBh4p91AZIWveN0gHuZSIGMhLWR7qSA==" }, "@types/json-schema": { "version": "7.0.11", diff --git a/packages/vue/package.json b/packages/vue/package.json index 82312a2c6b..00766f1b47 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/vue", - "version": "7.5.0", + "version": "7.5.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.5.0", + "@ionic/core": "^7.5.1", "ionicons": "^7.0.0" }, "vetur": {