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:
+
+
+
+
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:
+
+
+
+
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": {