Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53caa22212 | ||
|
|
6bbb372980 | ||
|
|
0fa68cfa61 | ||
|
|
8ec350ae65 | ||
|
|
74be79e9d8 | ||
|
|
51ab5f67b5 | ||
|
|
0548fe8588 | ||
|
|
479d56b3b2 | ||
|
|
d4d569ac09 | ||
|
|
ffcf8ec4e0 | ||
|
|
5d77fde503 | ||
|
|
1a6595b895 | ||
|
|
7e5c03ae40 | ||
|
|
2192409123 | ||
|
|
0e7f7fcdca | ||
|
|
fbbebee7be | ||
|
|
d76a24dd9e | ||
|
|
d60973b244 | ||
|
|
5e4892676c | ||
|
|
04df45a443 | ||
|
|
256b03f12a | ||
|
|
ff6df69a67 | ||
|
|
bbd6c9ae6c | ||
|
|
61cc278f05 | ||
|
|
01840741ce |
@@ -3,7 +3,7 @@ description: 'Build Ionic Angular Server'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
|
||||
@@ -3,19 +3,19 @@ description: 'Build Ionic Angular'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json')}}-v2
|
||||
- name: Cache Angular Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: angular-node-modules
|
||||
with:
|
||||
|
||||
@@ -3,16 +3,16 @@ description: 'Build Ionic Core'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# Checkout the latest commit in this branch
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
|
||||
@@ -3,12 +3,12 @@ description: 'Build Ionic React Router'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
|
||||
@@ -3,12 +3,12 @@ description: 'Build Ionic React'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
|
||||
@@ -3,12 +3,12 @@ description: 'Builds Ionic Vue Router'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
|
||||
@@ -3,12 +3,12 @@ description: 'Build Ionic Vue'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
|
||||
@@ -10,7 +10,7 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ inputs.name }}
|
||||
path: ${{ inputs.path }}
|
||||
|
||||
@@ -6,12 +6,12 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
|
||||
@@ -3,7 +3,7 @@ description: 'Test Core Clean Build'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@ description: 'Test Core E2E'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
|
||||
@@ -3,12 +3,12 @@ description: 'Test Core Lint'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
|
||||
@@ -10,12 +10,12 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
@@ -72,7 +72,7 @@ runs:
|
||||
working-directory: ./core
|
||||
- name: Archive Updated Screenshots
|
||||
if: inputs.update == 'true' && steps.test-and-update.outputs.hasUpdatedScreenshots == 'true'
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: updated-screenshots-${{ inputs.shard }}-${{ inputs.totalShards }}
|
||||
path: UpdatedScreenshots-${{ inputs.shard }}-${{ inputs.totalShards }}.zip
|
||||
|
||||
@@ -3,12 +3,12 @@ description: 'Test Core Spec'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
|
||||
@@ -3,12 +3,12 @@ description: 'Test React E2E'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
|
||||
@@ -3,12 +3,12 @@ description: 'Test React Router '
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
|
||||
@@ -6,12 +6,12 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
|
||||
@@ -7,10 +7,10 @@ on:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: ./artifacts
|
||||
- name: Extract Archives
|
||||
|
||||
@@ -13,7 +13,7 @@ runs:
|
||||
- name: Create Archive
|
||||
run: zip -q -r ${{ inputs.output }} ${{ inputs.paths }}
|
||||
shell: bash
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ inputs.name }}
|
||||
path: ${{ inputs.output }}
|
||||
|
||||
32
.github/workflows/build.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
build-core:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# Checkout the latest commit in this branch
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
@@ -25,28 +25,28 @@ jobs:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-core-clean-build
|
||||
|
||||
test-core-lint:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-core-lint
|
||||
|
||||
test-core-spec:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-core-spec
|
||||
|
||||
test-core-e2e:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-core-e2e
|
||||
|
||||
test-core-screenshot:
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-core-screenshot
|
||||
with:
|
||||
shard: ${{ matrix.shard }}
|
||||
@@ -95,14 +95,14 @@ jobs:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/build-vue
|
||||
|
||||
build-vue-router:
|
||||
needs: [build-vue]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/build-vue-router
|
||||
|
||||
test-vue-e2e:
|
||||
@@ -113,7 +113,7 @@ jobs:
|
||||
needs: [build-vue, build-vue-router]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-vue-e2e
|
||||
with:
|
||||
app: ${{ matrix.apps }}
|
||||
@@ -131,14 +131,14 @@ jobs:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/build-angular
|
||||
|
||||
build-angular-server:
|
||||
needs: [build-angular]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/build-angular-server
|
||||
|
||||
test-angular-e2e:
|
||||
@@ -149,7 +149,7 @@ jobs:
|
||||
needs: [build-angular, build-angular-server]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-angular-e2e
|
||||
with:
|
||||
app: ${{ matrix.apps }}
|
||||
@@ -167,26 +167,26 @@ jobs:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/build-react
|
||||
|
||||
build-react-router:
|
||||
needs: [build-react]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/build-react-router
|
||||
|
||||
test-react-router-e2e:
|
||||
needs: [build-react, build-react-router]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-react-router-e2e
|
||||
|
||||
test-react-e2e:
|
||||
needs: [build-react, build-react-router]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-react-e2e
|
||||
|
||||
4
.github/workflows/dev-build.yml
vendored
@@ -9,8 +9,8 @@ jobs:
|
||||
outputs:
|
||||
version: ${{ steps.dev-build.outputs.version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Install Dependencies
|
||||
|
||||
4
.github/workflows/nightly.yml
vendored
@@ -10,10 +10,10 @@ jobs:
|
||||
nightly-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v2
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Install Dependencies
|
||||
|
||||
4
.github/workflows/pre-release.yml
vendored
@@ -25,8 +25,8 @@ jobs:
|
||||
build-ionic:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Configure Identity
|
||||
|
||||
13
.github/workflows/release.yml
vendored
@@ -24,11 +24,11 @@ jobs:
|
||||
build-ionic:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.IONITRON_TOKEN }}
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v2
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Configure Identity
|
||||
@@ -55,6 +55,15 @@ jobs:
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
shell: bash
|
||||
# Lerna does not automatically bump versions
|
||||
# of Ionic dependencies that have changed,
|
||||
# so we do that here.
|
||||
- name: Bump Package Lock
|
||||
run: |
|
||||
lerna exec "npm install --package-lock-only --legacy-peer-deps"
|
||||
git add .
|
||||
git commit -m "chore(): update package lock files"
|
||||
git push
|
||||
# Purge the JSDeliver CDN cache so
|
||||
# component playgrounds always load
|
||||
# the latest version of Ionic.
|
||||
|
||||
6
.github/workflows/update-screenshots.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
build-core:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/build-core
|
||||
|
||||
test-core-screenshot:
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-core-screenshot
|
||||
with:
|
||||
shard: ${{ matrix.shard }}
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test-core-screenshot]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
# Normally, we could just push with the
|
||||
# default GITHUB_TOKEN, but that will
|
||||
# not cause the build workflow
|
||||
|
||||
30
CHANGELOG.md
@@ -3,6 +3,36 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.3.3](https://github.com/ionic-team/ionic-framework/compare/v6.3.2...v6.3.3) (2022-10-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** empty string is treated as no value ([#26131](https://github.com/ionic-team/ionic-framework/issues/26131)) ([51ab5f6](https://github.com/ionic-team/ionic-framework/commit/51ab5f67b50013c0ed8ca3160d6dfc56bc269f2a)), closes [#26116](https://github.com/ionic-team/ionic-framework/issues/26116)
|
||||
* **datetime:** preferWheel can now show title ([#26101](https://github.com/ionic-team/ionic-framework/issues/26101)) ([479d56b](https://github.com/ionic-team/ionic-framework/commit/479d56b3b26d45bfd03d4095458c37ed00485c54)), closes [#26095](https://github.com/ionic-team/ionic-framework/issues/26095)
|
||||
* **datetime:** values are adjusted to be in bounds ([#26125](https://github.com/ionic-team/ionic-framework/issues/26125)) ([0548fe8](https://github.com/ionic-team/ionic-framework/commit/0548fe858854f0187e0dfe00efaec142cd5bb6cf)), closes [#25894](https://github.com/ionic-team/ionic-framework/issues/25894) [#25708](https://github.com/ionic-team/ionic-framework/issues/25708)
|
||||
* **dependencies:** latest patch is installed ([#26148](https://github.com/ionic-team/ionic-framework/issues/26148)) ([74be79e](https://github.com/ionic-team/ionic-framework/commit/74be79e9d81fd5431ae2fc442fd6387cf37b2015)), closes [#26137](https://github.com/ionic-team/ionic-framework/issues/26137)
|
||||
* **many:** haptics only fire on supported platforms ([#26130](https://github.com/ionic-team/ionic-framework/issues/26130)) ([d4d569a](https://github.com/ionic-team/ionic-framework/commit/d4d569ac09ab25ab5a490825cf1fc655fe97bb87)), closes [#26109](https://github.com/ionic-team/ionic-framework/issues/26109)
|
||||
* **react:** inline overlays can be conditionally rendered ([#26111](https://github.com/ionic-team/ionic-framework/issues/26111)) ([8ec350a](https://github.com/ionic-team/ionic-framework/commit/8ec350ae652095ae29e2f02a7f105cb709a72583)), closes [#25590](https://github.com/ionic-team/ionic-framework/issues/25590)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.3.2](https://github.com/ionic-team/ionic-framework/compare/v6.3.1...v6.3.2) (2022-10-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** header renders correct date ([#26120](https://github.com/ionic-team/ionic-framework/issues/26120)) ([04df45a](https://github.com/ionic-team/ionic-framework/commit/04df45a443e4faeea644daa76dc509fea0d24ca2)), closes [#26116](https://github.com/ionic-team/ionic-framework/issues/26116)
|
||||
* **datetime:** selecting days updates value ([#26121](https://github.com/ionic-team/ionic-framework/issues/26121)) ([d76a24d](https://github.com/ionic-team/ionic-framework/commit/d76a24dd9e485a2f3cc517231bbb1dab51fa1fd3))
|
||||
* **modal:** sheet modal dismisses correctly ([#26110](https://github.com/ionic-team/ionic-framework/issues/26110)) ([256b03f](https://github.com/ionic-team/ionic-framework/commit/256b03f12a57c2b5904d9017e4fa93b11eea8fc7)), closes [#26108](https://github.com/ionic-team/ionic-framework/issues/26108)
|
||||
* **vue:** routing components define child components ([#26107](https://github.com/ionic-team/ionic-framework/issues/26107)) ([d60973b](https://github.com/ionic-team/ionic-framework/commit/d60973b2449b29a982b752a98b10d2b043ecff2f))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.3.1](https://github.com/ionic-team/ionic-framework/compare/v6.3.0...v6.3.1) (2022-10-12)
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,26 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.3.3](https://github.com/ionic-team/ionic/compare/v6.3.2...v6.3.3) (2022-10-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** empty string is treated as no value ([#26131](https://github.com/ionic-team/ionic/issues/26131)) ([51ab5f6](https://github.com/ionic-team/ionic/commit/51ab5f67b50013c0ed8ca3160d6dfc56bc269f2a)), closes [#26116](https://github.com/ionic-team/ionic/issues/26116)
|
||||
* **dependencies:** latest patch is installed ([#26148](https://github.com/ionic-team/ionic/issues/26148)) ([74be79e](https://github.com/ionic-team/ionic/commit/74be79e9d81fd5431ae2fc442fd6387cf37b2015)), closes [#26137](https://github.com/ionic-team/ionic/issues/26137)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.3.2](https://github.com/ionic-team/ionic/compare/v6.3.1...v6.3.2) (2022-10-17)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.3.1](https://github.com/ionic-team/ionic/compare/v6.3.0...v6.3.1) (2022-10-12)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
||||
18
angular/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "6.3.1",
|
||||
"version": "6.3.3",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular",
|
||||
"version": "6.3.1",
|
||||
"version": "6.3.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.3.1",
|
||||
"@ionic/core": "^6.3.3",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
@@ -1023,9 +1023,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz",
|
||||
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==",
|
||||
"version": "6.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.2.tgz",
|
||||
"integrity": "sha512-L4xqJyixmGApwYc5fQgGoK80wXGCrbjL8vGfeNbjYqxxP0ZIKGAhURPoMAtSTqLLK9gdhh4Mv6gw4gNKvxodPA==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.18.0",
|
||||
"ionicons": "^6.0.3",
|
||||
@@ -7951,9 +7951,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz",
|
||||
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==",
|
||||
"version": "6.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.2.tgz",
|
||||
"integrity": "sha512-L4xqJyixmGApwYc5fQgGoK80wXGCrbjL8vGfeNbjYqxxP0ZIKGAhURPoMAtSTqLLK9gdhh4Mv6gw4gNKvxodPA==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.18.0",
|
||||
"ionicons": "^6.0.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "6.3.1",
|
||||
"version": "6.3.3",
|
||||
"description": "Angular specific wrappers for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -45,7 +45,7 @@
|
||||
"validate": "npm i && npm run lint && npm run test && npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.3.1",
|
||||
"@ionic/core": "^6.3.3",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
|
||||
@@ -19,7 +19,7 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
|
||||
|
||||
writeValue(value: any): void {
|
||||
/**
|
||||
* TODO for Ionic 6:
|
||||
* TODO FW-2646
|
||||
* Change `value == null ? '' : value;`
|
||||
* to `value`. This was a fix for IE9, but IE9
|
||||
* is no longer supported; however, this change
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import * as d from './proxies';
|
||||
|
||||
export const DIRECTIVES = [
|
||||
@@ -76,5 +77,5 @@ export const DIRECTIVES = [
|
||||
d.IonThumbnail,
|
||||
d.IonTitle,
|
||||
d.IonToggle,
|
||||
d.IonToolbar,
|
||||
d.IonToolbar
|
||||
];
|
||||
|
||||
@@ -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.
|
||||
|
||||
## [6.3.3](https://github.com/ionic-team/ionic/compare/v6.3.2...v6.3.3) (2022-10-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** empty string is treated as no value ([#26131](https://github.com/ionic-team/ionic/issues/26131)) ([51ab5f6](https://github.com/ionic-team/ionic/commit/51ab5f67b50013c0ed8ca3160d6dfc56bc269f2a)), closes [#26116](https://github.com/ionic-team/ionic/issues/26116)
|
||||
* **datetime:** preferWheel can now show title ([#26101](https://github.com/ionic-team/ionic/issues/26101)) ([479d56b](https://github.com/ionic-team/ionic/commit/479d56b3b26d45bfd03d4095458c37ed00485c54)), closes [#26095](https://github.com/ionic-team/ionic/issues/26095)
|
||||
* **datetime:** values are adjusted to be in bounds ([#26125](https://github.com/ionic-team/ionic/issues/26125)) ([0548fe8](https://github.com/ionic-team/ionic/commit/0548fe858854f0187e0dfe00efaec142cd5bb6cf)), closes [#25894](https://github.com/ionic-team/ionic/issues/25894) [#25708](https://github.com/ionic-team/ionic/issues/25708)
|
||||
* **many:** haptics only fire on supported platforms ([#26130](https://github.com/ionic-team/ionic/issues/26130)) ([d4d569a](https://github.com/ionic-team/ionic/commit/d4d569ac09ab25ab5a490825cf1fc655fe97bb87)), closes [#26109](https://github.com/ionic-team/ionic/issues/26109)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.3.2](https://github.com/ionic-team/ionic/compare/v6.3.1...v6.3.2) (2022-10-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** header renders correct date ([#26120](https://github.com/ionic-team/ionic/issues/26120)) ([04df45a](https://github.com/ionic-team/ionic/commit/04df45a443e4faeea644daa76dc509fea0d24ca2)), closes [#26116](https://github.com/ionic-team/ionic/issues/26116)
|
||||
* **datetime:** selecting days updates value ([#26121](https://github.com/ionic-team/ionic/issues/26121)) ([d76a24d](https://github.com/ionic-team/ionic/commit/d76a24dd9e485a2f3cc517231bbb1dab51fa1fd3))
|
||||
* **modal:** sheet modal dismisses correctly ([#26110](https://github.com/ionic-team/ionic/issues/26110)) ([256b03f](https://github.com/ionic-team/ionic/commit/256b03f12a57c2b5904d9017e4fa93b11eea8fc7)), closes [#26108](https://github.com/ionic-team/ionic/issues/26108)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.3.1](https://github.com/ionic-team/ionic/compare/v6.3.0...v6.3.1) (2022-10-12)
|
||||
|
||||
|
||||
|
||||
4
core/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "6.3.1",
|
||||
"version": "6.3.3",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/core",
|
||||
"version": "6.3.1",
|
||||
"version": "6.3.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.18.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "6.3.1",
|
||||
"version": "6.3.3",
|
||||
"description": "Base components for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -86,7 +86,7 @@
|
||||
"css.sass": "sass --embed-sources src/css:./css",
|
||||
"eslint": "eslint src",
|
||||
"lint": "npm run lint.ts && npm run lint.sass && npm run prettier -- --write",
|
||||
"lint.fix": "npm run lint.ts.fix && npm run lint.sass.fix",
|
||||
"lint.fix": "npm run lint.ts.fix && npm run lint.sass.fix && npm run prettier -- --write",
|
||||
"lint.sass": "stylelint \"src/**/*.scss\"",
|
||||
"lint.sass.fix": "npm run lint.sass -- --fix",
|
||||
"lint.ts": "npm run eslint",
|
||||
|
||||
@@ -35,9 +35,12 @@ test.describe('alert: a11y', () => {
|
||||
});
|
||||
|
||||
test('should not have accessibility violations when header and message are defined', async ({ page }) => {
|
||||
const didPresent = await page.spyOnEvent('ionAlertDidPresent');
|
||||
const button = page.locator('#bothHeaders');
|
||||
await button.click();
|
||||
|
||||
await didPresent.next();
|
||||
|
||||
const results = await new AxeBuilder({ page }).analyze();
|
||||
expect(results.violations).toEqual([]);
|
||||
});
|
||||
|
||||
@@ -160,7 +160,8 @@ export class DatetimeButton implements ComponentInterface {
|
||||
* to keep checking if the datetime value is `string` or `string[]`.
|
||||
*/
|
||||
private getParsedDateValues = (value?: string[] | string | null): string[] => {
|
||||
if (value === undefined || value === null) {
|
||||
// TODO FW-2646 Remove value === ''
|
||||
if (value === '' || value === undefined || value === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
@@ -561,7 +561,7 @@ export class Datetime implements ComponentInterface {
|
||||
* "activePartsClone" and then falling back to
|
||||
* today's DatetimeParts if no active date is selected.
|
||||
*/
|
||||
private getDefaultPart = () => {
|
||||
private getDefaultPart = (): DatetimeParts => {
|
||||
const { activePartsClone, todayParts } = this;
|
||||
|
||||
const firstPart = Array.isArray(activePartsClone) ? activePartsClone[0] : activePartsClone;
|
||||
@@ -585,7 +585,7 @@ export class Datetime implements ComponentInterface {
|
||||
};
|
||||
|
||||
private setActiveParts = (parts: DatetimeParts, removeDate = false) => {
|
||||
const { multiple, activePartsClone } = this;
|
||||
const { multiple, minParts, maxParts, activePartsClone } = this;
|
||||
|
||||
/**
|
||||
* When setting the active parts, it is possible
|
||||
@@ -597,7 +597,7 @@ export class Datetime implements ComponentInterface {
|
||||
* Additionally, we need to update the working parts
|
||||
* too in the event that the validated parts are different.
|
||||
*/
|
||||
const validatedParts = validateParts(parts);
|
||||
const validatedParts = validateParts(parts, minParts, maxParts);
|
||||
this.setWorkingParts(validatedParts);
|
||||
|
||||
if (multiple) {
|
||||
@@ -1154,8 +1154,11 @@ export class Datetime implements ComponentInterface {
|
||||
}
|
||||
|
||||
private processValue = (value?: string | string[] | null) => {
|
||||
const hasValue = value !== null && value !== undefined;
|
||||
let valueToProcess = parseDate(value ?? getToday());
|
||||
/**
|
||||
* TODO FW-2646 remove value !== ''
|
||||
*/
|
||||
const hasValue = value !== '' && value !== null && value !== undefined;
|
||||
let valueToProcess = parseDate(hasValue ? value : getToday());
|
||||
|
||||
const { minParts, maxParts, multiple } = this;
|
||||
if (!multiple && Array.isArray(value)) {
|
||||
@@ -1393,7 +1396,9 @@ export class Datetime implements ComponentInterface {
|
||||
}
|
||||
|
||||
private renderCombinedDatePickerColumn() {
|
||||
const { activeParts, workingParts, locale, minParts, maxParts, todayParts, isDateEnabled } = this;
|
||||
const { workingParts, locale, minParts, maxParts, todayParts, isDateEnabled } = this;
|
||||
|
||||
const activePart = this.getDefaultPart();
|
||||
|
||||
/**
|
||||
* By default, generate a range of 3 months:
|
||||
@@ -1489,12 +1494,10 @@ export class Datetime implements ComponentInterface {
|
||||
...findPart,
|
||||
});
|
||||
|
||||
if (!Array.isArray(activeParts)) {
|
||||
this.setActiveParts({
|
||||
...activeParts,
|
||||
...findPart,
|
||||
});
|
||||
}
|
||||
this.setActiveParts({
|
||||
...activePart,
|
||||
...findPart,
|
||||
});
|
||||
|
||||
// We can re-attach the scroll listener after
|
||||
// the working parts have been updated.
|
||||
@@ -1583,7 +1586,9 @@ export class Datetime implements ComponentInterface {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { activeParts, workingParts } = this;
|
||||
const { workingParts } = this;
|
||||
|
||||
const activePart = this.getDefaultPart();
|
||||
|
||||
return (
|
||||
<ion-picker-column-internal
|
||||
@@ -1605,12 +1610,10 @@ export class Datetime implements ComponentInterface {
|
||||
day: ev.detail.value,
|
||||
});
|
||||
|
||||
if (!Array.isArray(activeParts)) {
|
||||
this.setActiveParts({
|
||||
...activeParts,
|
||||
day: ev.detail.value,
|
||||
});
|
||||
}
|
||||
this.setActiveParts({
|
||||
...activePart,
|
||||
day: ev.detail.value,
|
||||
});
|
||||
|
||||
// We can re-attach the scroll listener after
|
||||
// the working parts have been updated.
|
||||
@@ -1627,7 +1630,9 @@ export class Datetime implements ComponentInterface {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { activeParts, workingParts } = this;
|
||||
const { workingParts } = this;
|
||||
|
||||
const activePart = this.getDefaultPart();
|
||||
|
||||
return (
|
||||
<ion-picker-column-internal
|
||||
@@ -1649,12 +1654,10 @@ export class Datetime implements ComponentInterface {
|
||||
month: ev.detail.value,
|
||||
});
|
||||
|
||||
if (!Array.isArray(activeParts)) {
|
||||
this.setActiveParts({
|
||||
...activeParts,
|
||||
month: ev.detail.value,
|
||||
});
|
||||
}
|
||||
this.setActiveParts({
|
||||
...activePart,
|
||||
month: ev.detail.value,
|
||||
});
|
||||
|
||||
// We can re-attach the scroll listener after
|
||||
// the working parts have been updated.
|
||||
@@ -1670,7 +1673,9 @@ export class Datetime implements ComponentInterface {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { activeParts, workingParts } = this;
|
||||
const { workingParts } = this;
|
||||
|
||||
const activePart = this.getDefaultPart();
|
||||
|
||||
return (
|
||||
<ion-picker-column-internal
|
||||
@@ -1692,12 +1697,10 @@ export class Datetime implements ComponentInterface {
|
||||
year: ev.detail.value,
|
||||
});
|
||||
|
||||
if (!Array.isArray(activeParts)) {
|
||||
this.setActiveParts({
|
||||
...activeParts,
|
||||
year: ev.detail.value,
|
||||
});
|
||||
}
|
||||
this.setActiveParts({
|
||||
...activePart,
|
||||
year: ev.detail.value,
|
||||
});
|
||||
|
||||
// We can re-attach the scroll listener after
|
||||
// the working parts have been updated.
|
||||
@@ -1750,12 +1753,10 @@ export class Datetime implements ComponentInterface {
|
||||
hour: ev.detail.value,
|
||||
});
|
||||
|
||||
if (!Array.isArray(activePart)) {
|
||||
this.setActiveParts({
|
||||
...activePart,
|
||||
hour: ev.detail.value,
|
||||
});
|
||||
}
|
||||
this.setActiveParts({
|
||||
...activePart,
|
||||
hour: ev.detail.value,
|
||||
});
|
||||
|
||||
ev.stopPropagation();
|
||||
}}
|
||||
@@ -1780,12 +1781,10 @@ export class Datetime implements ComponentInterface {
|
||||
minute: ev.detail.value,
|
||||
});
|
||||
|
||||
if (!Array.isArray(activePart)) {
|
||||
this.setActiveParts({
|
||||
...activePart,
|
||||
minute: ev.detail.value,
|
||||
});
|
||||
}
|
||||
this.setActiveParts({
|
||||
...activePart,
|
||||
minute: ev.detail.value,
|
||||
});
|
||||
|
||||
ev.stopPropagation();
|
||||
}}
|
||||
@@ -1816,13 +1815,11 @@ export class Datetime implements ComponentInterface {
|
||||
hour,
|
||||
});
|
||||
|
||||
if (!Array.isArray(activePart)) {
|
||||
this.setActiveParts({
|
||||
...activePart,
|
||||
ampm: ev.detail.value,
|
||||
hour,
|
||||
});
|
||||
}
|
||||
this.setActiveParts({
|
||||
...activePart,
|
||||
ampm: ev.detail.value,
|
||||
hour,
|
||||
});
|
||||
|
||||
ev.stopPropagation();
|
||||
}}
|
||||
@@ -1914,6 +1911,8 @@ export class Datetime implements ComponentInterface {
|
||||
// can free-scroll the calendar.
|
||||
const isWorkingMonth = this.workingParts.month === month && this.workingParts.year === year;
|
||||
|
||||
const activePart = this.getDefaultPart();
|
||||
|
||||
return (
|
||||
<div
|
||||
// Non-visible months should be hidden from screen readers
|
||||
@@ -1998,7 +1997,7 @@ export class Datetime implements ComponentInterface {
|
||||
);
|
||||
} else {
|
||||
this.setActiveParts({
|
||||
...this.activeParts,
|
||||
...activePart,
|
||||
month,
|
||||
day,
|
||||
year,
|
||||
@@ -2106,17 +2105,13 @@ export class Datetime implements ComponentInterface {
|
||||
</ion-popover>,
|
||||
];
|
||||
}
|
||||
private renderCalendarViewHeader() {
|
||||
const hasSlottedTitle = this.el.querySelector('[slot="title"]') !== null;
|
||||
if (!hasSlottedTitle && !this.showDefaultTitle) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { activeParts, titleSelectedDatesFormatter } = this;
|
||||
private getHeaderSelectedDateText() {
|
||||
const { activeParts, multiple, titleSelectedDatesFormatter } = this;
|
||||
const isArray = Array.isArray(activeParts);
|
||||
|
||||
let headerText: string;
|
||||
if (isArray && activeParts.length !== 1) {
|
||||
if (multiple && isArray && activeParts.length !== 1) {
|
||||
headerText = `${activeParts.length} days`; // default/fallback for multiple selection
|
||||
if (titleSelectedDatesFormatter !== undefined) {
|
||||
try {
|
||||
@@ -2130,12 +2125,21 @@ export class Datetime implements ComponentInterface {
|
||||
headerText = getMonthAndDay(this.locale, this.getDefaultPart());
|
||||
}
|
||||
|
||||
return headerText;
|
||||
}
|
||||
|
||||
private renderCalendarViewHeader(showExpandedHeader = true) {
|
||||
const hasSlottedTitle = this.el.querySelector('[slot="title"]') !== null;
|
||||
if (!hasSlottedTitle && !this.showDefaultTitle) {
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="datetime-header">
|
||||
<div class="datetime-title">
|
||||
<slot name="title">Select Date</slot>
|
||||
</div>
|
||||
<div class="datetime-selected-date">{headerText}</div>
|
||||
{showExpandedHeader && <div class="datetime-selected-date">{this.getHeaderSelectedDateText()}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -2182,7 +2186,7 @@ export class Datetime implements ComponentInterface {
|
||||
*/
|
||||
const hasWheelVariant = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
||||
if (preferWheel && hasWheelVariant) {
|
||||
return [this.renderWheelView(), this.renderFooter()];
|
||||
return [this.renderCalendarViewHeader(false), this.renderWheelView(), this.renderFooter()];
|
||||
}
|
||||
|
||||
switch (presentation) {
|
||||
|
||||
@@ -72,6 +72,39 @@ test.describe('datetime: selecting a day', () => {
|
||||
|
||||
await expect(activeDay).toHaveText('13');
|
||||
});
|
||||
test('should set both date and time when no value is initially set', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime locale="en-US" presentation="date-time"></ion-datetime>
|
||||
|
||||
<script>
|
||||
const mockToday = '2022-10-10T16:22';
|
||||
Date = class extends Date {
|
||||
constructor(...args) {
|
||||
if (args.length === 0) {
|
||||
super(mockToday)
|
||||
} else {
|
||||
super(...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
const datetime = page.locator('ion-datetime');
|
||||
const ionChange = await page.spyOnEvent('ionChange');
|
||||
|
||||
// Oct 1, 2022
|
||||
await page.click('.calendar-day[data-month="10"][data-year="2022"][data-day="1"]');
|
||||
|
||||
await ionChange.next();
|
||||
|
||||
const value = await datetime.evaluate((el: HTMLIonDatetimeElement) => el.value);
|
||||
await expect(typeof value).toBe('string');
|
||||
|
||||
// Check to make sure value includes current time
|
||||
await expect(value!.includes('2022-10-01T16:22')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('datetime: confirm date', () => {
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
calculateHourFromAMPM,
|
||||
subtractDays,
|
||||
addDays,
|
||||
validateParts,
|
||||
} from '../utils/manipulation';
|
||||
|
||||
describe('addDays()', () => {
|
||||
@@ -487,3 +488,72 @@ describe('getPreviousYear()', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateParts()', () => {
|
||||
it('should move day in bounds', () => {
|
||||
expect(validateParts({ month: 2, day: 31, year: 2022, hour: 8, minute: 0 })).toEqual({
|
||||
month: 2,
|
||||
day: 28,
|
||||
year: 2022,
|
||||
hour: 8,
|
||||
minute: 0,
|
||||
});
|
||||
});
|
||||
it('should move the hour back in bounds according to the min', () => {
|
||||
expect(
|
||||
validateParts(
|
||||
{ month: 1, day: 1, year: 2022, hour: 8, minute: 0 },
|
||||
{ month: 1, day: 1, year: 2022, hour: 9, minute: 0 }
|
||||
)
|
||||
).toEqual({ month: 1, day: 1, year: 2022, hour: 9, minute: 0 });
|
||||
});
|
||||
it('should move the minute back in bounds according to the min', () => {
|
||||
expect(
|
||||
validateParts(
|
||||
{ month: 1, day: 1, year: 2022, hour: 9, minute: 20 },
|
||||
{ month: 1, day: 1, year: 2022, hour: 9, minute: 30 }
|
||||
)
|
||||
).toEqual({ month: 1, day: 1, year: 2022, hour: 9, minute: 30 });
|
||||
});
|
||||
it('should move the hour and minute back in bounds according to the min', () => {
|
||||
expect(
|
||||
validateParts(
|
||||
{ month: 1, day: 1, year: 2022, hour: 8, minute: 30 },
|
||||
{ month: 1, day: 1, year: 2022, hour: 9, minute: 0 }
|
||||
)
|
||||
).toEqual({ month: 1, day: 1, year: 2022, hour: 9, minute: 0 });
|
||||
});
|
||||
it('should move the hour back in bounds according to the max', () => {
|
||||
expect(
|
||||
validateParts({ month: 1, day: 1, year: 2022, hour: 10, minute: 0 }, undefined, {
|
||||
month: 1,
|
||||
day: 1,
|
||||
year: 2022,
|
||||
hour: 9,
|
||||
minute: 0,
|
||||
})
|
||||
).toEqual({ month: 1, day: 1, year: 2022, hour: 9, minute: 0 });
|
||||
});
|
||||
it('should move the minute back in bounds according to the max', () => {
|
||||
expect(
|
||||
validateParts({ month: 1, day: 1, year: 2022, hour: 9, minute: 40 }, undefined, {
|
||||
month: 1,
|
||||
day: 1,
|
||||
year: 2022,
|
||||
hour: 9,
|
||||
minute: 30,
|
||||
})
|
||||
).toEqual({ month: 1, day: 1, year: 2022, hour: 9, minute: 30 });
|
||||
});
|
||||
it('should move the hour and minute back in bounds according to the max', () => {
|
||||
expect(
|
||||
validateParts({ month: 1, day: 1, year: 2022, hour: 10, minute: 20 }, undefined, {
|
||||
month: 1,
|
||||
day: 1,
|
||||
year: 2022,
|
||||
hour: 9,
|
||||
minute: 30,
|
||||
})
|
||||
).toEqual({ month: 1, day: 1, year: 2022, hour: 9, minute: 30 });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -234,4 +234,53 @@ test.describe('datetime: minmax', () => {
|
||||
);
|
||||
await expect(hourPickerItems).toHaveText(['12', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11']);
|
||||
});
|
||||
|
||||
test.describe('minmax value adjustment when out of bounds', () => {
|
||||
test.beforeEach(({ skip }) => {
|
||||
skip.rtl();
|
||||
skip.mode('ios', 'This implementation is the same across modes.');
|
||||
});
|
||||
test('should reset to min time if out of bounds', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime
|
||||
min="2022-10-10T08:00"
|
||||
value="2022-10-11T06:00"
|
||||
></ion-datetime>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const datetime = page.locator('ion-datetime');
|
||||
const ionChange = await page.spyOnEvent('ionChange');
|
||||
const dayButton = page.locator('ion-datetime .calendar-day[data-day="10"][data-month="10"][data-year="2022"]');
|
||||
await dayButton.click();
|
||||
|
||||
await ionChange.next();
|
||||
|
||||
const value = await datetime.evaluate((el: HTMLIonDatetimeElement) => el.value);
|
||||
await expect(typeof value).toBe('string');
|
||||
await expect(value!.includes('2022-10-10T08:00')).toBe(true);
|
||||
});
|
||||
test('should reset to max time if out of bounds', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime
|
||||
max="2022-10-10T08:00"
|
||||
value="2022-10-11T09:00"
|
||||
></ion-datetime>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const datetime = page.locator('ion-datetime');
|
||||
const ionChange = await page.spyOnEvent('ionChange');
|
||||
const dayButton = page.locator('ion-datetime .calendar-day[data-day="10"][data-month="10"][data-year="2022"]');
|
||||
await dayButton.click();
|
||||
|
||||
await ionChange.next();
|
||||
|
||||
const value = await datetime.evaluate((el: HTMLIonDatetimeElement) => el.value);
|
||||
await expect(typeof value).toBe('string');
|
||||
await expect(value!.includes('2022-10-10T08:00')).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -189,4 +189,28 @@ test.describe('datetime: multiple date selection (functionality)', () => {
|
||||
await juneButtons.nth(0).click();
|
||||
await expect(header).toHaveText('Selected: 0');
|
||||
});
|
||||
|
||||
test('header text should render default date when multiple="false"', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime locale="en-US" show-default-title="true"></ion-datetime>
|
||||
|
||||
<script>
|
||||
const mockToday = '2022-10-10T16:22';
|
||||
Date = class extends Date {
|
||||
constructor(...args) {
|
||||
if (args.length === 0) {
|
||||
super(mockToday)
|
||||
} else {
|
||||
super(...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
`);
|
||||
await page.waitForSelector(`.datetime-ready`);
|
||||
const datetime = page.locator('ion-datetime');
|
||||
const header = datetime.locator('.datetime-selected-date');
|
||||
|
||||
await expect(header).toHaveText('Mon, Oct 10');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -40,6 +40,18 @@ test.describe('datetime: prefer wheel', () => {
|
||||
`datetime-wheel-time-date-diff-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
});
|
||||
test('should render a condense header when specified', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime size="cover" presentation="time-date" prefer-wheel="true" value="2019-05-30T16:30:00"><div slot="title">My Custom Title</div></ion-datetime>
|
||||
`);
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const datetime = page.locator('ion-datetime');
|
||||
|
||||
expect(await datetime.screenshot()).toMatchSnapshot(
|
||||
`datetime-wheel-header-diff-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
});
|
||||
});
|
||||
test.describe('datetime: date wheel', () => {
|
||||
test.beforeEach(({ skip }) => {
|
||||
@@ -112,6 +124,64 @@ test.describe('datetime: prefer wheel', () => {
|
||||
expect(await yearValues.count()).toBe(3);
|
||||
expect(await dayValues.count()).toBe(5);
|
||||
});
|
||||
test('selecting month should update value when no value is set', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime
|
||||
presentation="date"
|
||||
prefer-wheel="true"
|
||||
></ion-datetime>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const ionChange = await page.spyOnEvent('ionChange');
|
||||
const monthValues = page.locator('.month-column .picker-item:not(.picker-item-empty)');
|
||||
|
||||
// Change month value
|
||||
await monthValues.nth(0).click();
|
||||
|
||||
await ionChange.next();
|
||||
});
|
||||
test('selecting day should update value when no value is set', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime
|
||||
presentation="date"
|
||||
prefer-wheel="true"
|
||||
></ion-datetime>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const ionChange = await page.spyOnEvent('ionChange');
|
||||
const dayValues = page.locator('.day-column .picker-item:not(.picker-item-empty)');
|
||||
|
||||
// Change day value
|
||||
await dayValues.nth(0).click();
|
||||
|
||||
await ionChange.next();
|
||||
});
|
||||
test('selecting year should update value when no value is set', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime
|
||||
presentation="date"
|
||||
prefer-wheel="true"
|
||||
></ion-datetime>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const ionChange = await page.spyOnEvent('ionChange');
|
||||
const yearValues = page.locator('.year-column .picker-item:not(.picker-item-empty)');
|
||||
|
||||
/**
|
||||
* Change year value
|
||||
* The 0th index is the current
|
||||
* year, so select something other than that.
|
||||
*/
|
||||
await yearValues.nth(10).click();
|
||||
|
||||
await ionChange.next();
|
||||
});
|
||||
test.describe('datetime: date wheel localization', () => {
|
||||
test('should correctly localize the date data', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
@@ -314,6 +384,24 @@ test.describe('datetime: prefer wheel', () => {
|
||||
|
||||
expect(await dayValues.count()).toBe(15);
|
||||
});
|
||||
test('selecting date should update value when no value is set', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime
|
||||
presentation="date-time"
|
||||
prefer-wheel="true"
|
||||
></ion-datetime>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const ionChange = await page.spyOnEvent('ionChange');
|
||||
const dayValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
|
||||
|
||||
// Change day/month value
|
||||
await dayValues.nth(0).click();
|
||||
|
||||
await ionChange.next();
|
||||
});
|
||||
});
|
||||
test.describe('datetime: time-date wheel', () => {
|
||||
test.beforeEach(({ skip }) => {
|
||||
|
||||
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 52 KiB |
@@ -50,3 +50,17 @@ test.describe('datetime: values', () => {
|
||||
await expect(items).toHaveText(['01', '02', '03']);
|
||||
});
|
||||
});
|
||||
|
||||
test('setting value to empty string should treat it as having no date', async ({ page, skip }) => {
|
||||
skip.rtl();
|
||||
skip.mode('ios');
|
||||
await page.setContent(`
|
||||
<ion-datetime value="" locale="en-US"></ion-datetime>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
// Should render current month with today outlined.
|
||||
const calendarDayToday = page.locator('ion-datetime .calendar-day-today');
|
||||
await expect(calendarDayToday).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { DatetimeParts } from '../datetime-interface';
|
||||
|
||||
import { isSameDay } from './comparison';
|
||||
import { getNumDaysInMonth } from './helpers';
|
||||
|
||||
const twoDigit = (val: number | undefined): string => {
|
||||
@@ -345,7 +346,11 @@ export const calculateHourFromAMPM = (currentParts: DatetimeParts, newAMPM: 'am'
|
||||
* values are valid. For days that do not exist,
|
||||
* the closest valid day is used.
|
||||
*/
|
||||
export const validateParts = (parts: DatetimeParts): DatetimeParts => {
|
||||
export const validateParts = (
|
||||
parts: DatetimeParts,
|
||||
minParts?: DatetimeParts,
|
||||
maxParts?: DatetimeParts
|
||||
): DatetimeParts => {
|
||||
const { month, day, year } = parts;
|
||||
const partsCopy = { ...parts };
|
||||
|
||||
@@ -361,5 +366,66 @@ export const validateParts = (parts: DatetimeParts): DatetimeParts => {
|
||||
partsCopy.day = numDays;
|
||||
}
|
||||
|
||||
/**
|
||||
* If value is same day as min day,
|
||||
* make sure the time value is in bounds.
|
||||
*/
|
||||
if (minParts !== undefined && isSameDay(partsCopy, minParts)) {
|
||||
/**
|
||||
* If the hour is out of bounds,
|
||||
* update both the hour and minute.
|
||||
* This is done so that the new time
|
||||
* is closest to what the user selected.
|
||||
*/
|
||||
if (partsCopy.hour !== undefined && minParts.hour !== undefined) {
|
||||
if (partsCopy.hour < minParts.hour) {
|
||||
partsCopy.hour = minParts.hour;
|
||||
partsCopy.minute = minParts.minute;
|
||||
|
||||
/**
|
||||
* If only the minute is out of bounds,
|
||||
* set it to the min minute.
|
||||
*/
|
||||
} else if (
|
||||
partsCopy.hour === minParts.hour &&
|
||||
partsCopy.minute !== undefined &&
|
||||
minParts.minute !== undefined &&
|
||||
partsCopy.minute < minParts.minute
|
||||
) {
|
||||
partsCopy.minute = minParts.minute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If value is same day as max day,
|
||||
* make sure the time value is in bounds.
|
||||
*/
|
||||
if (maxParts !== undefined && isSameDay(parts, maxParts)) {
|
||||
/**
|
||||
* If the hour is out of bounds,
|
||||
* update both the hour and minute.
|
||||
* This is done so that the new time
|
||||
* is closest to what the user selected.
|
||||
*/
|
||||
if (partsCopy.hour !== undefined && maxParts.hour !== undefined) {
|
||||
if (partsCopy.hour > maxParts.hour) {
|
||||
partsCopy.hour = maxParts.hour;
|
||||
partsCopy.minute = maxParts.minute;
|
||||
/**
|
||||
* If only the minute is out of bounds,
|
||||
* set it to the max minute.
|
||||
*/
|
||||
} else if (
|
||||
partsCopy.hour === maxParts.hour &&
|
||||
partsCopy.minute !== undefined &&
|
||||
maxParts.minute !== undefined &&
|
||||
partsCopy.minute > maxParts.minute
|
||||
) {
|
||||
partsCopy.minute = maxParts.minute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return partsCopy;
|
||||
};
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('footer: basic', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/footer/test/basic?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
||||
57
core/src/components/footer/test/basic/footer.e2e.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('footer: basic', () => {
|
||||
test.describe('footer: rendering', () => {
|
||||
test('should not have visual regressions with basic footer', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-footer>
|
||||
<ion-toolbar>
|
||||
<ion-title>Footer - Default</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
`);
|
||||
|
||||
const footer = page.locator('ion-footer');
|
||||
expect(await footer.screenshot()).toMatchSnapshot(`footer-diff-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('footer: feature rendering', () => {
|
||||
test.beforeEach(({ skip }) => {
|
||||
skip.rtl();
|
||||
});
|
||||
|
||||
test('should not have visual regressions with no border', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-footer class="ion-no-border">
|
||||
<ion-toolbar>
|
||||
<ion-title>Footer - No Border</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
`);
|
||||
|
||||
const footer = page.locator('ion-footer');
|
||||
expect(await footer.screenshot()).toMatchSnapshot(`footer-no-border-diff-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
|
||||
test('should not have visual regressions with translucent footer', async ({ page, skip }) => {
|
||||
skip.mode('md', 'Translucent effect is only available in iOS mode.');
|
||||
skip.browser('firefox', 'Firefox has some issues rendering translucent effects on Linux.');
|
||||
|
||||
await page.setContent(`
|
||||
<ion-footer translucent="true">
|
||||
<div style="position: absolute; top: 0; left: 0; right: 0; bottom: 0">
|
||||
<img style="transform: rotate(145deg) scale(1.5)" src="/src/components/footer/test/img.jpg" />
|
||||
</div>
|
||||
<ion-toolbar>
|
||||
<ion-title>Footer - Translucent</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
`);
|
||||
|
||||
const footer = page.locator('ion-footer');
|
||||
expect(await footer.screenshot()).toMatchSnapshot(`footer-translucent-diff-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 53 KiB |
@@ -15,23 +15,14 @@
|
||||
</head>
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-content>
|
||||
<br />
|
||||
|
||||
<ion-footer>
|
||||
<ion-toolbar>
|
||||
<ion-title>Footer - Default</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
|
||||
<br />
|
||||
|
||||
<ion-footer class="ion-no-border">
|
||||
<ion-toolbar>
|
||||
<ion-title>Footer - No Border</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Content</h1>
|
||||
</ion-content>
|
||||
<ion-footer>
|
||||
<ion-toolbar>
|
||||
<ion-title>Footer</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
</ion-app>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import type { E2EPage } from '@stencil/core/testing';
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
import { scrollToBottom } from '@utils/test';
|
||||
|
||||
describe('footer: fade: iOS', () => {
|
||||
let page: E2EPage;
|
||||
|
||||
beforeEach(async () => {
|
||||
page = await newE2EPage({
|
||||
url: '/src/components/footer/test/fade?ionic:_testing=true&ionic:mode=ios',
|
||||
});
|
||||
});
|
||||
|
||||
it('should match existing visual screenshots', async () => {
|
||||
const compares = [];
|
||||
|
||||
compares.push(await page.compareScreenshot('footer: blurred'));
|
||||
|
||||
await scrollToBottom(page, 'ion-content');
|
||||
|
||||
compares.push(await page.compareScreenshot('footer: not blurred'));
|
||||
|
||||
for (const compare of compares) {
|
||||
expect(compare).toMatchScreenshot();
|
||||
}
|
||||
});
|
||||
});
|
||||
24
core/src/components/footer/test/fade/footer.e2e.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('footer: fade', () => {
|
||||
test.beforeEach(({ skip }) => {
|
||||
skip.rtl();
|
||||
});
|
||||
|
||||
test('should not have visual regressions with fade footer', async ({ page, skip }) => {
|
||||
skip.mode('md', 'Translucent effect is only available in iOS mode.');
|
||||
skip.browser('firefox', 'Firefox has some issues rendering translucent effects on Linux.');
|
||||
|
||||
await page.goto('/src/components/footer/test/fade');
|
||||
|
||||
const footer = page.locator('ion-footer');
|
||||
expect(await footer.screenshot()).toMatchSnapshot(`footer-fade-blurred-diff-${page.getSnapshotSettings()}.png`);
|
||||
|
||||
const content = page.locator('ion-content');
|
||||
await content.evaluate((el: HTMLIonContentElement) => el.scrollToBottom(0));
|
||||
await page.waitForChanges();
|
||||
|
||||
expect(await footer.screenshot()).toMatchSnapshot(`footer-fade-not-blurred-diff-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 49 KiB |
@@ -12,78 +12,73 @@
|
||||
<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>
|
||||
.red {
|
||||
background-color: #ea445a;
|
||||
}
|
||||
|
||||
.green {
|
||||
background-color: #76d672;
|
||||
}
|
||||
|
||||
.blue {
|
||||
background-color: #3478f6;
|
||||
}
|
||||
|
||||
.yellow {
|
||||
background-color: #ffff80;
|
||||
}
|
||||
|
||||
.pink {
|
||||
background-color: #ff6b86;
|
||||
}
|
||||
|
||||
.purple {
|
||||
background-color: #7e34f6;
|
||||
}
|
||||
|
||||
.black {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.orange {
|
||||
background-color: #f69234;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: 10px;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<ion-app>
|
||||
<div class="ion-page">
|
||||
<ion-header translucent="true">
|
||||
<ion-toolbar>
|
||||
<ion-title>Mailboxes</ion-title>
|
||||
<ion-title>Header</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content fullscreen="true">
|
||||
<ion-header collapse="condense">
|
||||
<ion-toolbar>
|
||||
<ion-title size="large">Mailboxes</ion-title>
|
||||
<ion-title size="large">Header</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<div class="grid ion-padding">
|
||||
<div class="grid-item red"></div>
|
||||
<div class="grid-item green"></div>
|
||||
<div class="grid-item blue"></div>
|
||||
<div class="grid-item yellow"></div>
|
||||
<div class="grid-item pink"></div>
|
||||
<div class="grid-item purple"></div>
|
||||
<div class="grid-item black"></div>
|
||||
<div class="grid-item orange"></div>
|
||||
<div class="ion-padding">
|
||||
<h1>Content</h1>
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas blandit, justo vitae rhoncus porttitor,
|
||||
massa elit molestie nisl, ut tincidunt orci enim ac ante. Vestibulum tincidunt dignissim elit. Morbi
|
||||
cursus hendrerit turpis, ut egestas tortor pulvinar sit amet. Interdum et malesuada fames ac ante ipsum
|
||||
primis in faucibus. Phasellus faucibus consequat purus vel mollis. Ut ultricies elit nunc. Quisque
|
||||
ultrices turpis vel augue auctor accumsan. Donec bibendum at nisi vel finibus. Fusce id imperdiet odio.
|
||||
Morbi orci ipsum, imperdiet ut iaculis sit amet, suscipit vulputate felis. Nullam arcu leo, volutpat eu
|
||||
porttitor sed, fringilla et arcu. Pellentesque ac libero sapien. Quisque id dui velit. Mauris et pretium
|
||||
tortor.
|
||||
</p>
|
||||
<p>
|
||||
Ut ultricies id augue vel aliquam. Etiam ornare finibus nisl, nec egestas urna. Nam pellentesque libero
|
||||
nec justo tristique lacinia. In sit amet gravida metus, ac tincidunt mauris. Fusce sit amet tempus turpis.
|
||||
Nulla ligula nunc, vestibulum quis quam in, feugiat aliquet nibh. Quisque in ante non nulla luctus gravida
|
||||
vel at lacus. Vivamus erat magna, elementum et dignissim nec, posuere eu ante. Praesent elementum, arcu
|
||||
scelerisque venenatis sodales, turpis nulla aliquam urna, id hendrerit est orci et purus. Duis sem ipsum,
|
||||
imperdiet eu elit id, tincidunt tempus sapien. Praesent tincidunt, sapien sed rhoncus euismod, lectus
|
||||
velit ornare nunc, dapibus varius turpis leo ut magna.
|
||||
</p>
|
||||
<p>
|
||||
Nam quis quam id ante mattis pulvinar non sed mauris. Donec tempor sed nulla at semper. Vivamus ac nunc
|
||||
bibendum, ullamcorper lacus quis, ornare massa. Cras gravida nibh risus, id sollicitudin eros ultricies
|
||||
non. Integer velit massa, suscipit tincidunt rhoncus ut, lacinia et nisl. Maecenas volutpat ipsum blandit
|
||||
sollicitudin lobortis. Suspendisse potenti. Cras non mi non arcu varius dapibus. Suspendisse maximus eget
|
||||
justo a lobortis. Donec nulla ipsum, efficitur eget velit eget, varius rutrum quam. Nulla metus risus,
|
||||
accumsan a tellus ac, faucibus blandit quam. Donec luctus, nisl ac ultricies ornare, nunc elit finibus
|
||||
magna, id elementum ante urna congue ex. Cras condimentum nisi sollicitudin tortor vestibulum luctus.
|
||||
Curabitur non ipsum et ex vestibulum congue.
|
||||
</p>
|
||||
<p>
|
||||
Maecenas rhoncus elit ut consectetur faucibus. Etiam sed sem sed mauris condimentum viverra sit amet at
|
||||
nibh. Mauris bibendum at purus a cursus. Suspendisse potenti. Donec vel lacus ac odio euismod lacinia id
|
||||
in urna. Donec commodo ipsum augue, at bibendum ex convallis suscipit. Nulla ac rhoncus odio. Aenean
|
||||
elementum est nec arcu ultricies dignissim.
|
||||
</p>
|
||||
<p>
|
||||
Sed tincidunt bibendum massa, egestas bibendum est imperdiet vitae. Fusce dignissim consectetur ante a
|
||||
fermentum. Morbi suscipit turpis sapien. Suspendisse eleifend sapien eget nunc mattis mattis. Phasellus
|
||||
rhoncus sodales libero a imperdiet. Nam in vulputate lectus. Proin accumsan enim non nibh sagittis
|
||||
ultricies. Nullam vitae ultricies nunc. Nullam ultrices dolor nec vehicula posuere.
|
||||
</p>
|
||||
</div>
|
||||
</ion-content>
|
||||
<ion-footer collapse="fade" translucent="true">
|
||||
<div style="position: absolute; top: 0; left: 0; right: 0; bottom: 0">
|
||||
<img src="/src/components/footer/test/img.jpg" />
|
||||
</div>
|
||||
<ion-toolbar>
|
||||
<ion-title>Updated Just Now</ion-title>
|
||||
<ion-title>Footer</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
</div>
|
||||
|
||||
BIN
core/src/components/footer/test/img.jpg
Normal file
|
After Width: | Height: | Size: 110 KiB |
@@ -1,32 +0,0 @@
|
||||
import type { E2EPage } from '@stencil/core/testing';
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
import { scrollToBottom } from '@utils/test';
|
||||
|
||||
/**
|
||||
* This test suite verifies that the fade effect for iOS is working correctly
|
||||
* when the `ion-footer` is using a custom scroll target with the `.ion-content-scroll-host`
|
||||
* selector.
|
||||
*/
|
||||
describe('footer: fade with custom scroll target: iOS', () => {
|
||||
let page: E2EPage;
|
||||
|
||||
beforeEach(async () => {
|
||||
page = await newE2EPage({
|
||||
url: '/src/components/footer/test/scroll-target?ionic:_testing=true&ionic:mode=ios',
|
||||
});
|
||||
});
|
||||
|
||||
it('should match existing visual screenshots', async () => {
|
||||
const compares = [];
|
||||
|
||||
compares.push(await page.compareScreenshot('footer: blurred'));
|
||||
|
||||
await scrollToBottom(page, '#scroll-target');
|
||||
|
||||
compares.push(await page.compareScreenshot('footer: not blurred'));
|
||||
|
||||
for (const compare of compares) {
|
||||
expect(compare).toMatchScreenshot();
|
||||
}
|
||||
});
|
||||
});
|
||||
33
core/src/components/footer/test/scroll-target/footer.e2e.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('footer: scroll-target', () => {
|
||||
test.beforeEach(({ skip }) => {
|
||||
skip.rtl();
|
||||
});
|
||||
|
||||
/**
|
||||
* This test suite verifies that the fade effect for iOS is working correctly
|
||||
* when the `ion-footer` is using a custom scroll target with the `.ion-content-scroll-host`
|
||||
* selector.
|
||||
*/
|
||||
test('should not have visual regressions with custom scroll target footer', async ({ page, skip }) => {
|
||||
skip.mode('md', 'Translucent effect is only available in iOS mode.');
|
||||
skip.browser('firefox', 'Firefox has some issues rendering translucent effects on Linux.');
|
||||
|
||||
await page.goto('/src/components/footer/test/scroll-target');
|
||||
|
||||
const footer = page.locator('ion-footer');
|
||||
expect(await footer.screenshot()).toMatchSnapshot(
|
||||
`footer-fade-scroll-target-blurred-diff-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
|
||||
const scrollTarget = page.locator('#scroll-target');
|
||||
await scrollTarget.evaluate((el: HTMLDivElement) => (el.scrollTop = el.scrollHeight));
|
||||
await page.waitForChanges();
|
||||
|
||||
expect(await footer.screenshot()).toMatchSnapshot(
|
||||
`footer-fade-scroll-target-not-blurred-diff-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 49 KiB |
@@ -2,7 +2,7 @@
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Footer - Fade (custom scroll host)</title>
|
||||
<title>Footer - Scroll Target</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
@@ -12,49 +12,8 @@
|
||||
<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>
|
||||
.red {
|
||||
background-color: #ea445a;
|
||||
}
|
||||
|
||||
.green {
|
||||
background-color: #76d672;
|
||||
}
|
||||
|
||||
.blue {
|
||||
background-color: #3478f6;
|
||||
}
|
||||
|
||||
.yellow {
|
||||
background-color: #ffff80;
|
||||
}
|
||||
|
||||
.pink {
|
||||
background-color: #ff6b86;
|
||||
}
|
||||
|
||||
.purple {
|
||||
background-color: #7e34f6;
|
||||
}
|
||||
|
||||
.black {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.orange {
|
||||
background-color: #f69234;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: 10px;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
#scroll-target {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -68,32 +27,67 @@
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<div class="ion-page">
|
||||
<ion-header translucent="true">
|
||||
<ion-toolbar>
|
||||
<ion-title>Mailboxes</ion-title>
|
||||
<ion-title>Header</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content fullscreen="true" scroll-y="false">
|
||||
<div id="scroll-target" class="ion-content-scroll-host">
|
||||
<div class="grid ion-padding">
|
||||
<div class="grid-item red"></div>
|
||||
<div class="grid-item green"></div>
|
||||
<div class="grid-item blue"></div>
|
||||
<div class="grid-item yellow"></div>
|
||||
<div class="grid-item pink"></div>
|
||||
<div class="grid-item purple"></div>
|
||||
<div class="grid-item black"></div>
|
||||
<div class="grid-item orange"></div>
|
||||
</div>
|
||||
<h1>Content</h1>
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas blandit, justo vitae rhoncus porttitor,
|
||||
massa elit molestie nisl, ut tincidunt orci enim ac ante. Vestibulum tincidunt dignissim elit. Morbi
|
||||
cursus hendrerit turpis, ut egestas tortor pulvinar sit amet. Interdum et malesuada fames ac ante ipsum
|
||||
primis in faucibus. Phasellus faucibus consequat purus vel mollis. Ut ultricies elit nunc. Quisque
|
||||
ultrices turpis vel augue auctor accumsan. Donec bibendum at nisi vel finibus. Fusce id imperdiet odio.
|
||||
Morbi orci ipsum, imperdiet ut iaculis sit amet, suscipit vulputate felis. Nullam arcu leo, volutpat eu
|
||||
porttitor sed, fringilla et arcu. Pellentesque ac libero sapien. Quisque id dui velit. Mauris et pretium
|
||||
tortor.
|
||||
</p>
|
||||
<p>
|
||||
Ut ultricies id augue vel aliquam. Etiam ornare finibus nisl, nec egestas urna. Nam pellentesque libero
|
||||
nec justo tristique lacinia. In sit amet gravida metus, ac tincidunt mauris. Fusce sit amet tempus turpis.
|
||||
Nulla ligula nunc, vestibulum quis quam in, feugiat aliquet nibh. Quisque in ante non nulla luctus gravida
|
||||
vel at lacus. Vivamus erat magna, elementum et dignissim nec, posuere eu ante. Praesent elementum, arcu
|
||||
scelerisque venenatis sodales, turpis nulla aliquam urna, id hendrerit est orci et purus. Duis sem ipsum,
|
||||
imperdiet eu elit id, tincidunt tempus sapien. Praesent tincidunt, sapien sed rhoncus euismod, lectus
|
||||
velit ornare nunc, dapibus varius turpis leo ut magna.
|
||||
</p>
|
||||
<p>
|
||||
Nam quis quam id ante mattis pulvinar non sed mauris. Donec tempor sed nulla at semper. Vivamus ac nunc
|
||||
bibendum, ullamcorper lacus quis, ornare massa. Cras gravida nibh risus, id sollicitudin eros ultricies
|
||||
non. Integer velit massa, suscipit tincidunt rhoncus ut, lacinia et nisl. Maecenas volutpat ipsum blandit
|
||||
sollicitudin lobortis. Suspendisse potenti. Cras non mi non arcu varius dapibus. Suspendisse maximus eget
|
||||
justo a lobortis. Donec nulla ipsum, efficitur eget velit eget, varius rutrum quam. Nulla metus risus,
|
||||
accumsan a tellus ac, faucibus blandit quam. Donec luctus, nisl ac ultricies ornare, nunc elit finibus
|
||||
magna, id elementum ante urna congue ex. Cras condimentum nisi sollicitudin tortor vestibulum luctus.
|
||||
Curabitur non ipsum et ex vestibulum congue.
|
||||
</p>
|
||||
<p>
|
||||
Maecenas rhoncus elit ut consectetur faucibus. Etiam sed sem sed mauris condimentum viverra sit amet at
|
||||
nibh. Mauris bibendum at purus a cursus. Suspendisse potenti. Donec vel lacus ac odio euismod lacinia id
|
||||
in urna. Donec commodo ipsum augue, at bibendum ex convallis suscipit. Nulla ac rhoncus odio. Aenean
|
||||
elementum est nec arcu ultricies dignissim.
|
||||
</p>
|
||||
<p>
|
||||
Sed tincidunt bibendum massa, egestas bibendum est imperdiet vitae. Fusce dignissim consectetur ante a
|
||||
fermentum. Morbi suscipit turpis sapien. Suspendisse eleifend sapien eget nunc mattis mattis. Phasellus
|
||||
rhoncus sodales libero a imperdiet. Nam in vulputate lectus. Proin accumsan enim non nibh sagittis
|
||||
ultricies. Nullam vitae ultricies nunc. Nullam ultrices dolor nec vehicula posuere.
|
||||
</p>
|
||||
</div>
|
||||
</ion-content>
|
||||
<ion-footer collapse="fade" translucent="true">
|
||||
<div style="position: absolute; top: 0; left: 0; right: 0; bottom: 0">
|
||||
<img src="/src/components/footer/test/img.jpg" />
|
||||
</div>
|
||||
<ion-toolbar>
|
||||
<ion-title>Updated Just Now</ion-title>
|
||||
<ion-title>Footer</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
import { checkComponentModeClasses } from '@utils/test';
|
||||
|
||||
test('footer: translucent', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/footer/test/translucent?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const globalMode = await page.evaluate(() => document.documentElement.getAttribute('mode'));
|
||||
await checkComponentModeClasses(await page.find('ion-footer'), globalMode!, 'footer-translucent');
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
||||
@@ -1,171 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Header - Translucent</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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-content fullscreen>
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col size="6">
|
||||
<f class="red"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="green"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="blue"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="yellow"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="pink"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="purple"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="black"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="orange"></f>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae lobortis felis, eu sodales enim. Nam
|
||||
risus nibh, placerat at rutrum ac, vehicula vel velit. Lorem ipsum dolor sit amet, consectetur adipiscing
|
||||
elit. Vestibulum quis elementum ligula, ac aliquet nulla. Mauris non placerat mauris. Aenean dignissim lacinia
|
||||
porttitor. Praesent fringilla at est et ullamcorper. In ac ante ac massa porta venenatis ut id nibh. Fusce
|
||||
felis neque, aliquet in velit vitae, venenatis euismod libero. Donec vulputate, urna sed sagittis tempor, mi
|
||||
arcu tristique lacus, eget fringilla urna sem eget felis. Fusce dignissim lacus a scelerisque vehicula. Nulla
|
||||
nec enim nunc. Quisque nec dui eu nibh pulvinar bibendum quis ut nunc. Duis ex odio, sollicitudin ac mollis
|
||||
nec, fringilla non lacus. Maecenas sed tincidunt urna. Nunc feugiat maximus venenatis. Donec porttitor, felis
|
||||
eget porttitor tempor, quam nulla dapibus nisl, sit amet posuere sapien sapien malesuada tortor. Pellentesque
|
||||
habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque luctus, sapien nec
|
||||
tincidunt efficitur, nibh turpis faucibus felis, in sodales massa augue nec erat. Morbi sollicitudin nisi ex,
|
||||
et gravida nisi euismod eu. Suspendisse hendrerit dapibus orci, non viverra neque vestibulum id. Quisque vitae
|
||||
interdum ligula, quis consectetur nibh. Phasellus in mi at erat ultrices semper. Fusce sollicitudin at dolor
|
||||
ac lobortis. Morbi sit amet sem quis nulla pellentesque imperdiet. Nullam eu sem a enim maximus eleifend non
|
||||
vulputate leo. Proin quis congue lacus. Pellentesque placerat, quam at tempus pulvinar, nisl ligula tempor
|
||||
risus, quis pretium arcu odio et nulla. Nullam mollis consequat pharetra. Phasellus dictum velit sed purus
|
||||
mattis maximus. In molestie eget massa ut dignissim. In a interdum elit. In finibus nibh a mauris lobortis
|
||||
aliquet. Proin rutrum varius consequat. In mollis dapibus nisl, eu finibus urna viverra ac. Quisque
|
||||
scelerisque nisl eu suscipit consectetur.
|
||||
</p>
|
||||
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col size="6">
|
||||
<f class="red"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="green"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="blue"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="yellow"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="pink"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="purple"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="black"></f>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<f class="orange"></f>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-content>
|
||||
|
||||
<ion-footer translucent>
|
||||
<ion-toolbar>
|
||||
<ion-title>Footer - Translucent</ion-title>
|
||||
</ion-toolbar>
|
||||
<ion-toolbar color="primary">
|
||||
<ion-title>Primary - Translucent</ion-title>
|
||||
</ion-toolbar>
|
||||
<ion-toolbar color="secondary">
|
||||
<ion-title>Secondary - Translucent</ion-title>
|
||||
</ion-toolbar>
|
||||
<ion-toolbar color="tertiary">
|
||||
<ion-title>Tertiary - Translucent</ion-title>
|
||||
</ion-toolbar>
|
||||
<ion-toolbar color="success">
|
||||
<ion-title>Success - Translucent</ion-title>
|
||||
</ion-toolbar>
|
||||
<ion-toolbar color="warning">
|
||||
<ion-title>Warning - Translucent</ion-title>
|
||||
</ion-toolbar>
|
||||
<ion-toolbar color="danger">
|
||||
<ion-title>Danger - Translucent</ion-title>
|
||||
</ion-toolbar>
|
||||
<ion-toolbar color="light">
|
||||
<ion-title>Light - Translucent</ion-title>
|
||||
</ion-toolbar>
|
||||
<ion-toolbar color="medium">
|
||||
<ion-title>Medium - Translucent</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
</ion-app>
|
||||
|
||||
<style>
|
||||
f {
|
||||
display: block;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.red {
|
||||
background-color: #ea445a;
|
||||
}
|
||||
|
||||
.green {
|
||||
background-color: #76d672;
|
||||
}
|
||||
|
||||
.blue {
|
||||
background-color: #3478f6;
|
||||
}
|
||||
|
||||
.yellow {
|
||||
background-color: #ffff80;
|
||||
}
|
||||
|
||||
.pink {
|
||||
background-color: #ff6b86;
|
||||
}
|
||||
|
||||
.purple {
|
||||
background-color: #7e34f6;
|
||||
}
|
||||
|
||||
.black {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.orange {
|
||||
background-color: #f69234;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
@@ -12,6 +12,7 @@
|
||||
<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>
|
||||
:root {
|
||||
--ion-safe-area-bottom: 40px;
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('item-sliding: basic', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/item-sliding/test/basic?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
||||
|
||||
test('item-sliding:rtl: basic', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/item-sliding/test/basic?ionic:_testing=true&rtl=true',
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
||||
@@ -19,33 +19,17 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Item Sliding - Basic</ion-title>
|
||||
<ion-buttons slot="secondary">
|
||||
<ion-button onclick="changeDynamicText()">Dynamic</ion-button>
|
||||
</ion-buttons>
|
||||
<ion-buttons slot="primary">
|
||||
<ion-button onclick="reload()">Reload</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-refresher id="refresher">
|
||||
<ion-refresher-content
|
||||
pulling-text="Pull to refresh..."
|
||||
refreshing-spinner="bubbles"
|
||||
refreshing-text="Refreshing..."
|
||||
>
|
||||
</ion-refresher-content>
|
||||
</ion-refresher>
|
||||
|
||||
<div class="ion-padding">
|
||||
<ion-button expand="block" onclick="toggleSliding()">Toggle sliding</ion-button>
|
||||
<ion-button expand="block" onclick="toggleDynamicOptions()">Toggle Dynamic Options</ion-button>
|
||||
<ion-button expand="block" onclick="closeOpened()">Close Opened Items</ion-button>
|
||||
<ion-button expand="block" onclick="openItem('start')">Open Item Start</ion-button>
|
||||
<ion-button expand="block" onclick="openItem('end')">Open Item End</ion-button>
|
||||
<ion-button expand="block" onclick="openItemOneSide()">Open Item with only one side</ion-button>
|
||||
<ion-button expand="block" onclick="setDynaicItem()">Swap dynamic item</ion-button>
|
||||
<ion-button expand="block" id="openItemStart" onclick="openItem('start')">Open Item Start</ion-button>
|
||||
<ion-button expand="block" id="openItemEnd" onclick="openItem('end')">Open Item End</ion-button>
|
||||
<ion-button expand="block" id="openItemOneSide" onclick="openItemOneSide()"
|
||||
>Open Item with only one side</ion-button
|
||||
>
|
||||
</div>
|
||||
|
||||
<ion-list id="list">
|
||||
@@ -59,66 +43,6 @@
|
||||
</ion-item>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="item6">
|
||||
<ion-item>
|
||||
<ion-label> One Line, dynamic option and text </ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options class="show-options">
|
||||
<ion-item-option color="primary">
|
||||
<ion-icon slot="start" ios="ellipsis-horizontal" md="ellipsis-vertical"></ion-icon>
|
||||
<span class="more-text"></span>
|
||||
</ion-item-option>
|
||||
<ion-item-option color="secondary" onclick="archive('item6')">
|
||||
<ion-icon slot="start" name="archive"></ion-icon>
|
||||
<span class="archive-text"></span>
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="two-options">
|
||||
<ion-item>
|
||||
<ion-label> Two options, one dynamic option and text </ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options side="start">
|
||||
<ion-item-option color="primary">
|
||||
<ion-icon slot="icon-only" ios="ellipsis-horizontal" md="ellipsis-vertical"></ion-icon>
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
<ion-item-options side="end" class="show-options">
|
||||
<ion-item-option color="primary">
|
||||
<ion-icon slot="start" ios="ellipsis-horizontal" md="ellipsis-vertical"></ion-icon>
|
||||
<span class="more-text"></span>
|
||||
</ion-item-option>
|
||||
<ion-item-option color="secondary" onclick="archive('two-options')">
|
||||
<ion-icon slot="start" name="archive"></ion-icon>
|
||||
<span class="archive-text"></span>
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="item100">
|
||||
<ion-item href="#">
|
||||
<ion-label>
|
||||
<h2>HubStruck Notifications</h2>
|
||||
<p>A new message from a repo in your network</p>
|
||||
<p>Oceanic Next has joined your network</p>
|
||||
</ion-label>
|
||||
<ion-note slot="end"> 10:45 AM </ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item-options side="start">
|
||||
<ion-item-option onclick="noclose('item100')"> No close </ion-item-option>
|
||||
</ion-item-options>
|
||||
<ion-item-options side="end">
|
||||
<ion-item-option color="danger" onclick="unread('item100')">
|
||||
<ion-icon slot="icon-only" name="trash"></ion-icon>
|
||||
</ion-item-option>
|
||||
<ion-item-option onclick="unread('item100')">
|
||||
<ion-icon slot="icon-only" name="star"></ion-icon>
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="item100">
|
||||
<ion-item href="#">
|
||||
<ion-label>
|
||||
@@ -141,15 +65,15 @@
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="item0">
|
||||
<ion-item onclick="clickedItem('item0')">
|
||||
<ion-item>
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>RIGHT side - no icons</h2>
|
||||
<p>Hey do you want to go to the game tonight?</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options class="sliding-enabled">
|
||||
<ion-item-option color="primary" onclick="archive('item0')">Archive</ion-item-option>
|
||||
<ion-item-option color="danger" onclick="del('item0')">Delete</ion-item-option>
|
||||
<ion-item-option color="primary">Archive</ion-item-option>
|
||||
<ion-item-option color="danger">Delete</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
@@ -161,8 +85,8 @@
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options side="start" class="sliding-enabled">
|
||||
<ion-item-option color="primary" onclick="archive('item1')">Archive</ion-item-option>
|
||||
<ion-item-option color="danger" onclick="del('item1')">Delete</ion-item-option>
|
||||
<ion-item-option color="primary">Archive</ion-item-option>
|
||||
<ion-item-option color="danger">Delete</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
@@ -174,138 +98,24 @@
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options side="start" class="sliding-enabled">
|
||||
<ion-item-option color="secondary" expandable onclick="unread('item2')">
|
||||
<ion-item-option color="secondary" expandable>
|
||||
<ion-icon slot="start" name="checkmark"></ion-icon>
|
||||
Unread
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
|
||||
<ion-item-options side="end" class="sliding-enabled">
|
||||
<ion-item-option color="primary" onclick="archive('item2')">
|
||||
<ion-icon slot="start" name="mail"></ion-icon>
|
||||
Archive
|
||||
</ion-item-option>
|
||||
<ion-item-option color="danger" onclick="del('item2')" expandable>
|
||||
<ion-icon slot="start" name="trash"></ion-icon>
|
||||
Delete
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="item3">
|
||||
<ion-item detail>
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>RIGHT/LEFT side - icons (slot="start")</h2>
|
||||
<p>I think I figured out how to get more Mountain Dew</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options side="start" icon-start class="sliding-enabled">
|
||||
<ion-item-option color="secondary" expandable onclick="unread('item3')">
|
||||
<ion-icon slot="start" name="checkmark"></ion-icon>
|
||||
Unread
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
|
||||
<ion-item-options icon-start>
|
||||
<ion-item-option color="primary" onclick="archive('item3')">
|
||||
<ion-icon slot="start" name="mail"></ion-icon>
|
||||
Archive
|
||||
</ion-item-option>
|
||||
<ion-item-option color="danger" onclick="del('item3')" expandable class="sliding-enabled">
|
||||
<ion-icon slot="start" name="trash"></ion-icon>
|
||||
Delete
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="item4">
|
||||
<ion-item>
|
||||
<ion-icon name="mail" slot="start"></ion-icon>
|
||||
<ion-label> One Line w/ Icon, div only text </ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options icon-start>
|
||||
<ion-item-option color="primary" onclick="archive('item4')" expandable class="sliding-enabled">
|
||||
<ion-icon slot="start" name="archive"></ion-icon>
|
||||
Archive
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="item5" class="sliding-enabled">
|
||||
<ion-item>
|
||||
<ion-avatar slot="start">
|
||||
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</ion-avatar>
|
||||
<ion-label> One Line w/ Avatar, div only text </ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options>
|
||||
<ion-item-option color="primary" expandable>
|
||||
<ion-icon slot="start" ios="ellipsis-horizontal" md="ellipsis-vertical"></ion-icon>
|
||||
More
|
||||
</ion-item-option>
|
||||
<ion-item-option color="secondary" onclick="archive('item5')">
|
||||
<ion-icon slot="start" name="archive"></ion-icon>
|
||||
Archive
|
||||
</ion-item-option>
|
||||
<ion-item-option color="light" onclick="del('item5')">
|
||||
<ion-icon slot="start" name="trash"></ion-icon>
|
||||
Delete
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="item7">
|
||||
<ion-item>
|
||||
<ion-label> One Line, dynamic icon-start option </ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options icon-start>
|
||||
<ion-item-option color="primary">
|
||||
<ion-icon slot="start" ios="ellipsis-horizontal" md="ellipsis-vertical"></ion-icon>
|
||||
<span class="more-text"></span>
|
||||
<ion-icon slot="start" name="mail"></ion-icon>
|
||||
Archive
|
||||
</ion-item-option>
|
||||
<ion-item-option color="secondary" onclick="archive('item7')">
|
||||
<ion-icon slot="start" name="archive"></ion-icon>
|
||||
<span class="archive-text"></span>
|
||||
<ion-item-option color="danger" expandable>
|
||||
<ion-icon slot="start" name="trash"></ion-icon>
|
||||
Delete
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="item8">
|
||||
<ion-item>
|
||||
<ion-thumbnail slot="start">
|
||||
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</ion-thumbnail>
|
||||
<ion-label>
|
||||
<h2>DOWNLOAD</h2>
|
||||
<p>Paragraph text.</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options>
|
||||
<ion-item-option color="primary" onclick="archive('item8')">
|
||||
<ion-icon name="archive"></ion-icon>Archive
|
||||
</ion-item-option>
|
||||
<ion-item-option color="secondary" expandable onclick="download('item8')">
|
||||
<ion-icon slot="start" name="download" class="download-hide"></ion-icon>
|
||||
<div class="download-hide">Download</div>
|
||||
|
||||
<ion-icon slot="start" class="download-spinner" name="refresh"></ion-icon>
|
||||
<div class="download-spinner">Loading...</div>
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="item9">
|
||||
<ion-item>
|
||||
<ion-thumbnail slot="start">
|
||||
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</ion-thumbnail>
|
||||
<ion-label>
|
||||
<h2>ion-item-sliding without options (no sliding)</h2>
|
||||
<p>Paragraph text.</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="item10">
|
||||
<ion-item detail>
|
||||
<ion-label class="ion-text-wrap">
|
||||
@@ -351,81 +161,10 @@
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item-sliding id="dynamic-item">
|
||||
<ion-item>
|
||||
<ion-label>Dynamic First Item</ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options side="end">
|
||||
<ion-item-option color="tertiary" expandable> First Item Options </ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
<ion-item>
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>Normal ion-item (no sliding)</h2>
|
||||
<p>Paragraph text.</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item onclick="clickedItem('item9')">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>Normal button (no sliding)</h2>
|
||||
<p>Hey do you want to go to the game tonight?</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</div>
|
||||
</ion-list>
|
||||
|
||||
<script>
|
||||
const setDynaicItem = () => {
|
||||
const sliding = document.querySelector('#dynamic-item');
|
||||
sliding.innerHTML = `
|
||||
<ion-item>
|
||||
<ion-label>Dynamic Second Item</ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options side="end">
|
||||
<ion-item-option color="tertiary" expandable>
|
||||
Second Item Options
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
`;
|
||||
};
|
||||
|
||||
var dynamicSlidingEnabled = document.getElementsByClassName('sliding-enabled');
|
||||
|
||||
// Toggle the dynamic options
|
||||
var dynamicShowOptions = document.getElementsByClassName('show-options');
|
||||
toggleDynamicOptions();
|
||||
|
||||
function toggleDynamicOptions() {
|
||||
// TODO the element needs to be removed / added to the DOM
|
||||
}
|
||||
|
||||
// Change the text for the more and archive buttons
|
||||
var dynamicText = true;
|
||||
var moreTextSpans = document.getElementsByClassName('more-text');
|
||||
var archiveTextSpans = document.getElementsByClassName('archive-text');
|
||||
changeDynamicText();
|
||||
|
||||
function changeDynamicText() {
|
||||
dynamicText = !dynamicText;
|
||||
|
||||
for (var i = 0; i < moreTextSpans.length; i++) {
|
||||
var moreText = dynamicText ? 'Changed More' : 'Dynamic More';
|
||||
moreTextSpans[i].innerHTML = moreText;
|
||||
}
|
||||
|
||||
for (var i = 0; i < archiveTextSpans.length; i++) {
|
||||
var archiveText = dynamicText ? 'Changed Archive' : 'Dynamic Archive';
|
||||
archiveTextSpans[i].innerHTML = archiveText;
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSliding() {
|
||||
// this.slidingEnabled = !this.slidingEnabled;
|
||||
}
|
||||
|
||||
function closeOpened() {
|
||||
var list = document.getElementById('list');
|
||||
list.closeSlidingItems();
|
||||
@@ -441,89 +180,14 @@
|
||||
item.open();
|
||||
}
|
||||
|
||||
function noclose(item) {
|
||||
var itemEle = document.getElementById(item);
|
||||
console.log('no close', itemEle);
|
||||
}
|
||||
|
||||
function unread(item) {
|
||||
closeSlidingItem('UNREAD', item);
|
||||
}
|
||||
|
||||
function archive(item) {
|
||||
closeSlidingItem('ARCHIVE', item);
|
||||
}
|
||||
|
||||
function del(item) {
|
||||
closeSlidingItem('DELETE', item);
|
||||
}
|
||||
|
||||
function download(item) {
|
||||
var itemEle = document.getElementById(item);
|
||||
console.log(itemEle);
|
||||
itemEle.classList.add('downloading');
|
||||
setTimeout(() => {
|
||||
alert('Item was downloaded!');
|
||||
|
||||
itemEle.classList.remove('downloading');
|
||||
itemEle.close();
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
function closeSlidingItem(option, item) {
|
||||
var itemEle = document.getElementById(item);
|
||||
|
||||
// TODO open alert instead
|
||||
if (itemEle) {
|
||||
itemEle.close();
|
||||
}
|
||||
console.log(option, itemEle);
|
||||
}
|
||||
|
||||
function clickedItem(item) {
|
||||
var itemEle = document.getElementById(item);
|
||||
console.log('Clicked, ion-item', itemEle);
|
||||
}
|
||||
|
||||
function reload() {
|
||||
window.location.reload();
|
||||
}
|
||||
document.addEventListener('ionSwipe', (ev) => console.log('SWIPE!!', ev.detail));
|
||||
document.addEventListener('ionDrag', (ev) => {
|
||||
// console.log('DRAG!!', ev.detail);
|
||||
|
||||
let slidingRatio = ev.target.getSlidingRatio();
|
||||
console.log('sliding', slidingRatio);
|
||||
|
||||
if (slidingRatio > 0) {
|
||||
// positive
|
||||
console.log('right side');
|
||||
} else {
|
||||
// negative
|
||||
console.log('left side');
|
||||
}
|
||||
if (Math.abs(slidingRatio) > 1) {
|
||||
console.log('overscroll');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.download-spinner {
|
||||
display: none;
|
||||
}
|
||||
|
||||
svg circle {
|
||||
stroke: white;
|
||||
}
|
||||
|
||||
.downloading .download-spinner {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.downloading .download-hide {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
</body>
|
||||
|
||||
@@ -1,14 +1,52 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
import { dragElementBy, test } from '@utils/test/playwright';
|
||||
|
||||
import { testSlidingItem } from '../test.utils';
|
||||
|
||||
test.describe('item-sliding: basic', () => {
|
||||
test.beforeEach(async ({ skip }) => {
|
||||
skip.mode('ios', "item-sliding doesn't have mode-specific styling");
|
||||
});
|
||||
|
||||
test('should not have visual regressions', async ({ page, browserName }, testInfo) => {
|
||||
// TODO(FW-2608)
|
||||
test.fixme(
|
||||
testInfo.project.metadata.rtl === true && (browserName === 'firefox' || browserName === 'webkit'),
|
||||
'https://github.com/ionic-team/ionic-framework/issues/26103'
|
||||
);
|
||||
|
||||
await page.goto(`/src/components/item-sliding/test/basic`);
|
||||
const item = page.locator('#item2');
|
||||
|
||||
await testSlidingItem(page, item, 'start', true);
|
||||
await testSlidingItem(page, item, 'end');
|
||||
});
|
||||
|
||||
// mouse gesture is flaky on CI, skip for now
|
||||
test.fixme('should open when swiped', async ({ page, skip }) => {
|
||||
skip.rtl();
|
||||
skip.browser(
|
||||
(browserName: string) => browserName !== 'chromium',
|
||||
'dragElementBy is flaky outside of Chrome browsers.'
|
||||
);
|
||||
|
||||
await page.goto(`/src/components/item-sliding/test/basic`);
|
||||
const item = page.locator('#item2');
|
||||
|
||||
await dragElementBy(item, page, -150);
|
||||
await page.waitForChanges();
|
||||
|
||||
// item-sliding doesn't have an easy way to tell whether it's fully open so just screenshot it
|
||||
expect(await item.screenshot()).toMatchSnapshot(`item-sliding-gesture-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
|
||||
test('should not scroll when the item-sliding is swiped', async ({ page, skip }) => {
|
||||
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
||||
skip.rtl();
|
||||
|
||||
await page.goto(`/src/components/item-sliding/test/basic`);
|
||||
|
||||
const itemSlidingEl = page.locator('#two-options');
|
||||
const itemSlidingEl = page.locator('#item2');
|
||||
const scrollEl = page.locator('ion-content .inner-scroll');
|
||||
|
||||
expect(await scrollEl.evaluate((el: HTMLElement) => el.scrollTop)).toEqual(0);
|
||||
|
||||