Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9211e5434 | ||
|
|
d4875df644 | ||
|
|
01fc9b4511 | ||
|
|
9eef62e4f2 | ||
|
|
04b9b31622 | ||
|
|
a7ed0a347a | ||
|
|
d1ce8e2f8d | ||
|
|
fa4113117d | ||
|
|
f450f0a58a | ||
|
|
314055cf7a | ||
|
|
b333bdffe6 | ||
|
|
5701f7661e | ||
|
|
2b5da93cdc | ||
|
|
e2be7fdf3a | ||
|
|
0ac3df3f37 | ||
|
|
5a1bbc9fa3 | ||
|
|
e2c1845a24 | ||
|
|
679821861a | ||
|
|
77707b8c1e | ||
|
|
444acc1f1b | ||
|
|
bbfb8f81a6 | ||
|
|
1015c06cbe | ||
|
|
6bcefcd9ed | ||
|
|
901679882c | ||
|
|
6877d659d3 | ||
|
|
16f7ec2284 | ||
|
|
a4f0dc9d18 | ||
|
|
076cadb696 | ||
|
|
f2611f23e0 | ||
|
|
7c24965216 | ||
|
|
47982aaa61 | ||
|
|
6ee41fd639 | ||
|
|
e9faf54d0a | ||
|
|
7585408e10 | ||
|
|
9e9ce9420d | ||
|
|
0324983924 | ||
|
|
3f093cec4f | ||
|
|
c421d7d806 | ||
|
|
0d3127ad09 | ||
|
|
06be0e5111 | ||
|
|
5ce4ec0439 | ||
|
|
9a685882b7 | ||
|
|
5d1ee1646f |
38
.github/CODEOWNERS
vendored
@@ -15,9 +15,9 @@
|
||||
|
||||
## Angular
|
||||
|
||||
/packages/angular/ @sean-perkins
|
||||
/packages/angular-server @sean-perkins
|
||||
/packages/angular/test
|
||||
/packages/angular/ @sean-perkins @thetaPC
|
||||
/packages/angular-server @sean-perkins @thetaPC
|
||||
/packages/angular/test @thetaPC
|
||||
|
||||
## React
|
||||
|
||||
@@ -28,19 +28,23 @@
|
||||
|
||||
## Vue
|
||||
|
||||
/packages/vue/ @liamdebeasi
|
||||
/packages/vue-router/ @liamdebeasi
|
||||
/packages/vue/test/
|
||||
/packages/vue-router/__tests__
|
||||
/packages/vue/ @liamdebeasi @thetaPC
|
||||
/packages/vue-router/ @liamdebeasi @thetaPC
|
||||
/packages/vue/test/ @thetaPC
|
||||
/packages/vue-router/__tests__ @thetaPC
|
||||
|
||||
# Components
|
||||
|
||||
/core/src/components/accordion/ @liamdebeasi
|
||||
/core/src/components/accordion-group/ @liamdebeasi
|
||||
|
||||
/core/src/components/checkbox/ @amandaejohnston
|
||||
|
||||
/core/src/components/datetime/ @liamdebeasi @amandaejohnston @sean-perkins
|
||||
/core/src/components/datetime-button/ @liamdebeasi
|
||||
|
||||
/core/src/components/item/ @brandyscarney
|
||||
|
||||
/core/src/components/menu/ @amandaejohnston
|
||||
/core/src/components/menu-toggle/ @amandaejohnston
|
||||
|
||||
@@ -50,9 +54,19 @@
|
||||
/core/src/components/picker-internal/ @liamdebeasi
|
||||
/core/src/components/picker-column-internal/ @liamdebeasi
|
||||
|
||||
/core/src/components/radio/ @amandaejohnston
|
||||
/core/src/components/radio-group/ @amandaejohnston
|
||||
|
||||
/core/src/components/refresher/ @liamdebeasi
|
||||
/core/src/components/refresher-content/ @liamdebeasi
|
||||
|
||||
/core/src/components/searchbar/ @brandyscarney
|
||||
|
||||
/core/src/components/segment/ @brandyscarney
|
||||
/core/src/components/segment-button/ @brandyscarney
|
||||
|
||||
/core/src/components/skeleton-text/ @brandyscarney
|
||||
|
||||
# Utilities
|
||||
|
||||
/core/src/utils/animation/ @liamdebeasi
|
||||
@@ -64,3 +78,13 @@
|
||||
/core/src/utils/sanitization/ @liamdebeasi
|
||||
/core/src/utils/tap-click/ @liamdebeasi
|
||||
/core/src/utils/transition/ @liamdebeasi
|
||||
|
||||
/core/src/css/ @brandyscarney
|
||||
/core/src/themes/ @brandyscarney
|
||||
|
||||
# Tests
|
||||
|
||||
**/datetime.e2e.ts @mapsandapps
|
||||
**/datetime-button.e2e.ts @mapsandapps
|
||||
**/icon.e2e.ts @mapsandapps
|
||||
**/loading.e2e.ts @mapsandapps
|
||||
|
||||
@@ -13,6 +13,15 @@ runs:
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- name: Check Diff
|
||||
run: git diff --exit-code
|
||||
run: |
|
||||
git diff --exit-code || {
|
||||
echo -e "\033[1;31m⚠️ Error: Differences Detected ⚠️\033[0m"
|
||||
echo -e "\033[1;31mThere are uncommitted changes between the build outputs from CI and your branch.\033[0m"
|
||||
echo -e "\033[1;31mPlease ensure you have followed these steps:\033[0m"
|
||||
echo -e "\033[1;31m1. Run 'npm run build' locally to generate the latest build output.\033[0m"
|
||||
echo -e "\033[1;31m2. Commit and push all necessary changes to your branch.\033[0m"
|
||||
echo -e "\033[1;31m3. Compare and validate the differences before proceeding.\033[0m"
|
||||
exit 1
|
||||
}
|
||||
shell: bash
|
||||
working-directory: ./core
|
||||
|
||||
43
CHANGELOG.md
@@ -3,6 +3,49 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.3.2](https://github.com/ionic-team/ionic-framework/compare/v7.3.1...v7.3.2) (2023-08-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** gracefully handle invalid min/max ([#28054](https://github.com/ionic-team/ionic-framework/issues/28054)) ([01fc9b4](https://github.com/ionic-team/ionic-framework/commit/01fc9b45116f7ad6ddc56c7fb1535dec798c2b3a)), closes [#28041](https://github.com/ionic-team/ionic-framework/issues/28041)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** ionTabsWillChange is fired before tab activation ([#27991](https://github.com/ionic-team/ionic-framework/issues/27991)) ([bbfb8f8](https://github.com/ionic-team/ionic-framework/commit/bbfb8f81a61475d7e73b63743db5d6a0cd979d21)), closes [#27212](https://github.com/ionic-team/ionic-framework/issues/27212)
|
||||
* **input, textarea:** clearOnEdit does not clear when pressing Tab ([#28005](https://github.com/ionic-team/ionic-framework/issues/28005)) ([444acc1](https://github.com/ionic-team/ionic-framework/commit/444acc1f1bca348b62dfb398067cc087529f67f1)), closes [#27746](https://github.com/ionic-team/ionic-framework/issues/27746)
|
||||
* **react:** avoid multiple invocations of onDidDismiss and onWillPresent ([#28020](https://github.com/ionic-team/ionic-framework/issues/28020)) ([0ac3df3](https://github.com/ionic-team/ionic-framework/commit/0ac3df3f378bdefc3a927adc798ebd9ec7a54fee)), closes [#28010](https://github.com/ionic-team/ionic-framework/issues/28010)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **alert:** radio and checkbox labels wrap to next line ([#27898](https://github.com/ionic-team/ionic-framework/issues/27898)) ([0d3127a](https://github.com/ionic-team/ionic-framework/commit/0d3127ad09df3c914a8c254f14931de5ca3beb31)), closes [#17269](https://github.com/ionic-team/ionic-framework/issues/17269)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **action-sheet:** add htmlAttributes property for passing attributes to buttons ([#27863](https://github.com/ionic-team/ionic-framework/issues/27863)) ([5ce4ec0](https://github.com/ionic-team/ionic-framework/commit/5ce4ec0439e4f31aba31062fd8af4a2ad792a54f))
|
||||
* **alert:** add htmlAttributes property for passing attributes to buttons ([#27862](https://github.com/ionic-team/ionic-framework/issues/27862)) ([06be0e5](https://github.com/ionic-team/ionic-framework/commit/06be0e511164ebdaa6af9a3747d0585260c030a9))
|
||||
* **toast:** add htmlAttributes property for passing attributes to buttons ([#27855](https://github.com/ionic-team/ionic-framework/issues/27855)) ([9a68588](https://github.com/ionic-team/ionic-framework/commit/9a685882b7085d911ff09eedacc367629e32348a))
|
||||
* **toast:** add shadow part for cancel button ([#27921](https://github.com/ionic-team/ionic-framework/issues/27921)) ([e9faf54](https://github.com/ionic-team/ionic-framework/commit/e9faf54d0a7409521706ce9c8b0d26f3fbe9ba41)), closes [#27920](https://github.com/ionic-team/ionic-framework/issues/27920)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.2.4](https://github.com/ionic-team/ionic-framework/compare/v7.2.3...v7.2.4) (2023-08-16)
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
| Project | Package | Version | Downloads| Links |
|
||||
| ------- | ------- | ------- | -------- |:-----:|
|
||||
| **Core** | [`@ionic/core`](https://www.npmjs.com/package/@ionic/core) | [](https://www.npmjs.com/package/@ionic/core) | <a href="https://www.npmjs.com/package/@ionic/core" target="_blank"><img src="https://img.shields.io/npm/dm/@ionic/core.svg" alt="NPM Downloads" /></a> | [`README.md`](core/README.md)
|
||||
| **Angular** | [`@ionic/angular`](https://www.npmjs.com/package/@ionic/angular) | [](https://www.npmjs.com/package/@ionic/angular) | <a href="https://www.npmjs.com/package/@ionic/angular" target="_blank"><img src="https://img.shields.io/npm/dm/@ionic/angular.svg" alt="NPM Downloads" /></a> | [`README.md`](angular/README.md)
|
||||
| **Angular** | [`@ionic/angular`](https://www.npmjs.com/package/@ionic/angular) | [](https://www.npmjs.com/package/@ionic/angular) | <a href="https://www.npmjs.com/package/@ionic/angular" target="_blank"><img src="https://img.shields.io/npm/dm/@ionic/angular.svg" alt="NPM Downloads" /></a> | [`README.md`](packages/angular/README.md)
|
||||
| **Vue** | [`@ionic/vue`](https://www.npmjs.com/package/@ionic/vue) | [](https://www.npmjs.com/package/@ionic/vue) | <a href="https://www.npmjs.com/package/@ionic/vue" target="_blank"><img src="https://img.shields.io/npm/dm/@ionic/vue.svg" alt="NPM Downloads" /></a> | [`README.md`](packages/vue/README.md)
|
||||
| **React** | [`@ionic/react`](https://www.npmjs.com/package/@ionic/react) | [](https://www.npmjs.com/package/@ionic/react) | <a href="https://www.npmjs.com/package/@ionic/react" target="_blank"><img src="https://img.shields.io/npm/dm/@ionic/react.svg" alt="NPM Downloads" /></a> |[`README.md`](packages/react/README.md)
|
||||
|
||||
|
||||
@@ -3,6 +3,47 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.3.2](https://github.com/ionic-team/ionic-framework/compare/v7.3.1...v7.3.2) (2023-08-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** gracefully handle invalid min/max ([#28054](https://github.com/ionic-team/ionic-framework/issues/28054)) ([01fc9b4](https://github.com/ionic-team/ionic-framework/commit/01fc9b45116f7ad6ddc56c7fb1535dec798c2b3a)), closes [#28041](https://github.com/ionic-team/ionic-framework/issues/28041)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **input, textarea:** clearOnEdit does not clear when pressing Tab ([#28005](https://github.com/ionic-team/ionic-framework/issues/28005)) ([444acc1](https://github.com/ionic-team/ionic-framework/commit/444acc1f1bca348b62dfb398067cc087529f67f1)), closes [#27746](https://github.com/ionic-team/ionic-framework/issues/27746)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **alert:** radio and checkbox labels wrap to next line ([#27898](https://github.com/ionic-team/ionic-framework/issues/27898)) ([0d3127a](https://github.com/ionic-team/ionic-framework/commit/0d3127ad09df3c914a8c254f14931de5ca3beb31)), closes [#17269](https://github.com/ionic-team/ionic-framework/issues/17269)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **action-sheet:** add htmlAttributes property for passing attributes to buttons ([#27863](https://github.com/ionic-team/ionic-framework/issues/27863)) ([5ce4ec0](https://github.com/ionic-team/ionic-framework/commit/5ce4ec0439e4f31aba31062fd8af4a2ad792a54f))
|
||||
* **alert:** add htmlAttributes property for passing attributes to buttons ([#27862](https://github.com/ionic-team/ionic-framework/issues/27862)) ([06be0e5](https://github.com/ionic-team/ionic-framework/commit/06be0e511164ebdaa6af9a3747d0585260c030a9))
|
||||
* **toast:** add htmlAttributes property for passing attributes to buttons ([#27855](https://github.com/ionic-team/ionic-framework/issues/27855)) ([9a68588](https://github.com/ionic-team/ionic-framework/commit/9a685882b7085d911ff09eedacc367629e32348a))
|
||||
* **toast:** add shadow part for cancel button ([#27921](https://github.com/ionic-team/ionic-framework/issues/27921)) ([e9faf54](https://github.com/ionic-team/ionic-framework/commit/e9faf54d0a7409521706ce9c8b0d26f3fbe9ba41)), closes [#27920](https://github.com/ionic-team/ionic-framework/issues/27920)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.2.4](https://github.com/ionic-team/ionic-framework/compare/v7.2.3...v7.2.4) (2023-08-16)
|
||||
|
||||
|
||||
|
||||
@@ -1471,6 +1471,7 @@ ion-toast,css-prop,--start
|
||||
ion-toast,css-prop,--white-space
|
||||
ion-toast,css-prop,--width
|
||||
ion-toast,part,button
|
||||
ion-toast,part,button cancel
|
||||
ion-toast,part,container
|
||||
ion-toast,part,header
|
||||
ion-toast,part,icon
|
||||
|
||||
66
core/package-lock.json
generated
@@ -1,28 +1,28 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/core",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^3.4.0",
|
||||
"@stencil/core": "^4.1.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@axe-core/playwright": "^4.7.3",
|
||||
"@capacitor/core": "^5.2.3",
|
||||
"@capacitor/core": "^5.3.0",
|
||||
"@capacitor/haptics": "^5.0.6",
|
||||
"@capacitor/keyboard": "^5.0.6",
|
||||
"@capacitor/status-bar": "^5.0.6",
|
||||
"@ionic/eslint-config": "^0.3.0",
|
||||
"@ionic/prettier-config": "^2.0.0",
|
||||
"@jest/core": "^27.5.1",
|
||||
"@playwright/test": "^1.37.0",
|
||||
"@playwright/test": "^1.37.1",
|
||||
"@rollup/plugin-node-resolve": "^8.4.0",
|
||||
"@rollup/plugin-virtual": "^2.0.3",
|
||||
"@stencil/angular-output-target": "^0.7.1",
|
||||
@@ -607,9 +607,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@capacitor/core": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.2.3.tgz",
|
||||
"integrity": "sha512-Q1zbgt3Mvldy7six2/GX54kTL0ozgnR37jeDUAXL/fOJBF4Iorr/8A0OjGEAnwEjpR1la7uFZUunESMFyMLhEQ==",
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.3.0.tgz",
|
||||
"integrity": "sha512-mvhh1yJtcUTZ0hUUriBKKpxq47hn75bjxH3tYPRgAFu1z3gowCg+OtG4Rce3W5gr5fSfCjQgOSL0Vp7k9hPUWw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
@@ -1541,13 +1541,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.37.0",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.0.tgz",
|
||||
"integrity": "sha512-181WBLk4SRUyH1Q96VZl7BP6HcK0b7lbdeKisn3N/vnjitk+9HbdlFz/L5fey05vxaAhldIDnzo8KUoy8S3mmQ==",
|
||||
"version": "1.37.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz",
|
||||
"integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"playwright-core": "1.37.0"
|
||||
"playwright-core": "1.37.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
@@ -1634,15 +1634,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/core": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.0.tgz",
|
||||
"integrity": "sha512-kEtPtV6QegME8YgMjWrhS7KktItbhqOpAuK9aXypDdI/7bLU9iM/4DtnQGWY/DARBophk+XRBfNXcE62Bmi0dw==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.10.0",
|
||||
"npm": ">=6.0.0"
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=7.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/react-output-target": {
|
||||
@@ -8194,9 +8194,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.37.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.0.tgz",
|
||||
"integrity": "sha512-1c46jhTH/myQw6sesrcuHVtLoSNfJv8Pfy9t3rs6subY7kARv0HRw5PpyfPYPpPtQvBOmgbE6K+qgYUpj81LAA==",
|
||||
"version": "1.37.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz",
|
||||
"integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
@@ -10788,9 +10788,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@capacitor/core": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.2.3.tgz",
|
||||
"integrity": "sha512-Q1zbgt3Mvldy7six2/GX54kTL0ozgnR37jeDUAXL/fOJBF4Iorr/8A0OjGEAnwEjpR1la7uFZUunESMFyMLhEQ==",
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.3.0.tgz",
|
||||
"integrity": "sha512-mvhh1yJtcUTZ0hUUriBKKpxq47hn75bjxH3tYPRgAFu1z3gowCg+OtG4Rce3W5gr5fSfCjQgOSL0Vp7k9hPUWw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "^2.1.0"
|
||||
@@ -11455,14 +11455,14 @@
|
||||
}
|
||||
},
|
||||
"@playwright/test": {
|
||||
"version": "1.37.0",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.0.tgz",
|
||||
"integrity": "sha512-181WBLk4SRUyH1Q96VZl7BP6HcK0b7lbdeKisn3N/vnjitk+9HbdlFz/L5fey05vxaAhldIDnzo8KUoy8S3mmQ==",
|
||||
"version": "1.37.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz",
|
||||
"integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"fsevents": "2.3.2",
|
||||
"playwright-core": "1.37.0"
|
||||
"playwright-core": "1.37.1"
|
||||
}
|
||||
},
|
||||
"@rollup/plugin-node-resolve": {
|
||||
@@ -11524,9 +11524,9 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@stencil/core": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.0.tgz",
|
||||
"integrity": "sha512-kEtPtV6QegME8YgMjWrhS7KktItbhqOpAuK9aXypDdI/7bLU9iM/4DtnQGWY/DARBophk+XRBfNXcE62Bmi0dw=="
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg=="
|
||||
},
|
||||
"@stencil/react-output-target": {
|
||||
"version": "0.5.3",
|
||||
@@ -16332,9 +16332,9 @@
|
||||
}
|
||||
},
|
||||
"playwright-core": {
|
||||
"version": "1.37.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.0.tgz",
|
||||
"integrity": "sha512-1c46jhTH/myQw6sesrcuHVtLoSNfJv8Pfy9t3rs6subY7kARv0HRw5PpyfPYPpPtQvBOmgbE6K+qgYUpj81LAA==",
|
||||
"version": "1.37.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz",
|
||||
"integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==",
|
||||
"dev": true
|
||||
},
|
||||
"postcss": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"description": "Base components for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -31,20 +31,20 @@
|
||||
"loader/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@stencil/core": "^3.4.0",
|
||||
"@stencil/core": "^4.1.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@axe-core/playwright": "^4.7.3",
|
||||
"@capacitor/core": "^5.2.3",
|
||||
"@capacitor/core": "^5.3.0",
|
||||
"@capacitor/haptics": "^5.0.6",
|
||||
"@capacitor/keyboard": "^5.0.6",
|
||||
"@capacitor/status-bar": "^5.0.6",
|
||||
"@ionic/eslint-config": "^0.3.0",
|
||||
"@ionic/prettier-config": "^2.0.0",
|
||||
"@jest/core": "^27.5.1",
|
||||
"@playwright/test": "^1.37.0",
|
||||
"@playwright/test": "^1.37.1",
|
||||
"@rollup/plugin-node-resolve": "^8.4.0",
|
||||
"@rollup/plugin-virtual": "^2.0.3",
|
||||
"@stencil/angular-output-target": "^0.7.1",
|
||||
|
||||
@@ -23,6 +23,7 @@ export interface ActionSheetButton<T = any> {
|
||||
icon?: string;
|
||||
cssClass?: string | string[];
|
||||
id?: string;
|
||||
htmlAttributes?: { [key: string]: any };
|
||||
handler?: () => boolean | void | Promise<boolean | void>;
|
||||
data?: T;
|
||||
}
|
||||
|
||||
@@ -394,7 +394,13 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
|
||||
</div>
|
||||
)}
|
||||
{buttons.map((b) => (
|
||||
<button type="button" id={b.id} class={buttonClass(b)} onClick={() => this.buttonClick(b)}>
|
||||
<button
|
||||
{...b.htmlAttributes}
|
||||
type="button"
|
||||
id={b.id}
|
||||
class={buttonClass(b)}
|
||||
onClick={() => this.buttonClick(b)}
|
||||
>
|
||||
<span class="action-sheet-button-inner">
|
||||
{b.icon && <ion-icon icon={b.icon} aria-hidden="true" lazy={false} class="action-sheet-icon" />}
|
||||
{b.text}
|
||||
@@ -406,7 +412,12 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
|
||||
|
||||
{cancelButton && (
|
||||
<div class="action-sheet-group action-sheet-group-cancel">
|
||||
<button type="button" class={buttonClass(cancelButton)} onClick={() => this.buttonClick(cancelButton)}>
|
||||
<button
|
||||
{...cancelButton.htmlAttributes}
|
||||
type="button"
|
||||
class={buttonClass(cancelButton)}
|
||||
onClick={() => this.buttonClick(cancelButton)}
|
||||
>
|
||||
<span class="action-sheet-button-inner">
|
||||
{cancelButton.icon && (
|
||||
<ion-icon icon={cancelButton.icon} aria-hidden="true" lazy={false} class="action-sheet-icon" />
|
||||
|
||||
@@ -10,16 +10,36 @@ const testAria = async (page: E2EPage, buttonID: string, expectedAriaLabelledBy:
|
||||
await button.click();
|
||||
await didPresent.next();
|
||||
|
||||
const alert = page.locator('ion-action-sheet');
|
||||
const actionSheet = page.locator('ion-action-sheet');
|
||||
|
||||
/**
|
||||
* expect().toHaveAttribute() can't check for a null value, so grab and check
|
||||
* the value manually instead.
|
||||
*/
|
||||
const ariaLabelledBy = await alert.getAttribute('aria-labelledby');
|
||||
const ariaLabelledBy = await actionSheet.getAttribute('aria-labelledby');
|
||||
|
||||
expect(ariaLabelledBy).toBe(expectedAriaLabelledBy);
|
||||
};
|
||||
|
||||
const testAriaButton = async (
|
||||
page: E2EPage,
|
||||
buttonID: string,
|
||||
expectedAriaLabelledBy: string,
|
||||
expectedAriaLabel: string
|
||||
) => {
|
||||
const didPresent = await page.spyOnEvent('ionActionSheetDidPresent');
|
||||
|
||||
const button = page.locator(`#${buttonID}`);
|
||||
await button.click();
|
||||
|
||||
await didPresent.next();
|
||||
|
||||
const actionSheetButton = page.locator('ion-action-sheet .action-sheet-button');
|
||||
|
||||
await expect(actionSheetButton).toHaveAttribute('aria-labelledby', expectedAriaLabelledBy);
|
||||
await expect(actionSheetButton).toHaveAttribute('aria-label', expectedAriaLabel);
|
||||
};
|
||||
|
||||
configs({ directions: ['ltr'] }).forEach(({ config, title }) => {
|
||||
test.describe(title('action-sheet: a11y'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
@@ -52,5 +72,17 @@ configs({ directions: ['ltr'] }).forEach(({ config, title }) => {
|
||||
test('should allow for manually specifying aria attributes', async ({ page }) => {
|
||||
await testAria(page, 'customAria', 'Custom title');
|
||||
});
|
||||
|
||||
test('should have aria-labelledby and aria-label added to the button when htmlAttributes is set', async ({
|
||||
page,
|
||||
}) => {
|
||||
await testAriaButton(page, 'ariaLabelButton', 'close-label', 'close button');
|
||||
});
|
||||
|
||||
test('should have aria-labelledby and aria-label added to the cancel button when htmlAttributes is set', async ({
|
||||
page,
|
||||
}) => {
|
||||
await testAriaButton(page, 'ariaLabelCancelButton', 'cancel-label', 'cancel button');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
<ion-button id="subHeaderOnly" expand="block" onclick="presentSubHeaderOnly()">Subheader Only</ion-button>
|
||||
<ion-button id="noHeaders" expand="block" onclick="presentNoHeaders()">No Headers</ion-button>
|
||||
<ion-button id="customAria" expand="block" onclick="presentCustomAria()">Custom Aria</ion-button>
|
||||
<ion-button id="ariaLabelButton" expand="block" onclick="presentAriaLabelButton()">Aria Label Button</ion-button>
|
||||
<ion-button id="ariaLabelCancelButton" expand="block" onclick="presentAriaLabelCancelButton()"
|
||||
>Aria Label Cancel Button</ion-button
|
||||
>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
@@ -63,6 +67,39 @@
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function presentAriaLabelButton() {
|
||||
openActionSheet({
|
||||
header: 'Header',
|
||||
subHeader: 'Subtitle',
|
||||
buttons: [
|
||||
{
|
||||
text: 'Close',
|
||||
htmlAttributes: {
|
||||
'aria-label': 'close button',
|
||||
'aria-labelledby': 'close-label',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
function presentAriaLabelCancelButton() {
|
||||
openActionSheet({
|
||||
header: 'Header',
|
||||
subHeader: 'Subtitle',
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel',
|
||||
htmlAttributes: {
|
||||
'aria-label': 'cancel button',
|
||||
'aria-labelledby': 'cancel-label',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -48,6 +48,7 @@ export interface AlertButton {
|
||||
role?: 'cancel' | 'destructive' | string;
|
||||
cssClass?: string | string[];
|
||||
id?: string;
|
||||
htmlAttributes?: { [key: string]: any };
|
||||
// TODO(FW-2832): type
|
||||
handler?: (value: any) => AlertButtonOverlayHandler | Promise<AlertButtonOverlayHandler>;
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
}
|
||||
|
||||
.alert-tappable {
|
||||
height: $alert-ios-tappable-height;
|
||||
min-height: $alert-ios-tappable-height;
|
||||
}
|
||||
|
||||
|
||||
@@ -137,12 +137,6 @@
|
||||
order: 0;
|
||||
|
||||
color: $alert-ios-radio-label-text-color;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
@@ -196,12 +190,6 @@
|
||||
flex: 1;
|
||||
|
||||
color: $alert-ios-checkbox-label-text-color;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// iOS Alert Checkbox Outer Circle: Unchecked
|
||||
|
||||
@@ -113,9 +113,7 @@
|
||||
.alert-tappable {
|
||||
position: relative;
|
||||
|
||||
height: $alert-md-tappable-height;
|
||||
|
||||
overflow: hidden;
|
||||
min-height: $alert-md-tappable-height;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,12 +128,6 @@
|
||||
color: $alert-md-radio-label-text-color;
|
||||
|
||||
font-size: $alert-md-radio-label-font-size;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Material Design Alert Radio Unchecked Circle
|
||||
@@ -203,12 +195,6 @@
|
||||
color: $alert-md-checkbox-label-text-color;
|
||||
|
||||
font-size: $alert-md-checkbox-label-font-size;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -152,6 +152,8 @@
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
min-height: inherit;
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +186,7 @@
|
||||
text-align: start;
|
||||
appearance: none;
|
||||
|
||||
contain: strict;
|
||||
contain: content;
|
||||
}
|
||||
|
||||
.alert-button,
|
||||
|
||||
@@ -673,6 +673,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
|
||||
<div class={alertButtonGroupClass}>
|
||||
{buttons.map((button) => (
|
||||
<button
|
||||
{...button.htmlAttributes}
|
||||
type="button"
|
||||
id={button.id}
|
||||
class={buttonClass(button)}
|
||||
|
||||
@@ -60,5 +60,21 @@ configs({ directions: ['ltr'] }).forEach(({ config, title }) => {
|
||||
test('should allow for manually specifying aria attributes', async ({ page }) => {
|
||||
await testAria(page, 'customAria', 'Custom title', 'Custom description');
|
||||
});
|
||||
|
||||
test('should have aria-labelledby and aria-label added to the button when htmlAttributes is set', async ({
|
||||
page,
|
||||
}) => {
|
||||
const didPresent = await page.spyOnEvent('ionAlertDidPresent');
|
||||
|
||||
const button = page.locator('#ariaLabelButton');
|
||||
await button.click();
|
||||
|
||||
await didPresent.next();
|
||||
|
||||
const alertButton = page.locator('ion-alert .alert-button');
|
||||
|
||||
await expect(alertButton).toHaveAttribute('aria-labelledby', 'close-label');
|
||||
await expect(alertButton).toHaveAttribute('aria-label', 'close button');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<ion-button id="noHeaders" expand="block" onclick="presentNoHeaders()">No Headers</ion-button>
|
||||
<ion-button id="noMessage" expand="block" onclick="presentNoMessage()">No Message</ion-button>
|
||||
<ion-button id="customAria" expand="block" onclick="presentCustomAria()">Custom Aria</ion-button>
|
||||
<ion-button id="ariaLabelButton" expand="block" onclick="presentAriaLabelButton()">Aria Label Button</ion-button>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
@@ -76,6 +77,23 @@
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function presentAriaLabelButton() {
|
||||
openAlert({
|
||||
header: 'Header',
|
||||
subHeader: 'Subtitle',
|
||||
message: 'This is an alert message with custom aria attributes passed to the button.',
|
||||
buttons: [
|
||||
{
|
||||
text: 'Close',
|
||||
htmlAttributes: {
|
||||
'aria-label': 'close button',
|
||||
'aria-labelledby': 'close-label',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
@@ -246,17 +246,12 @@
|
||||
type: 'radio',
|
||||
label: 'Radio 4',
|
||||
value: 'value4',
|
||||
},
|
||||
{
|
||||
type: 'radio',
|
||||
label: 'Radio 5',
|
||||
value: 'value5',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
type: 'radio',
|
||||
label: 'Radio 6 Radio 6 Radio 6 Radio 6 Radio 6 Radio 6 Radio 6 Radio 6 Radio 6 Radio 6 ',
|
||||
value: 'value6',
|
||||
label: 'Radio 5 Radio 5 Radio 5 Radio 5 Radio 5 Radio 5 Radio 5 Radio 5 Radio 5 Radio 5 ',
|
||||
value: 'value5',
|
||||
},
|
||||
],
|
||||
buttons: [
|
||||
@@ -305,20 +300,13 @@
|
||||
type: 'checkbox',
|
||||
label: 'Checkbox 4',
|
||||
value: 'value4',
|
||||
},
|
||||
|
||||
{
|
||||
type: 'checkbox',
|
||||
label: 'Checkbox 5',
|
||||
value: 'value5',
|
||||
disabled: true,
|
||||
},
|
||||
|
||||
{
|
||||
type: 'checkbox',
|
||||
label:
|
||||
'Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6',
|
||||
value: 'value6',
|
||||
'Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5',
|
||||
value: 'value5',
|
||||
},
|
||||
],
|
||||
buttons: [
|
||||
|
||||
@@ -153,6 +153,15 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
||||
*/
|
||||
@Event() ionBlur!: EventEmitter<void>;
|
||||
|
||||
/**
|
||||
* This is responsible for rendering a hidden native
|
||||
* button element inside the associated form. This allows
|
||||
* users to submit a form by pressing "Enter" when a text
|
||||
* field inside of the form is focused. The native button
|
||||
* rendered inside of `ion-button` is in the Shadow DOM
|
||||
* and therefore does not participate in form submission
|
||||
* which is why the following code is necessary.
|
||||
*/
|
||||
private renderHiddenButton() {
|
||||
const formEl = (this.formEl = this.findForm());
|
||||
if (formEl) {
|
||||
@@ -323,6 +332,13 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
||||
fill = this.inToolbar || this.inListHeader ? 'clear' : 'solid';
|
||||
}
|
||||
|
||||
/**
|
||||
* We call renderHiddenButton in the render function to account
|
||||
* for any properties being set async. For example, changing the
|
||||
* "type" prop from "button" to "submit" after the component has
|
||||
* loaded would warrant the hidden button being added to the
|
||||
* associated form.
|
||||
*/
|
||||
{
|
||||
type !== 'button' && this.renderHiddenButton();
|
||||
}
|
||||
|
||||
@@ -154,6 +154,18 @@ describe('parseMinParts()', () => {
|
||||
minute: 30,
|
||||
});
|
||||
});
|
||||
it('should return undefined when given invalid info', () => {
|
||||
const today = {
|
||||
day: 14,
|
||||
month: 3,
|
||||
year: 2022,
|
||||
minute: 4,
|
||||
hour: 2,
|
||||
};
|
||||
expect(parseMinParts(undefined, today)).toEqual(undefined);
|
||||
expect(parseMinParts(null, today)).toEqual(undefined);
|
||||
expect(parseMinParts('foo', today)).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseMaxParts()', () => {
|
||||
@@ -205,4 +217,16 @@ describe('parseMaxParts()', () => {
|
||||
minute: 59,
|
||||
});
|
||||
});
|
||||
it('should return undefined when given invalid info', () => {
|
||||
const today = {
|
||||
day: 14,
|
||||
month: 3,
|
||||
year: 2022,
|
||||
minute: 4,
|
||||
hour: 2,
|
||||
};
|
||||
expect(parseMaxParts(undefined, today)).toEqual(undefined);
|
||||
expect(parseMaxParts(null, today)).toEqual(undefined);
|
||||
expect(parseMaxParts('foo', today)).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -132,8 +132,17 @@ export const parseAmPm = (hour: number) => {
|
||||
* For example, max="2012" would fill in the missing
|
||||
* month, day, hour, and minute information.
|
||||
*/
|
||||
export const parseMaxParts = (max: string, todayParts: DatetimeParts): DatetimeParts => {
|
||||
const { month, day, year, hour, minute } = parseDate(max);
|
||||
export const parseMaxParts = (max: string, todayParts: DatetimeParts): DatetimeParts | undefined => {
|
||||
const result = parseDate(max);
|
||||
|
||||
/**
|
||||
* If min was not a valid date then return undefined.
|
||||
*/
|
||||
if (result === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { month, day, year, hour, minute } = result;
|
||||
|
||||
/**
|
||||
* When passing in `max` or `min`, developers
|
||||
@@ -168,8 +177,17 @@ export const parseMaxParts = (max: string, todayParts: DatetimeParts): DatetimeP
|
||||
* For example, min="2012" would fill in the missing
|
||||
* month, day, hour, and minute information.
|
||||
*/
|
||||
export const parseMinParts = (min: string, todayParts: DatetimeParts): DatetimeParts => {
|
||||
const { month, day, year, hour, minute } = parseDate(min);
|
||||
export const parseMinParts = (min: string, todayParts: DatetimeParts): DatetimeParts | undefined => {
|
||||
const result = parseDate(min);
|
||||
|
||||
/**
|
||||
* If min was not a valid date then return undefined.
|
||||
*/
|
||||
if (result === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { month, day, year, hour, minute } = result;
|
||||
|
||||
/**
|
||||
* When passing in `max` or `min`, developers
|
||||
|
||||
@@ -532,7 +532,7 @@ export class Input implements ComponentInterface {
|
||||
* Clear the input if the control has not been previously cleared during focus.
|
||||
* Do not clear if the user hitting enter to submit a form.
|
||||
*/
|
||||
if (!this.didInputClearOnEdit && this.hasValue() && ev.key !== 'Enter') {
|
||||
if (!this.didInputClearOnEdit && this.hasValue() && ev.key !== 'Enter' && ev.key !== 'Tab') {
|
||||
this.value = '';
|
||||
this.emitInputChange(ev);
|
||||
}
|
||||
|
||||
57
core/src/components/input/test/basic/index.html
Normal file
@@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Input - Basic</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
<style>
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, minmax(250px, 1fr));
|
||||
grid-row-gap: 20px;
|
||||
grid-column-gap: 20px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
|
||||
color: #6f7378;
|
||||
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
.grid {
|
||||
grid-template-columns: 1fr;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Input - Basic</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content id="content" class="ion-padding">
|
||||
<div class="grid">
|
||||
<div class="grid-item">
|
||||
<h2>Default</h2>
|
||||
<ion-input value="hi@ionic.io" label="Email"></ion-input>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
</body>
|
||||
</html>
|
||||
43
core/src/components/input/test/clear-on-edit/input.e2e.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test, configs } from '@utils/test/playwright';
|
||||
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('input: clearOnEdit'), () => {
|
||||
test('should clear when typed into', async ({ page }) => {
|
||||
await page.setContent(`<ion-input value="abc" clear-on-edit="true" aria-label="input"></ion-input>`, config);
|
||||
|
||||
const ionInput = await page.spyOnEvent('ionInput');
|
||||
|
||||
const input = page.locator('ion-input');
|
||||
await input.locator('input').type('h');
|
||||
|
||||
await ionInput.next();
|
||||
|
||||
await expect(input).toHaveJSProperty('value', 'h');
|
||||
});
|
||||
|
||||
test('should not clear when enter is pressed', async ({ page }) => {
|
||||
await page.setContent(`<ion-input value="abc" clear-on-edit="true" aria-label="input"></ion-input>`, config);
|
||||
|
||||
const input = page.locator('ion-input');
|
||||
await input.locator('input').focus();
|
||||
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(input).toHaveJSProperty('value', 'abc');
|
||||
});
|
||||
|
||||
test('should not clear when tab is pressed', async ({ page }) => {
|
||||
await page.setContent(`<ion-input value="abc" clear-on-edit="true" aria-label="input"></ion-input>`, config);
|
||||
|
||||
const input = page.locator('ion-input');
|
||||
await input.locator('input').focus();
|
||||
|
||||
await page.keyboard.press('Tab');
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(input).toHaveJSProperty('value', 'abc');
|
||||
});
|
||||
});
|
||||
});
|
||||
64
core/src/components/menu-button/test/async/index.html
Normal file
@@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Menu - Async</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
||||
/>
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
<script type="module">
|
||||
import { menuController } from '../../../../dist/ionic/index.esm.js';
|
||||
window.menuController = menuController;
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<div id="menu-container">
|
||||
<ion-menu content-id="main">
|
||||
<ion-content class="ion-padding"> Menu Content </ion-content>
|
||||
</ion-menu>
|
||||
</div>
|
||||
|
||||
<div class="ion-page" id="main">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Menu - Async</ion-title>
|
||||
<ion-buttons slot="start" id="buttons-container"></ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
Main Content
|
||||
<button onclick="trigger()" id="trigger">Add Menu To DOM</button>
|
||||
</ion-content>
|
||||
</div>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
const buttons = document.querySelector('ion-buttons');
|
||||
const menuButton = document.createElement('ion-menu-button');
|
||||
const menu = document.querySelector('ion-menu');
|
||||
const menuContainer = document.querySelector('#menu-container');
|
||||
|
||||
let firstLoad = true;
|
||||
|
||||
// When the menu loads, immediately remove it from the DOM
|
||||
document.body.addEventListener('ionMenuChange', () => {
|
||||
if (firstLoad) {
|
||||
menuContainer.removeChild(menu);
|
||||
buttons.appendChild(menuButton);
|
||||
firstLoad = false;
|
||||
}
|
||||
});
|
||||
const trigger = () => {
|
||||
menuContainer.append(menu);
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
/**
|
||||
* This behavior does not vary across modes/directions
|
||||
*/
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('menu button: async'), () => {
|
||||
test('menu button should be visible if menu is moved', async ({ page }) => {
|
||||
await page.goto(`/src/components/menu-button/test/async`, config);
|
||||
|
||||
const menu = page.locator('ion-menu');
|
||||
const menuButton = page.locator('ion-menu-button');
|
||||
const triggerButton = page.locator('#trigger');
|
||||
|
||||
await expect(menu).not.toBeAttached();
|
||||
await expect(menuButton).toBeHidden();
|
||||
|
||||
await triggerButton.click();
|
||||
|
||||
await expect(menu).toBeAttached();
|
||||
await expect(menuButton).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -38,6 +38,7 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
private lastOnEnd = 0;
|
||||
private gesture?: Gesture;
|
||||
private blocker = GESTURE_CONTROLLER.createBlocker({ disableScroll: true });
|
||||
private didLoad = false;
|
||||
|
||||
isAnimating = false;
|
||||
width!: number;
|
||||
@@ -216,6 +217,7 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
|
||||
// register this menu with the app's menu controller
|
||||
menuController._register(this);
|
||||
this.menuChanged();
|
||||
|
||||
this.gesture = (await import('../../utils/gesture')).createGesture({
|
||||
el: document,
|
||||
@@ -237,10 +239,22 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
}
|
||||
|
||||
async componentDidLoad() {
|
||||
this.ionMenuChange.emit({ disabled: this.disabled, open: this._isOpen });
|
||||
this.didLoad = true;
|
||||
this.menuChanged();
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
private menuChanged() {
|
||||
/**
|
||||
* Inform dependent components such as ion-menu-button
|
||||
* that the menu is ready. Note that we only want to do this
|
||||
* once the menu has been rendered which is why we check for didLoad.
|
||||
*/
|
||||
if (this.didLoad) {
|
||||
this.ionMenuChange.emit({ disabled: this.disabled, open: this._isOpen });
|
||||
}
|
||||
}
|
||||
|
||||
async disconnectedCallback() {
|
||||
/**
|
||||
* The menu should be closed when it is
|
||||
|
||||
@@ -27,6 +27,9 @@ export interface PickerButton {
|
||||
export interface PickerColumn {
|
||||
name: string;
|
||||
align?: string;
|
||||
/**
|
||||
* Changing this value allows the initial value of a picker column to be set.
|
||||
*/
|
||||
selectedIndex?: number;
|
||||
prevSelected?: number;
|
||||
prefix?: string;
|
||||
|
||||
@@ -20,7 +20,7 @@ import type { RouteID, RouterDirection, RouteWrite, NavOutlet } from '../router/
|
||||
|
||||
@Component({
|
||||
tag: 'ion-router-outlet',
|
||||
styleUrl: 'route-outlet.scss',
|
||||
styleUrl: 'router-outlet.scss',
|
||||
shadow: true,
|
||||
})
|
||||
export class RouterOutlet implements ComponentInterface, NavOutlet {
|
||||
@@ -0,0 +1,37 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test, configs } from '@utils/test/playwright';
|
||||
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('textarea: clearOnEdit'), () => {
|
||||
test('should clear when typed into', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`<ion-textarea value="abc" clear-on-edit="true" aria-label="textarea"></ion-textarea>`,
|
||||
config
|
||||
);
|
||||
|
||||
const ionInput = await page.spyOnEvent('ionInput');
|
||||
|
||||
const textarea = page.locator('ion-textarea');
|
||||
await textarea.locator('textarea').type('h');
|
||||
|
||||
await ionInput.next();
|
||||
|
||||
await expect(textarea).toHaveJSProperty('value', 'h');
|
||||
});
|
||||
|
||||
test('should not clear when tab is pressed', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`<ion-textarea value="abc" clear-on-edit="true" aria-label="textarea"></ion-textarea>`,
|
||||
config
|
||||
);
|
||||
|
||||
const textarea = page.locator('ion-textarea');
|
||||
await textarea.locator('textarea').focus();
|
||||
|
||||
await page.keyboard.press('Tab');
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(textarea).toHaveJSProperty('value', 'abc');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -434,7 +434,7 @@ export class Textarea implements ComponentInterface {
|
||||
/**
|
||||
* Check if we need to clear the text input if clearOnEdit is enabled
|
||||
*/
|
||||
private checkClearOnEdit(ev: Event) {
|
||||
private checkClearOnEdit(ev: KeyboardEvent) {
|
||||
if (!this.clearOnEdit) {
|
||||
return;
|
||||
}
|
||||
@@ -442,7 +442,7 @@ export class Textarea implements ComponentInterface {
|
||||
* Clear the textarea if the control has not been previously cleared
|
||||
* during focus.
|
||||
*/
|
||||
if (!this.didTextareaClearOnEdit && this.hasValue()) {
|
||||
if (!this.didTextareaClearOnEdit && this.hasValue() && ev.key !== 'Tab') {
|
||||
this.value = '';
|
||||
this.emitInputChange(ev);
|
||||
}
|
||||
@@ -501,7 +501,7 @@ export class Textarea implements ComponentInterface {
|
||||
this.ionBlur.emit(ev);
|
||||
};
|
||||
|
||||
private onKeyDown = (ev: Event) => {
|
||||
private onKeyDown = (ev: KeyboardEvent) => {
|
||||
this.checkClearOnEdit(ev);
|
||||
};
|
||||
|
||||
|
||||
@@ -34,6 +34,14 @@
|
||||
Present Controller Toast
|
||||
</ion-button>
|
||||
|
||||
<ion-button id="aria-label-toast-trigger">Present Aria Label Toast</ion-button>
|
||||
<ion-toast
|
||||
id="aria-label-toast"
|
||||
trigger="aria-label-toast-trigger"
|
||||
header="Aria Label Toast Header"
|
||||
message="Aria Label Toast Message"
|
||||
></ion-toast>
|
||||
|
||||
<ion-button onclick="updateContent()">Update Inner Content</ion-button>
|
||||
</main>
|
||||
</ion-app>
|
||||
@@ -41,6 +49,17 @@
|
||||
const inlineToast = document.querySelector('#inline-toast');
|
||||
inlineToast.buttons = ['Ok'];
|
||||
|
||||
const ariaLabelToast = document.querySelector('#aria-label-toast');
|
||||
ariaLabelToast.buttons = [
|
||||
{
|
||||
icon: 'close',
|
||||
htmlAttributes: {
|
||||
'aria-label': 'close button',
|
||||
'aria-labelledby': 'close-label',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const presentToast = async (opts) => {
|
||||
const toast = await toastController.create(opts);
|
||||
|
||||
|
||||
@@ -11,10 +11,10 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
await page.goto(`/src/components/toast/test/a11y`, config);
|
||||
});
|
||||
test('should not have any axe violations with inline toasts', async ({ page }) => {
|
||||
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
|
||||
const didPresent = await page.spyOnEvent('ionToastDidPresent');
|
||||
|
||||
await page.click('#inline-toast-trigger');
|
||||
await ionToastDidPresent.next();
|
||||
await didPresent.next();
|
||||
|
||||
/**
|
||||
* IonToast overlays the entire screen, so
|
||||
@@ -25,10 +25,10 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
expect(results.violations).toEqual([]);
|
||||
});
|
||||
test('should not have any axe violations with controller toasts', async ({ page }) => {
|
||||
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
|
||||
const didPresent = await page.spyOnEvent('ionToastDidPresent');
|
||||
|
||||
await page.click('#controller-toast-trigger');
|
||||
await ionToastDidPresent.next();
|
||||
await didPresent.next();
|
||||
|
||||
/**
|
||||
* IonToast overlays the entire screen, so
|
||||
@@ -38,5 +38,19 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
const results = await new AxeBuilder({ page }).disableRules('color-contrast').analyze();
|
||||
expect(results.violations).toEqual([]);
|
||||
});
|
||||
|
||||
test('should have aria-labelledby and aria-label added to the button when htmlAttributes is set', async ({
|
||||
page,
|
||||
}) => {
|
||||
const didPresent = await page.spyOnEvent('ionToastDidPresent');
|
||||
|
||||
await page.click('#aria-label-toast-trigger');
|
||||
await didPresent.next();
|
||||
|
||||
const toastButton = page.locator('#aria-label-toast .toast-button');
|
||||
|
||||
await expect(toastButton).toHaveAttribute('aria-labelledby', 'close-label');
|
||||
await expect(toastButton).toHaveAttribute('aria-label', 'close button');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -129,3 +129,18 @@ describe('toast: htmlAttributes', () => {
|
||||
await expect(toast.getAttribute('data-testid')).toBe('basic-toast');
|
||||
});
|
||||
});
|
||||
|
||||
describe('toast: button cancel', () => {
|
||||
it('should render the cancel button with part button-cancel', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Toast],
|
||||
template: () => <ion-toast buttons={[{ text: 'Cancel', role: 'cancel' }]}></ion-toast>,
|
||||
});
|
||||
|
||||
const toast = page.body.querySelector('ion-toast');
|
||||
|
||||
const buttonCancel = toast?.shadowRoot?.querySelector('.toast-button-cancel');
|
||||
|
||||
expect(buttonCancel.getAttribute('part')).toBe('button cancel');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,6 +31,7 @@ export interface ToastButton {
|
||||
side?: 'start' | 'end';
|
||||
role?: 'cancel' | string;
|
||||
cssClass?: string | string[];
|
||||
htmlAttributes?: { [key: string]: any };
|
||||
handler?: () => boolean | void | Promise<boolean | void>;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import type { ToastButton, ToastPosition, ToastLayout } from './toast-interface'
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
*
|
||||
* @part button - Any button element that is displayed inside of the toast.
|
||||
* @part button cancel - Any button element with role "cancel" that is displayed inside of the toast.
|
||||
* @part container - The element that wraps all child elements.
|
||||
* @part header - The header text of the toast.
|
||||
* @part message - The body text of the toast.
|
||||
@@ -416,7 +417,14 @@ export class Toast implements ComponentInterface, OverlayInterface {
|
||||
return (
|
||||
<div class={buttonGroupsClasses}>
|
||||
{buttons.map((b) => (
|
||||
<button type="button" class={buttonClass(b)} tabIndex={0} onClick={() => this.buttonClick(b)} part="button">
|
||||
<button
|
||||
{...b.htmlAttributes}
|
||||
type="button"
|
||||
class={buttonClass(b)}
|
||||
tabIndex={0}
|
||||
onClick={() => this.buttonClick(b)}
|
||||
part={buttonPart(b)}
|
||||
>
|
||||
<div class="toast-button-inner">
|
||||
{b.icon && (
|
||||
<ion-icon
|
||||
@@ -579,5 +587,9 @@ const buttonClass = (button: ToastButton): CssClassMap => {
|
||||
};
|
||||
};
|
||||
|
||||
const buttonPart = (button: ToastButton): string => {
|
||||
return isCancel(button.role) ? 'button cancel' : 'button';
|
||||
};
|
||||
|
||||
type ToastPresentOptions = ToastPosition;
|
||||
type ToastDismissOptions = ToastPosition;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { newSpecPage } from '@stencil/core/testing';
|
||||
|
||||
import { Nav } from '../../../components/nav/nav';
|
||||
import { RouterOutlet } from '../../../components/router-outlet/route-outlet';
|
||||
import { RouterOutlet } from '../../../components/router-outlet/router-outlet';
|
||||
import { setRootAriaHidden } from '../../overlays';
|
||||
|
||||
describe('setRootAriaHidden()', () => {
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.3.2](https://github.com/ionic-team/ionic-framework/compare/v7.3.1...v7.3.2) (2023-08-30)
|
||||
|
||||
**Note:** Version bump only for package @ionic/docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
|
||||
|
||||
**Note:** Version bump only for package @ionic/docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.2.4](https://github.com/ionic-team/ionic-framework/compare/v7.2.3...v7.2.4) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/docs
|
||||
|
||||
4
docs/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ionic/docs",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/docs",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/docs",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"description": "Pre-packaged API documentation for the Ionic docs.",
|
||||
"main": "core.json",
|
||||
"types": "core.d.ts",
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
"docs",
|
||||
"packages/*"
|
||||
],
|
||||
"version": "7.2.4"
|
||||
"version": "7.3.2"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.3.2](https://github.com/ionic-team/ionic-framework/compare/v7.3.1...v7.3.2) (2023-08-30)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular-server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular-server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular-server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.2.4](https://github.com/ionic-team/ionic-framework/compare/v7.2.3...v7.2.4) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular-server
|
||||
|
||||
38
packages/angular-server/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.2.4"
|
||||
"@ionic/core": "^7.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-eslint/eslint-plugin": "^14.0.0",
|
||||
@@ -1060,25 +1060,25 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.2.3.tgz",
|
||||
"integrity": "sha512-9ms4JTozhoFzOlgVRozuRcXiyW5YDNlPqJYZx6xVPYPfcRUTIANQ9PZbU/Xqb9RA1xucTSgbKy91nt/hzJIalg==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz",
|
||||
"integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^3.4.0",
|
||||
"@stencil/core": "^4.1.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core/node_modules/@stencil/core": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.1.tgz",
|
||||
"integrity": "sha512-7rjOmM0W9K5op2gtOQRLERGH1155rv2fm6ppxOzYqqG8ISct4m9skp5XgUBYPu+GSPsJFdRuCIQs0IuVsG/7+g==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.10.0",
|
||||
"npm": ">=6.0.0"
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=7.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/eslint-config": {
|
||||
@@ -7342,19 +7342,19 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.2.3.tgz",
|
||||
"integrity": "sha512-9ms4JTozhoFzOlgVRozuRcXiyW5YDNlPqJYZx6xVPYPfcRUTIANQ9PZbU/Xqb9RA1xucTSgbKy91nt/hzJIalg==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz",
|
||||
"integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^3.4.0",
|
||||
"@stencil/core": "^4.1.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@stencil/core": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.1.tgz",
|
||||
"integrity": "sha512-7rjOmM0W9K5op2gtOQRLERGH1155rv2fm6ppxOzYqqG8ISct4m9skp5XgUBYPu+GSPsJFdRuCIQs0IuVsG/7+g=="
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"description": "Angular SSR Module for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -61,6 +61,6 @@
|
||||
},
|
||||
"prettier": "@ionic/prettier-config",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.2.4"
|
||||
"@ionic/core": "^7.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,33 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.3.2](https://github.com/ionic-team/ionic-framework/compare/v7.3.1...v7.3.2) (2023-08-30)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** ionTabsWillChange is fired before tab activation ([#27991](https://github.com/ionic-team/ionic-framework/issues/27991)) ([bbfb8f8](https://github.com/ionic-team/ionic-framework/commit/bbfb8f81a61475d7e73b63743db5d6a0cd979d21)), closes [#27212](https://github.com/ionic-team/ionic-framework/issues/27212)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.2.4](https://github.com/ionic-team/ionic-framework/compare/v7.2.3...v7.2.4) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
||||
38
packages/angular/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.2.4",
|
||||
"@ionic/core": "^7.3.2",
|
||||
"ionicons": "^7.0.0",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"tslib": "^2.3.0"
|
||||
@@ -1227,25 +1227,25 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.2.3.tgz",
|
||||
"integrity": "sha512-9ms4JTozhoFzOlgVRozuRcXiyW5YDNlPqJYZx6xVPYPfcRUTIANQ9PZbU/Xqb9RA1xucTSgbKy91nt/hzJIalg==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz",
|
||||
"integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^3.4.0",
|
||||
"@stencil/core": "^4.1.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core/node_modules/@stencil/core": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.1.tgz",
|
||||
"integrity": "sha512-7rjOmM0W9K5op2gtOQRLERGH1155rv2fm6ppxOzYqqG8ISct4m9skp5XgUBYPu+GSPsJFdRuCIQs0IuVsG/7+g==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.10.0",
|
||||
"npm": ">=6.0.0"
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=7.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/eslint-config": {
|
||||
@@ -8104,19 +8104,19 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.2.3.tgz",
|
||||
"integrity": "sha512-9ms4JTozhoFzOlgVRozuRcXiyW5YDNlPqJYZx6xVPYPfcRUTIANQ9PZbU/Xqb9RA1xucTSgbKy91nt/hzJIalg==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz",
|
||||
"integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^3.4.0",
|
||||
"@stencil/core": "^4.1.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@stencil/core": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.1.tgz",
|
||||
"integrity": "sha512-7rjOmM0W9K5op2gtOQRLERGH1155rv2fm6ppxOzYqqG8ISct4m9skp5XgUBYPu+GSPsJFdRuCIQs0IuVsG/7+g=="
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"description": "Angular specific wrappers for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -47,7 +47,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.2.4",
|
||||
"@ionic/core": "^7.3.2",
|
||||
"ionicons": "^7.0.0",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"tslib": "^2.3.0"
|
||||
|
||||
@@ -30,7 +30,7 @@ import { Config } from '../../providers/config';
|
||||
import { NavController } from '../../providers/nav-controller';
|
||||
|
||||
import { StackController } from './stack-controller';
|
||||
import { RouteView, getUrl } from './stack-utils';
|
||||
import { RouteView, StackDidChangeEvent, StackWillChangeEvent, getUrl, isTabSwitch } from './stack-utils';
|
||||
|
||||
// TODO(FW-2827): types
|
||||
|
||||
@@ -66,7 +66,11 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
*/
|
||||
@Input() name = PRIMARY_OUTLET;
|
||||
|
||||
@Output() stackEvents = new EventEmitter<any>();
|
||||
/** @internal */
|
||||
@Output() stackWillChange = new EventEmitter<StackWillChangeEvent>();
|
||||
/** @internal */
|
||||
@Output() stackDidChange = new EventEmitter<StackDidChangeEvent>();
|
||||
|
||||
// eslint-disable-next-line @angular-eslint/no-output-rename
|
||||
@Output('activate') activateEvents = new EventEmitter<any>();
|
||||
// eslint-disable-next-line @angular-eslint/no-output-rename
|
||||
@@ -304,9 +308,16 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
*/
|
||||
this.navCtrl.setTopOutlet(this);
|
||||
|
||||
const leavingView = this.stackCtrl.getActiveView();
|
||||
|
||||
this.stackWillChange.emit({
|
||||
enteringView,
|
||||
tabSwitch: isTabSwitch(enteringView, leavingView),
|
||||
});
|
||||
|
||||
this.stackCtrl.setActive(enteringView).then((data) => {
|
||||
this.activateEvents.emit(cmpRef.instance);
|
||||
this.stackEvents.emit(data);
|
||||
this.stackDidChange.emit(data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,19 @@ import { NavController } from '../../providers/nav-controller';
|
||||
import { IonTabBar } from '../proxies';
|
||||
|
||||
import { IonRouterOutlet } from './ion-router-outlet';
|
||||
import { StackEvent } from './stack-utils';
|
||||
import { StackDidChangeEvent, StackWillChangeEvent } from './stack-utils';
|
||||
|
||||
@Component({
|
||||
selector: 'ion-tabs',
|
||||
template: `
|
||||
<ng-content select="[slot=top]"></ng-content>
|
||||
<div class="tabs-inner" #tabsInner>
|
||||
<ion-router-outlet #outlet tabs="true" (stackEvents)="onPageSelected($event)"></ion-router-outlet>
|
||||
<ion-router-outlet
|
||||
#outlet
|
||||
tabs="true"
|
||||
(stackWillChange)="onStackWillChange($event)"
|
||||
(stackDidChange)="onStackDidChange($event)"
|
||||
></ion-router-outlet>
|
||||
</div>
|
||||
<ng-content></ng-content>
|
||||
`,
|
||||
@@ -62,7 +67,13 @@ export class IonTabs implements AfterContentInit, AfterContentChecked {
|
||||
@ContentChild(IonTabBar, { static: false }) tabBar: IonTabBar | undefined;
|
||||
@ContentChildren(IonTabBar) tabBars: QueryList<IonTabBar>;
|
||||
|
||||
/**
|
||||
* Emitted before the tab view is changed.
|
||||
*/
|
||||
@Output() ionTabsWillChange = new EventEmitter<{ tab: string }>();
|
||||
/**
|
||||
* Emitted after the tab view is changed.
|
||||
*/
|
||||
@Output() ionTabsDidChange = new EventEmitter<{ tab: string }>();
|
||||
|
||||
private tabBarSlot = 'bottom';
|
||||
@@ -80,10 +91,19 @@ export class IonTabs implements AfterContentInit, AfterContentChecked {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
onPageSelected(detail: StackEvent): void {
|
||||
const stackId = detail.enteringView.stackId;
|
||||
if (detail.tabSwitch && stackId !== undefined) {
|
||||
onStackWillChange({ enteringView, tabSwitch }: StackWillChangeEvent): void {
|
||||
const stackId = enteringView.stackId;
|
||||
if (tabSwitch && stackId !== undefined) {
|
||||
this.ionTabsWillChange.emit({ tab: stackId });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
onStackDidChange({ enteringView, tabSwitch }: StackDidChangeEvent): void {
|
||||
const stackId = enteringView.stackId;
|
||||
if (tabSwitch && stackId !== undefined) {
|
||||
if (this.tabBar) {
|
||||
this.tabBar.selectedTab = stackId;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { NavController } from '../../providers/nav-controller';
|
||||
|
||||
import {
|
||||
RouteView,
|
||||
StackEvent,
|
||||
StackDidChangeEvent,
|
||||
computeStackId,
|
||||
destroyView,
|
||||
getUrl,
|
||||
@@ -61,7 +61,7 @@ export class StackController {
|
||||
return view;
|
||||
}
|
||||
|
||||
setActive(enteringView: RouteView): Promise<StackEvent> {
|
||||
setActive(enteringView: RouteView): Promise<StackDidChangeEvent> {
|
||||
const consumeResult = this.navCtrl.consumeTransition();
|
||||
let { direction, animation, animationBuilder } = consumeResult;
|
||||
const leavingView = this.activeView;
|
||||
@@ -224,6 +224,13 @@ export class StackController {
|
||||
return this.activeView ? this.activeView.stackId : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getActiveView(): RouteView | undefined {
|
||||
return this.activeView;
|
||||
}
|
||||
|
||||
hasRunningTask(): boolean {
|
||||
return this.runningTask !== undefined;
|
||||
}
|
||||
|
||||
@@ -79,10 +79,23 @@ export const destroyView = (view: RouteView | undefined): void => {
|
||||
}
|
||||
};
|
||||
|
||||
export interface StackEvent {
|
||||
export interface StackWillChangeEvent {
|
||||
enteringView: RouteView;
|
||||
/**
|
||||
* `true` if the event is trigged as a result of a switch
|
||||
* between tab navigation stacks.
|
||||
*/
|
||||
tabSwitch: boolean;
|
||||
}
|
||||
|
||||
export interface StackDidChangeEvent {
|
||||
enteringView: RouteView;
|
||||
direction: RouterDirection;
|
||||
animation: NavDirection | undefined;
|
||||
/**
|
||||
* `true` if the event is trigged as a result of a switch
|
||||
* between tab navigation stacks.
|
||||
*/
|
||||
tabSwitch: boolean;
|
||||
}
|
||||
|
||||
|
||||
2
packages/angular/src/directives/validators/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './max-validator';
|
||||
export * from './min-validator';
|
||||
22
packages/angular/src/directives/validators/max-validator.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Directive, forwardRef, Provider } from '@angular/core';
|
||||
import { MaxValidator, NG_VALIDATORS } from '@angular/forms';
|
||||
|
||||
/**
|
||||
* @description
|
||||
* Provider which adds `MaxValidator` to the `NG_VALIDATORS` multi-provider list.
|
||||
*/
|
||||
export const ION_MAX_VALIDATOR: Provider = {
|
||||
provide: NG_VALIDATORS,
|
||||
useExisting: forwardRef(() => IonMaxValidator),
|
||||
multi: true,
|
||||
};
|
||||
|
||||
@Directive({
|
||||
selector:
|
||||
'ion-input[type=number][max][formControlName],ion-input[type=number][max][formControl],ion-input[type=number][max][ngModel]',
|
||||
providers: [ION_MAX_VALIDATOR],
|
||||
// eslint-disable-next-line @angular-eslint/no-host-metadata-property
|
||||
host: { '[attr.max]': '_enabled ? max : null' },
|
||||
})
|
||||
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
||||
export class IonMaxValidator extends MaxValidator {}
|
||||
22
packages/angular/src/directives/validators/min-validator.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Directive, forwardRef, Provider } from '@angular/core';
|
||||
import { MinValidator, NG_VALIDATORS } from '@angular/forms';
|
||||
|
||||
/**
|
||||
* @description
|
||||
* Provider which adds `MinValidator` to the `NG_VALIDATORS` multi-provider list.
|
||||
*/
|
||||
export const ION_MIN_VALIDATOR: Provider = {
|
||||
provide: NG_VALIDATORS,
|
||||
useExisting: forwardRef(() => IonMinValidator),
|
||||
multi: true,
|
||||
};
|
||||
|
||||
@Directive({
|
||||
selector:
|
||||
'ion-input[type=number][min][formControlName],ion-input[type=number][min][formControl],ion-input[type=number][min][ngModel]',
|
||||
providers: [ION_MIN_VALIDATOR],
|
||||
// eslint-disable-next-line @angular-eslint/no-host-metadata-property
|
||||
host: { '[attr.min]': '_enabled ? min : null' },
|
||||
})
|
||||
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
||||
export class IonMinValidator extends MinValidator {}
|
||||
@@ -17,6 +17,7 @@ export { NavParams } from './directives/navigation/nav-params';
|
||||
export { IonModal } from './directives/overlays/modal';
|
||||
export { IonPopover } from './directives/overlays/popover';
|
||||
export * from './directives/proxies';
|
||||
export * from './directives/validators';
|
||||
|
||||
// PROVIDERS
|
||||
export { AngularDelegate } from './providers/angular-delegate';
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
import { IonModal } from './directives/overlays/modal';
|
||||
import { IonPopover } from './directives/overlays/popover';
|
||||
import { DIRECTIVES } from './directives/proxies-list';
|
||||
import { IonMaxValidator, IonMinValidator } from './directives/validators';
|
||||
import { AngularDelegate } from './providers/angular-delegate';
|
||||
import { ConfigToken } from './providers/config';
|
||||
import { ModalController } from './providers/modal-controller';
|
||||
@@ -49,6 +50,10 @@ const DECLARATIONS = [
|
||||
NavDelegate,
|
||||
RouterLinkDelegateDirective,
|
||||
RouterLinkWithHrefDelegateDirective,
|
||||
|
||||
// validators
|
||||
IonMinValidator,
|
||||
IonMaxValidator,
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
@@ -30,6 +30,8 @@ describe('Form', () => {
|
||||
toggle: false,
|
||||
input: '',
|
||||
input2: 'Default Value',
|
||||
inputMin: 1,
|
||||
inputMax: 1,
|
||||
checkbox: false
|
||||
});
|
||||
});
|
||||
@@ -55,6 +57,8 @@ describe('Form', () => {
|
||||
toggle: false,
|
||||
input: 'Some value',
|
||||
input2: 'Default Value',
|
||||
inputMin: 1,
|
||||
inputMax: 1,
|
||||
checkbox: false
|
||||
});
|
||||
});
|
||||
@@ -67,6 +71,8 @@ describe('Form', () => {
|
||||
toggle: true,
|
||||
input: '',
|
||||
input2: 'Default Value',
|
||||
inputMin: 1,
|
||||
inputMax: 1,
|
||||
checkbox: false
|
||||
});
|
||||
});
|
||||
@@ -79,6 +85,8 @@ describe('Form', () => {
|
||||
toggle: false,
|
||||
input: '',
|
||||
input2: 'Default Value',
|
||||
inputMin: 1,
|
||||
inputMax: 1,
|
||||
checkbox: true
|
||||
});
|
||||
});
|
||||
@@ -99,6 +107,8 @@ describe('Form', () => {
|
||||
toggle: true,
|
||||
input: '',
|
||||
input2: 'Default Value',
|
||||
inputMin: 1,
|
||||
inputMax: 1,
|
||||
checkbox: false
|
||||
});
|
||||
cy.get('ion-checkbox').click();
|
||||
@@ -108,10 +118,39 @@ describe('Form', () => {
|
||||
toggle: true,
|
||||
input: '',
|
||||
input2: 'Default Value',
|
||||
inputMin: 1,
|
||||
inputMax: 1,
|
||||
checkbox: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('validators', () => {
|
||||
|
||||
it('ion-input should error with min set', () => {
|
||||
const control = cy.get('form ion-input[formControlName="inputMin"]');
|
||||
|
||||
control.should('have.class', 'ng-valid');
|
||||
|
||||
control.type('{backspace}0');
|
||||
|
||||
control.within(() => cy.get('input').blur());
|
||||
|
||||
control.should('have.class', 'ng-invalid');
|
||||
});
|
||||
|
||||
it('ion-input should error with max set', () => {
|
||||
const control = cy.get('form ion-input[formControlName="inputMax"]');
|
||||
|
||||
control.should('have.class', 'ng-valid');
|
||||
|
||||
control.type('2');
|
||||
control.within(() => cy.get('input').blur());
|
||||
|
||||
control.should('have.class', 'ng-invalid');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
function testStatus(status) {
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
Forms test
|
||||
</ion-title>
|
||||
<ion-title> Forms test </ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
|
||||
<ion-list>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>DateTime</ion-label>
|
||||
<ion-datetime formControlName="datetime" min="1994-03-14" max="2017-12-09" display-format="MM/DD/YYYY">
|
||||
@@ -29,13 +26,16 @@
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-toggle formControlName="toggle">
|
||||
Toggle
|
||||
</ion-toggle>
|
||||
<ion-toggle formControlName="toggle"> Toggle </ion-toggle>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-input label="Input (required)" formControlName="input" class="required" id="touched-input-test"></ion-input>
|
||||
<ion-input
|
||||
label="Input (required)"
|
||||
formControlName="input"
|
||||
class="required"
|
||||
id="touched-input-test"
|
||||
></ion-input>
|
||||
</ion-item>
|
||||
|
||||
<ion-button id="input-touched" (click)="setTouched()">Set Input Touched</ion-button>
|
||||
@@ -45,11 +45,20 @@
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-checkbox formControlName="checkbox">
|
||||
Checkbox
|
||||
</ion-checkbox>
|
||||
<ion-checkbox formControlName="checkbox"> Checkbox </ion-checkbox>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Min</ion-label>
|
||||
<ion-input formControlName="inputMin" type="number"></ion-input>
|
||||
<pre>errors: {{ profileForm.controls['inputMin'].errors | json }}</pre>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Max</ion-label>
|
||||
<ion-input formControlName="inputMax" type="number"></ion-input>
|
||||
<pre>errors: {{ profileForm.controls['inputMax'].errors | json }}</pre>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
<p>
|
||||
Form Status: <span id="status">{{ profileForm.status }}</span>
|
||||
@@ -58,18 +67,15 @@
|
||||
Form value: <span id="data">{{ profileForm.value | json }}</span>
|
||||
</p>
|
||||
<p>
|
||||
Form Submit: <span id="submit">{{submitted}}</span>
|
||||
Form Submit: <span id="submit">{{ submitted }}</span>
|
||||
</p>
|
||||
<ion-button id="mark-all-touched-button" (click)="markAllAsTouched()">Mark all as touched</ion-button>
|
||||
<ion-button id="submit-button" type="submit" [disabled]="!profileForm.valid">Submit</ion-button>
|
||||
|
||||
</form>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-toggle [formControl]="outsideToggle">
|
||||
Outside form
|
||||
</ion-toggle>
|
||||
<ion-note slot="end">{{outsideToggle.value}}</ion-note>
|
||||
<ion-toggle [formControl]="outsideToggle"> Outside form </ion-toggle>
|
||||
<ion-note slot="end">{{ outsideToggle.value }}</ion-note>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
<p>
|
||||
|
||||
@@ -18,6 +18,8 @@ export class FormComponent {
|
||||
toggle: [false],
|
||||
input: ['', Validators.required],
|
||||
input2: ['Default Value'],
|
||||
inputMin: [1, Validators.min(1)],
|
||||
inputMax: [1, Validators.max(1)],
|
||||
checkbox: [false]
|
||||
}, {
|
||||
updateOn: typeof (window as any) !== 'undefined' && window.location.hash === '#blur' ? 'blur' : 'change'
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.3.2](https://github.com/ionic-team/ionic-framework/compare/v7.3.1...v7.3.2) (2023-08-30)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.2.4](https://github.com/ionic-team/ionic-framework/compare/v7.2.3...v7.2.4) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react-router
|
||||
|
||||
54
packages/react-router/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/react-router",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/react-router",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/react": "^7.2.4",
|
||||
"@ionic/react": "^7.3.2",
|
||||
"tslib": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -205,11 +205,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.2.3.tgz",
|
||||
"integrity": "sha512-9ms4JTozhoFzOlgVRozuRcXiyW5YDNlPqJYZx6xVPYPfcRUTIANQ9PZbU/Xqb9RA1xucTSgbKy91nt/hzJIalg==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz",
|
||||
"integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^3.4.0",
|
||||
"@stencil/core": "^4.1.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
@@ -401,11 +401,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/react": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.2.3.tgz",
|
||||
"integrity": "sha512-yynxE2AdTd05wtYT1Cw3Gf2qSGy4VuUDk42M12CEtX00929oFDzbVATNnNqOOD14Kjwb9OUGJWYDzxS/VqqQxg==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.3.1.tgz",
|
||||
"integrity": "sha512-X1n81R85mprFqwqNiISiqrzYWbMJm0chPxJZkVOzFwuWG7fKDKY1vigNvm5eI/lOTbfC2xjJZOYwuHAxHi3BoQ==",
|
||||
"dependencies": {
|
||||
"@ionic/core": "7.2.3",
|
||||
"@ionic/core": "7.3.1",
|
||||
"ionicons": "^7.0.0",
|
||||
"tslib": "*"
|
||||
},
|
||||
@@ -486,15 +486,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/core": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.2.tgz",
|
||||
"integrity": "sha512-FAUhUVaakCy29nU2GwO/HQBRV1ihPRvncz3PUc8oR+UJLAxGabTmP8PLY7wvHfbw+Cvi4VXfJFTBvdfDu6iKPQ==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.10.0",
|
||||
"npm": ">=6.0.0"
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=7.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
@@ -3663,11 +3663,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.2.3.tgz",
|
||||
"integrity": "sha512-9ms4JTozhoFzOlgVRozuRcXiyW5YDNlPqJYZx6xVPYPfcRUTIANQ9PZbU/Xqb9RA1xucTSgbKy91nt/hzJIalg==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz",
|
||||
"integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^3.4.0",
|
||||
"@stencil/core": "^4.1.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
@@ -3786,11 +3786,11 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@ionic/react": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.2.3.tgz",
|
||||
"integrity": "sha512-yynxE2AdTd05wtYT1Cw3Gf2qSGy4VuUDk42M12CEtX00929oFDzbVATNnNqOOD14Kjwb9OUGJWYDzxS/VqqQxg==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.3.1.tgz",
|
||||
"integrity": "sha512-X1n81R85mprFqwqNiISiqrzYWbMJm0chPxJZkVOzFwuWG7fKDKY1vigNvm5eI/lOTbfC2xjJZOYwuHAxHi3BoQ==",
|
||||
"requires": {
|
||||
"@ionic/core": "7.2.3",
|
||||
"@ionic/core": "7.3.1",
|
||||
"ionicons": "^7.0.0",
|
||||
"tslib": "*"
|
||||
}
|
||||
@@ -3844,9 +3844,9 @@
|
||||
}
|
||||
},
|
||||
"@stencil/core": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.2.tgz",
|
||||
"integrity": "sha512-FAUhUVaakCy29nU2GwO/HQBRV1ihPRvncz3PUc8oR+UJLAxGabTmP8PLY7wvHfbw+Cvi4VXfJFTBvdfDu6iKPQ=="
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg=="
|
||||
},
|
||||
"@types/estree": {
|
||||
"version": "0.0.39",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/react-router",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"description": "React Router wrapper for @ionic/react",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -37,7 +37,7 @@
|
||||
"dist/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ionic/react": "^7.2.4",
|
||||
"@ionic/react": "^7.3.2",
|
||||
"tslib": "*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -3,6 +3,33 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.3.2](https://github.com/ionic-team/ionic-framework/compare/v7.3.1...v7.3.2) (2023-08-30)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react:** avoid multiple invocations of onDidDismiss and onWillPresent ([#28020](https://github.com/ionic-team/ionic-framework/issues/28020)) ([0ac3df3](https://github.com/ionic-team/ionic-framework/commit/0ac3df3f378bdefc3a927adc798ebd9ec7a54fee)), closes [#28010](https://github.com/ionic-team/ionic-framework/issues/28010)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.2.4](https://github.com/ionic-team/ionic-framework/compare/v7.2.3...v7.2.4) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react
|
||||
|
||||
38
packages/react/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/react",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/react",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.2.4",
|
||||
"@ionic/core": "^7.3.2",
|
||||
"ionicons": "^7.0.0",
|
||||
"tslib": "*"
|
||||
},
|
||||
@@ -697,25 +697,25 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.2.3.tgz",
|
||||
"integrity": "sha512-9ms4JTozhoFzOlgVRozuRcXiyW5YDNlPqJYZx6xVPYPfcRUTIANQ9PZbU/Xqb9RA1xucTSgbKy91nt/hzJIalg==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz",
|
||||
"integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^3.4.0",
|
||||
"@stencil/core": "^4.1.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core/node_modules/@stencil/core": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.1.tgz",
|
||||
"integrity": "sha512-7rjOmM0W9K5op2gtOQRLERGH1155rv2fm6ppxOzYqqG8ISct4m9skp5XgUBYPu+GSPsJFdRuCIQs0IuVsG/7+g==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.10.0",
|
||||
"npm": ">=6.0.0"
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=7.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/eslint-config": {
|
||||
@@ -11778,19 +11778,19 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.2.3.tgz",
|
||||
"integrity": "sha512-9ms4JTozhoFzOlgVRozuRcXiyW5YDNlPqJYZx6xVPYPfcRUTIANQ9PZbU/Xqb9RA1xucTSgbKy91nt/hzJIalg==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz",
|
||||
"integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^3.4.0",
|
||||
"@stencil/core": "^4.1.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@stencil/core": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.1.tgz",
|
||||
"integrity": "sha512-7rjOmM0W9K5op2gtOQRLERGH1155rv2fm6ppxOzYqqG8ISct4m9skp5XgUBYPu+GSPsJFdRuCIQs0IuVsG/7+g=="
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/react",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"description": "React specific wrapper for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -41,7 +41,7 @@
|
||||
"css/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ionic/core": "^7.2.4",
|
||||
"@ionic/core": "^7.3.2",
|
||||
"ionicons": "^7.0.0",
|
||||
"tslib": "*"
|
||||
},
|
||||
|
||||
@@ -2,8 +2,11 @@
|
||||
|
||||
set -e
|
||||
|
||||
# Copy core dist
|
||||
rm -rf node_modules/@ionic/core/dist node_modules/@ionic/core/components
|
||||
cp -a ../../core/dist node_modules/@ionic/core/dist
|
||||
cp -a ../../core/components node_modules/@ionic/core/components
|
||||
cp -a ../../core/package.json node_modules/@ionic/core/package.json
|
||||
# Delete old packages
|
||||
rm -f *.tgz
|
||||
|
||||
# Pack @ionic/core
|
||||
npm pack ../../core
|
||||
|
||||
# Install Dependencies
|
||||
npm install *.tgz --no-save
|
||||
|
||||
@@ -63,7 +63,14 @@ export const createInlineOverlayComponent = <PropType, ElementType>(
|
||||
|
||||
componentDidUpdate(prevProps: IonicReactInternalProps<PropType>) {
|
||||
const node = this.ref.current! as HTMLElement;
|
||||
attachProps(node, this.props, prevProps);
|
||||
/**
|
||||
* onDidDismiss and onWillPresent have manual implementations that
|
||||
* will invoke the original handler. We need to filter those out
|
||||
* so they don't get attached twice and called twice.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { onDidDismiss, onWillPresent, ...cProps } = this.props;
|
||||
attachProps(node, cProps, prevProps);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import React from 'react';
|
||||
import { IonButton, IonContent, IonPage, IonActionSheet } from '@ionic/react';
|
||||
import { useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const ActionSheetComponent: React.FC = () => {
|
||||
const [message, setMessage] = useState('');
|
||||
const [show, setShow] = useState(false);
|
||||
const [willPresentCount, setWillPresentCount] = useState(0);
|
||||
const [didDismissCount, setDidDismissCount] = useState(0);
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
@@ -26,7 +27,13 @@ const ActionSheetComponent: React.FC = () => {
|
||||
},
|
||||
]}
|
||||
header="Action Sheet"
|
||||
onDidDismiss={() => setShow(false)}
|
||||
onWillPresent={() => {
|
||||
setWillPresentCount(willPresentCount + 1);
|
||||
}}
|
||||
onDidDismiss={() => {
|
||||
setDidDismissCount(didDismissCount + 1);
|
||||
setShow(false);
|
||||
}}
|
||||
/>
|
||||
<IonButton expand="block" onClick={() => setShow(true)}>
|
||||
Show ActionSheet
|
||||
@@ -41,6 +48,8 @@ const ActionSheetComponent: React.FC = () => {
|
||||
Show ActionSheet, hide after 250 mss
|
||||
</IonButton>
|
||||
<div>{message}</div>
|
||||
<div>onWillPresent count: {willPresentCount}</div>
|
||||
<div>onDidDismiss count: {didDismissCount}</div>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
|
||||
@@ -17,11 +17,19 @@ describe('IonActionSheet', () => {
|
||||
});
|
||||
|
||||
it('display action and call dismiss to close it', () => {
|
||||
//show action sheet
|
||||
cy.get('ion-content').contains('onWillPresent count: 0');
|
||||
cy.get('ion-content').contains('onDidDismiss count: 0');
|
||||
|
||||
// show action sheet
|
||||
cy.get('ion-button').contains('Show ActionSheet, hide after 250 ms').click();
|
||||
cy.get('ion-action-sheet').contains('Action Sheet');
|
||||
|
||||
//verify action sheet is hidden
|
||||
// verify action sheet is hidden
|
||||
cy.get('ion-action-sheet').should('not.be.visible');
|
||||
|
||||
// verify lifecycle events are called once
|
||||
cy.get('ion-content').contains('onWillPresent count: 1');
|
||||
cy.get('ion-content').contains('onDidDismiss count: 0');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.3.2](https://github.com/ionic-team/ionic-framework/compare/v7.3.1...v7.3.2) (2023-08-30)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.2.4](https://github.com/ionic-team/ionic-framework/compare/v7.2.3...v7.2.4) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue-router
|
||||
|
||||
66
packages/vue-router/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/vue-router",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/vue-router",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/vue": "^7.2.4"
|
||||
"@ionic/vue": "^7.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ionic/eslint-config": "^0.3.0",
|
||||
@@ -660,11 +660,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.2.3.tgz",
|
||||
"integrity": "sha512-9ms4JTozhoFzOlgVRozuRcXiyW5YDNlPqJYZx6xVPYPfcRUTIANQ9PZbU/Xqb9RA1xucTSgbKy91nt/hzJIalg==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz",
|
||||
"integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^3.4.0",
|
||||
"@stencil/core": "^4.1.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
@@ -871,11 +871,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/vue": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.2.3.tgz",
|
||||
"integrity": "sha512-LZBIoPOG/XeJS90pwR2Z7qIwsgyOQ8/nFMywj+SimRmgVaTO7h+ow4aAmbVEWH+DiOdlvtCsoZzJZGv+wy3EkA==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.3.1.tgz",
|
||||
"integrity": "sha512-URxNXLYo4gh0riQlHiCoGDo7GqEqbVJi/1gMamM3tGBQHCMNZdm9IDfIDYjHY4L3dVi5pF+szl/b4p2lsIV3hw==",
|
||||
"dependencies": {
|
||||
"@ionic/core": "7.2.3",
|
||||
"@ionic/core": "7.3.1",
|
||||
"ionicons": "^7.0.0"
|
||||
}
|
||||
},
|
||||
@@ -1323,15 +1323,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/core": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.2.tgz",
|
||||
"integrity": "sha512-FAUhUVaakCy29nU2GwO/HQBRV1ihPRvncz3PUc8oR+UJLAxGabTmP8PLY7wvHfbw+Cvi4VXfJFTBvdfDu6iKPQ==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.10.0",
|
||||
"npm": ">=6.0.0"
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=7.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tootallnate/once": {
|
||||
@@ -6807,9 +6807,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz",
|
||||
"integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig=="
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/tsutils": {
|
||||
"version": "3.21.0",
|
||||
@@ -7697,11 +7697,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.2.3.tgz",
|
||||
"integrity": "sha512-9ms4JTozhoFzOlgVRozuRcXiyW5YDNlPqJYZx6xVPYPfcRUTIANQ9PZbU/Xqb9RA1xucTSgbKy91nt/hzJIalg==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.3.1.tgz",
|
||||
"integrity": "sha512-RdSJsFYx2oJ08duw+DMWVAfzjxlnA+o1saX5gOLSjP5SpwP7FqURFfXrFHIFN2vIKbeqUZTZjQwPHnrFsX04dQ==",
|
||||
"requires": {
|
||||
"@stencil/core": "^3.4.0",
|
||||
"@stencil/core": "^4.1.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
@@ -7829,11 +7829,11 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@ionic/vue": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.2.3.tgz",
|
||||
"integrity": "sha512-LZBIoPOG/XeJS90pwR2Z7qIwsgyOQ8/nFMywj+SimRmgVaTO7h+ow4aAmbVEWH+DiOdlvtCsoZzJZGv+wy3EkA==",
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-7.3.1.tgz",
|
||||
"integrity": "sha512-URxNXLYo4gh0riQlHiCoGDo7GqEqbVJi/1gMamM3tGBQHCMNZdm9IDfIDYjHY4L3dVi5pF+szl/b4p2lsIV3hw==",
|
||||
"requires": {
|
||||
"@ionic/core": "7.2.3",
|
||||
"@ionic/core": "7.3.1",
|
||||
"ionicons": "^7.0.0"
|
||||
}
|
||||
},
|
||||
@@ -8192,9 +8192,9 @@
|
||||
}
|
||||
},
|
||||
"@stencil/core": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.2.tgz",
|
||||
"integrity": "sha512-FAUhUVaakCy29nU2GwO/HQBRV1ihPRvncz3PUc8oR+UJLAxGabTmP8PLY7wvHfbw+Cvi4VXfJFTBvdfDu6iKPQ=="
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg=="
|
||||
},
|
||||
"@tootallnate/once": {
|
||||
"version": "2.0.0",
|
||||
@@ -12220,9 +12220,9 @@
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz",
|
||||
"integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig=="
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"tsutils": {
|
||||
"version": "3.21.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/vue-router",
|
||||
"version": "7.2.4",
|
||||
"version": "7.3.2",
|
||||
"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.2.4"
|
||||
"@ionic/vue": "^7.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ionic/eslint-config": "^0.3.0",
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.3.2](https://github.com/ionic-team/ionic-framework/compare/v7.3.1...v7.3.2) (2023-08-30)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.2.4](https://github.com/ionic-team/ionic-framework/compare/v7.2.3...v7.2.4) (2023-08-16)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue
|
||||
|
||||