Compare commits
12 Commits
sp/react-r
...
FW-4949
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a08a07cbab | ||
|
|
c2bcdcbec3 | ||
|
|
f02aff87af | ||
|
|
2af3702b3e | ||
|
|
783a653071 | ||
|
|
954baf3bef | ||
|
|
48b4cc36b8 | ||
|
|
3cef069078 | ||
|
|
82f8ca8dd1 | ||
|
|
6f276099fc | ||
|
|
f295b35671 | ||
|
|
1a9714783f |
@@ -14,6 +14,6 @@ runs:
|
||||
with:
|
||||
name: ${{ inputs.name }}
|
||||
path: ${{ inputs.path }}
|
||||
- name: Extract Archive
|
||||
- name: Exract Archive
|
||||
run: unzip -q -o ${{ inputs.path }}/${{ inputs.filename }}
|
||||
shell: bash
|
||||
|
||||
@@ -13,15 +13,6 @@ runs:
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- name: Check Diff
|
||||
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
|
||||
}
|
||||
run: git diff --exit-code
|
||||
shell: bash
|
||||
working-directory: ./core
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
name: 'Test Core Spec'
|
||||
description: 'Test Core Spec'
|
||||
inputs:
|
||||
stencil-version:
|
||||
description: 'The NPM tag of @stencil/core to install.'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
@@ -10,14 +7,9 @@ runs:
|
||||
with:
|
||||
node-version: 16.x
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
run: npm install
|
||||
working-directory: ./core
|
||||
shell: bash
|
||||
- name: Install Stencil ${{ inputs.stencil-version }}
|
||||
run: npm install @stencil/core@${{ inputs.stencil-version }}
|
||||
shell: bash
|
||||
working-directory: ./core
|
||||
if: ${{ inputs.stencil-version != '' }}
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
|
||||
2
.github/workflows/stencil-nightly.yml
vendored
@@ -46,8 +46,6 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-core-spec
|
||||
with:
|
||||
stencil-version: nightly
|
||||
|
||||
test-core-screenshot:
|
||||
strategy:
|
||||
|
||||
44
CHANGELOG.md
@@ -3,50 +3,6 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** ionTabsWillChange is fired before tab activation ([#27991](https://github.com/ionic-team/ionic-framework/issues/27991)) ([bbfb8f8](https://github.com/ionic-team/ionic-framework/commit/bbfb8f81a61475d7e73b63743db5d6a0cd979d21)), closes [#27212](https://github.com/ionic-team/ionic-framework/issues/27212)
|
||||
* **input, textarea:** clearOnEdit does not clear when pressing Tab ([#28005](https://github.com/ionic-team/ionic-framework/issues/28005)) ([444acc1](https://github.com/ionic-team/ionic-framework/commit/444acc1f1bca348b62dfb398067cc087529f67f1)), closes [#27746](https://github.com/ionic-team/ionic-framework/issues/27746)
|
||||
* **react:** avoid multiple invocations of onDidDismiss and onWillPresent ([#28020](https://github.com/ionic-team/ionic-framework/issues/28020)) ([0ac3df3](https://github.com/ionic-team/ionic-framework/commit/0ac3df3f378bdefc3a927adc798ebd9ec7a54fee)), closes [#28010](https://github.com/ionic-team/ionic-framework/issues/28010)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
|
||||
|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **tap-click:** do not error in document-less environment ([#27972](https://github.com/ionic-team/ionic-framework/issues/27972)) ([28bd4ba](https://github.com/ionic-team/ionic-framework/commit/28bd4ba720bb77d5f5c48cd7a45e0015daddc9dd))
|
||||
* **title:** large title aligns with ios spec ([#27969](https://github.com/ionic-team/ionic-framework/issues/27969)) ([8fa12fc](https://github.com/ionic-team/ionic-framework/commit/8fa12fc88857df27a1ca11249f0085e100fe1474)), closes [#27966](https://github.com/ionic-team/ionic-framework/issues/27966)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.2.3](https://github.com/ionic-team/ionic-framework/compare/v7.2.2...v7.2.3) (2023-08-09)
|
||||
|
||||
|
||||
|
||||
@@ -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`](packages/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`](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,48 +3,6 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **input, textarea:** clearOnEdit does not clear when pressing Tab ([#28005](https://github.com/ionic-team/ionic-framework/issues/28005)) ([444acc1](https://github.com/ionic-team/ionic-framework/commit/444acc1f1bca348b62dfb398067cc087529f67f1)), closes [#27746](https://github.com/ionic-team/ionic-framework/issues/27746)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
|
||||
|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **tap-click:** do not error in document-less environment ([#27972](https://github.com/ionic-team/ionic-framework/issues/27972)) ([28bd4ba](https://github.com/ionic-team/ionic-framework/commit/28bd4ba720bb77d5f5c48cd7a45e0015daddc9dd))
|
||||
* **title:** large title aligns with ios spec ([#27969](https://github.com/ionic-team/ionic-framework/issues/27969)) ([8fa12fc](https://github.com/ionic-team/ionic-framework/commit/8fa12fc88857df27a1ca11249f0085e100fe1474)), closes [#27966](https://github.com/ionic-team/ionic-framework/issues/27966)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.2.3](https://github.com/ionic-team/ionic-framework/compare/v7.2.2...v7.2.3) (2023-08-09)
|
||||
|
||||
|
||||
|
||||
@@ -1471,7 +1471,6 @@ 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.3.1",
|
||||
"version": "7.2.3",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/core",
|
||||
"version": "7.3.1",
|
||||
"version": "7.2.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^4.1.0",
|
||||
"@stencil/core": "^3.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@axe-core/playwright": "^4.7.3",
|
||||
"@capacitor/core": "^5.3.0",
|
||||
"@capacitor/core": "^5.2.2",
|
||||
"@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.1",
|
||||
"@playwright/test": "^1.36.2",
|
||||
"@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.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.3.0.tgz",
|
||||
"integrity": "sha512-mvhh1yJtcUTZ0hUUriBKKpxq47hn75bjxH3tYPRgAFu1z3gowCg+OtG4Rce3W5gr5fSfCjQgOSL0Vp7k9hPUWw==",
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.2.2.tgz",
|
||||
"integrity": "sha512-3jKECZC5+YD2rljMZm1e/K3AYyoxUmLDZCyofTPbRYPBSI0wJh5ZCkX+XIGzNM0o/Wokl3Voa1JB8xsLC0MPxA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
@@ -1541,13 +1541,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.37.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz",
|
||||
"integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==",
|
||||
"version": "1.36.2",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.36.2.tgz",
|
||||
"integrity": "sha512-2rVZeyPRjxfPH6J0oGJqE8YxiM1IBRyM8hyrXYK7eSiAqmbNhxwcLa7dZ7fy9Kj26V7FYia5fh9XJRq4Dqme+g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"playwright-core": "1.37.1"
|
||||
"playwright-core": "1.36.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
@@ -1634,15 +1634,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/core": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg==",
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.0.tgz",
|
||||
"integrity": "sha512-kEtPtV6QegME8YgMjWrhS7KktItbhqOpAuK9aXypDdI/7bLU9iM/4DtnQGWY/DARBophk+XRBfNXcE62Bmi0dw==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=7.10.0"
|
||||
"node": ">=14.10.0",
|
||||
"npm": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/react-output-target": {
|
||||
@@ -8194,9 +8194,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.37.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz",
|
||||
"integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==",
|
||||
"version": "1.36.2",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.36.2.tgz",
|
||||
"integrity": "sha512-sQYZt31dwkqxOrP7xy2ggDfEzUxM1lodjhsQ3NMMv5uGTRDsLxU0e4xf4wwMkF2gplIxf17QMBCodSFgm6bFVQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
@@ -10788,9 +10788,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@capacitor/core": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.3.0.tgz",
|
||||
"integrity": "sha512-mvhh1yJtcUTZ0hUUriBKKpxq47hn75bjxH3tYPRgAFu1z3gowCg+OtG4Rce3W5gr5fSfCjQgOSL0Vp7k9hPUWw==",
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.2.2.tgz",
|
||||
"integrity": "sha512-3jKECZC5+YD2rljMZm1e/K3AYyoxUmLDZCyofTPbRYPBSI0wJh5ZCkX+XIGzNM0o/Wokl3Voa1JB8xsLC0MPxA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "^2.1.0"
|
||||
@@ -11455,14 +11455,14 @@
|
||||
}
|
||||
},
|
||||
"@playwright/test": {
|
||||
"version": "1.37.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz",
|
||||
"integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==",
|
||||
"version": "1.36.2",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.36.2.tgz",
|
||||
"integrity": "sha512-2rVZeyPRjxfPH6J0oGJqE8YxiM1IBRyM8hyrXYK7eSiAqmbNhxwcLa7dZ7fy9Kj26V7FYia5fh9XJRq4Dqme+g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"fsevents": "2.3.2",
|
||||
"playwright-core": "1.37.1"
|
||||
"playwright-core": "1.36.2"
|
||||
}
|
||||
},
|
||||
"@rollup/plugin-node-resolve": {
|
||||
@@ -11524,9 +11524,9 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@stencil/core": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-yIpL+CX02fy5zvFXwXcHZjjEILRm3aiONbucpfLIWPS7zcBAuucdROssartEa+D7E1JRko97ydxn1Ntdu4GoWg=="
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-3.4.0.tgz",
|
||||
"integrity": "sha512-kEtPtV6QegME8YgMjWrhS7KktItbhqOpAuK9aXypDdI/7bLU9iM/4DtnQGWY/DARBophk+XRBfNXcE62Bmi0dw=="
|
||||
},
|
||||
"@stencil/react-output-target": {
|
||||
"version": "0.5.3",
|
||||
@@ -16332,9 +16332,9 @@
|
||||
}
|
||||
},
|
||||
"playwright-core": {
|
||||
"version": "1.37.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz",
|
||||
"integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==",
|
||||
"version": "1.36.2",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.36.2.tgz",
|
||||
"integrity": "sha512-sQYZt31dwkqxOrP7xy2ggDfEzUxM1lodjhsQ3NMMv5uGTRDsLxU0e4xf4wwMkF2gplIxf17QMBCodSFgm6bFVQ==",
|
||||
"dev": true
|
||||
},
|
||||
"postcss": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "7.3.1",
|
||||
"version": "7.2.3",
|
||||
"description": "Base components for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -31,20 +31,20 @@
|
||||
"loader/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@stencil/core": "^4.1.0",
|
||||
"@stencil/core": "^3.4.0",
|
||||
"ionicons": "7.1.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@axe-core/playwright": "^4.7.3",
|
||||
"@capacitor/core": "^5.3.0",
|
||||
"@capacitor/core": "^5.2.2",
|
||||
"@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.1",
|
||||
"@playwright/test": "^1.36.2",
|
||||
"@rollup/plugin-node-resolve": "^8.4.0",
|
||||
"@rollup/plugin-virtual": "^2.0.3",
|
||||
"@stencil/angular-output-target": "^0.7.1",
|
||||
|
||||
12
core/src/components.d.ts
vendored
@@ -819,7 +819,7 @@ export namespace Components {
|
||||
}
|
||||
interface IonDatetime {
|
||||
/**
|
||||
* Emits the ionCancel event and optionally closes the popover or modal that the datetime was presented in.
|
||||
* The cancel method performs the following actions: 1. Emits the ionCancel event 2. Resets the internal state of the datetime 3. Closes the parent popover or modal if "closeOverlay" is true.
|
||||
*/
|
||||
"cancel": (closeOverlay?: boolean) => Promise<void>;
|
||||
/**
|
||||
@@ -915,15 +915,15 @@ export namespace Components {
|
||||
*/
|
||||
"readonly": boolean;
|
||||
/**
|
||||
* Resets the internal state of the datetime but does not update the value. Passing a valid ISO-8601 string will reset the state of the component to the provided date. If no value is provided, the internal state will be reset to the clamped value of the min, max and today.
|
||||
* Resets the internal state of the datetime but does not update the value property. Passing a valid ISO-8601 string will reset the state of the component to the provided date. If no date string was passed but the value property is set, then the internal state of datetime will be reset to that value. Otherwise, the internal state will be reset to the clamped value of the min, max and today.
|
||||
*/
|
||||
"reset": (startDate?: string) => Promise<void>;
|
||||
/**
|
||||
* If `true`, a "Clear" button will be rendered alongside the default "Cancel" and "OK" buttons at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered.
|
||||
* If `true`, a "Clear" button will be rendered alongside the default "Cancel" and "OK" buttons at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered. Pressing the "Clear" button will call the "reset" method.
|
||||
*/
|
||||
"showClearButton": boolean;
|
||||
/**
|
||||
* If `true`, the default "Cancel" and "OK" buttons will be rendered at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered.
|
||||
* If `true`, the default "Cancel" and "OK" buttons will be rendered at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered. Pressing the "Cancel" button will call the "cancel" method. Pressing the "OK" button will the "confirm" method.
|
||||
*/
|
||||
"showDefaultButtons": boolean;
|
||||
/**
|
||||
@@ -4954,11 +4954,11 @@ declare namespace LocalJSX {
|
||||
*/
|
||||
"readonly"?: boolean;
|
||||
/**
|
||||
* If `true`, a "Clear" button will be rendered alongside the default "Cancel" and "OK" buttons at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered.
|
||||
* If `true`, a "Clear" button will be rendered alongside the default "Cancel" and "OK" buttons at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered. Pressing the "Clear" button will call the "reset" method.
|
||||
*/
|
||||
"showClearButton"?: boolean;
|
||||
/**
|
||||
* If `true`, the default "Cancel" and "OK" buttons will be rendered at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered.
|
||||
* If `true`, the default "Cancel" and "OK" buttons will be rendered at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered. Pressing the "Cancel" button will call the "cancel" method. Pressing the "OK" button will the "confirm" method.
|
||||
*/
|
||||
"showDefaultButtons"?: boolean;
|
||||
/**
|
||||
|
||||
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
@@ -23,7 +23,6 @@ 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,13 +394,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
|
||||
</div>
|
||||
)}
|
||||
{buttons.map((b) => (
|
||||
<button
|
||||
{...b.htmlAttributes}
|
||||
type="button"
|
||||
id={b.id}
|
||||
class={buttonClass(b)}
|
||||
onClick={() => this.buttonClick(b)}
|
||||
>
|
||||
<button 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}
|
||||
@@ -412,12 +406,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
|
||||
|
||||
{cancelButton && (
|
||||
<div class="action-sheet-group action-sheet-group-cancel">
|
||||
<button
|
||||
{...cancelButton.htmlAttributes}
|
||||
type="button"
|
||||
class={buttonClass(cancelButton)}
|
||||
onClick={() => this.buttonClick(cancelButton)}
|
||||
>
|
||||
<button 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,36 +10,16 @@ const testAria = async (page: E2EPage, buttonID: string, expectedAriaLabelledBy:
|
||||
await button.click();
|
||||
await didPresent.next();
|
||||
|
||||
const actionSheet = page.locator('ion-action-sheet');
|
||||
const alert = 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 actionSheet.getAttribute('aria-labelledby');
|
||||
const ariaLabelledBy = await alert.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 }) => {
|
||||
@@ -72,17 +52,5 @@ 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,10 +23,6 @@
|
||||
<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>
|
||||
@@ -67,39 +63,6 @@
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
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,7 +48,6 @@ 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 {
|
||||
min-height: $alert-ios-tappable-height;
|
||||
height: $alert-ios-tappable-height;
|
||||
}
|
||||
|
||||
|
||||
@@ -137,6 +137,12 @@
|
||||
order: 0;
|
||||
|
||||
color: $alert-ios-radio-label-text-color;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
@@ -190,6 +196,12 @@
|
||||
flex: 1;
|
||||
|
||||
color: $alert-ios-checkbox-label-text-color;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// iOS Alert Checkbox Outer Circle: Unchecked
|
||||
|
||||
@@ -113,7 +113,9 @@
|
||||
.alert-tappable {
|
||||
position: relative;
|
||||
|
||||
min-height: $alert-md-tappable-height;
|
||||
height: $alert-md-tappable-height;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
@@ -128,6 +130,12 @@
|
||||
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
|
||||
@@ -195,6 +203,12 @@
|
||||
color: $alert-md-checkbox-label-text-color;
|
||||
|
||||
font-size: $alert-md-checkbox-label-font-size;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -152,8 +152,6 @@
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
min-height: inherit;
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +184,7 @@
|
||||
text-align: start;
|
||||
appearance: none;
|
||||
|
||||
contain: content;
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.alert-button,
|
||||
|
||||
@@ -673,7 +673,6 @@ export class Alert implements ComponentInterface, OverlayInterface {
|
||||
<div class={alertButtonGroupClass}>
|
||||
{buttons.map((button) => (
|
||||
<button
|
||||
{...button.htmlAttributes}
|
||||
type="button"
|
||||
id={button.id}
|
||||
class={buttonClass(button)}
|
||||
|
||||
@@ -60,21 +60,5 @@ 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,7 +24,6 @@
|
||||
<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>
|
||||
@@ -77,23 +76,6 @@
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
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: 38 KiB After Width: | Height: | Size: 37 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: 38 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 45 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: 34 KiB After Width: | Height: | Size: 31 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: 34 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
@@ -246,12 +246,17 @@
|
||||
type: 'radio',
|
||||
label: 'Radio 4',
|
||||
value: 'value4',
|
||||
},
|
||||
{
|
||||
type: 'radio',
|
||||
label: 'Radio 5',
|
||||
value: 'value5',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
type: 'radio',
|
||||
label: 'Radio 5 Radio 5 Radio 5 Radio 5 Radio 5 Radio 5 Radio 5 Radio 5 Radio 5 Radio 5 ',
|
||||
value: 'value5',
|
||||
label: 'Radio 6 Radio 6 Radio 6 Radio 6 Radio 6 Radio 6 Radio 6 Radio 6 Radio 6 Radio 6 ',
|
||||
value: 'value6',
|
||||
},
|
||||
],
|
||||
buttons: [
|
||||
@@ -300,13 +305,20 @@
|
||||
type: 'checkbox',
|
||||
label: 'Checkbox 4',
|
||||
value: 'value4',
|
||||
},
|
||||
|
||||
{
|
||||
type: 'checkbox',
|
||||
label: 'Checkbox 5',
|
||||
value: 'value5',
|
||||
disabled: true,
|
||||
},
|
||||
|
||||
{
|
||||
type: 'checkbox',
|
||||
label:
|
||||
'Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5 Checkbox 5',
|
||||
value: 'value5',
|
||||
'Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6 Checkbox 6',
|
||||
value: 'value6',
|
||||
},
|
||||
],
|
||||
buttons: [
|
||||
|
||||
@@ -153,15 +153,6 @@ 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) {
|
||||
@@ -332,13 +323,6 @@ 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();
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 16 KiB |
@@ -424,6 +424,9 @@ export class Datetime implements ComponentInterface {
|
||||
* if they want to customize these buttons. If custom
|
||||
* buttons are set in the `button` slot then the
|
||||
* default buttons will not be rendered.
|
||||
*
|
||||
* Pressing the "Cancel" button will call the "cancel" method.
|
||||
* Pressing the "OK" button will the "confirm" method.
|
||||
*/
|
||||
@Prop() showDefaultButtons = false;
|
||||
|
||||
@@ -434,6 +437,8 @@ export class Datetime implements ComponentInterface {
|
||||
* if they want to customize these buttons. If custom
|
||||
* buttons are set in the `button` slot then the
|
||||
* default buttons will not be rendered.
|
||||
*
|
||||
* Pressing the "Clear" button will call the "reset" method.
|
||||
*/
|
||||
@Prop() showClearButton = false;
|
||||
|
||||
@@ -540,25 +545,29 @@ export class Datetime implements ComponentInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the internal state of the datetime but does not update the value.
|
||||
* Resets the internal state of the datetime but does not update the value property.
|
||||
* Passing a valid ISO-8601 string will reset the state of the component to the provided date.
|
||||
* If no value is provided, the internal state will be reset to the clamped value of the min, max and today.
|
||||
* If no date string was passed but the value property is set, then the internal state of
|
||||
* datetime will be reset to that value. Otherwise, the internal state will be reset to the
|
||||
* clamped value of the min, max and today.
|
||||
*/
|
||||
@Method()
|
||||
async reset(startDate?: string) {
|
||||
this.processValue(startDate);
|
||||
this.processValue(startDate ?? this.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits the ionCancel event and
|
||||
* optionally closes the popover
|
||||
* or modal that the datetime was
|
||||
* presented in.
|
||||
* The cancel method performs the following actions:
|
||||
* 1. Emits the ionCancel event
|
||||
* 2. Resets the internal state of the datetime
|
||||
* 3. Closes the parent popover or modal if "closeOverlay" is true.
|
||||
*/
|
||||
@Method()
|
||||
async cancel(closeOverlay = false) {
|
||||
this.ionCancel.emit();
|
||||
|
||||
this.reset();
|
||||
|
||||
if (closeOverlay) {
|
||||
this.closeParentOverlay();
|
||||
}
|
||||
@@ -1376,11 +1385,6 @@ export class Datetime implements ComponentInterface {
|
||||
return;
|
||||
}
|
||||
|
||||
const clearButtonClick = () => {
|
||||
this.reset();
|
||||
this.setValue(undefined);
|
||||
};
|
||||
|
||||
/**
|
||||
* By default we render two buttons:
|
||||
* Cancel - Dismisses the datetime and
|
||||
@@ -1406,7 +1410,7 @@ export class Datetime implements ComponentInterface {
|
||||
)}
|
||||
<div>
|
||||
{showClearButton && (
|
||||
<ion-button id="clear-button" color={this.color} onClick={() => clearButtonClick()}>
|
||||
<ion-button id="clear-button" color={this.color} onClick={() => this.reset()}>
|
||||
{this.clearText}
|
||||
</ion-button>
|
||||
)}
|
||||
|
||||
@@ -380,40 +380,6 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* This behavior does not differ across
|
||||
* modes/directions.
|
||||
*/
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('datetime: clear button'), () => {
|
||||
test('should clear the active calendar day', async ({ page }, testInfo) => {
|
||||
testInfo.annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/ionic-team/ionic-framework/issues/26258',
|
||||
});
|
||||
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-datetime value="2022-11-10" show-clear-button="true"></ion-datetime>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const selectedDay = page.locator('ion-datetime .calendar-day-active');
|
||||
|
||||
await expect(selectedDay).toHaveText('10');
|
||||
|
||||
await page.click('ion-datetime #clear-button');
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(selectedDay).toHaveCount(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* This behavior does not differ across
|
||||
* modes/directions.
|
||||
|
||||
75
core/src/components/datetime/test/cancel/datetime.e2e.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('datetime: cancel method'), () => {
|
||||
test('should emit ionCancel', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-datetime></ion-datetime>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const ionCancel = await page.spyOnEvent('ionCancel');
|
||||
const datetime = page.locator('ion-datetime');
|
||||
|
||||
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.cancel());
|
||||
|
||||
await ionCancel.next();
|
||||
});
|
||||
|
||||
test('parent overlay should be dismissed when true is passed', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-modal>
|
||||
<ion-datetime></ion-datetime>
|
||||
</ion-modal>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
const datetime = page.locator('ion-datetime');
|
||||
const modal = page.locator('ion-modal');
|
||||
|
||||
await modal.evaluate((el: HTMLIonModalElement) => el.present());
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.cancel(true));
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
|
||||
test('should reset the internal state of datetime', async ({ page }, testInfo) => {
|
||||
testInfo.annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/ionic-team/ionic-framework/issues/27975',
|
||||
});
|
||||
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-datetime value="2023-06-06T16:30" show-default-buttons="true"></ion-datetime>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const datetime = page.locator('ion-datetime');
|
||||
|
||||
const dayOne = datetime.locator('.calendar-day[data-month="6"][data-day="1"][data-year="2023"]');
|
||||
const daySix = datetime.locator('.calendar-day[data-month="6"][data-day="6"][data-year="2023"]');
|
||||
await dayOne.click();
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(dayOne).toHaveClass(/calendar-day-active/);
|
||||
|
||||
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.cancel());
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(daySix).toHaveClass(/calendar-day-active/);
|
||||
});
|
||||
});
|
||||
});
|
||||
100
core/src/components/datetime/test/reset/datetime.e2e.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('datetime: reset method'), () => {
|
||||
test('should reset the internal state of datetime to the set value', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-datetime value="2023-06-06T16:30" show-default-buttons="true"></ion-datetime>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const datetime = page.locator('ion-datetime');
|
||||
|
||||
const dayOne = datetime.locator('.calendar-day[data-month="6"][data-day="1"][data-year="2023"]');
|
||||
const daySix = datetime.locator('.calendar-day[data-month="6"][data-day="6"][data-year="2023"]');
|
||||
await dayOne.click();
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(dayOne).toHaveClass(/calendar-day-active/);
|
||||
|
||||
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.reset());
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(daySix).toHaveClass(/calendar-day-active/);
|
||||
});
|
||||
|
||||
test('should reset the internal state of datetime to the provided value', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-datetime show-default-buttons="true"></ion-datetime>
|
||||
|
||||
<script>
|
||||
const mockToday = '2023-06-12T16:22';
|
||||
Date = class extends Date {
|
||||
constructor(...args) {
|
||||
if (args.length === 0) {
|
||||
super(mockToday)
|
||||
} else {
|
||||
super(...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const datetime = page.locator('ion-datetime');
|
||||
|
||||
const dayOne = datetime.locator('.calendar-day[data-month="6"][data-day="1"][data-year="2023"]');
|
||||
const daySix = datetime.locator('.calendar-day[data-month="6"][data-day="6"][data-year="2023"]');
|
||||
await dayOne.click();
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(dayOne).toHaveClass(/calendar-day-active/);
|
||||
|
||||
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.reset('2023-06-06T16:30'));
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(daySix).toHaveClass(/calendar-day-active/);
|
||||
});
|
||||
|
||||
test('should reset the internal state of datetime to today when value is set or passed', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-datetime show-default-buttons="true"></ion-datetime>
|
||||
|
||||
<script>
|
||||
const mockToday = '2023-06-06T16:22';
|
||||
Date = class extends Date {
|
||||
constructor(...args) {
|
||||
if (args.length === 0) {
|
||||
super(mockToday)
|
||||
} else {
|
||||
super(...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const datetime = page.locator('ion-datetime');
|
||||
|
||||
const dayOne = datetime.locator('.calendar-day[data-month="6"][data-day="1"][data-year="2023"]');
|
||||
await dayOne.click();
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(dayOne).toHaveClass(/calendar-day-active/);
|
||||
|
||||
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.reset());
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(await datetime.locator('.calendar-day-active').count()).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -51,7 +51,7 @@
|
||||
}
|
||||
|
||||
.header-collapse-condense ion-toolbar:first-of-type {
|
||||
padding-top: 1px;
|
||||
padding-top: 7px;
|
||||
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
@@ -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' && ev.key !== 'Tab') {
|
||||
if (!this.didInputClearOnEdit && this.hasValue() && ev.key !== 'Enter') {
|
||||
this.value = '';
|
||||
this.emitInputChange(ev);
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
<!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>
|
||||
@@ -1,43 +0,0 @@
|
||||
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');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -3,6 +3,7 @@ import { configs, dragElementBy, test } from '@utils/test/playwright';
|
||||
|
||||
import { testSlidingItem } from '../test.utils';
|
||||
|
||||
// TODO FW-3006
|
||||
/**
|
||||
* item-sliding doesn't have mode-specific styling
|
||||
*/
|
||||
@@ -17,12 +18,19 @@ configs({ modes: ['md'] }).forEach(({ title, screenshot, config }) => {
|
||||
});
|
||||
});
|
||||
|
||||
// TODO FW-3006
|
||||
/**
|
||||
* This behavior does not vary across modes/directions
|
||||
*/
|
||||
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('item-sliding: basic'), () => {
|
||||
test('should open when swiped', async ({ page }) => {
|
||||
// mouse gesture is flaky on CI, skip for now
|
||||
test.fixme('should open when swiped', async ({ page, skip }) => {
|
||||
skip.browser(
|
||||
(browserName: string) => browserName !== 'chromium',
|
||||
'dragElementBy is flaky outside of Chrome browsers.'
|
||||
);
|
||||
|
||||
await page.goto(`/src/components/item-sliding/test/basic`, config);
|
||||
const item = page.locator('#item2');
|
||||
|
||||
@@ -33,7 +41,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
|
||||
await expect(item).toHaveScreenshot(screenshot(`item-sliding-gesture`));
|
||||
});
|
||||
|
||||
test('should not scroll when the item-sliding is swiped', async ({ page, skip }) => {
|
||||
test.skip('should not scroll when the item-sliding is swiped', async ({ page, skip }) => {
|
||||
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
||||
|
||||
await page.goto(`/src/components/item-sliding/test/basic`, config);
|
||||
|
||||
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 4.3 KiB |
@@ -2,7 +2,6 @@
|
||||
|
||||
// Item
|
||||
// --------------------------------------------------
|
||||
// TODO: FW-4955
|
||||
|
||||
:host {
|
||||
/**
|
||||
@@ -46,10 +45,10 @@
|
||||
*
|
||||
* @prop --ripple-color: Color of the item ripple effect
|
||||
*
|
||||
* @prop --highlight-height: The height of the highlight on the item. Only applies to inputs and textareas using the legacy form syntax. DEPRECATED: Highlights can be styled on `ion-input` or `ion-textarea` when using the modern form syntax.
|
||||
* @prop --highlight-color-focused: The color of the highlight on the item when focused. Only applies to inputs and textareas using the legacy form syntax. DEPRECATED: Highlights can be styled on `ion-input` or `ion-textarea` when using the modern form syntax.
|
||||
* @prop --highlight-color-valid: The color of the highlight on the item when valid. Only applies to inputs and textareas using the legacy form syntax. DEPRECATED: Highlights can be styled on `ion-input` or `ion-textarea` when using the modern form syntax.
|
||||
* @prop --highlight-color-invalid: The color of the highlight on the item when invalid. Only applies to inputs and textareas using the legacy form syntax. DEPRECATED: Highlights can be styled on `ion-input` or `ion-textarea` when using the modern form syntax.
|
||||
* @prop --highlight-height: The height of the highlight on the item
|
||||
* @prop --highlight-color-focused: The color of the highlight on the item when focused
|
||||
* @prop --highlight-color-valid: The color of the highlight on the item when valid
|
||||
* @prop --highlight-color-invalid: The color of the highlight on the item when invalid
|
||||
*/
|
||||
--border-radius: 0px;
|
||||
--border-width: 0px;
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
<!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>
|
||||
@@ -1,25 +0,0 @@
|
||||
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,7 +38,6 @@ 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;
|
||||
@@ -217,7 +216,6 @@ 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,
|
||||
@@ -239,22 +237,10 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
}
|
||||
|
||||
async componentDidLoad() {
|
||||
this.didLoad = true;
|
||||
this.menuChanged();
|
||||
this.ionMenuChange.emit({ disabled: this.disabled, open: this._isOpen });
|
||||
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
|
||||
|
||||
@@ -73,7 +73,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 30);
|
||||
await dragElementBy(modalHeader, page, 0, -500);
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
expect(modal).not.toBe(null);
|
||||
|
||||
@@ -9,7 +9,12 @@ import { CardModalPage } from '../fixtures';
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('card modal - nav'), () => {
|
||||
let cardModalPage: CardModalPage;
|
||||
test.beforeEach(async ({ page }) => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.browser(
|
||||
(browserName: string) => browserName !== 'chromium',
|
||||
'dragElementBy is flaky outside of Chrome browsers.'
|
||||
);
|
||||
|
||||
cardModalPage = new CardModalPage(page);
|
||||
await cardModalPage.navigate('/src/components/modal/test/card-nav?ionic:_testing=false', config);
|
||||
});
|
||||
@@ -28,7 +33,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
|
||||
const content = page.locator('.page-two-content');
|
||||
|
||||
await dragElementBy(content, page, 370, 0, 10);
|
||||
await dragElementBy(content, page, 1000, 0, 10);
|
||||
|
||||
await ionNavDidChange.next();
|
||||
});
|
||||
@@ -42,7 +47,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
|
||||
await ionNavDidChange.next();
|
||||
|
||||
await cardModalPage.swipeToCloseModal('ion-modal ion-content.page-two-content', true, 270);
|
||||
await cardModalPage.swipeToCloseModal('ion-modal ion-content.page-two-content');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
const modal = page.locator('ion-modal');
|
||||
const content = (await page.$('ion-modal ion-content'))!;
|
||||
|
||||
await dragElementBy(content, page, 0, 300);
|
||||
await dragElementBy(content, page, 0, 500);
|
||||
|
||||
await content.waitForElementState('stable');
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
|
||||
await content.evaluate((el: HTMLElement) => (el.scrollTop = 500));
|
||||
|
||||
await dragElementBy(content, page, 0, 300);
|
||||
await dragElementBy(content, page, 0, 500);
|
||||
|
||||
await content.waitForElementState('stable');
|
||||
|
||||
|
||||
@@ -61,12 +61,12 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
test('it should not swipe to close when swiped on the content but the content is scrolled', async ({ page }) => {
|
||||
const modal = await cardModalPage.openModalByTrigger('#card');
|
||||
|
||||
const content = page.locator('ion-modal ion-content');
|
||||
const content = (await page.$('ion-modal ion-content'))!;
|
||||
await content.evaluate((el: HTMLIonContentElement) => el.scrollToBottom(0));
|
||||
|
||||
await cardModalPage.swipeToCloseModal('ion-modal ion-content', false);
|
||||
|
||||
await content.waitFor();
|
||||
await content.waitForElementState('stable');
|
||||
await expect(modal).toBeVisible();
|
||||
});
|
||||
test('it should not swipe to close when swiped on the content but the content is scrolled even when content is replaced', async ({
|
||||
@@ -76,12 +76,12 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
|
||||
await page.click('ion-button.replace');
|
||||
|
||||
const content = page.locator('ion-modal ion-content');
|
||||
const content = (await page.$('ion-modal ion-content'))!;
|
||||
await content.evaluate((el: HTMLIonContentElement) => el.scrollToBottom(0));
|
||||
|
||||
await cardModalPage.swipeToCloseModal('ion-modal ion-content', false);
|
||||
|
||||
await content.waitFor();
|
||||
await content.waitForElementState('stable');
|
||||
await expect(modal).toBeVisible();
|
||||
});
|
||||
test('content should be scrollable after gesture ends', async ({ page }) => {
|
||||
|
||||
@@ -16,7 +16,7 @@ export class CardModalPage {
|
||||
this.ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
}
|
||||
async openModalByTrigger(selector: string) {
|
||||
await this.page.locator(selector).click();
|
||||
await this.page.click(selector);
|
||||
await this.ionModalDidPresent.next();
|
||||
|
||||
return this.page.locator('ion-modal');
|
||||
|
||||
@@ -129,7 +129,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
const ionBreakpointDidChange = await page.spyOnEvent('ionBreakpointDidChange');
|
||||
const header = page.locator('.modal-sheet ion-header');
|
||||
|
||||
await dragElementBy(header, page, 0, 125);
|
||||
await dragElementBy(header, page, 0, 150);
|
||||
|
||||
await ionBreakpointDidChange.next();
|
||||
|
||||
|
||||
@@ -27,9 +27,6 @@ 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;
|
||||
|
||||
@@ -77,7 +77,13 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
|
||||
expect(await scrollEl.evaluate((el: HTMLElement) => el.scrollTop)).toEqual(0);
|
||||
|
||||
await dragElementBy(knobEl, page, 30, 0, undefined, undefined, false);
|
||||
const box = (await knobEl.boundingBox())!;
|
||||
const centerX = box.x + box.width / 2;
|
||||
const centerY = box.y + box.height / 2;
|
||||
|
||||
await page.mouse.move(centerX, centerY);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(centerX + 30, centerY);
|
||||
|
||||
/**
|
||||
* Do not use scrollToBottom() or other scrolling methods
|
||||
|
||||
@@ -10,28 +10,15 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
/**
|
||||
* The mouse events are flaky on CI
|
||||
*/
|
||||
test.fixme('should emit start/end events', async ({ page }) => {
|
||||
/**
|
||||
* Requires padding to prevent the knob from being clipped.
|
||||
* If it's clipped, then the value might be one off.
|
||||
* For example, if the knob is clipped on the right, then the value
|
||||
* will be 99 instead of 100.
|
||||
*/
|
||||
await page.setContent(
|
||||
`
|
||||
<div style="padding: 0 20px">
|
||||
<ion-range value="20"></ion-range>
|
||||
</div>
|
||||
`,
|
||||
config
|
||||
);
|
||||
test.fixme('should emit start/end events', async ({ page }, testInfo) => {
|
||||
await page.setContent(`<ion-range value="20"></ion-range>`, config);
|
||||
|
||||
const rangeStart = await page.spyOnEvent('ionKnobMoveStart');
|
||||
const rangeEnd = await page.spyOnEvent('ionKnobMoveEnd');
|
||||
|
||||
const rangeEl = page.locator('ion-range');
|
||||
|
||||
await dragElementBy(rangeEl, page, 300, 0);
|
||||
await dragElementBy(rangeEl, page, testInfo.project.metadata.rtl ? -300 : 300, 0);
|
||||
await page.waitForChanges();
|
||||
|
||||
/**
|
||||
@@ -78,7 +65,13 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
|
||||
expect(await scrollEl.evaluate((el: HTMLElement) => el.scrollTop)).toEqual(0);
|
||||
|
||||
await dragElementBy(knobEl, page, 30, 0, undefined, undefined, false);
|
||||
const box = (await knobEl.boundingBox())!;
|
||||
const centerX = box.x + box.width / 2;
|
||||
const centerY = box.y + box.height / 2;
|
||||
|
||||
await page.mouse.move(centerX, centerY);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(centerX + 30, centerY);
|
||||
|
||||
/**
|
||||
* Do not use scrollToBottom() or other scrolling methods
|
||||
@@ -125,7 +118,13 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
const rangeHandle = page.locator('ion-range .range-knob-handle');
|
||||
const ionChangeSpy = await page.spyOnEvent('ionChange');
|
||||
|
||||
await dragElementBy(rangeHandle, page, 100, 0);
|
||||
const boundingBox = await rangeHandle.boundingBox();
|
||||
|
||||
await rangeHandle.hover();
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(boundingBox!.x + 100, boundingBox!.y);
|
||||
|
||||
await page.mouse.up();
|
||||
|
||||
await ionChangeSpy.next();
|
||||
|
||||
@@ -170,9 +169,11 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
const rangeHandle = page.locator('ion-range .range-knob-handle');
|
||||
const ionInputSpy = await page.spyOnEvent('ionInput');
|
||||
|
||||
await rangeHandle.hover();
|
||||
const boundingBox = await rangeHandle.boundingBox();
|
||||
|
||||
await dragElementBy(rangeHandle, page, 100, 0, undefined, undefined, false);
|
||||
await rangeHandle.hover();
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(boundingBox!.x + 100, boundingBox!.y);
|
||||
|
||||
await ionInputSpy.next();
|
||||
|
||||
|
||||
@@ -3,11 +3,13 @@ import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
import { pullToRefresh } from '../test.utils';
|
||||
|
||||
// TODO FW-2795: Enable this test when touch events/gestures are better supported in Playwright
|
||||
|
||||
/**
|
||||
* This behavior does not vary across directions.
|
||||
*/
|
||||
configs({ directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('refresher: basic'), () => {
|
||||
test.describe.skip(title('refresher: basic'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/refresher/test/basic', config);
|
||||
});
|
||||
|
||||
@@ -3,11 +3,12 @@ import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
import { pullToRefresh } from '../test.utils';
|
||||
|
||||
// TODO FW-2795: Enable this test when touch events/gestures are better supported in Playwright
|
||||
/**
|
||||
* This behavior does not vary across directions.
|
||||
*/
|
||||
configs({ directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('refresher: custom scroll target'), () => {
|
||||
test.describe.skip(title('refresher: custom scroll target'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/refresher/test/scroll-target', config);
|
||||
});
|
||||
@@ -18,7 +19,7 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
|
||||
expect(await items.count()).toBe(30);
|
||||
|
||||
await pullToRefresh(page);
|
||||
await pullToRefresh(page, '#inner-scroll');
|
||||
|
||||
expect(await items.count()).toBe(60);
|
||||
});
|
||||
@@ -38,7 +39,7 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
|
||||
expect(await items.count()).toBe(30);
|
||||
|
||||
await pullToRefresh(page);
|
||||
await pullToRefresh(page, '#inner-scroll');
|
||||
|
||||
expect(await items.count()).toBe(60);
|
||||
});
|
||||
|
||||
@@ -18,7 +18,7 @@ const pullToRefresh = async (page: E2EPage, selector = 'body') => {
|
||||
|
||||
const ev = await page.spyOnEvent('ionRefreshComplete');
|
||||
|
||||
await dragElementByYAxis(target, page, 320);
|
||||
await dragElementByYAxis(target, page, 400);
|
||||
await ev.next();
|
||||
};
|
||||
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test, dragElementBy } from '@utils/test/playwright';
|
||||
|
||||
// TODO FW-3079
|
||||
/**
|
||||
* Reorder group does not have per-mode styles
|
||||
*/
|
||||
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('reorder group: interactive'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
test.describe.skip(title('reorder group: interactive'), () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.browser(
|
||||
(browserName: string) => browserName !== 'chromium',
|
||||
'dragElementBy is flaky outside of Chrome browsers.'
|
||||
);
|
||||
|
||||
await page.goto(`/src/components/reorder-group/test/interactive`, config);
|
||||
});
|
||||
test('should drag and drop when ion-reorder wraps ion-item', async ({ page }) => {
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test, dragElementBy } from '@utils/test/playwright';
|
||||
|
||||
// TODO FW-3079
|
||||
/**
|
||||
* Reorder group does not have per-mode styles
|
||||
*/
|
||||
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('reorder group: nested'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
test.describe.skip(title('reorder group: nested'), () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.browser(
|
||||
(browserName: string) => browserName !== 'chromium',
|
||||
'dragElementBy is flaky outside of Chrome browsers.'
|
||||
);
|
||||
await page.goto(`/src/components/reorder-group/test/nested`, config);
|
||||
});
|
||||
test('should drag and drop when ion-reorder wraps ion-item', async ({ page }) => {
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test, dragElementBy } from '@utils/test/playwright';
|
||||
|
||||
// TODO FW-3079
|
||||
/**
|
||||
* Reorder group does not have per-mode styles
|
||||
*/
|
||||
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('reorder group: scroll-target'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
test.describe.skip(title('reorder group: scroll-target'), () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.browser(
|
||||
(browserName: string) => browserName !== 'chromium',
|
||||
'dragElementBy is flaky outside of Chrome browsers.'
|
||||
);
|
||||
await page.goto(`/src/components/reorder-group/test/scroll-target`, config);
|
||||
});
|
||||
test('should drag and drop when ion-reorder wraps ion-item', async ({ page }) => {
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
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: KeyboardEvent) {
|
||||
private checkClearOnEdit(ev: Event) {
|
||||
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() && ev.key !== 'Tab') {
|
||||
if (!this.didTextareaClearOnEdit && this.hasValue()) {
|
||||
this.value = '';
|
||||
this.emitInputChange(ev);
|
||||
}
|
||||
@@ -501,7 +501,7 @@ export class Textarea implements ComponentInterface {
|
||||
this.ionBlur.emit(ev);
|
||||
};
|
||||
|
||||
private onKeyDown = (ev: KeyboardEvent) => {
|
||||
private onKeyDown = (ev: Event) => {
|
||||
this.checkClearOnEdit(ev);
|
||||
};
|
||||
|
||||
|
||||
@@ -12,23 +12,3 @@ configs().forEach(({ title, screenshot, config }) => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('title: special characters'), () => {
|
||||
test('should not cut off characters', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title size="large">ÔÔÔ</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const title = page.locator('ion-title');
|
||||
await expect(title).toHaveScreenshot(screenshot('title-characters'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -49,6 +49,8 @@
|
||||
|
||||
min-width: 100%;
|
||||
|
||||
padding-bottom: 6px;
|
||||
|
||||
font-size: 34px;
|
||||
font-weight: 700;
|
||||
|
||||
|
||||
@@ -34,14 +34,6 @@
|
||||
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>
|
||||
@@ -49,17 +41,6 @@
|
||||
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 didPresent = await page.spyOnEvent('ionToastDidPresent');
|
||||
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
|
||||
|
||||
await page.click('#inline-toast-trigger');
|
||||
await didPresent.next();
|
||||
await ionToastDidPresent.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 didPresent = await page.spyOnEvent('ionToastDidPresent');
|
||||
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
|
||||
|
||||
await page.click('#controller-toast-trigger');
|
||||
await didPresent.next();
|
||||
await ionToastDidPresent.next();
|
||||
|
||||
/**
|
||||
* IonToast overlays the entire screen, so
|
||||
@@ -38,19 +38,5 @@ 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,18 +129,3 @@ 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');
|
||||
});
|
||||
});
|
||||
|
||||