Compare commits

..

17 Commits

Author SHA1 Message Date
github-actions
d0f7b8f443 v6.0.16 2022-04-08 13:25:35 +00:00
Liam DeBeasi
fb994fa9a7 fix(angular): button components now route correctly without reload (#25071) 2022-04-08 09:21:56 -04:00
Liam DeBeasi
a83fa402cf merge release-6.0.15
Release 6.0.15
2022-04-06 16:08:26 -04:00
github-actions
9532d04608 v6.0.15 2022-04-06 19:04:14 +00:00
Liam DeBeasi
bafd1871ce merge release-6.0.14
Release 6.0.14
2022-03-30 09:45:18 -04:00
Liam DeBeasi
7f3de340a7 merge release-6.0.13
Release 6.0.13
2022-03-23 09:39:28 -04:00
Liam DeBeasi
60dfe41741 merge release-6.0.12
Release 6.0.12
2022-03-16 09:37:12 -04:00
Liam DeBeasi
c983abeb3e merge release-6.0.11
Release 6.0.11
2022-03-10 08:54:21 -05:00
Liam DeBeasi
80022a36ae merge release-6.0.10
Release 6.0.10
2022-03-02 17:42:31 -05:00
Sean Perkins
d1602183a7 merge release-6.0.9
Release 6.0.9
2022-02-23 13:14:51 -05:00
Liam DeBeasi
59ed574685 merge release-6.0.8
Release 6.0.8
2022-02-15 16:49:10 -05:00
Liam DeBeasi
4fa8565788 merge release-6.0.7
Release 6.0.7
2022-02-09 11:45:31 -05:00
Liam DeBeasi
544c510ec8 merge release-6.0.6
Release 6.0.6
2022-02-09 10:43:21 -05:00
Liam DeBeasi
e6322ebcff merge release-6.0.5
Release 6.0.5
2022-02-02 10:02:56 -05:00
Liam DeBeasi
4025eafe3b merge release-6.0.4
Release 6.0.4
2022-01-26 15:36:18 -05:00
Liam DeBeasi
4785a7a929 merge release-6.0.3
Release 6.0.3
2022-01-19 10:21:21 -05:00
Liam DeBeasi
7d562e1e03 merge release-6.0.2
Release 6.0.2
2022-01-11 12:32:33 -05:00
4320 changed files with 205730 additions and 188281 deletions

View File

@@ -140,13 +140,12 @@ Before creating a pull request, please read our requirements that explains the m
#### Modifying Documentation
- Changes to manually written documentation should be made in the `ionic-docs` repo: https://github.com/ionic-team/ionic-docs/tree/main/docs
- In your `ionic-docs` PR, please add a link back to the related `ionic-framework` PR.
- Changes to auto generated documentation should be made in the `ionic-framework` repo. These can be done in the same PR as your fix or feature.
- Run `npm run build` and commit all updates to ensure your changes make it into the generated documentation.
- `Usage`: update the component's usage examples in the component's `usage/` directory.
- `Properties`, `Events`, or `Methods`: update the component's TypeScript file (`*.tsx`).
- `CSS Custom Properties`: update the component's main Sass file (`*.scss`).
1. Locate the `readme.md` file in the component's directory.
2. Modify the documentation **above** the line that says `<!-- Auto Generated Below -->` in this file.
3. To update any of the auto generated documentation below that line, make the relevant changes in the following places:
- `Usage`: update the component's usage examples in the component's `usage/` directory
- `Properties`, `Events`, or `Methods`: update the component's TypeScript file (`*.tsx`)
- `CSS Custom Properties`: update the component's main Sass file (`*.scss`)
#### Modifying Tests
@@ -231,12 +230,6 @@ Before creating a pull request, please read our requirements that explains the m
2. See the [Creating a pull request from a fork](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) GitHub help article for more information.
3. Please fill out the provided Pull Request template to the best of your ability and include any issues that are related.
### Review Process for Feature PRs
The team has an internal design process for new Ionic features, which must be completed before the PR can be reviewed or merged. As a result of the design process, community feature PRs are subject to large changes. In some cases, the team may instead create a separate PR using pieces of the community PR. Either way, you will always receive co-author commit credit when the feature is merged.
To expedite the process, please ensure that all feature PRs have an associated issue created, with a clear use case for why the feature should be added to Ionic.
## Commit Message Guidelines

View File

@@ -21,7 +21,6 @@ body:
- label: v4.x
- label: v5.x
- label: v6.x
- label: Nightly
- type: textarea
attributes:
label: Current Behavior

261
.github/PROCESS.md vendored Normal file
View File

@@ -0,0 +1,261 @@
# Process
This document is to describe the internal process that the Ionic team uses for issue management, project planning and the development workflow.
## Table of contents
* [Project Boards](#project-boards)
* [Managing Issues](#managing-issues)
* [Workflow](#workflow)
* [Releasing](#releasing)
## Project Boards
The project boards are located under the `Projects` tab in GitHub: https://github.com/ionic-team/ionic/projects/
### Core Project Board
The `Core` project board contains issues related to the `@ionic/core` package. A description of each column is below.
#### Backlog :robot:
Contains up to 20 issues that are important to work on soon but we don't think we can fit in the current sprint. If we finish everything we planned for the week we can pull from this column. Issues will automatically move to this column when they are added to the project board.
#### On Deck :baseball:
Contains issues that we believe we can accomplish in the current sprint. Issues should be manually moved to this column when we have our sprint planning meeting.
#### In Progress :person_fencing:
Issues and pull requests that are currently being worked on. Issues should be manually moved to this column and assigned to yourself when you begin working on them. Pull requests are automatically added to this column when added to the project board.
#### Needs Review :thinking:
Issues and pull requests that need review. Pull requests will automatically move here when a reviewer requests changes, or it no longer meets the minimum number of required approving reviews.
#### Done :tada:
Issues and pull requests that are completed. Issues will automatically move here when they are closed. Pull requests will automatically moved here when they are merged or closed with unmerged commits.
## Managing Issues
### Issues to Triage
The issues that need to be triaged all have the `triage` label. In many cases the issue can be automatically processed by the Ionic Issue Bot by applying a specific label.
Once another label is applied to the issue, the `triage` label is automatically removed by the bot.
### Wrong Repository
If an issue does not pertain to the Ionic Framework but does pertain to another repository, it should be moved to that repository. The bot has been set up to automatically create the issue in other repositories while closing and locking the issue in this repository. Use one of the following labels to perform that action:
- ionitron: cli
- ionitron: docs
- ionitron: stencil
- ionitron: native
### Ionic Appflow Issues
If the issue is associated with Ionic Appflow the submitter should be told to use the [Ionic Appflow Support Forum](https://ionic.zendesk.com/hc/en-us/requests/new). The issue should be closed and locked. Use the `ionitron: ionic appflow` label to accomplish this.
### Support Questions
If the issue is a support question, the submitter should be redirected to our [forum](https://forum.ionicframework.com). The issue should be closed and locked. Use the `ionitron: support` label to accomplish this.
### Incomplete Template
If the issue template has not been filled out completely, the issue should be closed and locked. The submitter should be informed to re-submit the issue making sure they fill the form out completely. Use the `ionitron: missing template` label to accomplish this.
### Issues with Open Questions
In many cases, the template is mostly filled out but just missing a thing or two or you may have a question or need clarification. In such a case, the submitter should be asked to supply that information.
1. add a comment requesting the additional information or clarification
1. add the `needs: reply` label to the task
NOTE: be sure to perform those actions in the order stated. If you add the comment second it will trigger the removal of the label.
If there is a response to the question, the bot will remove the `needs: reply` and apply the `triage` label. The issue will then go through the triage handling again.
If there is no response within 14 days, the issue will be closed and locked.
### Missing Code Reproduction
If the information the submitter has supplied is not enough for you to reproduce the issue, add the `ionitron: needs reproduction` label. An automated comment will be added to the thread asking the submitter to provide a code reproduction of the issue.
This label can also be added when the submitter has supplied some code, but not enough for you to reproduce the issue (i.e. code snippets).
Issues with this label are not automatically closed and locked, so we manually close and lock them if there is no response within 14 days.
## Workflow
### Overview
![](https://user-images.githubusercontent.com/6577830/53817482-80e6c480-3f33-11e9-9e09-be8dcf840ef8.png)
We have two long-living branches:
- `main`: completed features, bug fixes, refactors, chores
- `stable`: the latest release
The overall flow:
1. Feature, refactor, and bug fix branches are created from `main`
1. When a feature, refactor, or fix is complete it is merged into `main`
1. A release branch is created from `main`
1. When the release branch is done it is merged into `main` and `stable`
1. If an issue in `stable` is detected a hotfix branch is created from `stable`
1. Once the hotfix is complete it is merged to both `main` and `stable`
1. All branches should follow the syntax of `{type}-{details}` where `{type}` is the type of branch (`hotfix`, `release`, or one of the [commit types](https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md#commit-message-format)) and `{details}` is a few hyphen separated words explaining the branch
### Stable and Main Branches
#### Stable Branch
Branches created from `stable`:
The following branch should be merged back to **both** `main` and `stable`:
- A `hotfix` branch (e.g. `hotfix-missing-export`): a bug fix that is fixing a regression or issue with a published release
A `hotfix` branch should be the **only** branch that is created from stable.
#### Main Branch
Branches created from `main`:
The following branches should be merged back to `main` via a pull request:
1. A feature branch (e.g. `feat-desktop-support`): an addition to the API that is not a bug fix or regression fix
1. A bug fix branch (e.g. `fix-tab-color`): a bug fix that is not fixing a regression or issue with a published release
1. All other types listed in the [commit message types](https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md#commit-message-format): `docs`, `style`, `refactor`, `perf`, `test`, `chore`
The following branch should be merged back to **both** `main` and `stable`:
1. A `release` branch (e.g. `release-4.1.x`): contains all fixes and (optionally) features that are tested and should go into the release
### Feature Branches
Each new feature should reside in its own branch, based on the `main` branch. When a feature is complete, it should go into a pull request that gets merged back into `main`. A pull request adding a feature should be approved by two team members. Features should never interact directly with `stable`.
### Release Branches
Once `main` has acquired enough features for a release (or a predetermined release date is approaching), fork a release branch off of `main`. Creating this branch starts the next release cycle, so no new features can be added after this point - only bug fixes, documentation generation, and other release-oriented tasks should go in this branch.
Once the release is ready to ship, it will get merged into `stable` and `main`, then the release branch will be deleted. Its important to merge back into `main` because critical updates may have been added to the release branch and they need to be accessible to new features. This should be done in a pull request after review.
See the [steps for releasing](#releasing) below for detailed information on how to publish a release.
### Version Branches
Once a release has shipped and the release branch has been merged into `stable` and `main` it should also be merged into its corresponding version branch. These version branches allow us to ship updates for specific versions of the framework (i.e. Lets us ship a bug fix that only affects 4.2.x).
Patch releases should be merged into their corresponding version branches. For example, a `release-4.1.1` branch should be merged into the `4.1.x` version branch and a `release-5.0.1` branch should be merged into the `5.0.x` version branch.
When releasing a major version such as `5.0.0 ` or a minor version such as `4.1.0` , the version branch will not exist. The version branch should be created once the release branch has been merged into `stable` and `main`. For example, when releasing `4.1.0`, the `release-4.1.0` release branch should be merged into `stable` and `main` and then the `4.1.x` version branch should be created off the latest `stable`.
### Hotfix Branches
Maintenance or “hotfix” branches are used to quickly patch production releases. This is the only branch that should fork directly off of `stable`. As soon as the fix is complete, it should be merged into both `stable` and `main` (or the current release branch).
### Examples
#### Making a Change
1. Create a branch from `main`.
1. Make changes. Limit your changes to a "unit of work", meaning don't include irrelevant changes that may confuse and delay the change.
1. Push changes.
1. Create a PR with the base of `main`.
1. Have someone approve your change (optional right now--at your discretion).
<img width="236" alt="image" src="https://user-images.githubusercontent.com/236501/47031893-913e0480-d136-11e8-9d9a-4b6297a4d7ba.png">
1. Wait for status checks to succeed. Fix errors if any occur.
<img width="223" alt="All checks have passed" src="https://user-images.githubusercontent.com/236501/47031830-62c02980-d136-11e8-9055-08af1b717304.png">
1. Click **Squash and merge**. Use the dropdown to select this option if necessary.
<img width="192" alt="Squash and merge button" src="https://user-images.githubusercontent.com/236501/47031620-da418900-d135-11e8-91ff-e84f2478b2b3.png">
1. During confirmation, rewrite the commit message using our [Commit Message Format guidelines](https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md#commit-message-format). Keep the `(#1234)` at the end; it will create a link to the PR in the commit history and `CHANGELOG.md`. This is where commits on `main` become permanent.
<img width="672" alt="Squash and merge confirmation" src="https://user-images.githubusercontent.com/236501/47031753-31dff480-d136-11e8-9116-03934961bdc2.png">
1. Confirm squash and merge into `main`.
#### Updating from `main`
1. Pull the latest changes locally.
1. Merge the changes, fixing any conflicts.
1. Push the merged changes.
OR
1. Click **Update branch** on the PR:
<img width="672" alt="Update branch button" src="https://user-images.githubusercontent.com/236501/47032205-66a07b80-d137-11e8-8c9b-ee37d2d147c9.png">
1. Pull the merged changes locally.
#### Hotfixes
Hotfixes bypass `main` and should only be used for urgent fixes that can't wait for the next release to be ready.
1. Create a branch from `stable`.
1. Make changes.
1. Run `npm run release.prepare`.
1. Push changes.
1. Create a PR, making sure the PR will merge into `stable`.
1. Click **Squash and merge**. Use the dropdown to select this option if necessary.
<img width="192" alt="Squash and merge button" src="https://user-images.githubusercontent.com/236501/47031620-da418900-d135-11e8-91ff-e84f2478b2b3.png">
1. During confirmation, rewrite the commit message using our [Commit Message Format guidelines](https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md#commit-message-format). Keep the `(#1234)` at the end; it will create a link to the PR in the commit history and `CHANGELOG.md`. This is where commits on `main` become permanent.
<img width="672" alt="Squash and merge confirmation" src="https://user-images.githubusercontent.com/236501/47031753-31dff480-d136-11e8-9116-03934961bdc2.png">
1. Confirm squash and merge into `stable`.
1. CI builds `stable`, performing the release.
1. Create a PR to merge `stable` into `main`.
1. Click **Merge pull request**. Use the dropdown to select this option if necessary.
<img width="191" alt="Merge pull request button" src="https://user-images.githubusercontent.com/236501/47032669-8be1b980-d138-11e8-9a90-d1518c223184.png">
## Releasing
1. Create the release branch from `main`, for example: `release-4.5.0`.
1. For major or minor releases, create a version branch based off the latest version branch. For example, if releasing 4.5.0, create a branch called `4.5.x` based off `4.4.x`.
1. Submit a pull request from the release branch into the version branch. Do not merge this pull request yet.
1. Verify all tests are passing, fix any bugs if needed and make sure no undesired commits are in.
1. Navigate to the root of the repository while on the release branch.
1. Run `npm i` if it hasn't already been done.
1. Run `npm run release.prepare`
- Select the version based on the type of commits and the [Ionic Versioning](https://ionicframework.com/docs/intro/versioning)
- After the process completes, verify the version number in all packages (`core`, `docs`, `angular`)
- Verify the changelog commits are accurate and follow the [proper format]((https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md#commit-message-format))
- For major or minor releases, ensure that the version number has an associated title (for example: `4.5.0 Boron`)
- Commit these changes with the version number as the message, e.g. `git commit -m "4.5.0"`
1. *(Optional)* Run `npm run release -- --dry-run` to run the release without publishing and verify the version.
1. Run `npm run release`
1. Click **Merge pull request**. Use the dropdown to select this option if necessary.
<img width="191" alt="Merge pull request button" src="https://user-images.githubusercontent.com/236501/47032669-8be1b980-d138-11e8-9a90-d1518c223184.png">
1. Rewrite the commit message to `merge release-[VERSION]` with the proper release branch. For example, if this release is for `4.5.0`, the message would be `merge release-4.5.0`.
1. Submit a pull request from the release branch into `main`. Merge this pull request using the same commit format in the last step, to ensure any changes made on the release branch get added to future releases.

View File

@@ -5,7 +5,6 @@
Please check if your PR fulfills the following requirements:
- [ ] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been reviewed and added / updated if needed (for bug fixes / features)
- Some docs updates need to be made in the `ionic-docs` repo, in a separate PR. See the [contributing guide](https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#modifying-documentation) for details.
- [ ] Build (`npm run build`) was run locally and any changes were pushed
- [ ] Lint (`npm run lint`) has passed locally and any fixes were made for failures

View File

@@ -5,7 +5,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Install Angular Server Dependencies
run: npm install --legacy-peer-deps

View File

@@ -5,7 +5,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Core Node Modules
uses: actions/cache@v2
@@ -27,7 +27,7 @@ runs:
path: ./core
filename: CoreBuild.zip
- name: Install Angular Dependencies
run: npm install --legacy-peer-deps
run: npm install
shell: bash
working-directory: ./angular
- name: Link @ionic/core
@@ -46,10 +46,6 @@ runs:
run: npm run build
shell: bash
working-directory: ./angular
- name: Check Diff
run: git diff --exit-code
shell: bash
working-directory: ./angular
- uses: ./.github/workflows/actions/upload-archive
with:
name: ionic-angular

View File

@@ -9,7 +9,7 @@ runs:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Node Modules
uses: actions/cache@v2
@@ -30,7 +30,7 @@ runs:
with:
name: ionic-core
output: core/CoreBuild.zip
paths: core/dist core/components core/css core/hydrate core/loader core/src/components.d.ts
paths: core/dist core/components core/css core/hydrate core/loader
- uses: ./.github/workflows/actions/upload-archive
with:
name: ionic-core-src

View File

@@ -5,7 +5,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Core Node Modules
uses: actions/cache@v2

View File

@@ -5,7 +5,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Core Node Modules
uses: actions/cache@v2
@@ -39,10 +39,6 @@ runs:
run: npm run test.spec
shell: bash
working-directory: ./packages/react
- name: Check Diff
run: git diff --exit-code
shell: bash
working-directory: ./packages/react
- uses: ./.github/workflows/actions/upload-archive
with:
name: ionic-react

View File

@@ -5,7 +5,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Core Node Modules
uses: actions/cache@v2

View File

@@ -5,7 +5,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Core Node Modules
uses: actions/cache@v2
@@ -20,7 +20,7 @@ runs:
path: ./core
filename: CoreBuild.zip
- name: Install Vue Dependencies
run: npm install --legacy-peer-deps
run: npm install
shell: bash
working-directory: ./packages/vue
- name: Sync
@@ -35,10 +35,6 @@ runs:
run: npm run build
shell: bash
working-directory: ./packages/vue
- name: Check Diff
run: git diff --exit-code
shell: bash
working-directory: ./packages/vue
- uses: ./.github/workflows/actions/upload-archive
with:
name: ionic-vue

View File

@@ -1,8 +1,5 @@
name: 'Test Angular E2E'
description: 'Test Angular E2E'
inputs:
app:
description: 'The specific test application'
runs:
using: 'composite'
steps:
@@ -32,19 +29,15 @@ runs:
name: ionic-angular-server
path: ./packages/angular-server
filename: AngularServerBuild.zip
- name: Create Test App
run: ./build.sh ${{ inputs.app }}
shell: bash
working-directory: ./angular/test
- name: Install Dependencies
run: npm install
shell: bash
working-directory: ./angular/test/build/${{ inputs.app }}
working-directory: ./angular/test/test-app
- name: Sync Built Changes
run: npm run sync
shell: bash
working-directory: ./angular/test/build/${{ inputs.app }}
working-directory: ./angular/test/test-app
- name: Run Tests
run: npm run test
shell: bash
working-directory: ./angular/test/build/${{ inputs.app }}
working-directory: ./angular/test/test-app

View File

@@ -5,7 +5,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- uses: ./.github/workflows/actions/download-archive
with:

View File

@@ -5,7 +5,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Core Node Modules
uses: actions/cache@v2

View File

@@ -5,7 +5,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Core Node Modules
uses: actions/cache@v2
@@ -18,10 +18,3 @@ runs:
run: npm run lint
shell: bash
working-directory: ./core
# Lint changes should be pushed
# to the branch before the branch
# is merge eligible.
- name: Check Lint Results
run: git diff --exit-code
shell: bash
working-directory: ./core

View File

@@ -12,7 +12,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Core Node Modules
uses: actions/cache@v2
@@ -41,41 +41,10 @@ runs:
shell: bash
working-directory: ./core
- name: Test and Update
id: test-and-update
if: inputs.update == 'true'
# Keep track of the files that were
# changed so they can be correctly restored
# in the combine step.
# To do this, we move only the changed files
# to a separate directory, while preserving the
# directory structure of the source.
# When, we create and archive of these results
# so that the combine step can simply
# unzip and move the changed files into place.
# We have extra logic added so that job runners
# that do not have any new screenshots do not create
# an unnecessary .zip.
# Note that we need to unzip directory to be "core"
# which is why we not using the upload-archive
# composite step here.
run: |
npx playwright test --shard=${{ inputs.shard }}/${{ inputs.totalShards }} --update-snapshots
git add src/\*.png --force
mkdir updated-screenshots
cd ../ && rsync -R --progress $(git diff --name-only --cached) core/updated-screenshots
if [ -d core/updated-screenshots/core ]; then
echo "::set-output name=hasUpdatedScreenshots::$(echo 'true')"
cd core/updated-screenshots
zip -q -r ../../UpdatedScreenshots-${{ inputs.shard }}-${{ inputs.totalShards }}.zip core
fi
run: npx playwright test --shard=${{ inputs.shard }}/${{ inputs.totalShards }} --update-snapshots
shell: bash
working-directory: ./core
- name: Archive Updated Screenshots
if: inputs.update == 'true' && steps.test-and-update.outputs.hasUpdatedScreenshots == 'true'
uses: actions/upload-artifact@v2
with:
name: updated-screenshots-${{ inputs.shard }}-${{ inputs.totalShards }}
path: UpdatedScreenshots-${{ inputs.shard }}-${{ inputs.totalShards }}.zip
- name: Archive Test Results
# The always() ensures that this step
# runs even if the previous step fails.
@@ -88,4 +57,4 @@ runs:
with:
name: test-results-${{ inputs.shard }}-${{ inputs.totalShards }}
output: core/TestResults-${{ inputs.shard }}-${{ inputs.totalShards }}.zip
paths: core/playwright-report
paths: core/playwright-report core/src

View File

@@ -5,7 +5,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Core Node Modules
uses: actions/cache@v2

View File

@@ -5,7 +5,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Core Node Modules
uses: actions/cache@v2

View File

@@ -5,7 +5,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Core Node Modules
uses: actions/cache@v2

View File

@@ -1,14 +1,11 @@
name: 'Test Vue E2E'
description: 'Test Vue E2E'
inputs:
app:
description: 'The specific test application'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- name: Cache Core Node Modules
uses: actions/cache@v2
@@ -32,23 +29,19 @@ runs:
name: ionic-vue-router
path: ./packages/vue-router
filename: VueRouterBuild.zip
- name: Create Test App
run: ./build.sh ${{ inputs.app }}
shell: bash
working-directory: ./packages/vue/test
- name: Install Dependencies
run: npm install
shell: bash
working-directory: ./packages/vue/test/build/${{ inputs.app }}
working-directory: ./packages/vue/test-app
- name: Sync
run: npm run sync
shell: bash
working-directory: ./packages/vue/test/build/${{ inputs.app }}
working-directory: ./packages/vue/test-app
- name: Run Spec Tests
run: npm run test:unit
shell: bash
working-directory: ./packages/vue/test/build/${{ inputs.app }}
working-directory: ./packages/vue/test-app
- name: Run E2E Tests
run: npm run test:e2e
shell: bash
working-directory: ./packages/vue/test/build/${{ inputs.app }}
working-directory: ./packages/vue/test-app

View File

@@ -9,7 +9,7 @@ runs:
steps:
- uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 15.x
- uses: actions/download-artifact@v2
with:
path: ./artifacts
@@ -18,7 +18,7 @@ runs:
# directory, including nested directories.
# It then unzips every .zip to the root directory
run: |
find . -type f -name 'UpdatedScreenshots-*.zip' -exec unzip -q -o -d ../ {} \;
find . -type f -name '*.zip' -exec unzip -q -o -d ../ -- '{}' -x '*.zip' \;
shell: bash
working-directory: ./artifacts
- name: Push Screenshots

View File

@@ -4,21 +4,15 @@ on:
pull_request:
branches: [ '**' ]
# When pushing a new commit we should
# cancel the previous test run to not
# consume more runners than we need to.
concurrency:
group: ${{ github.ref }}
cancel-in-progress: true
jobs:
build-core:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
# Checkout the latest commit in this branch
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/checkout@v2
with:
# Checkout the latest commit in this branch
ref: ${{ github.event.pull_request.head.sha }}
- uses: ./.github/workflows/actions/build-core
test-core-clean-build:
@@ -62,8 +56,8 @@ jobs:
# add new items to the shard array
# and change the value of totalShards
# to be the length of the shard array.
shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
totalShards: [20]
shard: [1, 2, 3, 4, 5]
totalShards: [5]
needs: [build-core]
runs-on: ubuntu-latest
steps:
@@ -73,24 +67,6 @@ jobs:
shard: ${{ matrix.shard }}
totalShards: ${{ matrix.totalShards }}
# Screenshots are required to pass
# in order for the branch to be merge
# eligible. However, the screenshot tests
# are run on n runners where n can change
# over time. The verify-screenshots step allows
# us to have a required status check for screenshot
# results without having to manually add each
# matrix run in the branch protection rules
# Source: https://github.community/t/status-check-for-a-matrix-jobs/127354
verify-screenshots:
if: ${{ always() }}
needs: test-core-screenshot
runs-on: ubuntu-latest
steps:
- name: Check build matrix status
if: ${{ needs.test-core-screenshot.result != 'success' }}
run: exit 1
build-vue:
needs: [build-core]
runs-on: ubuntu-latest
@@ -106,26 +82,11 @@ jobs:
- uses: ./.github/workflows/actions/build-vue-router
test-vue-e2e:
strategy:
fail-fast: false
matrix:
apps: [vue3]
needs: [build-vue, build-vue-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./.github/workflows/actions/test-vue-e2e
with:
app: ${{ matrix.apps }}
verify-test-vue-e2e:
if: ${{ always() }}
needs: test-vue-e2e
runs-on: ubuntu-latest
steps:
- name: Check build matrix status
if: ${{ needs.test-vue-e2e.result != 'success' }}
run: exit 1
build-angular:
needs: [build-core]
@@ -142,26 +103,11 @@ jobs:
- uses: ./.github/workflows/actions/build-angular-server
test-angular-e2e:
strategy:
fail-fast: false
matrix:
apps: [ng12, ng13, ng14]
needs: [build-angular, build-angular-server]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./.github/workflows/actions/test-angular-e2e
with:
app: ${{ matrix.apps }}
verify-test-angular-e2e:
if: ${{ always() }}
needs: test-angular-e2e
runs-on: ubuntu-latest
steps:
- name: Check build matrix status
if: ${{ needs.test-angular-e2e.result != 'success' }}
run: exit 1
build-react:
needs: [build-core]

View File

@@ -1,21 +0,0 @@
name: CodeQL
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v3
- uses: github/codeql-action/init@v2
with:
languages: javascript
- uses: github/codeql-action/analyze@v2

View File

@@ -1,60 +0,0 @@
name: 'Ionic Nightly Build'
on:
schedule:
# Run every Monday-Friday
# at 6:00 UTC (6:00 am UTC)
- cron: '00 06 * * 1-5'
jobs:
nightly-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/setup-node@v2
with:
node-version: 16
- name: Install Dependencies
run: npm ci --no-package-lock && lerna bootstrap --ignore-scripts -- --legacy-peer-deps
shell: bash
- name: Prepare NPM Token
run: echo //registry.npmjs.org/:_authToken=${NPM_TOKEN} > .npmrc
shell: bash
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Configure Identity
run: |
git config user.name github-actions
git config user.email github-actions@github.com
# A 1 is required before the timestamp
# as lerna will fail when there is a leading 0
# See https://github.com/lerna/lerna/issues/2840
- name: Create Nightly Hash
# The date should output YYYYMMDD
# so that it is human readable
run: |
echo "DATE=$(date +%Y%m%d)" >> $GITHUB_ENV
echo "CURRENT_VERSION=$(node ./.scripts/bump-version.js)" >> $GITHUB_ENV
shell: bash
- name: Checkout Nightly Branch
run: |
git checkout -b nightly-$(echo "${{ env.DATE }}")
git push origin nightly-$(echo "${{ env.DATE }}")
shell: bash
- name: Create Nightly Build
run: |
HUSKY_SKIP_HOOKS=1 lerna publish $(echo "${{ env.CURRENT_VERSION }}")-nightly.$(echo "${{ env.DATE }}") --no-verify-access --yes --force-publish='*' --dist-tag nightly --conventional-commits --conventional-prerelease --exact --create-release github
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
# We need to push the commit changes in order for the tags
# to get updated, but we don't need to keep the changelog
# changes around.
- name: Delete Nightly Branch
run: |
git checkout main
git branch -D nightly-$(echo "${{ env.DATE }}")
git push origin --delete nightly-$(echo "${{ env.DATE }}")
shell: bash

View File

@@ -26,7 +26,6 @@ jobs:
steps:
- uses: actions/checkout@v2
with:
token: ${{ secrets.IONITRON_TOKEN }}
fetch-depth: 0
- uses: actions/setup-node@v2
with:
@@ -50,32 +49,3 @@ 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 config user.name ionitron
git config user.email hi@ionicframework.com
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.
- name: Purge JSDelivr Cache
run: |
curl -X POST \
https://purge.jsdelivr.net/ \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-d '{
"path": [
"/npm/@ionic/core@6/dist/ionic/ionic.esm.js",
"/npm/@ionic/core@latest/dist/ionic/ionic.esm.js",
"/npm/@ionic/core@6/css/ionic.bundle.css",
"/npm/@ionic/core@latest/css/ionic.bundle.css"
]}'

View File

@@ -23,8 +23,8 @@ jobs:
# add new items to the shard array
# and change the value of totalShards
# to be the length of the shard array.
shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
totalShards: [20]
shard: [1, 2, 3, 4, 5]
totalShards: [5]
needs: [build-core]
runs-on: ubuntu-latest
steps:

11
.gitignore vendored
View File

@@ -22,6 +22,7 @@ temp/
core/theme-builder/
core/test-components/
core/css/
angular/css/
$RECYCLE.BIN/
.DS_Store
@@ -55,6 +56,7 @@ prerender-hydrated.html
prerender-static.html
# stencil
angular/css/
packages/react/css/
packages/vue/css/
core/components/
@@ -63,18 +65,11 @@ core/hydrate/
core/loader/
core/www/
.stencil/
angular/build/
# playwright
core/test-results/
core/playwright-report/
core/**/*-snapshots
# angular
angular/css/
angular/test/build/
.angular/
# vue
packages/vue/test/build/
.npmrc

View File

@@ -3,419 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.2.8](https://github.com/ionic-team/ionic-framework/compare/v6.2.7...v6.2.8) (2022-09-21)
### Bug Fixes
* **datetime:** account for 12AM with min times and 12 hour format ([#25952](https://github.com/ionic-team/ionic-framework/issues/25952)) ([55ebd6c](https://github.com/ionic-team/ionic-framework/commit/55ebd6cdf39c01b401e876b76e755bfa04db8f65)), closes [#25183](https://github.com/ionic-team/ionic-framework/issues/25183)
* **item:** show the highlight on iOS when --highlight-height is set ([#25905](https://github.com/ionic-team/ionic-framework/issues/25905)) ([d7db133](https://github.com/ionic-team/ionic-framework/commit/d7db1333f13834ecb447b4b1da62cfffed9fb333))
* **overlays:** focus trapping no longer includes disabled elements ([#25949](https://github.com/ionic-team/ionic-framework/issues/25949)) ([6cb5827](https://github.com/ionic-team/ionic-framework/commit/6cb5827d069c255ab0a9a8c319aba9994a4c5196))
* **overlays:** focus trapping no longer includes hidden elements ([#25948](https://github.com/ionic-team/ionic-framework/issues/25948)) ([5c10f98](https://github.com/ionic-team/ionic-framework/commit/5c10f98ceb3ae42d3363b38ba786b9122676a59c))
### Performance Improvements
* **card:** avoid force compositing on ios ([#25942](https://github.com/ionic-team/ionic-framework/issues/25942)) ([174c3b3](https://github.com/ionic-team/ionic-framework/commit/174c3b30a0bce7e7ab13e5605348ec107af69dd6))
## [6.2.7](https://github.com/ionic-team/ionic-framework/compare/v6.2.6...v6.2.7) (2022-09-14)
### Bug Fixes
* **angular:** nav controller can pop views after leaving tabs outlet ([#25690](https://github.com/ionic-team/ionic-framework/issues/25690)) ([725b13f](https://github.com/ionic-team/ionic-framework/commit/725b13fa60775dc9f9c3491cb545c70a5a9162eb)), closes [#18593](https://github.com/ionic-team/ionic-framework/issues/18593)
* **datetime:** correct year is set in wheel picker ([#25896](https://github.com/ionic-team/ionic-framework/issues/25896)) ([fb653eb](https://github.com/ionic-team/ionic-framework/commit/fb653ebe67458a088adf0626741d190ceb2880a6)), closes [#25895](https://github.com/ionic-team/ionic-framework/issues/25895)
* **footer:** padding is added correctly with tabs ([#25921](https://github.com/ionic-team/ionic-framework/issues/25921)) ([edbb64c](https://github.com/ionic-team/ionic-framework/commit/edbb64c4b6de7ace7043675a85fd503da18304d7)), closes [#25918](https://github.com/ionic-team/ionic-framework/issues/25918)
* **input,textarea:** data-form-type attribute is assigned to inner input ([#25927](https://github.com/ionic-team/ionic-framework/issues/25927)) ([9451b28](https://github.com/ionic-team/ionic-framework/commit/9451b283e2cb30ac9087574461f6b9f4b6cc3e0f)), closes [#25908](https://github.com/ionic-team/ionic-framework/issues/25908)
* **modal:** sheet is easier to dismiss with swipe ([#25883](https://github.com/ionic-team/ionic-framework/issues/25883)) ([fa169d2](https://github.com/ionic-team/ionic-framework/commit/fa169d2dca649107342fe365ef6c7da892ebb8fd)), closes [#24296](https://github.com/ionic-team/ionic-framework/issues/24296)
* **react:** add correct type for CreateAnimation ([#25931](https://github.com/ionic-team/ionic-framework/issues/25931)) ([89d3e3c](https://github.com/ionic-team/ionic-framework/commit/89d3e3c819b282e4d7ce716b9099eaab82ab4de2))
* **tab-bar:** use correct import path ([#25898](https://github.com/ionic-team/ionic-framework/issues/25898)) ([ad46045](https://github.com/ionic-team/ionic-framework/commit/ad46045bcc251c9719ecf6621792f1a5b3c6afce)), closes [#25897](https://github.com/ionic-team/ionic-framework/issues/25897)
* **textarea:** auto grow textarea line wraps long contents ([#25928](https://github.com/ionic-team/ionic-framework/issues/25928)) ([777109a](https://github.com/ionic-team/ionic-framework/commit/777109a7e8625ed61a8cc09e52fc06e104b124ea)), closes [#25893](https://github.com/ionic-team/ionic-framework/issues/25893)
## [6.2.6](https://github.com/ionic-team/ionic-framework/compare/v6.2.5...v6.2.6) (2022-09-07)
### Bug Fixes
* **datetime:** calendar day and years are now localized ([#25847](https://github.com/ionic-team/ionic-framework/issues/25847)) ([cbd1268](https://github.com/ionic-team/ionic-framework/commit/cbd1268a03204f05314f2ba284ad433457a9cf33)), closes [#25843](https://github.com/ionic-team/ionic-framework/issues/25843)
* **datetime:** hourCycle formats hour correctly ([#25869](https://github.com/ionic-team/ionic-framework/issues/25869)) ([1a1491d](https://github.com/ionic-team/ionic-framework/commit/1a1491df0242da1cb3c9a7f128bbd4d5ce4dbf3e)), closes [#25862](https://github.com/ionic-team/ionic-framework/issues/25862)
* **datetime:** month grid no longer loops on ios ([#25857](https://github.com/ionic-team/ionic-framework/issues/25857)) ([c938054](https://github.com/ionic-team/ionic-framework/commit/c938054605dffb6c3002a64a3d8aaf36892c7a93)), closes [#25752](https://github.com/ionic-team/ionic-framework/issues/25752)
* **vue:** custom animation plays when replacing ([#25863](https://github.com/ionic-team/ionic-framework/issues/25863)) ([2d3661a](https://github.com/ionic-team/ionic-framework/commit/2d3661ae3894b98ac4b8b158594b8de0f0823073)), closes [#25831](https://github.com/ionic-team/ionic-framework/issues/25831)
## [6.2.5](https://github.com/ionic-team/ionic-framework/compare/v6.2.4...v6.2.5) (2022-08-31)
### Bug Fixes
* **action-sheet:** add aria-labelledby ([#25837](https://github.com/ionic-team/ionic-framework/issues/25837)) ([5270151](https://github.com/ionic-team/ionic-framework/commit/527015184e9413c1037277d3197bcaa33044c38c))
* **angular:** router outlet has mode property ([#25816](https://github.com/ionic-team/ionic-framework/issues/25816)) ([afd0bbc](https://github.com/ionic-team/ionic-framework/commit/afd0bbc60aa8f4edc88dc311d6484ac60117fce5)), closes [#25813](https://github.com/ionic-team/ionic-framework/issues/25813)
* **datetime:** next and previous buttons have correct labels ([#25845](https://github.com/ionic-team/ionic-framework/issues/25845)) ([41e3387](https://github.com/ionic-team/ionic-framework/commit/41e338730d32837fc9dd8a15477e37dea4cc76c9)), closes [#25844](https://github.com/ionic-team/ionic-framework/issues/25844)
* **datetime:** only log out of bounds warning if value set ([#25835](https://github.com/ionic-team/ionic-framework/issues/25835)) ([85af6ce](https://github.com/ionic-team/ionic-framework/commit/85af6ce436890eb922d2ba32053fb8b8bc7fd4ff)), closes [#25833](https://github.com/ionic-team/ionic-framework/issues/25833)
* **input:** clear button is not activated on swipe ([#25825](https://github.com/ionic-team/ionic-framework/issues/25825)) ([ff71ad4](https://github.com/ionic-team/ionic-framework/commit/ff71ad492d7671f8e550da7e08dbde30cb05ebf7)), closes [#24857](https://github.com/ionic-team/ionic-framework/issues/24857)
* **modal:** handleBehavior can be used with controller ([#25821](https://github.com/ionic-team/ionic-framework/issues/25821)) ([79ef1b5](https://github.com/ionic-team/ionic-framework/commit/79ef1b57dc74fd856ed7c2904d7400d283cc081e)), closes [#25820](https://github.com/ionic-team/ionic-framework/issues/25820)
* **searchbar:** clear button has focus indicator ([#25828](https://github.com/ionic-team/ionic-framework/issues/25828)) ([373b4ff](https://github.com/ionic-team/ionic-framework/commit/373b4ffe216ba584b92014cef501f64668e1f177))
* **searchbar:** keypress can activate clear button ([#25824](https://github.com/ionic-team/ionic-framework/issues/25824)) ([c270756](https://github.com/ionic-team/ionic-framework/commit/c270756356c7b23a1959ac5f4b8206a5cd1825c2))
## [6.2.4](https://github.com/ionic-team/ionic-framework/compare/v6.2.3...v6.2.4) (2022-08-24)
### Bug Fixes
* **alert:** add default aria-label ([#25800](https://github.com/ionic-team/ionic-framework/issues/25800)) ([d395a73](https://github.com/ionic-team/ionic-framework/commit/d395a73cb6c419e6c0072746b8e4768cd5f78ef3))
* **alert:** use aria-labelledby and aria-describedby instead of aria-label ([#25805](https://github.com/ionic-team/ionic-framework/issues/25805)) ([27318d7](https://github.com/ionic-team/ionic-framework/commit/27318d75df60dfce1a90f23ba31ea2b6636ba42f))
* **breadcrumb:** separator is not announced by narrators ([#25796](https://github.com/ionic-team/ionic-framework/issues/25796)) ([71fad38](https://github.com/ionic-team/ionic-framework/commit/71fad3884bc55b266067efb346500c848b856946))
* **datetime:** close month/year picker when hidden ([#25789](https://github.com/ionic-team/ionic-framework/issues/25789)) ([3b211b6](https://github.com/ionic-team/ionic-framework/commit/3b211b60fd9a88be6e232f839ecc4be090181530)), closes [#25787](https://github.com/ionic-team/ionic-framework/issues/25787)
* **modal:** role attribute can be customized ([#25804](https://github.com/ionic-team/ionic-framework/issues/25804)) ([037d579](https://github.com/ionic-team/ionic-framework/commit/037d579b2a3a660358f1e9c9b020c9510bb9c6b0))
* **react:** duplicate page transitions do not happen on react 18 ([#25798](https://github.com/ionic-team/ionic-framework/issues/25798)) ([a39d776](https://github.com/ionic-team/ionic-framework/commit/a39d776f087514b7fa744f44ce8ce2a04ed8aa43)), closes [#25797](https://github.com/ionic-team/ionic-framework/issues/25797)
* **refresher:** use componentOnReady utility for CE build ([#25783](https://github.com/ionic-team/ionic-framework/issues/25783)) ([bd715a5](https://github.com/ionic-team/ionic-framework/commit/bd715a52562f1f175d4bb6ea2dbfdd67a3e91db1)), closes [#25782](https://github.com/ionic-team/ionic-framework/issues/25782)
* **select:** compareWith passes params in correct order ([#25764](https://github.com/ionic-team/ionic-framework/issues/25764)) ([d631195](https://github.com/ionic-team/ionic-framework/commit/d6311951243fd9b867ae5d4a7a08c8d341f8eb7a)), closes [#25759](https://github.com/ionic-team/ionic-framework/issues/25759)
* **vue:** lifecycles now fire on tabs pages ([#25786](https://github.com/ionic-team/ionic-framework/issues/25786)) ([3020005](https://github.com/ionic-team/ionic-framework/commit/30200051bbab6ce57fd363668dafc49287c87c56)), closes [#25784](https://github.com/ionic-team/ionic-framework/issues/25784)
## [6.2.3](https://github.com/ionic-team/ionic-framework/compare/v6.2.2...v6.2.3) (2022-08-17)
### Bug Fixes
* **css:** preserve whitespace in selectors when minifying css ([#25767](https://github.com/ionic-team/ionic-framework/issues/25767)) ([bafa759](https://github.com/ionic-team/ionic-framework/commit/bafa759655a0f3ca206255ba429f21d319c37aed)), closes [#25766](https://github.com/ionic-team/ionic-framework/issues/25766)
* **datetime:** highlights now show above content in modal ([#25756](https://github.com/ionic-team/ionic-framework/issues/25756)) ([d711658](https://github.com/ionic-team/ionic-framework/commit/d7116581c8e92716f49877abc78d93dc39c34e1d)), closes [#25755](https://github.com/ionic-team/ionic-framework/issues/25755)
* **footer:** remove toolbar bottom padding if near bottom slot tabs or keyboard is open ([#25746](https://github.com/ionic-team/ionic-framework/issues/25746)) ([bb37446](https://github.com/ionic-team/ionic-framework/commit/bb374460320b0ba2ee03a5a0ecebb3e7a9f0728e))
* **header:** hide from screen readers when collapsed ([#25744](https://github.com/ionic-team/ionic-framework/issues/25744)) ([d0ba963](https://github.com/ionic-team/ionic-framework/commit/d0ba9635998f2157970156438c1bb74d6b9682f2))
* **input:** exclude date inputs from scroll assist ([#25749](https://github.com/ionic-team/ionic-framework/issues/25749)) ([abb56d2](https://github.com/ionic-team/ionic-framework/commit/abb56d22b4a81d1bc34c689de4ef7218e7503b20)), closes [#25745](https://github.com/ionic-team/ionic-framework/issues/25745)
* **item:** form validation caret color renders correctly ([#25725](https://github.com/ionic-team/ionic-framework/issues/25725)) ([de20541](https://github.com/ionic-team/ionic-framework/commit/de20541486bcf6e1d15f0ae5b0c5f177cce5eb38)), closes [#25719](https://github.com/ionic-team/ionic-framework/issues/25719)
* **refresher:** refresher is visible with multiple custom scroll targets ([#25750](https://github.com/ionic-team/ionic-framework/issues/25750)) ([e750e33](https://github.com/ionic-team/ionic-framework/commit/e750e336167397ed996d9833763286f4881e79b5)), closes [#25495](https://github.com/ionic-team/ionic-framework/issues/25495)
## [6.2.2](https://github.com/ionic-team/ionic-framework/compare/v6.2.1...v6.2.2) (2022-08-10)
### Bug Fixes
* **angular:** DatetimeButton is declared on IonicModule ([#25727](https://github.com/ionic-team/ionic-framework/issues/25727)) ([76ad1d1](https://github.com/ionic-team/ionic-framework/commit/76ad1d18c81272435db1994977aa9dd5d880504a))
* **datetime:** add correct null check when value changes ([#25716](https://github.com/ionic-team/ionic-framework/issues/25716)) ([36bea1c](https://github.com/ionic-team/ionic-framework/commit/36bea1ca2520c9eb9ee7705abb046607a52d198d)), closes [#25714](https://github.com/ionic-team/ionic-framework/issues/25714)
* **datetime:** preferWheel respects column ordering by locale ([#25726](https://github.com/ionic-team/ionic-framework/issues/25726)) ([dee0f51](https://github.com/ionic-team/ionic-framework/commit/dee0f513ee443c0c69ea8e38a292c900e9c70221)), closes [#25722](https://github.com/ionic-team/ionic-framework/issues/25722)
* **react:** outlet will not clear in react 18 with hot reload ([#25703](https://github.com/ionic-team/ionic-framework/issues/25703)) ([3878bf7](https://github.com/ionic-team/ionic-framework/commit/3878bf76523f2e1c26c147473fd7c07ee4d0e820)), closes [#25507](https://github.com/ionic-team/ionic-framework/issues/25507)
* **vue:** go back to correct view with memory history ([#25732](https://github.com/ionic-team/ionic-framework/issues/25732)) ([8327889](https://github.com/ionic-team/ionic-framework/commit/832788971a7098e52812f66563cbc0a63d3e5df7)), closes [#25705](https://github.com/ionic-team/ionic-framework/issues/25705)
## [6.2.1](https://github.com/ionic-team/ionic-framework/compare/v6.2.0...v6.2.1) (2022-08-03)
### Bug Fixes
* **datetime:** display time in user's timezone after selection ([#25694](https://github.com/ionic-team/ionic-framework/issues/25694)) ([11c69c8](https://github.com/ionic-team/ionic-framework/commit/11c69c8df50b75440c9e876b4d99d469d16e144f)), closes [#25693](https://github.com/ionic-team/ionic-framework/issues/25693)
* **datetime:** selecting today with multiple date select now works ([#25699](https://github.com/ionic-team/ionic-framework/issues/25699)) ([86b7000](https://github.com/ionic-team/ionic-framework/commit/86b7000bcd1b4519e8c20907050e15ba7c99bab0))
* **nav:** exclude nav from custom dialog ([#25689](https://github.com/ionic-team/ionic-framework/issues/25689)) ([d1e517b](https://github.com/ionic-team/ionic-framework/commit/d1e517bfef03b822dfa7651681013277762eda08)), closes [#25677](https://github.com/ionic-team/ionic-framework/issues/25677) [#25688](https://github.com/ionic-team/ionic-framework/issues/25688)
* **react:** IonNav apply properties to page components ([#25603](https://github.com/ionic-team/ionic-framework/issues/25603)) ([61e4ffe](https://github.com/ionic-team/ionic-framework/commit/61e4ffe47f73034808b65ee37342f540ee5a6a97)), closes [#25602](https://github.com/ionic-team/ionic-framework/issues/25602)
# [6.2.0](https://github.com/ionic-team/ionic-framework/compare/v6.1.15...v6.2.0) (2022-07-27)
### Bug Fixes
* **datetime:** account for previous years with preferWheel ([#25656](https://github.com/ionic-team/ionic-framework/issues/25656)) ([3a7f5f1](https://github.com/ionic-team/ionic-framework/commit/3a7f5f166ee8d8d7e1861313e2bc6f4856e4fbe9))
* **datetime:** switching months in wheel picker now selected nearest neighbor ([#25559](https://github.com/ionic-team/ionic-framework/issues/25559)) ([dd256e1](https://github.com/ionic-team/ionic-framework/commit/dd256e1313fa1c307f30b0dbb7fd0d1da8c555f7))
* **datetime:** switching presentation closes month/year picker ([#25667](https://github.com/ionic-team/ionic-framework/issues/25667)) ([57a21ad](https://github.com/ionic-team/ionic-framework/commit/57a21adb38331ee5d74dacd1b0a2568f41a2d21e))
* **nav:** pop() will unmount views within a modal ([#25638](https://github.com/ionic-team/ionic-framework/issues/25638)) ([db28794](https://github.com/ionic-team/ionic-framework/commit/db28794f0b75f2824ae26c101a8c52af70f43ffd)), closes [#25637](https://github.com/ionic-team/ionic-framework/issues/25637) [#21831](https://github.com/ionic-team/ionic-framework/issues/21831)
* **picker-column-internal:** tabbing between columns works ([#25464](https://github.com/ionic-team/ionic-framework/issues/25464)) ([db02772](https://github.com/ionic-team/ionic-framework/commit/db027721ac299e7d23c42b52b0274be06b909f89))
* **textarea:** textarea with autogrow will size to its contents ([#24205](https://github.com/ionic-team/ionic-framework/issues/24205)) ([a9cf2ab](https://github.com/ionic-team/ionic-framework/commit/a9cf2ab87012cdb6360d10536a29213adda3f585)), closes [#24793](https://github.com/ionic-team/ionic-framework/issues/24793) [#21242](https://github.com/ionic-team/ionic-framework/issues/21242)
* **vue:** input v-model accepts numbers ([#25666](https://github.com/ionic-team/ionic-framework/issues/25666)) ([ab65e9a](https://github.com/ionic-team/ionic-framework/commit/ab65e9a7b51c3a3f8c59962d3e1faff1564ab801)), closes [#25575](https://github.com/ionic-team/ionic-framework/issues/25575)
### Features
* **angular, react, vue:** add support for autoMountComponent ([#25552](https://github.com/ionic-team/ionic-framework/issues/25552)) ([805dfa0](https://github.com/ionic-team/ionic-framework/commit/805dfa05663098ef9c02b0745a383b5e7555908b))
* **datetime-button:** add button for displaying datetime in overlays ([#25655](https://github.com/ionic-team/ionic-framework/issues/25655)) ([4997331](https://github.com/ionic-team/ionic-framework/commit/499733105e4be23405e8afeeb26fee5cd2afc25b)), closes [#24316](https://github.com/ionic-team/ionic-framework/issues/24316)
* **datetime:** add multiple date selection ([#25514](https://github.com/ionic-team/ionic-framework/issues/25514)) ([9d31608](https://github.com/ionic-team/ionic-framework/commit/9d31608f2d471f531eb253832c8558d1effaf68a))
* **datetime:** add wheel style picker for dates and times ([#25468](https://github.com/ionic-team/ionic-framework/issues/25468)) ([3d19771](https://github.com/ionic-team/ionic-framework/commit/3d19771185301870a2eb60f1ef4afd6f1c182494))
* **datetime:** localize am/pm labels in time picker ([#25389](https://github.com/ionic-team/ionic-framework/issues/25389)) ([6bc0acc](https://github.com/ionic-team/ionic-framework/commit/6bc0acc4279a18c3309b11eeec76676c5015419a)), closes [#16279](https://github.com/ionic-team/ionic-framework/issues/16279)
* **modal:** clicking handle advances to the next breakpoint ([#25540](https://github.com/ionic-team/ionic-framework/issues/25540)) ([7cdc388](https://github.com/ionic-team/ionic-framework/commit/7cdc388b7805cbf23c9e1e928aa977cd77ebc8c4)), closes [#24069](https://github.com/ionic-team/ionic-framework/issues/24069)
* **picker-column-internal:** add ability to disable items ([#25412](https://github.com/ionic-team/ionic-framework/issues/25412)) ([8b7c079](https://github.com/ionic-team/ionic-framework/commit/8b7c07968e1a60389a22e5af0e0cac62d31d397a))
* **range:** add reference point for start position of range slider ([#25598](https://github.com/ionic-team/ionic-framework/issues/25598)) ([c2781cc](https://github.com/ionic-team/ionic-framework/commit/c2781cc1c3b7e56a0e6f6c03cfa04fc2c82d6e8a)), closes [#24348](https://github.com/ionic-team/ionic-framework/issues/24348)
* **toggle:** on/off icons for toggle ([#25459](https://github.com/ionic-team/ionic-framework/issues/25459)) ([bc0bdc4](https://github.com/ionic-team/ionic-framework/commit/bc0bdc438ba72c695f9d961ddf837ec45e7816dd)), closes [#20524](https://github.com/ionic-team/ionic-framework/issues/20524)
## [6.1.15](https://github.com/ionic-team/ionic-framework/compare/v6.1.14...v6.1.15) (2022-07-20)
### Bug Fixes
* **datetime:** use scroll listener to detect month changes ([#25586](https://github.com/ionic-team/ionic-framework/issues/25586)) ([b7afcb0](https://github.com/ionic-team/ionic-framework/commit/b7afcb0f0c36d84f3b4d65844df28e6293bc1ea5)), closes [#25257](https://github.com/ionic-team/ionic-framework/issues/25257) [#25608](https://github.com/ionic-team/ionic-framework/issues/25608) [#24980](https://github.com/ionic-team/ionic-framework/issues/24980)
* **fab-button:** aria attributes are inherited ([#25635](https://github.com/ionic-team/ionic-framework/issues/25635)) ([64ae3d2](https://github.com/ionic-team/ionic-framework/commit/64ae3d2b9729c5c6be8644b1df6c8b3d40584d3b)), closes [#25633](https://github.com/ionic-team/ionic-framework/issues/25633)
* **modal:** allow for custom dialog implementations ([#25630](https://github.com/ionic-team/ionic-framework/issues/25630)) ([a6f3ae6](https://github.com/ionic-team/ionic-framework/commit/a6f3ae67ab91ab95408ad425156167edc3570978)), closes [#24080](https://github.com/ionic-team/ionic-framework/issues/24080)
* **react:** swipe to go back gesture works on ios ([#25563](https://github.com/ionic-team/ionic-framework/issues/25563)) ([7ec3683](https://github.com/ionic-team/ionic-framework/commit/7ec3683e94e5397022560ce8489532ff40d3f40c)), closes [#22342](https://github.com/ionic-team/ionic-framework/issues/22342)
### Performance Improvements
* **input:** passive event listener for touch start events ([#25610](https://github.com/ionic-team/ionic-framework/issues/25610)) ([2d1efdb](https://github.com/ionic-team/ionic-framework/commit/2d1efdbe6dd9436badab4684f2a484476489c166)), closes [#25599](https://github.com/ionic-team/ionic-framework/issues/25599)
## [6.1.14](https://github.com/ionic-team/ionic-framework/compare/v6.1.13...v6.1.14) (2022-07-13)
### Bug Fixes
* **datetime:** datetime works within stencil apps ([#25592](https://github.com/ionic-team/ionic-framework/issues/25592)) ([7b10fa6](https://github.com/ionic-team/ionic-framework/commit/7b10fa6476c2c2896c6810c57b3160f8c8896faa)), closes [#25591](https://github.com/ionic-team/ionic-framework/issues/25591)
* **react:** IonNav works with react ([#25565](https://github.com/ionic-team/ionic-framework/issues/25565)) ([420f9bb](https://github.com/ionic-team/ionic-framework/commit/420f9bbebd41f3eab6def795bcdd1933d5c5a47a)), closes [#24002](https://github.com/ionic-team/ionic-framework/issues/24002)
## [6.1.13](https://github.com/ionic-team/ionic-framework/compare/v6.1.12...v6.1.13) (2022-07-06)
### Bug Fixes
* **all:** long press now preserves activated state ([#25551](https://github.com/ionic-team/ionic-framework/issues/25551)) ([a8286f6](https://github.com/ionic-team/ionic-framework/commit/a8286f6e42f734a027416ac6cd659e3dce4edccb)), closes [#25544](https://github.com/ionic-team/ionic-framework/issues/25544)
* **datetime:** typing in time now updates value ([#25561](https://github.com/ionic-team/ionic-framework/issues/25561)) ([1b1b1a3](https://github.com/ionic-team/ionic-framework/commit/1b1b1a3800c4d044b4a3e7418f534e9271770ec6)), closes [#25560](https://github.com/ionic-team/ionic-framework/issues/25560)
## [6.1.12](https://github.com/ionic-team/ionic-framework/compare/v6.1.11...v6.1.12) (2022-06-29)
### Bug Fixes
* **angular:** warn devs that standalone components are not supported ([#25516](https://github.com/ionic-team/ionic-framework/issues/25516)) ([c53785c](https://github.com/ionic-team/ionic-framework/commit/c53785c0c786113f3516c09fa512687ecb84c717))
* **datetime:** add dev warnings when setting out of bounds value ([#25513](https://github.com/ionic-team/ionic-framework/issues/25513)) ([5dfaf63](https://github.com/ionic-team/ionic-framework/commit/5dfaf63c6582811b61339a6fa50cf551cd8724d0))
## [6.1.11](https://github.com/ionic-team/ionic-framework/compare/v6.1.10...v6.1.11) (2022-06-22)
### Bug Fixes
* **datetime:** closing time picker no longer changes month ([#25478](https://github.com/ionic-team/ionic-framework/issues/25478)) ([f9ab9b5](https://github.com/ionic-team/ionic-framework/commit/f9ab9b54ddb5a3004673e4aaa9cb62fd8e97ba07)), closes [#25438](https://github.com/ionic-team/ionic-framework/issues/25438)
* **item:** multiple input appearance when using datetime ([#25498](https://github.com/ionic-team/ionic-framework/issues/25498)) ([1a8d23d](https://github.com/ionic-team/ionic-framework/commit/1a8d23da8125d54c3119eacb51206f7541c9f410)), closes [#25484](https://github.com/ionic-team/ionic-framework/issues/25484) [#25483](https://github.com/ionic-team/ionic-framework/issues/25483)
* **overlays:** focus is not moved if active element is in overlay ([#25481](https://github.com/ionic-team/ionic-framework/issues/25481)) ([dcc2da2](https://github.com/ionic-team/ionic-framework/commit/dcc2da2800e69d938b4a62db436d9f07d9663dce)), closes [#24127](https://github.com/ionic-team/ionic-framework/issues/24127) [#24820](https://github.com/ionic-team/ionic-framework/issues/24820)
* **refresher:** quickly swiping down no longer causes duplicate refresh ([#25476](https://github.com/ionic-team/ionic-framework/issues/25476)) ([3abfa78](https://github.com/ionic-team/ionic-framework/commit/3abfa780ccb32484b4d9f1b509e7ab910dfb901a)), closes [#25418](https://github.com/ionic-team/ionic-framework/issues/25418)
* **vue:** adding class to IonPage no longer hides component ([#25490](https://github.com/ionic-team/ionic-framework/issues/25490)) ([cbaa971](https://github.com/ionic-team/ionic-framework/commit/cbaa9711f094975569e2fcb28060f8e456804073))
* **vue:** components have correct type definitions ([#25499](https://github.com/ionic-team/ionic-framework/issues/25499)) ([b1821e9](https://github.com/ionic-team/ionic-framework/commit/b1821e9d0a55f20f74696f119de724ab70647977)), closes [#25485](https://github.com/ionic-team/ionic-framework/issues/25485)
## [6.1.10](https://github.com/ionic-team/ionic-framework/compare/v6.1.9...v6.1.10) (2022-06-15)
### Bug Fixes
* **angular:** router compatibility with Angular 12/13 ([#25456](https://github.com/ionic-team/ionic-framework/issues/25456)) ([7b105a3](https://github.com/ionic-team/ionic-framework/commit/7b105a3471e5bc588ba63f820b707e131c878b6f)), closes [#25448](https://github.com/ionic-team/ionic-framework/issues/25448)
* **fab-button:** improve ripple effect behavior on click ([#25413](https://github.com/ionic-team/ionic-framework/issues/25413)) ([efdaf90](https://github.com/ionic-team/ionic-framework/commit/efdaf90c5a767211e0034bab7cce5bd463ff5aa0)), closes [#21772](https://github.com/ionic-team/ionic-framework/issues/21772)
* **modal:** backdrop animation when backdropBreakpoint is 1 ([#25430](https://github.com/ionic-team/ionic-framework/issues/25430)) ([c10df52](https://github.com/ionic-team/ionic-framework/commit/c10df52f39c527dd7e03176c56a2e6cb0ebe455f)), closes [#25402](https://github.com/ionic-team/ionic-framework/issues/25402)
* **modal:** status bar color now correct with sheet modal ([#25424](https://github.com/ionic-team/ionic-framework/issues/25424)) ([377c4f5](https://github.com/ionic-team/ionic-framework/commit/377c4f597b972818d90132017d50c33074ddadab)), closes [#20501](https://github.com/ionic-team/ionic-framework/issues/20501)
* **picker-column-internal:** switching off an input mode column preserves scroll ([#25467](https://github.com/ionic-team/ionic-framework/issues/25467)) ([989429d](https://github.com/ionic-team/ionic-framework/commit/989429d65cf57ef8fb69854639f8eac1a12369bc))
* **popover:** ensure popover does not go offscreen when adjusting top position ([#25350](https://github.com/ionic-team/ionic-framework/issues/25350)) ([6926538](https://github.com/ionic-team/ionic-framework/commit/692653842b43b5e36c51163f8261fde3b5bea40d)), closes [#25349](https://github.com/ionic-team/ionic-framework/issues/25349)
## [6.1.9](https://github.com/ionic-team/ionic-framework/compare/v6.1.8...v6.1.9) (2022-06-08)
### Bug Fixes
* **all:** ripple effect is no longer added when scrolling ([#25352](https://github.com/ionic-team/ionic-framework/issues/25352)) ([0b275af](https://github.com/ionic-team/ionic-framework/commit/0b275af5ac06f470b4d908b889f513956bf5d868)), closes [#22030](https://github.com/ionic-team/ionic-framework/issues/22030)
* **angular:** add support for Angular 14 ([#25403](https://github.com/ionic-team/ionic-framework/issues/25403)) ([122cdcc](https://github.com/ionic-team/ionic-framework/commit/122cdcc8253e46d9537105b11045fd7d9ccd8917)), closes [#25353](https://github.com/ionic-team/ionic-framework/issues/25353)
* **datetime:** emit ionChange for non-calendar picker presentation ([#25380](https://github.com/ionic-team/ionic-framework/issues/25380)) ([4e6a60b](https://github.com/ionic-team/ionic-framework/commit/4e6a60b6a42287e5091728aecb61f6097e131b83)), closes [#25375](https://github.com/ionic-team/ionic-framework/issues/25375)
* **datetime:** ensure that default month shown is always in bounds ([#25351](https://github.com/ionic-team/ionic-framework/issues/25351)) ([866d452](https://github.com/ionic-team/ionic-framework/commit/866d4528ad1b8ffa65258595d553ea934daa4add)), closes [#25320](https://github.com/ionic-team/ionic-framework/issues/25320)
* **label:** text contents will repaint on change ([#25395](https://github.com/ionic-team/ionic-framework/issues/25395)) ([52ec741](https://github.com/ionic-team/ionic-framework/commit/52ec74193b4e2478cb84a6dfea261cb2113dcbff))
## [6.1.8](https://github.com/ionic-team/ionic-framework/compare/v6.1.7...v6.1.8) (2022-06-01)
### Bug Fixes
* **all:** improve compatibility with vite ([#25381](https://github.com/ionic-team/ionic-framework/issues/25381)) ([d83bcd2](https://github.com/ionic-team/ionic-framework/commit/d83bcd2b7f9937550008f995ff91517777584373)), closes [#23823](https://github.com/ionic-team/ionic-framework/issues/23823)
* **item-sliding:** swiping inside of virtual scroller now prevents scrolling ([#25345](https://github.com/ionic-team/ionic-framework/issues/25345)) ([5a1a5f6](https://github.com/ionic-team/ionic-framework/commit/5a1a5f6b4c2ab4059158986e907fff45d03be753))
* **range:** dragging knob no longer scrolls page ([#25343](https://github.com/ionic-team/ionic-framework/issues/25343)) ([0b92dff](https://github.com/ionic-team/ionic-framework/commit/0b92dffa92c05705ff83518c10608e3dc3651d51)), closes [#19004](https://github.com/ionic-team/ionic-framework/issues/19004)
* **react:** present controller overlays in React 18 ([#25361](https://github.com/ionic-team/ionic-framework/issues/25361)) ([01c40ea](https://github.com/ionic-team/ionic-framework/commit/01c40eae5509f1c150d79269a7a75c05112fa343)), closes [#25247](https://github.com/ionic-team/ionic-framework/issues/25247)
## [6.1.7](https://github.com/ionic-team/ionic-framework/compare/v6.1.6...v6.1.7) (2022-05-26)
### Bug Fixes
* **accordion:** accordions expand when using binding ([#25322](https://github.com/ionic-team/ionic-framework/issues/25322)) ([61e571e](https://github.com/ionic-team/ionic-framework/commit/61e571e585ed8ad9b0ca2f98f57bb16616413ba6)), closes [#25307](https://github.com/ionic-team/ionic-framework/issues/25307)
* **datetime:** don't update value on confirm call if no date was selected ([#25338](https://github.com/ionic-team/ionic-framework/issues/25338)) ([9e5b10a](https://github.com/ionic-team/ionic-framework/commit/9e5b10a2155c6b9de565931da384e0e49aeca7b7))
* **item, list:** list aria roles are added ([#25336](https://github.com/ionic-team/ionic-framework/issues/25336)) ([311c634](https://github.com/ionic-team/ionic-framework/commit/311c634d20e9e597db676d6f54e4b79cfe742a61)), closes [#19939](https://github.com/ionic-team/ionic-framework/issues/19939)
* **menu:** rtl menu no longer disappears on ios 15 ([#25309](https://github.com/ionic-team/ionic-framework/issues/25309)) ([6005431](https://github.com/ionic-team/ionic-framework/commit/60054310afbab6151f6c29ff6e74666acd181a41)), closes [#25192](https://github.com/ionic-team/ionic-framework/issues/25192)
* **modal:** swipe to close on content blocks scroll in ion-nav ([#25300](https://github.com/ionic-team/ionic-framework/issues/25300)) ([fdc55c0](https://github.com/ionic-team/ionic-framework/commit/fdc55c072765c87ad7c783e6d8a238b007f5f3ff)), closes [#25298](https://github.com/ionic-team/ionic-framework/issues/25298)
* **nav:** swipe to go back works inside card modal ([#25333](https://github.com/ionic-team/ionic-framework/issues/25333)) ([0156be6](https://github.com/ionic-team/ionic-framework/commit/0156be61cbf73b25cb3c2cba1bd20adebbb3db4f)), closes [#25327](https://github.com/ionic-team/ionic-framework/issues/25327)
* **range:** interfaces are now correctly exported ([#25342](https://github.com/ionic-team/ionic-framework/issues/25342)) ([15f0c06](https://github.com/ionic-team/ionic-framework/commit/15f0c0669f7598386edf487f408462b90ed91a08)), closes [#25341](https://github.com/ionic-team/ionic-framework/issues/25341)
* **react:** add param types to useIonPopover dismiss function ([#25311](https://github.com/ionic-team/ionic-framework/issues/25311)) ([7111370](https://github.com/ionic-team/ionic-framework/commit/7111370dd787fdec78a1e3368679bc4c73570b98))
* **react:** IonTabButton will call custom onClick handlers ([#25313](https://github.com/ionic-team/ionic-framework/issues/25313)) ([6034418](https://github.com/ionic-team/ionic-framework/commit/6034418b33c32fdd682c470eaf61b9fcbe86c4bb)), closes [#22511](https://github.com/ionic-team/ionic-framework/issues/22511)
* **refresher:** attach scroll listener to custom scroll target ([#25335](https://github.com/ionic-team/ionic-framework/issues/25335)) ([8f5e4cd](https://github.com/ionic-team/ionic-framework/commit/8f5e4cd9350b10a98afb7c98353c6719eee918bb)), closes [#25318](https://github.com/ionic-team/ionic-framework/issues/25318)
* **types:** improve intellisense with colors ([#25347](https://github.com/ionic-team/ionic-framework/issues/25347)) ([97cfbbb](https://github.com/ionic-team/ionic-framework/commit/97cfbbb65d3e63c32d720e01c7368c68616bb531))
* **vue:** correct views are now unmounted in tabs ([#25270](https://github.com/ionic-team/ionic-framework/issues/25270)) ([5e23fb1](https://github.com/ionic-team/ionic-framework/commit/5e23fb1ce4e5b6e53828bde59268170f604167ba)), closes [#25255](https://github.com/ionic-team/ionic-framework/issues/25255)
## [6.1.6](https://github.com/ionic-team/ionic-framework/compare/v6.1.5...v6.1.6) (2022-05-18)
### Bug Fixes
* **loading:** spinner now respects —spinner-color ([#25261](https://github.com/ionic-team/ionic-framework/issues/25261)) ([65f4c74](https://github.com/ionic-team/ionic-framework/commit/65f4c742e7a5e5756f6f72dd853e38e885f90385)), closes [#25180](https://github.com/ionic-team/ionic-framework/issues/25180)
* **modal:** reset breakpoint to initial breakpoint on present ([#25246](https://github.com/ionic-team/ionic-framework/issues/25246)) ([2557bf3](https://github.com/ionic-team/ionic-framework/commit/2557bf3c3eed9e33e89e07a8d73489da8d81bee3)), closes [#25245](https://github.com/ionic-team/ionic-framework/issues/25245)
* **scroll-assist:** touch end events continue to bubble on inputs ([#25282](https://github.com/ionic-team/ionic-framework/issues/25282)) ([780f16d](https://github.com/ionic-team/ionic-framework/commit/780f16d9e04ee5aaaf91bb7c6ef15c72cc8aeb45)), closes [#25229](https://github.com/ionic-team/ionic-framework/issues/25229)
## [6.1.5](https://github.com/ionic-team/ionic-framework/compare/v6.1.4...v6.1.5) (2022-05-11)
### Bug Fixes
* **core:** @axe-core/playwright should be a devDependency ([#25244](https://github.com/ionic-team/ionic-framework/issues/25244)) ([617ec48](https://github.com/ionic-team/ionic-framework/commit/617ec48265157d1502c443395472c21ebdb2989e)), closes [#25242](https://github.com/ionic-team/ionic-framework/issues/25242)
* **item:** counter has appropriate contrast ([#25266](https://github.com/ionic-team/ionic-framework/issues/25266)) ([750be33](https://github.com/ionic-team/ionic-framework/commit/750be33772e9ba71a3cda35709d17b7912aa68e2)), closes [#25262](https://github.com/ionic-team/ionic-framework/issues/25262)
* **modal:** add canDismiss input binding for angular ([#25240](https://github.com/ionic-team/ionic-framework/issues/25240)) ([bdf0383](https://github.com/ionic-team/ionic-framework/commit/bdf0383b0c9ec4595129a2633760fd4f4788df90)), closes [#25239](https://github.com/ionic-team/ionic-framework/issues/25239)
* **spinner:** alignment is now correct in rtl ([#25260](https://github.com/ionic-team/ionic-framework/issues/25260)) ([e3c996d](https://github.com/ionic-team/ionic-framework/commit/e3c996dea878a8dd276a0ca99f59b330125f9b75))
## [6.1.4](https://github.com/ionic-team/ionic-framework/compare/v6.1.3...v6.1.4) (2022-05-04)
### Bug Fixes
* **datetime:** arrow navigation respects min/max values ([#25182](https://github.com/ionic-team/ionic-framework/issues/25182)) ([6946e09](https://github.com/ionic-team/ionic-framework/commit/6946e09815da605e37ff8e4d613a14288ea35fb0)), closes [#25073](https://github.com/ionic-team/ionic-framework/issues/25073)
* **datetime:** hide footer when month-year picker is open ([#25205](https://github.com/ionic-team/ionic-framework/issues/25205)) ([aa5e1b9](https://github.com/ionic-team/ionic-framework/commit/aa5e1b962150b9ed9629812ec566873784526c83))
* **modal:** card modal can now be swiped to close on the content ([#25185](https://github.com/ionic-team/ionic-framework/issues/25185)) ([7633ddb](https://github.com/ionic-team/ionic-framework/commit/7633ddbc845745dfe36b5c8025c54c22c083c2f4)), closes [#22046](https://github.com/ionic-team/ionic-framework/issues/22046)
* **modal:** card modal no longer dismisses from content with refresher ([#25227](https://github.com/ionic-team/ionic-framework/issues/25227)) ([c4f811f](https://github.com/ionic-team/ionic-framework/commit/c4f811f1dde0dcbcdaebaa3a4f5ef87e192b5cc5))
* **react:** useIonModal/useIonPopover dismiss accepts data and role ([#25209](https://github.com/ionic-team/ionic-framework/issues/25209)) ([68b2f8b](https://github.com/ionic-team/ionic-framework/commit/68b2f8bfe10946580b996e48c4ec1e2df94b8d49)), closes [#25208](https://github.com/ionic-team/ionic-framework/issues/25208)
* **vue:** switching between tabs and going back resolves to correct route ([#25206](https://github.com/ionic-team/ionic-framework/issues/25206)) ([b4ba70e](https://github.com/ionic-team/ionic-framework/commit/b4ba70ea148d4f8fc7475d3de798b485238470c8)), closes [#24303](https://github.com/ionic-team/ionic-framework/issues/24303)
## [6.1.3](https://github.com/ionic-team/ionic-framework/compare/v6.1.2...v6.1.3) (2022-04-27)
### Bug Fixes
* **core:** inherit aria attributes on host elements ([#25156](https://github.com/ionic-team/ionic-framework/issues/25156)) ([611832b](https://github.com/ionic-team/ionic-framework/commit/611832b0d51da295c1bf2897972c4e8baf6e23a3)), closes [#20127](https://github.com/ionic-team/ionic-framework/issues/20127)
* **datetime:** if no default value, don't highlight active day until one is selected ([#25151](https://github.com/ionic-team/ionic-framework/issues/25151)) ([9896939](https://github.com/ionic-team/ionic-framework/commit/98969395abd400cc44d2d3825581a63eb64a56e0))
* **picker-column-internal:** center active item when rapidly opened ([#25155](https://github.com/ionic-team/ionic-framework/issues/25155)) ([8e17fa9](https://github.com/ionic-team/ionic-framework/commit/8e17fa9d5f9b00139693e34bc93b1f9c718ea3cf)), closes [#25154](https://github.com/ionic-team/ionic-framework/issues/25154)
* **select:** avoid duplicate dialogs and backdrops when clicking ([#25175](https://github.com/ionic-team/ionic-framework/issues/25175)) ([70d2784](https://github.com/ionic-team/ionic-framework/commit/70d278414eb5124d17c5ffaba5231c6bfd285656)), closes [#25126](https://github.com/ionic-team/ionic-framework/issues/25126)
* **vue:** canDismiss definition is now exposed ([#25195](https://github.com/ionic-team/ionic-framework/issues/25195)) ([e5e0e24](https://github.com/ionic-team/ionic-framework/commit/e5e0e24f76c15c1a49f759b1a140e337f5393edd))
* **vue:** replacing routes across nested outlets preserves previous route info ([#25171](https://github.com/ionic-team/ionic-framework/issues/25171)) ([7b71607](https://github.com/ionic-team/ionic-framework/commit/7b716076b66fbb5bd4620ea8ba74318bbbc1b7e8)), closes [#25017](https://github.com/ionic-team/ionic-framework/issues/25017)
## [6.1.2](https://github.com/ionic-team/ionic-framework/compare/v6.1.1...v6.1.2) (2022-04-20)
### Bug Fixes
* **datetime:** time picker display matches dynamically set value ([#25010](https://github.com/ionic-team/ionic-framework/issues/25010)) ([11493a0](https://github.com/ionic-team/ionic-framework/commit/11493a086a4e3f2a4e9d3acdf5a9d49e810a5ef0)), closes [#24967](https://github.com/ionic-team/ionic-framework/issues/24967)
* **modal:** add canDismiss option to modal options ([#25144](https://github.com/ionic-team/ionic-framework/issues/25144)) ([2984ddf](https://github.com/ionic-team/ionic-framework/commit/2984ddf111b6acbd9e47ed90830b6522179b6cee)), closes [#25143](https://github.com/ionic-team/ionic-framework/issues/25143)
## [6.1.1](https://github.com/ionic-team/ionic-framework/compare/v6.1.0...v6.1.1) (2022-04-15)
### Bug Fixes
* **all:** import path is now correct when using ionic in a stencil app ([#25123](https://github.com/ionic-team/ionic-framework/issues/25123)) ([1b407ab](https://github.com/ionic-team/ionic-framework/commit/1b407abdf5d8a2a18b6a2b9daca2d58b7b0f782b)), closes [#25122](https://github.com/ionic-team/ionic-framework/issues/25122)
* **datetime:** account for 30 and 45 minute timezones when getting current date ([#25120](https://github.com/ionic-team/ionic-framework/issues/25120)) ([96b2003](https://github.com/ionic-team/ionic-framework/commit/96b2003b2bd5089d1faafe262e96c7445c5c3349)), closes [#25112](https://github.com/ionic-team/ionic-framework/issues/25112)
* **modal, popover:** do not dismiss when ionDismiss is emitted from select ([#25125](https://github.com/ionic-team/ionic-framework/issues/25125)) ([90115db](https://github.com/ionic-team/ionic-framework/commit/90115db98540a5fc67b611ac2742d1221b8e96ff)), closes [#25124](https://github.com/ionic-team/ionic-framework/issues/25124)
# [6.1.0 Vanadium](https://github.com/ionic-team/ionic-framework/compare/v6.0.16...v6.1.0) (2022-04-13)
### Bug Fixes
* **accordion-group:** only allow keyboard interaction if header is focused ([#25091](https://github.com/ionic-team/ionic-framework/issues/25091)) ([e1b555f](https://github.com/ionic-team/ionic-framework/commit/e1b555f286956574876924068304fc44a78c027c))
* **datetime:** resolve warnings when importing into Stencil app ([#25106](https://github.com/ionic-team/ionic-framework/issues/25106)) ([a61c004](https://github.com/ionic-team/ionic-framework/commit/a61c004fb0c10d9fb0eca0987edf798386251ec2))
* **menu:** preserve scroll position when focusing on open ([#25044](https://github.com/ionic-team/ionic-framework/issues/25044)) ([da89684](https://github.com/ionic-team/ionic-framework/commit/da896848776105ba1f7035c4412495786199bade))
* **popover:** only focus trap ion-item children ([#24990](https://github.com/ionic-team/ionic-framework/issues/24990)) ([0cd06a6](https://github.com/ionic-team/ionic-framework/commit/0cd06a675474e1893b4c0801fab8ab79813537c8)), closes [#24633](https://github.com/ionic-team/ionic-framework/issues/24633)
* **ripple-effect:** ripple displays on click or touch ([#25102](https://github.com/ionic-team/ionic-framework/issues/25102)) ([2a313e9](https://github.com/ionic-team/ionic-framework/commit/2a313e91179e19660a758470ed2218bbcf03e0bb)), closes [#25094](https://github.com/ionic-team/ionic-framework/issues/25094)
* **vue:** ensure that only tab pages get added to the tab navigation stack ([#25045](https://github.com/ionic-team/ionic-framework/issues/25045)) ([a0054a7](https://github.com/ionic-team/ionic-framework/commit/a0054a7cbd52def24c18fd2dadfd2e49a42b8980)), closes [#24859](https://github.com/ionic-team/ionic-framework/issues/24859)
### Features
* **content, reorder-group, header, footer, infinite-scroll, refresher:** add custom scroll target to improve compatibility with virtual scroll ([#24883](https://github.com/ionic-team/ionic-framework/issues/24883)) ([2a438da](https://github.com/ionic-team/ionic-framework/commit/2a438da010ddd4d4211e1879e27d7b28409daaa2)), closes [#23437](https://github.com/ionic-team/ionic-framework/issues/23437)
* **datetime:** isDateEnabled to enable/disable specific days ([#24898](https://github.com/ionic-team/ionic-framework/issues/24898)) ([e932a04](https://github.com/ionic-team/ionic-framework/commit/e932a042237e6f44bf278bcbd895d8569fc17348)), closes [#24209](https://github.com/ionic-team/ionic-framework/issues/24209)
* **item:** counter formatter to customize counter text display ([#24336](https://github.com/ionic-team/ionic-framework/issues/24336)) ([171020e](https://github.com/ionic-team/ionic-framework/commit/171020e9d200ccfdef0f01c427b295bb50dd1fef)), closes [#24327](https://github.com/ionic-team/ionic-framework/issues/24327)
* **modal:** ability to programmatically set current sheet breakpoint ([#24648](https://github.com/ionic-team/ionic-framework/issues/24648)) ([3145c76](https://github.com/ionic-team/ionic-framework/commit/3145c76934ac711038f9dcba98a385dfbe754953)), closes [#23917](https://github.com/ionic-team/ionic-framework/issues/23917)
* **modal:** add canDismiss property to manage modal dismissing ([#24928](https://github.com/ionic-team/ionic-framework/issues/24928)) ([4b21958](https://github.com/ionic-team/ionic-framework/commit/4b21958ec57019afcde786598880e1f8edada2b1)), closes [#22297](https://github.com/ionic-team/ionic-framework/issues/22297)
* **range:** add knobMoveStart and knobMoveEnd events ([#25011](https://github.com/ionic-team/ionic-framework/issues/25011)) ([f5cb1f8](https://github.com/ionic-team/ionic-framework/commit/f5cb1f8444ba050042e788f9f9ec7b6309bf1b60))
* **select:** add event for when overlay is dismissed ([#24400](https://github.com/ionic-team/ionic-framework/issues/24400)) ([b835b7c](https://github.com/ionic-team/ionic-framework/commit/b835b7c0c7840f41c54f96743cc0a779ff474ab6))
## [6.0.16](https://github.com/ionic-team/ionic-framework/compare/v6.0.15...v6.0.16) (2022-04-08)

36
LICENSE
View File

@@ -1,21 +1,23 @@
Copyright 2015-present Drifty Co.
http://drifty.com/
MIT License
Copyright (c) 2015-present Drifty Co.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -3,256 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.2.8](https://github.com/ionic-team/ionic/compare/v6.2.7...v6.2.8) (2022-09-21)
**Note:** Version bump only for package @ionic/angular
## [6.2.7](https://github.com/ionic-team/ionic/compare/v6.2.6...v6.2.7) (2022-09-14)
### Bug Fixes
* **angular:** nav controller can pop views after leaving tabs outlet ([#25690](https://github.com/ionic-team/ionic/issues/25690)) ([725b13f](https://github.com/ionic-team/ionic/commit/725b13fa60775dc9f9c3491cb545c70a5a9162eb)), closes [#18593](https://github.com/ionic-team/ionic/issues/18593)
## [6.2.6](https://github.com/ionic-team/ionic/compare/v6.2.5...v6.2.6) (2022-09-07)
**Note:** Version bump only for package @ionic/angular
## [6.2.5](https://github.com/ionic-team/ionic/compare/v6.2.4...v6.2.5) (2022-08-31)
### Bug Fixes
* **angular:** router outlet has mode property ([#25816](https://github.com/ionic-team/ionic/issues/25816)) ([afd0bbc](https://github.com/ionic-team/ionic/commit/afd0bbc60aa8f4edc88dc311d6484ac60117fce5)), closes [#25813](https://github.com/ionic-team/ionic/issues/25813)
## [6.2.4](https://github.com/ionic-team/ionic/compare/v6.2.3...v6.2.4) (2022-08-24)
**Note:** Version bump only for package @ionic/angular
## [6.2.3](https://github.com/ionic-team/ionic/compare/v6.2.2...v6.2.3) (2022-08-17)
**Note:** Version bump only for package @ionic/angular
## [6.2.2](https://github.com/ionic-team/ionic/compare/v6.2.1...v6.2.2) (2022-08-10)
### Bug Fixes
* **angular:** DatetimeButton is declared on IonicModule ([#25727](https://github.com/ionic-team/ionic/issues/25727)) ([76ad1d1](https://github.com/ionic-team/ionic/commit/76ad1d18c81272435db1994977aa9dd5d880504a))
## [6.2.1](https://github.com/ionic-team/ionic/compare/v6.2.0...v6.2.1) (2022-08-03)
**Note:** Version bump only for package @ionic/angular
# [6.2.0](https://github.com/ionic-team/ionic/compare/v6.1.15...v6.2.0) (2022-07-27)
### Features
* **angular, react, vue:** add support for autoMountComponent ([#25552](https://github.com/ionic-team/ionic/issues/25552)) ([805dfa0](https://github.com/ionic-team/ionic/commit/805dfa05663098ef9c02b0745a383b5e7555908b))
* **datetime-button:** add button for displaying datetime in overlays ([#25655](https://github.com/ionic-team/ionic/issues/25655)) ([4997331](https://github.com/ionic-team/ionic/commit/499733105e4be23405e8afeeb26fee5cd2afc25b)), closes [#24316](https://github.com/ionic-team/ionic/issues/24316)
* **datetime:** add multiple date selection ([#25514](https://github.com/ionic-team/ionic/issues/25514)) ([9d31608](https://github.com/ionic-team/ionic/commit/9d31608f2d471f531eb253832c8558d1effaf68a))
* **datetime:** add wheel style picker for dates and times ([#25468](https://github.com/ionic-team/ionic/issues/25468)) ([3d19771](https://github.com/ionic-team/ionic/commit/3d19771185301870a2eb60f1ef4afd6f1c182494))
* **modal:** clicking handle advances to the next breakpoint ([#25540](https://github.com/ionic-team/ionic/issues/25540)) ([7cdc388](https://github.com/ionic-team/ionic/commit/7cdc388b7805cbf23c9e1e928aa977cd77ebc8c4)), closes [#24069](https://github.com/ionic-team/ionic/issues/24069)
* **range:** add reference point for start position of range slider ([#25598](https://github.com/ionic-team/ionic/issues/25598)) ([c2781cc](https://github.com/ionic-team/ionic/commit/c2781cc1c3b7e56a0e6f6c03cfa04fc2c82d6e8a)), closes [#24348](https://github.com/ionic-team/ionic/issues/24348)
## [6.1.15](https://github.com/ionic-team/ionic/compare/v6.1.14...v6.1.15) (2022-07-20)
**Note:** Version bump only for package @ionic/angular
## [6.1.14](https://github.com/ionic-team/ionic/compare/v6.1.13...v6.1.14) (2022-07-13)
**Note:** Version bump only for package @ionic/angular
## [6.1.13](https://github.com/ionic-team/ionic/compare/v6.1.12...v6.1.13) (2022-07-06)
**Note:** Version bump only for package @ionic/angular
## [6.1.12](https://github.com/ionic-team/ionic/compare/v6.1.11...v6.1.12) (2022-06-29)
### Bug Fixes
* **angular:** warn devs that standalone components are not supported ([#25516](https://github.com/ionic-team/ionic/issues/25516)) ([c53785c](https://github.com/ionic-team/ionic/commit/c53785c0c786113f3516c09fa512687ecb84c717))
## [6.1.11](https://github.com/ionic-team/ionic/compare/v6.1.10...v6.1.11) (2022-06-22)
**Note:** Version bump only for package @ionic/angular
## [6.1.10](https://github.com/ionic-team/ionic/compare/v6.1.9...v6.1.10) (2022-06-15)
### Bug Fixes
* **angular:** router compatibility with Angular 12/13 ([#25456](https://github.com/ionic-team/ionic/issues/25456)) ([7b105a3](https://github.com/ionic-team/ionic/commit/7b105a3471e5bc588ba63f820b707e131c878b6f)), closes [#25448](https://github.com/ionic-team/ionic/issues/25448)
## [6.1.9](https://github.com/ionic-team/ionic/compare/v6.1.8...v6.1.9) (2022-06-08)
### Bug Fixes
* **angular:** add support for Angular 14 ([#25403](https://github.com/ionic-team/ionic/issues/25403)) ([122cdcc](https://github.com/ionic-team/ionic/commit/122cdcc8253e46d9537105b11045fd7d9ccd8917)), closes [#25353](https://github.com/ionic-team/ionic/issues/25353)
## [6.1.8](https://github.com/ionic-team/ionic/compare/v6.1.7...v6.1.8) (2022-06-01)
**Note:** Version bump only for package @ionic/angular
## [6.1.7](https://github.com/ionic-team/ionic/compare/v6.1.6...v6.1.7) (2022-05-26)
### Bug Fixes
* **accordion:** accordions expand when using binding ([#25322](https://github.com/ionic-team/ionic/issues/25322)) ([61e571e](https://github.com/ionic-team/ionic/commit/61e571e585ed8ad9b0ca2f98f57bb16616413ba6)), closes [#25307](https://github.com/ionic-team/ionic/issues/25307)
* **range:** interfaces are now correctly exported ([#25342](https://github.com/ionic-team/ionic/issues/25342)) ([15f0c06](https://github.com/ionic-team/ionic/commit/15f0c0669f7598386edf487f408462b90ed91a08)), closes [#25341](https://github.com/ionic-team/ionic/issues/25341)
## [6.1.6](https://github.com/ionic-team/ionic/compare/v6.1.5...v6.1.6) (2022-05-18)
**Note:** Version bump only for package @ionic/angular
## [6.1.5](https://github.com/ionic-team/ionic/compare/v6.1.4...v6.1.5) (2022-05-11)
### Bug Fixes
* **modal:** add canDismiss input binding for angular ([#25240](https://github.com/ionic-team/ionic/issues/25240)) ([bdf0383](https://github.com/ionic-team/ionic/commit/bdf0383b0c9ec4595129a2633760fd4f4788df90)), closes [#25239](https://github.com/ionic-team/ionic/issues/25239)
## [6.1.4](https://github.com/ionic-team/ionic/compare/v6.1.3...v6.1.4) (2022-05-04)
**Note:** Version bump only for package @ionic/angular
## [6.1.3](https://github.com/ionic-team/ionic/compare/v6.1.2...v6.1.3) (2022-04-27)
### Bug Fixes
* **vue:** canDismiss definition is now exposed ([#25195](https://github.com/ionic-team/ionic/issues/25195)) ([e5e0e24](https://github.com/ionic-team/ionic/commit/e5e0e24f76c15c1a49f759b1a140e337f5393edd))
## [6.1.2](https://github.com/ionic-team/ionic/compare/v6.1.1...v6.1.2) (2022-04-20)
**Note:** Version bump only for package @ionic/angular
## [6.1.1](https://github.com/ionic-team/ionic/compare/v6.1.0...v6.1.1) (2022-04-15)
**Note:** Version bump only for package @ionic/angular
# [6.1.0](https://github.com/ionic-team/ionic/compare/v6.0.14...v6.1.0) (2022-04-13)
### Bug Fixes
* **angular:** button components now route correctly without reload ([#25071](https://github.com/ionic-team/ionic/issues/25071)) ([1c26e9b](https://github.com/ionic-team/ionic/commit/1c26e9b9b0fc45a8691e972fe17a168f89a27a79))
* **angular:** item styling when control has value ([#24932](https://github.com/ionic-team/ionic/issues/24932)) ([eea25d0](https://github.com/ionic-team/ionic/commit/eea25d091d7eb319d6ec1de8b793881d3a10949b)), closes [#23809](https://github.com/ionic-team/ionic/issues/23809)
* **angular:** routerLink allows opening in a new tab for link elements ([#25014](https://github.com/ionic-team/ionic/issues/25014)) ([b010f07](https://github.com/ionic-team/ionic/commit/b010f077fe51992dd9dd8ced69769a8eb91ac055)), closes [#24413](https://github.com/ionic-team/ionic/issues/24413)
### Features
* **datetime:** isDateEnabled to enable/disable specific days ([#24898](https://github.com/ionic-team/ionic/issues/24898)) ([e932a04](https://github.com/ionic-team/ionic/commit/e932a042237e6f44bf278bcbd895d8569fc17348)), closes [#24209](https://github.com/ionic-team/ionic/issues/24209)
* **item:** counter formatter to customize counter text display ([#24336](https://github.com/ionic-team/ionic/issues/24336)) ([171020e](https://github.com/ionic-team/ionic/commit/171020e9d200ccfdef0f01c427b295bb50dd1fef)), closes [#24327](https://github.com/ionic-team/ionic/issues/24327)
* **modal:** ability to programmatically set current sheet breakpoint ([#24648](https://github.com/ionic-team/ionic/issues/24648)) ([3145c76](https://github.com/ionic-team/ionic/commit/3145c76934ac711038f9dcba98a385dfbe754953)), closes [#23917](https://github.com/ionic-team/ionic/issues/23917)
* **range:** add knobMoveStart and knobMoveEnd events ([#25011](https://github.com/ionic-team/ionic/issues/25011)) ([f5cb1f8](https://github.com/ionic-team/ionic/commit/f5cb1f8444ba050042e788f9f9ec7b6309bf1b60))
* **select:** add event for when overlay is dismissed ([#24400](https://github.com/ionic-team/ionic/issues/24400)) ([b835b7c](https://github.com/ionic-team/ionic/commit/b835b7c0c7840f41c54f96743cc0a779ff474ab6))
## [6.0.16](https://github.com/ionic-team/ionic/compare/v6.0.15...v6.0.16) (2022-04-08)

View File

@@ -1,15 +1,15 @@
{
"name": "@ionic/angular",
"version": "6.2.8",
"version": "6.0.16",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/angular",
"version": "6.2.8",
"version": "6.0.1",
"license": "MIT",
"dependencies": {
"@ionic/core": "^6.2.7",
"@ionic/core": "6.0.0",
"jsonc-parser": "^3.0.0",
"tslib": "^2.0.0"
},
@@ -1023,27 +1023,15 @@
"dev": true
},
"node_modules/@ionic/core": {
"version": "6.2.7",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.7.tgz",
"integrity": "sha512-pQWcIqr5zfCX5De/MQ9kFs+nhaPCr8HIh5QjmydxvmlLv6WU4vlny/Mg0y1+JwLE0qxPD0T9sMykawWH9e3y5Q==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.0.0.tgz",
"integrity": "sha512-3e5EJhDebK4pCiFREpNB95o2kBSAdhRb3eMsBDOCYWYuFlcZEOGOpiGx+kYF/klYVQnB45UXAmR8nCX1indmHQ==",
"dependencies": {
"@stencil/core": "^2.17.4",
"ionicons": "^6.0.3",
"@stencil/core": "~2.11.0-0",
"ionicons": "^6.0.0",
"tslib": "^2.1.0"
}
},
"node_modules/@ionic/core/node_modules/@stencil/core": {
"version": "2.17.4",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.17.4.tgz",
"integrity": "sha512-SGRlHpjV1RyFvzw6jFMVKpLNox9Eds3VvpbpD2SW9CuxdLonHDSFtQks5zmT4zs1Rse9I6kFc2mFK/dHNTalkg==",
"bin": {
"stencil": "bin/stencil"
},
"engines": {
"node": ">=12.10.0",
"npm": ">=6.0.0"
}
},
"node_modules/@ionic/eslint-config": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@ionic/eslint-config/-/eslint-config-0.3.0.tgz",
@@ -1234,9 +1222,9 @@
}
},
"node_modules/@stencil/core": {
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.16.1.tgz",
"integrity": "sha512-s/UJp9qxExL3DyQPT70kiuWeb3AdjbUZM+5lEIXn30I2DLcLYPOPXfsoWJODieQywq+3vPiLZeIdkoqjf6jcSw==",
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.11.0.tgz",
"integrity": "sha512-/IubCWhVXCguyMUp/3zGrg3c882+RJNg/zpiKfyfJL3kRCOwe+/MD8OoAXVGdd+xAohZKIi1Ik+EHFlsptsjLg==",
"bin": {
"stencil": "bin/stencil"
},
@@ -2060,9 +2048,9 @@
"dev": true
},
"node_modules/commander": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.2.0.tgz",
"integrity": "sha512-LLKxDvHeL91/8MIyTAD5BFMNtoIwztGPMiM/7Bl8rIPmHCZXRxmSWr91h57dpOpnQ6jIUqEWdXE/uBYMfiVZDA==",
"dev": true,
"engines": {
"node": ">= 12"
@@ -2320,9 +2308,9 @@
"dev": true
},
"node_modules/debug": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
"integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"dependencies": {
"ms": "2.1.2"
@@ -3569,11 +3557,23 @@
}
},
"node_modules/ionicons": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.0.3.tgz",
"integrity": "sha512-kVOWER991EMqLiVShrCSWKMHkgHZP7XfVdyN6YPMuoO33W7pc5CPNVNfR8OMe/I8rYEbaunyBs6dXNYpR6gGZw==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.0.0.tgz",
"integrity": "sha512-p83W1T8jZUlllHAjuIWaDQbI36OYqdrwcf8MhYbKW7+9rjGlCMP9+5OaR0W7tl0QfM004uAiy/zkc7HTpDNKgA==",
"dependencies": {
"@stencil/core": "~2.16.0"
"@stencil/core": "~2.10.0"
}
},
"node_modules/ionicons/node_modules/@stencil/core": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.10.0.tgz",
"integrity": "sha512-15rWMTPQ/sp0lSV82HVCXkIya3QLN+uBl7pqK4JnTrp4HiLrzLmNbWjbvgCs55gw0lULbCIGbRIEsFz+Pe/Q+A==",
"bin": {
"stencil": "bin/stencil"
},
"engines": {
"node": ">=12.10.0",
"npm": ">=6.0.0"
}
},
"node_modules/is-bigint": {
@@ -7951,20 +7951,13 @@
"dev": true
},
"@ionic/core": {
"version": "6.2.7",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.7.tgz",
"integrity": "sha512-pQWcIqr5zfCX5De/MQ9kFs+nhaPCr8HIh5QjmydxvmlLv6WU4vlny/Mg0y1+JwLE0qxPD0T9sMykawWH9e3y5Q==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.0.0.tgz",
"integrity": "sha512-3e5EJhDebK4pCiFREpNB95o2kBSAdhRb3eMsBDOCYWYuFlcZEOGOpiGx+kYF/klYVQnB45UXAmR8nCX1indmHQ==",
"requires": {
"@stencil/core": "^2.17.4",
"ionicons": "^6.0.3",
"@stencil/core": "~2.11.0-0",
"ionicons": "^6.0.0",
"tslib": "^2.1.0"
},
"dependencies": {
"@stencil/core": {
"version": "2.17.4",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.17.4.tgz",
"integrity": "sha512-SGRlHpjV1RyFvzw6jFMVKpLNox9Eds3VvpbpD2SW9CuxdLonHDSFtQks5zmT4zs1Rse9I6kFc2mFK/dHNTalkg=="
}
}
},
"@ionic/eslint-config": {
@@ -8111,9 +8104,9 @@
}
},
"@stencil/core": {
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.16.1.tgz",
"integrity": "sha512-s/UJp9qxExL3DyQPT70kiuWeb3AdjbUZM+5lEIXn30I2DLcLYPOPXfsoWJODieQywq+3vPiLZeIdkoqjf6jcSw=="
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.11.0.tgz",
"integrity": "sha512-/IubCWhVXCguyMUp/3zGrg3c882+RJNg/zpiKfyfJL3kRCOwe+/MD8OoAXVGdd+xAohZKIi1Ik+EHFlsptsjLg=="
},
"@types/estree": {
"version": "0.0.39",
@@ -8674,9 +8667,9 @@
"dev": true
},
"commander": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.2.0.tgz",
"integrity": "sha512-LLKxDvHeL91/8MIyTAD5BFMNtoIwztGPMiM/7Bl8rIPmHCZXRxmSWr91h57dpOpnQ6jIUqEWdXE/uBYMfiVZDA==",
"dev": true
},
"commondir": {
@@ -8874,9 +8867,9 @@
"dev": true
},
"debug": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
"integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -9818,11 +9811,18 @@
}
},
"ionicons": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.0.3.tgz",
"integrity": "sha512-kVOWER991EMqLiVShrCSWKMHkgHZP7XfVdyN6YPMuoO33W7pc5CPNVNfR8OMe/I8rYEbaunyBs6dXNYpR6gGZw==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.0.0.tgz",
"integrity": "sha512-p83W1T8jZUlllHAjuIWaDQbI36OYqdrwcf8MhYbKW7+9rjGlCMP9+5OaR0W7tl0QfM004uAiy/zkc7HTpDNKgA==",
"requires": {
"@stencil/core": "~2.16.0"
"@stencil/core": "~2.10.0"
},
"dependencies": {
"@stencil/core": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.10.0.tgz",
"integrity": "sha512-15rWMTPQ/sp0lSV82HVCXkIya3QLN+uBl7pqK4JnTrp4HiLrzLmNbWjbvgCs55gw0lULbCIGbRIEsFz+Pe/Q+A=="
}
}
},
"is-bigint": {

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular",
"version": "6.2.8",
"version": "6.0.16",
"description": "Angular specific wrappers for @ionic/core",
"keywords": [
"ionic",
@@ -44,7 +44,7 @@
"validate": "npm i && npm run lint && npm run test && npm run build"
},
"dependencies": {
"@ionic/core": "^6.2.8",
"@ionic/core": "^6.0.16",
"jsonc-parser": "^3.0.0",
"tslib": "^2.0.0"
},

View File

@@ -1,34 +0,0 @@
/**
* This class is taken directly from Angular's codebase. It can be removed once
* we remove support for < Angular 14. The replacement class will come from @angular/core.
*
* TODO: FW-1641: Remove this class once Angular 13 support is dropped.
*
*/
import { Injector, ProviderToken, InjectFlags } from '@angular/core';
/**
* An `Injector` that's part of the environment injector hierarchy, which exists outside of the
* component tree.
*
* @developerPreview
*/
export abstract class EnvironmentInjector implements Injector {
/**
* Retrieves an instance from the injector based on the provided token.
* @returns The instance from the injector if defined, otherwise the `notFoundValue`.
* @throws When the `notFoundValue` is `undefined` or `Injector.THROW_IF_NOT_FOUND`.
*/
abstract get<T>(token: ProviderToken<T>, notFoundValue?: T, flags?: InjectFlags): T;
/**
* @deprecated from v4.0.0 use ProviderToken<T>
* @suppress {duplicate}
*/
abstract get(token: any, notFoundValue?: any): any;
abstract destroy(): void;
/**
* @internal
*/
abstract onDestroy(callback: () => void): void;
}

View File

@@ -20,11 +20,9 @@ import { componentOnReady } from '@ionic/core';
import { Observable, BehaviorSubject } from 'rxjs';
import { distinctUntilChanged, filter, switchMap } from 'rxjs/operators';
import { EnvironmentInjector } from '../../di/r3_injector';
import { AnimationBuilder } from '../../ionic-core';
import { Config } from '../../providers/config';
import { NavController } from '../../providers/nav-controller';
import { isComponentFactoryResolver } from '../../util/util';
import { StackController } from './stack-controller';
import { RouteView, getUrl } from './stack-utils';
@@ -33,7 +31,7 @@ import { RouteView, getUrl } from './stack-utils';
selector: 'ion-router-outlet',
exportAs: 'outlet',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['animated', 'animation', 'mode', 'swipeGesture'],
inputs: ['animated', 'animation', 'swipeGesture'],
})
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class IonRouterOutlet implements OnDestroy, OnInit {
@@ -84,12 +82,11 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
constructor(
private parentContexts: ChildrenOutletContexts,
private location: ViewContainerRef,
private resolver: ComponentFactoryResolver,
@Attribute('name') name: string,
@Optional() @Attribute('tabs') tabs: string,
private config: Config,
private navCtrl: NavController,
@Optional() private environmentInjector: EnvironmentInjector,
@Optional() private componentFactoryResolver: ComponentFactoryResolver,
commonLocation: Location,
elementRef: ElementRef,
router: Router,
@@ -209,10 +206,7 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
}
}
activateWith(
activatedRoute: ActivatedRoute,
resolverOrInjector?: ComponentFactoryResolver | EnvironmentInjector | null
): void {
activateWith(activatedRoute: ActivatedRoute, resolver: ComponentFactoryResolver | null): void {
if (this.isActivated) {
throw new Error('Cannot activate an already activated outlet');
}
@@ -233,25 +227,11 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
this.updateActivatedRouteProxy(cmpRef.instance, activatedRoute);
} else {
const snapshot = (activatedRoute as any)._futureSnapshot;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const component = snapshot.routeConfig!.component as any;
resolver = resolver || this.resolver;
/**
* Angular 14 introduces a new `loadComponent` property to the route config,
* that assigns the component to load to the `component` property of
* the route snapshot. We can check for the presence of this property
* to determine if the route is using standalone components.
*
* TODO: FW-1631: Remove this check when supporting standalone components
*/
if (component == null && snapshot.component) {
console.warn(
'[Ionic Warning]: Standalone components are not currently supported with ion-router-outlet. You can track this feature request at https://github.com/ionic-team/ionic-framework/issues/25404'
);
return;
}
const factory = resolver.resolveComponentFactory(component);
const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
// We create an activated route proxy object that will maintain future updates for this component
@@ -260,41 +240,8 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
const activatedRouteProxy = this.createActivatedRouteProxy(component$, activatedRoute);
const injector = new OutletInjector(activatedRouteProxy, childContexts, this.location.injector);
cmpRef = this.activated = this.location.createComponent(factory, this.location.length, injector);
/**
* The resolver is not always provided and is required in Angular 12.
* Fallback to the class-level provider when the resolver is not set.
*/
resolverOrInjector = resolverOrInjector || this.componentFactoryResolver;
if (resolverOrInjector && isComponentFactoryResolver(resolverOrInjector)) {
// Backwards compatibility for Angular 13 and lower
const factory = resolverOrInjector.resolveComponentFactory(component);
cmpRef = this.activated = this.location.createComponent(factory, this.location.length, injector);
} else {
/**
* Angular 14 and higher.
*
* TODO: FW-1641: Migrate once Angular 13 support is dropped.
*
* When we drop < Angular 14, we can replace the following code with:
* ```ts
const environmentInjector = resolverOrInjector ?? this.environmentInjector;
cmpRef = this.activated = location.createComponent(component, {
index: location.length,
injector,
environmentInjector,
});
* ```
* where `this.environmentInjector` is a provider of `EnvironmentInjector` from @angular/core.
*/
const environmentInjector = resolverOrInjector ?? this.environmentInjector;
cmpRef = this.activated = this.location.createComponent(component, {
index: this.location.length,
injector,
environmentInjector,
} as any);
}
// Once the component is created we can push it to our local subject supplied to the proxy
component$.next(cmpRef.instance);
@@ -308,19 +255,8 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
}
this.activatedView = enteringView;
/**
* The top outlet is set prior to the entering view's transition completing,
* so that when we have nested outlets (e.g. ion-tabs inside an ion-router-outlet),
* the tabs outlet will be assigned as the top outlet when a view inside tabs is
* activated.
*
* In this scenario, activeWith is called for both the tabs and the root router outlet.
* To avoid a race condition, we assign the top outlet synchronously.
*/
this.navCtrl.setTopOutlet(this);
this.stackCtrl.setActive(enteringView).then((data) => {
this.navCtrl.setTopOutlet(this);
this.activateEvents.emit(cmpRef.instance);
this.stackEvents.emit(data);
});

View File

@@ -11,7 +11,7 @@ import {
TemplateRef,
} from '@angular/core';
import { ProxyCmp, proxyOutputs } from '../angular-component-lib/utils';
import { Components, ModalBreakpointChangeEventDetail } from '@ionic/core';
import { Components } from '@ionic/core';
export declare interface IonModal extends Components.IonModal {
/**
@@ -30,10 +30,6 @@ export declare interface IonModal extends Components.IonModal {
* Emitted after the modal has dismissed.
*/
ionModalDidDismiss: EventEmitter<CustomEvent>;
/**
* Emitted after the modal breakpoint has changed.
*/
ionBreakpointDidChange: EventEmitter<CustomEvent<ModalBreakpointChangeEventDetail>>;
/**
* Emitted after the modal has presented. Shorthand for ionModalWillDismiss.
*/
@@ -54,16 +50,13 @@ export declare interface IonModal extends Components.IonModal {
@ProxyCmp({
inputs: [
'animated',
'keepContentsMounted',
'backdropBreakpoint',
'backdropDismiss',
'breakpoints',
'canDismiss',
'cssClass',
'enterAnimation',
'event',
'handle',
'handleBehavior',
'initialBreakpoint',
'isOpen',
'keyboardClose',
@@ -75,26 +68,21 @@ export declare interface IonModal extends Components.IonModal {
'translucent',
'trigger',
],
methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss', 'setCurrentBreakpoint', 'getCurrentBreakpoint'],
methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'],
})
@Component({
selector: 'ion-modal',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `<div class="ion-page" *ngIf="isCmpOpen || keepContentsMounted">
<ng-container [ngTemplateOutlet]="template"></ng-container>
</div>`,
template: `<div class="ion-page" *ngIf="isCmpOpen"><ng-container [ngTemplateOutlet]="template"></ng-container></div>`,
inputs: [
'animated',
'keepContentsMounted',
'backdropBreakpoint',
'backdropDismiss',
'breakpoints',
'canDismiss',
'cssClass',
'enterAnimation',
'event',
'handle',
'handleBehavior',
'initialBreakpoint',
'isOpen',
'keyboardClose',
@@ -131,7 +119,6 @@ export class IonModal {
'ionModalWillPresent',
'ionModalWillDismiss',
'ionModalDidDismiss',
'ionBreakpointDidChange',
'didPresent',
'willPresent',
'willDismiss',

View File

@@ -51,7 +51,6 @@ export declare interface IonPopover extends Components.IonPopover {
'alignment',
'animated',
'arrow',
'keepContentsMounted',
'backdropDismiss',
'cssClass',
'dismissOnSelect',
@@ -74,12 +73,11 @@ export declare interface IonPopover extends Components.IonPopover {
@Component({
selector: 'ion-popover',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `<ng-container [ngTemplateOutlet]="template" *ngIf="isCmpOpen || keepContentsMounted"></ng-container>`,
template: `<ng-container [ngTemplateOutlet]="template" *ngIf="isCmpOpen"></ng-container>`,
inputs: [
'alignment',
'animated',
'arrow',
'keepContentsMounted',
'backdropDismiss',
'cssClass',
'dismissOnSelect',

View File

@@ -1,80 +0,0 @@
import * as d from './proxies';
export const DIRECTIVES = [
d.IonAccordion,
d.IonAccordionGroup,
d.IonApp,
d.IonAvatar,
d.IonBackButton,
d.IonBackdrop,
d.IonBadge,
d.IonBreadcrumb,
d.IonBreadcrumbs,
d.IonButton,
d.IonButtons,
d.IonCard,
d.IonCardContent,
d.IonCardHeader,
d.IonCardSubtitle,
d.IonCardTitle,
d.IonCheckbox,
d.IonChip,
d.IonCol,
d.IonContent,
d.IonDatetime,
d.IonDatetimeButton,
d.IonFab,
d.IonFabButton,
d.IonFabList,
d.IonFooter,
d.IonGrid,
d.IonHeader,
d.IonIcon,
d.IonImg,
d.IonInfiniteScroll,
d.IonInfiniteScrollContent,
d.IonInput,
d.IonItem,
d.IonItemDivider,
d.IonItemGroup,
d.IonItemOption,
d.IonItemOptions,
d.IonItemSliding,
d.IonLabel,
d.IonList,
d.IonListHeader,
d.IonMenu,
d.IonMenuButton,
d.IonMenuToggle,
d.IonNav,
d.IonNavLink,
d.IonNote,
d.IonProgressBar,
d.IonRadio,
d.IonRadioGroup,
d.IonRange,
d.IonRefresher,
d.IonRefresherContent,
d.IonReorder,
d.IonReorderGroup,
d.IonRippleEffect,
d.IonRow,
d.IonSearchbar,
d.IonSegment,
d.IonSegmentButton,
d.IonSelect,
d.IonSelectOption,
d.IonSkeletonText,
d.IonSlide,
d.IonSlides,
d.IonSpinner,
d.IonSplitPane,
d.IonTabBar,
d.IonTabButton,
d.IonText,
d.IonTextarea,
d.IonThumbnail,
d.IonTitle,
d.IonToggle,
d.IonToolbar,
];

View File

@@ -0,0 +1,80 @@
import * as d from './proxies';
export const DIRECTIVES = [
d.IonAccordion,
d.IonAccordionGroup,
d.IonApp,
d.IonAvatar,
d.IonBackButton,
d.IonBackdrop,
d.IonBadge,
d.IonBreadcrumb,
d.IonBreadcrumbs,
d.IonButton,
d.IonButtons,
d.IonCard,
d.IonCardContent,
d.IonCardHeader,
d.IonCardSubtitle,
d.IonCardTitle,
d.IonCheckbox,
d.IonChip,
d.IonCol,
d.IonContent,
d.IonDatetime,
d.IonFab,
d.IonFabButton,
d.IonFabList,
d.IonFooter,
d.IonGrid,
d.IonHeader,
d.IonIcon,
d.IonImg,
d.IonInfiniteScroll,
d.IonInfiniteScrollContent,
d.IonInput,
d.IonItem,
d.IonItemDivider,
d.IonItemGroup,
d.IonItemOption,
d.IonItemOptions,
d.IonItemSliding,
d.IonLabel,
d.IonList,
d.IonListHeader,
d.IonMenu,
d.IonMenuButton,
d.IonMenuToggle,
d.IonNav,
d.IonNavLink,
d.IonNote,
d.IonProgressBar,
d.IonRadio,
d.IonRadioGroup,
d.IonRange,
d.IonRefresher,
d.IonRefresherContent,
d.IonReorder,
d.IonReorderGroup,
d.IonRippleEffect,
d.IonRow,
d.IonSearchbar,
d.IonSegment,
d.IonSegmentButton,
d.IonSelect,
d.IonSelectOption,
d.IonSkeletonText,
d.IonSlide,
d.IonSlides,
d.IonSpinner,
d.IonSplitPane,
d.IonTabBar,
d.IonTabButton,
d.IonText,
d.IonTextarea,
d.IonThumbnail,
d.IonTitle,
d.IonToggle,
d.IonToolbar
];

View File

@@ -464,18 +464,16 @@ import type { ScrollBaseDetail as IContentScrollBaseDetail } from '@ionic/core';
import type { ScrollDetail as IContentScrollDetail } from '@ionic/core';
export declare interface IonContent extends Components.IonContent {
/**
* Emitted when the scroll has started. This event is disabled by default.
Set `scrollEvents` to `true` to enable.
* Emitted when the scroll has started.
*/
ionScrollStart: EventEmitter<CustomEvent<IContentScrollBaseDetail>>;
/**
* Emitted while scrolling. This event is disabled by default.
Set `scrollEvents` to `true` to enable.
Look at the property: `scrollEvents`
*/
ionScroll: EventEmitter<CustomEvent<IContentScrollDetail>>;
/**
* Emitted when the scroll has ended. This event is disabled by default.
Set `scrollEvents` to `true` to enable.
* Emitted when the scroll has ended.
*/
ionScrollEnd: EventEmitter<CustomEvent<IContentScrollBaseDetail>>;
@@ -524,14 +522,14 @@ export declare interface IonDatetime extends Components.IonDatetime {
@ProxyCmp({
defineCustomElementFn: undefined,
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'hourCycle', 'hourValues', 'isDateEnabled', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'multiple', 'name', 'preferWheel', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'value', 'yearValues'],
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'hourCycle', 'hourValues', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'name', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'value', 'yearValues'],
methods: ['confirm', 'reset', 'cancel']
})
@Component({
selector: 'ion-datetime',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'hourCycle', 'hourValues', 'isDateEnabled', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'multiple', 'name', 'preferWheel', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'value', 'yearValues']
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'hourCycle', 'hourValues', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'name', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'value', 'yearValues']
})
export class IonDatetime {
protected el: HTMLElement;
@@ -543,27 +541,6 @@ export class IonDatetime {
}
export declare interface IonDatetimeButton extends Components.IonDatetimeButton {}
@ProxyCmp({
defineCustomElementFn: undefined,
inputs: ['color', 'datetime', 'disabled', 'mode']
})
@Component({
selector: 'ion-datetime-button',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
inputs: ['color', 'datetime', 'disabled', 'mode']
})
export class IonDatetimeButton {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
}
export declare interface IonFab extends Components.IonFab {}
@ProxyCmp({
@@ -857,13 +834,13 @@ export declare interface IonItem extends Components.IonItem {}
@ProxyCmp({
defineCustomElementFn: undefined,
inputs: ['button', 'color', 'counter', 'counterFormatter', 'detail', 'detailIcon', 'disabled', 'download', 'fill', 'href', 'lines', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'target', 'type']
inputs: ['button', 'color', 'counter', 'detail', 'detailIcon', 'disabled', 'download', 'fill', 'href', 'lines', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'target', 'type']
})
@Component({
selector: 'ion-item',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
inputs: ['button', 'color', 'counter', 'counterFormatter', 'detail', 'detailIcon', 'disabled', 'download', 'fill', 'href', 'lines', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'target', 'type']
inputs: ['button', 'color', 'counter', 'detail', 'detailIcon', 'disabled', 'download', 'fill', 'href', 'lines', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'target', 'type']
})
export class IonItem {
protected el: HTMLElement;
@@ -1295,8 +1272,6 @@ export class IonRadioGroup {
}
import type { RangeChangeEventDetail as IRangeRangeChangeEventDetail } from '@ionic/core';
import type { RangeKnobMoveStartEventDetail as IRangeRangeKnobMoveStartEventDetail } from '@ionic/core';
import type { RangeKnobMoveEndEventDetail as IRangeRangeKnobMoveEndEventDetail } from '@ionic/core';
export declare interface IonRange extends Components.IonRange {
/**
* Emitted when the value property has changed.
@@ -1310,35 +1285,25 @@ export declare interface IonRange extends Components.IonRange {
* Emitted when the range loses focus.
*/
ionBlur: EventEmitter<CustomEvent<void>>;
/**
* Emitted when the user starts moving the range knob, whether through
mouse drag, touch gesture, or keyboard interaction.
*/
ionKnobMoveStart: EventEmitter<CustomEvent<IRangeRangeKnobMoveStartEventDetail>>;
/**
* Emitted when the user finishes moving the range knob, whether through
mouse drag, touch gesture, or keyboard interaction.
*/
ionKnobMoveEnd: EventEmitter<CustomEvent<IRangeRangeKnobMoveEndEventDetail>>;
}
@ProxyCmp({
defineCustomElementFn: undefined,
inputs: ['activeBarStart', 'color', 'debounce', 'disabled', 'dualKnobs', 'max', 'min', 'mode', 'name', 'pin', 'pinFormatter', 'snaps', 'step', 'ticks', 'value']
inputs: ['color', 'debounce', 'disabled', 'dualKnobs', 'max', 'min', 'mode', 'name', 'pin', 'pinFormatter', 'snaps', 'step', 'ticks', 'value']
})
@Component({
selector: 'ion-range',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
inputs: ['activeBarStart', 'color', 'debounce', 'disabled', 'dualKnobs', 'max', 'min', 'mode', 'name', 'pin', 'pinFormatter', 'snaps', 'step', 'ticks', 'value']
inputs: ['color', 'debounce', 'disabled', 'dualKnobs', 'max', 'min', 'mode', 'name', 'pin', 'pinFormatter', 'snaps', 'step', 'ticks', 'value']
})
export class IonRange {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur', 'ionKnobMoveStart', 'ionKnobMoveEnd']);
proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur']);
}
}
@@ -1603,10 +1568,6 @@ export declare interface IonSelect extends Components.IonSelect {
* Emitted when the selection is cancelled.
*/
ionCancel: EventEmitter<CustomEvent<void>>;
/**
* Emitted when the overlay is dismissed.
*/
ionDismiss: EventEmitter<CustomEvent<void>>;
/**
* Emitted when the select has focus.
*/
@@ -1634,7 +1595,7 @@ export class IonSelect {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionChange', 'ionCancel', 'ionDismiss', 'ionFocus', 'ionBlur']);
proxyOutputs(this, this.el, ['ionChange', 'ionCancel', 'ionFocus', 'ionBlur']);
}
}
@@ -1814,7 +1775,7 @@ export declare interface IonSplitPane extends Components.IonSplitPane {
/**
* Expression to be called when the split-pane visibility has changed
*/
ionSplitPaneVisible: EventEmitter<CustomEvent<{ visible: boolean }>>;
ionSplitPaneVisible: EventEmitter<CustomEvent<{visible: boolean}>>;
}
@@ -2000,13 +1961,13 @@ export declare interface IonToggle extends Components.IonToggle {
@ProxyCmp({
defineCustomElementFn: undefined,
inputs: ['checked', 'color', 'disabled', 'enableOnOffLabels', 'mode', 'name', 'value']
inputs: ['checked', 'color', 'disabled', 'mode', 'name', 'value']
})
@Component({
selector: 'ion-toggle',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
inputs: ['checked', 'color', 'disabled', 'enableOnOffLabels', 'mode', 'name', 'value']
inputs: ['checked', 'color', 'disabled', 'mode', 'name', 'value']
})
export class IonToggle {
protected el: HTMLElement;

View File

@@ -1,6 +1,6 @@
// DIRECTIVES
export { BooleanValueAccessorDirective as BooleanValueAccessor } from './directives/control-value-accessors/boolean-value-accessor';
export { NumericValueAccessorDirective as NumericValueAccessor } from './directives/control-value-accessors/numeric-value-accessor';
export { NumericValueAccessorDirective as NumericValueAccessor } from './directives/control-value-accessors/numeric-value-accesssor';
export { RadioValueAccessorDirective as RadioValueAccessor } from './directives/control-value-accessors/radio-value-accessor';
export { SelectValueAccessorDirective as SelectValueAccessor } from './directives/control-value-accessors/select-value-accessor';
export { TextValueAccessorDirective as TextValueAccessor } from './directives/control-value-accessors/text-value-accessor';
@@ -107,10 +107,6 @@ export {
PopoverOptions,
RadioGroupCustomEvent,
RadioGroupChangeEventDetail,
RangeCustomEvent,
RangeChangeEventDetail,
RangeKnobMoveStartEventDetail,
RangeKnobMoveEndEventDetail,
RefresherCustomEvent,
RefresherEventDetail,
RouterEventDetail,

View File

@@ -4,7 +4,7 @@ import { IonicConfig } from '@ionic/core';
import { appInitialize } from './app-initialize';
import { BooleanValueAccessorDirective } from './directives/control-value-accessors/boolean-value-accessor';
import { NumericValueAccessorDirective } from './directives/control-value-accessors/numeric-value-accessor';
import { NumericValueAccessorDirective } from './directives/control-value-accessors/numeric-value-accesssor';
import { RadioValueAccessorDirective } from './directives/control-value-accessors/radio-value-accessor';
import { SelectValueAccessorDirective } from './directives/control-value-accessors/select-value-accessor';
import { TextValueAccessorDirective } from './directives/control-value-accessors/text-value-accessor';
@@ -18,7 +18,83 @@ import {
} from './directives/navigation/router-link-delegate';
import { IonModal } from './directives/overlays/modal';
import { IonPopover } from './directives/overlays/popover';
import { DIRECTIVES } from './directives/proxies-list';
import {
IonAccordion,
IonAccordionGroup,
IonApp,
IonAvatar,
IonBackButton,
IonBackdrop,
IonBadge,
IonBreadcrumb,
IonBreadcrumbs,
IonButton,
IonButtons,
IonCard,
IonCardContent,
IonCardHeader,
IonCardSubtitle,
IonCardTitle,
IonCheckbox,
IonChip,
IonCol,
IonContent,
IonDatetime,
IonFab,
IonFabButton,
IonFabList,
IonFooter,
IonGrid,
IonHeader,
IonIcon,
IonImg,
IonInfiniteScroll,
IonInfiniteScrollContent,
IonInput,
IonItem,
IonItemDivider,
IonItemGroup,
IonItemOption,
IonItemOptions,
IonItemSliding,
IonLabel,
IonList,
IonListHeader,
IonMenu,
IonMenuButton,
IonMenuToggle,
IonNav,
IonNavLink,
IonNote,
IonProgressBar,
IonRadio,
IonRadioGroup,
IonRange,
IonRefresher,
IonRefresherContent,
IonReorder,
IonReorderGroup,
IonRippleEffect,
IonRow,
IonSearchbar,
IonSegment,
IonSegmentButton,
IonSelect,
IonSelectOption,
IonSkeletonText,
IonSlide,
IonSlides,
IonSpinner,
IonSplitPane,
IonTabBar,
IonTabButton,
IonText,
IonTextarea,
IonThumbnail,
IonTitle,
IonToggle,
IonToolbar,
} from './directives/proxies';
import { VirtualFooter } from './directives/virtual-scroll/virtual-footer';
import { VirtualHeader } from './directives/virtual-scroll/virtual-header';
import { VirtualItem } from './directives/virtual-scroll/virtual-item';
@@ -29,12 +105,86 @@ import { ModalController } from './providers/modal-controller';
import { PopoverController } from './providers/popover-controller';
const DECLARATIONS = [
// generated proxies
...DIRECTIVES,
// manual proxies
// proxies
IonAccordion,
IonAccordionGroup,
IonApp,
IonAvatar,
IonBackButton,
IonBackdrop,
IonBadge,
IonBreadcrumb,
IonBreadcrumbs,
IonButton,
IonButtons,
IonCard,
IonCardContent,
IonCardHeader,
IonCardSubtitle,
IonCardTitle,
IonCheckbox,
IonChip,
IonCol,
IonContent,
IonDatetime,
IonFab,
IonFabButton,
IonFabList,
IonFooter,
IonGrid,
IonHeader,
IonIcon,
IonImg,
IonInfiniteScroll,
IonInfiniteScrollContent,
IonInput,
IonItem,
IonItemDivider,
IonItemGroup,
IonItemOption,
IonItemOptions,
IonItemSliding,
IonLabel,
IonList,
IonListHeader,
IonMenu,
IonMenuButton,
IonMenuToggle,
IonModal,
IonNav,
IonNavLink,
IonNote,
IonPopover,
IonProgressBar,
IonRadio,
IonRadioGroup,
IonRange,
IonRefresher,
IonRefresherContent,
IonReorder,
IonReorderGroup,
IonRippleEffect,
IonRow,
IonSearchbar,
IonSegment,
IonSegmentButton,
IonSelect,
IonSelectOption,
IonSkeletonText,
IonSlide,
IonSlides,
IonSpinner,
IonSplitPane,
IonTabBar,
IonTabButton,
IonText,
IonTextarea,
IonThumbnail,
IonToggle,
IonToolbar,
IonTitle,
IonTabs,
// ngModel accessors
BooleanValueAccessorDirective,
@@ -44,7 +194,6 @@ const DECLARATIONS = [
TextValueAccessorDirective,
// navigation
IonTabs,
IonRouterOutlet,
IonBackButtonDelegateDirective,
NavDelegate,

View File

@@ -6,7 +6,6 @@ import {
Injectable,
InjectionToken,
Injector,
ComponentRef,
} from '@angular/core';
import {
FrameworkDelegate,
@@ -17,20 +16,18 @@ import {
LIFECYCLE_WILL_UNLOAD,
} from '@ionic/core';
import { EnvironmentInjector } from '../di/r3_injector';
import { NavParams } from '../directives/navigation/nav-params';
import { isComponentFactoryResolver } from '../util/util';
@Injectable()
export class AngularDelegate {
constructor(private zone: NgZone, private appRef: ApplicationRef) {}
create(
resolverOrInjector: ComponentFactoryResolver,
resolver: ComponentFactoryResolver,
injector: Injector,
location?: ViewContainerRef
): AngularFrameworkDelegate {
return new AngularFrameworkDelegate(resolverOrInjector, injector, location, this.appRef, this.zone);
return new AngularFrameworkDelegate(resolver, injector, location, this.appRef, this.zone);
}
}
@@ -39,7 +36,7 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
private elEventsMap = new WeakMap<HTMLElement, () => void>();
constructor(
private resolverOrInjector: ComponentFactoryResolver | EnvironmentInjector,
private resolver: ComponentFactoryResolver,
private injector: Injector,
private location: ViewContainerRef | undefined,
private appRef: ApplicationRef,
@@ -51,7 +48,7 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
return new Promise((resolve) => {
const el = attachView(
this.zone,
this.resolverOrInjector,
this.resolver,
this.injector,
this.location,
this.appRef,
@@ -88,7 +85,7 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
export const attachView = (
zone: NgZone,
resolverOrInjector: ComponentFactoryResolver | EnvironmentInjector,
resolver: ComponentFactoryResolver,
injector: Injector,
location: ViewContainerRef | undefined,
appRef: ApplicationRef,
@@ -99,29 +96,14 @@ export const attachView = (
params: any,
cssClasses: string[] | undefined
): any => {
let componentRef: ComponentRef<any>;
const factory = resolver.resolveComponentFactory(component);
const childInjector = Injector.create({
providers: getProviders(params),
parent: injector,
});
if (resolverOrInjector && isComponentFactoryResolver(resolverOrInjector)) {
// Angular 13 and lower
const factory = resolverOrInjector.resolveComponentFactory(component);
componentRef = location
? location.createComponent(factory, location.length, childInjector)
: factory.create(childInjector);
} else if (location) {
// Angular 14
const environmentInjector = resolverOrInjector;
componentRef = location.createComponent(component, {
index: location.indexOf,
injector: childInjector,
environmentInjector,
} as any);
} else {
return null;
}
const componentRef = location
? location.createComponent(factory, location.length, childInjector)
: factory.create(childInjector);
const instance = componentRef.instance;
const hostElement = componentRef.location.nativeElement;

View File

@@ -1,7 +1,6 @@
import { ComponentFactoryResolver, Injector, Injectable, Optional } from '@angular/core';
import { ComponentFactoryResolver, Injector, Injectable } from '@angular/core';
import { ModalOptions, modalController } from '@ionic/core';
import { EnvironmentInjector } from '../di/r3_injector';
import { OverlayBaseController } from '../util/overlay';
import { AngularDelegate } from './angular-delegate';
@@ -11,9 +10,7 @@ export class ModalController extends OverlayBaseController<ModalOptions, HTMLIon
constructor(
private angularDelegate: AngularDelegate,
private resolver: ComponentFactoryResolver,
private injector: Injector,
// TODO: FW-1641: Migrate to Angular's version once Angular 13 is dropped
@Optional() private environmentInjector: EnvironmentInjector
private injector: Injector
) {
super(modalController);
}
@@ -21,7 +18,7 @@ export class ModalController extends OverlayBaseController<ModalOptions, HTMLIon
create(opts: ModalOptions): Promise<HTMLIonModalElement> {
return super.create({
...opts,
delegate: this.angularDelegate.create(this.resolver ?? this.environmentInjector, this.injector),
delegate: this.angularDelegate.create(this.resolver, this.injector),
});
}
}

View File

@@ -253,7 +253,7 @@ export class Platform {
}
const readQueryParam = (url: string, key: string) => {
key = key.replace(/[[\]\\]/g, '\\$&');
key = key.replace(/[[]/, '\\[').replace(/[\]]/, '\\]');
const regex = new RegExp('[\\?&]' + key + '=([^&#]*)');
const results = regex.exec(url);
return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null;

View File

@@ -1,7 +1,6 @@
import { ComponentFactoryResolver, Injector, Injectable, Optional } from '@angular/core';
import { ComponentFactoryResolver, Injector, Injectable } from '@angular/core';
import { PopoverOptions, popoverController } from '@ionic/core';
import { EnvironmentInjector } from '../di/r3_injector';
import { OverlayBaseController } from '../util/overlay';
import { AngularDelegate } from './angular-delegate';
@@ -11,9 +10,7 @@ export class PopoverController extends OverlayBaseController<PopoverOptions, HTM
constructor(
private angularDelegate: AngularDelegate,
private resolver: ComponentFactoryResolver,
private injector: Injector,
// TODO: FW-1641: Migrate to Angular's version once Angular 13 is dropped
@Optional() private environmentInjector: EnvironmentInjector
private injector: Injector
) {
super(popoverController);
}
@@ -21,7 +18,7 @@ export class PopoverController extends OverlayBaseController<PopoverOptions, HTM
create(opts: PopoverOptions): Promise<HTMLIonPopoverElement> {
return super.create({
...opts,
delegate: this.angularDelegate.create(this.resolver ?? this.environmentInjector, this.injector),
delegate: this.angularDelegate.create(this.resolver, this.injector),
});
}
}

View File

@@ -1,5 +1,3 @@
import { ComponentFactoryResolver } from '@angular/core';
declare const __zone_symbol__requestAnimationFrame: any;
declare const requestAnimationFrame: any;
@@ -12,7 +10,3 @@ export const raf = (h: any): any => {
}
return setTimeout(h);
};
export const isComponentFactoryResolver = (item: any): item is ComponentFactoryResolver => {
return !!item.resolveComponentFactory;
};

View File

@@ -1,89 +0,0 @@
# Angular E2E Test Apps
Ionic Framework supports multiple versions of Angular. As a result, we need to verify that Ionic works correctly with each of these Angular versions.
## Application Cache
Angular CLI creates a cache of several files on disk by default in the `.angular` directory. This decreases the time taken to build the test application. When testing changes by directly modifying Ionic's source code in `node_modules`, you may need to manually clear the `.angular` cache and restart the local server every time you make a change. As a result, it may be desirable to disable the `.angular` cache while making changes to the code.
See https://angular.io/cli/cache for more information.
### Disable Cache
```
ng cache disable
```
> Note: You may need to manually remove the `.angular` directory once after running this command.
### Enable Cache
```
ng cache enable
```
## Test App Build Structure
Unlike other test applications, these test apps are broken up into multiple directories. These directories are then combined to create a single application. This allows us to share common application code, tests, etc so that each app is being tested the same way. Below details the different pieces that help create a single test application.
**apps** - This directory contains partial applications for each version of Angular we want to test. Typically these directories contain new `package.json` files, `angular.json` files, and more. If you have code that is specific to a particular version of Angular, put it in this directory.
**base** - This directory contains the base application that each test app will use. This is where tests, application logic, and more live. If you have code that needs to be run on every test app, put it in this directory.
**build** - When the `apps` and `base` directories are merged, the final result is put in this directory. The `build` directory should never be committed to git.
**build.sh** - This is the script that merges the `apps` and `base` directories and places the built application in the `build` directory.
Usage:
```shell
# Build a test app using apps/ng14 as a reference
./build.sh ng14
```
## How to modify test apps
To add new tests, components, or pages, modify the `base` project. This ensures that tests are run for every tested version.
If you want to add a version-specific change, add the change inside of the appropriate projects in `apps`. Be sure to replicate the directory structure. For example, if you are adding a new E2E test file called `test.spec.ts` in `apps/ng14`, make sure you place the file in `apps/ng14/e2e/src/test.spec.ts`.
### Version-specific tests
If you need to add E2E tests that are only run on a specific version of the JS Framework, replicate the `VersionTest` component on each partial application. This ensures that tests for framework version X do not get run for framework version Y.
## Adding New Test Apps
As we add support for new versions of Angular, we will also need to update this directory to test against new applications. The following steps can serve as a guide for adding new apps:
1. Navigate to the built app for the most recent version of Angular that Ionic tests.
2. Update the application by following the steps on https://update.angular.io/.
3. Make note of any files that changed during the upgrade (`package.json`, `package-lock.json`, `angular.json`, etc).
4. Copy the changed files to a new directory in `apps`.
5. Add a new entry to the matrix for `test-core-angular` in `./github/workflows/build.yml`. This will allow the new test app to run against all PRs.
6. Commit these changes and push.
Example:
In this example, we are going to add the Angular 14 test app.
1. Build the Angular 13 test app using `./build.sh ng13`.
2. Navigate to `build/ng13`.
3. Perform the upgrade steps on https://update.angular.io/. The "From" field should say "13.0" and the "To" field should say "14.0".
Note: You may encounter some other peer dependency issues not covered by the Angular Upgrade Guide. These peer dependency issues can be resolved manually by updating the installed version of each dependency.
4. Observe that the output of the Angular upgrade indicates that the following files were modified:
`angular.json`
`package-lock.json`
`package.json`
`tsconfig.json`
`src/app/form/form.component.ts`
`src/app/modal-example/modal-example.component.ts`
5. Create a directory in `apps` named `ng14`.
6. Copy the modified files to the `apps/ng14` directory.
7. Open `./github/workflows/build.yml` and find the `test-angular-e2e` job.
8. Find the `apps` field under `matrix`.
9. Add "ng14" to the `apps` field.
10. Committ these changes and push.

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,68 +0,0 @@
{
"name": "ionic-angular-test-app",
"version": "0.0.0",
"private": true,
"scripts": {
"ng": "ng",
"start": "ng serve",
"sync:build": "sh scripts/build-ionic.sh",
"sync": "sh scripts/sync.sh",
"build": "ng build --configuration production --no-progress",
"lint": "ng lint",
"postinstall": "ngcc",
"serve:ssr": "node dist/test-app/server/main.js",
"build:ssr": "ng build --prod && ng run test-app:server:production",
"dev:ssr": "ng run test-app:serve-ssr",
"prerender": "ng run test-app:prerender",
"cy.open": "cypress open",
"cy.run": "cypress run",
"test": "concurrently \"npm run start -- --configuration production\" \"wait-on http-get://localhost:4200 && npm run cy.run\" --kill-others --success first",
"test.watch": "concurrently \"npm run start\" \"wait-on http-get://localhost:4200 && npm run cy.open\" --kill-others --success first"
},
"dependencies": {
"@angular/animations": "^12.2.16",
"@angular/common": "^12.2.16",
"@angular/compiler": "^12.2.16",
"@angular/core": "^12.2.16",
"@angular/forms": "^12.2.16",
"@angular/platform-browser": "^12.2.16",
"@angular/platform-browser-dynamic": "^12.2.16",
"@angular/platform-server": "^12.2.16",
"@angular/router": "^12.2.16",
"@ionic/angular": "^6.1.15",
"@ionic/angular-server": "^6.1.15",
"@nguniversal/express-engine": "^12.1.3",
"angular-in-memory-web-api": "^0.11.0",
"core-js": "^2.6.11",
"express": "^4.15.2",
"rxjs": "^6.5.5",
"tslib": "^2.0.0",
"typescript-eslint-language-service": "^4.1.5",
"zone.js": "^0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "^12.2.18",
"@angular-eslint/builder": "^12.7.0",
"@angular-eslint/eslint-plugin": "^12.7.0",
"@angular-eslint/eslint-plugin-template": "^12.7.0",
"@angular-eslint/schematics": "^12.7.0",
"@angular-eslint/template-parser": "^12.7.0",
"@angular/cli": "^12.2.16",
"@angular/compiler-cli": "^12.2.16",
"@angular/language-service": "^12.2.16",
"@nguniversal/builders": "^12.1.3",
"@types/express": "^4.17.7",
"@types/node": "^12.12.54",
"@typescript-eslint/eslint-plugin": "4.28.2",
"@typescript-eslint/parser": "4.28.2",
"concurrently": "^6.0.0",
"cypress": "^10.2.0",
"eslint": "^7.26.0",
"ts-loader": "^6.2.2",
"ts-node": "^8.3.0",
"typescript": "~4.3.5",
"wait-on": "^5.2.1",
"webpack": "^5.61.0",
"webpack-cli": "^4.9.2"
}
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,68 +0,0 @@
{
"name": "ionic-angular-test-app",
"version": "0.0.0",
"private": true,
"scripts": {
"ng": "ng",
"start": "ng serve",
"sync:build": "sh scripts/build-ionic.sh",
"sync": "sh scripts/sync.sh",
"build": "ng build --configuration production --no-progress",
"lint": "ng lint",
"postinstall": "ngcc",
"serve:ssr": "node dist/test-app/server/main.js",
"build:ssr": "ng build --prod && ng run test-app:server:production",
"dev:ssr": "ng run test-app:serve-ssr",
"prerender": "ng run test-app:prerender",
"cy.open": "cypress open",
"cy.run": "cypress run",
"test": "concurrently \"npm run start -- --configuration production\" \"wait-on http-get://localhost:4200 && npm run cy.run\" --kill-others --success first",
"test.watch": "concurrently \"npm run start\" \"wait-on http-get://localhost:4200 && npm run cy.open\" --kill-others --success first"
},
"dependencies": {
"@angular/animations": "^13.1.3",
"@angular/common": "^13.1.3",
"@angular/compiler": "^13.1.3",
"@angular/core": "^13.1.3",
"@angular/forms": "^13.1.3",
"@angular/platform-browser": "^13.1.3",
"@angular/platform-browser-dynamic": "^13.1.3",
"@angular/platform-server": "^13.1.3",
"@angular/router": "^13.1.3",
"@ionic/angular": "^6.1.15",
"@ionic/angular-server": "^6.1.15",
"@nguniversal/express-engine": "^13.1.1",
"angular-in-memory-web-api": "^0.11.0",
"core-js": "^2.6.11",
"express": "^4.15.2",
"rxjs": "^6.5.5",
"tslib": "^2.0.0",
"typescript-eslint-language-service": "^4.1.5",
"zone.js": "^0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "^13.1.4",
"@angular-eslint/builder": "13.0.1",
"@angular-eslint/eslint-plugin": "13.0.1",
"@angular-eslint/eslint-plugin-template": "13.0.1",
"@angular-eslint/schematics": "13.0.1",
"@angular-eslint/template-parser": "13.0.1",
"@angular/cli": "^13.1.4",
"@angular/compiler-cli": "^13.1.3",
"@angular/language-service": "^13.1.3",
"@nguniversal/builders": "^13.0.2",
"@types/express": "^4.17.7",
"@types/node": "^12.12.54",
"@typescript-eslint/eslint-plugin": "4.28.2",
"@typescript-eslint/parser": "4.28.2",
"concurrently": "^6.0.0",
"cypress": "^10.2.0",
"eslint": "^7.26.0",
"ts-loader": "^6.2.2",
"ts-node": "^8.3.0",
"typescript": "~4.6.0",
"wait-on": "^5.2.1",
"webpack": "^5.61.0",
"webpack-cli": "^4.9.2"
}
}

View File

@@ -1,53 +0,0 @@
import { Component } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
})
export class FormComponent {
submitted = 'false';
profileForm: FormGroup;
outsideToggle = new FormControl(true);
constructor(fb: FormBuilder) {
this.profileForm = fb.group({
datetime: ['2010-08-20', Validators.required],
select: [undefined, Validators.required],
toggle: [false],
input: ['', Validators.required],
input2: ['Default Value'],
checkbox: [false],
range: [5, Validators.min(10)],
}, {
updateOn: typeof (window as any) !== 'undefined' && window.location.hash === '#blur' ? 'blur' : 'change'
});
}
setTouched() {
const formControl = this.profileForm.get('input');
formControl.markAsTouched();
}
onSubmit(_ev) {
this.submitted = 'true';
}
setValues() {
this.profileForm.patchValue({
datetime: '2010-08-20',
select: 'nes',
toggle: true,
input: 'Some value',
input2: 'Another values',
checkbox: true,
range: 50
});
}
markAllAsTouched() {
this.profileForm.markAllAsTouched();
}
}

View File

@@ -1,70 +0,0 @@
import { Component, Input, NgZone, OnInit, Optional } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { ModalController, NavParams, IonNav, ViewWillLeave, ViewDidEnter, ViewDidLeave } from '@ionic/angular';
@Component({
selector: 'app-modal-example',
templateUrl: './modal-example.component.html',
})
export class ModalExampleComponent implements OnInit, ViewWillLeave, ViewDidEnter, ViewWillLeave, ViewDidLeave {
@Input() value: string;
form = new FormGroup({
select: new FormControl([])
});
valueFromParams: string;
onInit = 0;
willEnter = 0;
didEnter = 0;
willLeave = 0;
didLeave = 0;
modal: HTMLElement;
constructor(
private modalCtrl: ModalController,
@Optional() public nav: IonNav,
navParams: NavParams
) {
this.valueFromParams = navParams.get('prop');
}
ngOnInit() {
NgZone.assertInAngularZone();
this.onInit++;
}
ionViewWillEnter() {
if (this.onInit !== 1) {
throw new Error('ngOnInit was not called');
}
NgZone.assertInAngularZone();
this.willEnter++;
}
ionViewDidEnter() {
NgZone.assertInAngularZone();
this.didEnter++;
}
ionViewWillLeave() {
NgZone.assertInAngularZone();
this.willLeave++;
}
ionViewDidLeave() {
NgZone.assertInAngularZone();
this.didLeave++;
}
closeModal() {
this.modalCtrl.dismiss();
}
push() {
this.nav.push(ModalExampleComponent, {
'value': 'pushed!'
});
}
pop() {
this.nav.pop();
}
}

View File

@@ -1,26 +0,0 @@
{
"compileOnSave": false,
"compilerOptions": {
"importHelpers": true,
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"module": "es2020",
"target": "es2015",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
],
"plugins": [
{
"name": "typescript-eslint-language-service"
}
]
}
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,68 +0,0 @@
{
"name": "ionic-angular-test-app",
"version": "0.0.0",
"private": true,
"scripts": {
"ng": "ng",
"start": "ng serve",
"sync:build": "sh scripts/build-ionic.sh",
"sync": "sh scripts/sync.sh",
"build": "ng build --configuration production --no-progress",
"lint": "ng lint",
"postinstall": "ngcc",
"serve:ssr": "node dist/test-app/server/main.js",
"build:ssr": "ng build --prod && ng run test-app:server:production",
"dev:ssr": "ng run test-app:serve-ssr",
"prerender": "ng run test-app:prerender",
"cy.open": "cypress open",
"cy.run": "cypress run",
"test": "concurrently \"npm run start -- --configuration production\" \"wait-on http-get://localhost:4200 && npm run cy.run\" --kill-others --success first",
"test.watch": "concurrently \"npm run start\" \"wait-on http-get://localhost:4200 && npm run cy.open\" --kill-others --success first"
},
"dependencies": {
"@angular/animations": "^14.1.0",
"@angular/common": "^14.1.0",
"@angular/compiler": "^14.1.0",
"@angular/core": "^14.1.0",
"@angular/forms": "^14.1.0",
"@angular/platform-browser": "^14.1.0",
"@angular/platform-browser-dynamic": "^14.1.0",
"@angular/platform-server": "^14.1.0",
"@angular/router": "^14.1.0",
"@ionic/angular": "^6.1.15",
"@ionic/angular-server": "^6.1.15",
"@nguniversal/express-engine": "^14.0.3",
"angular-in-memory-web-api": "^0.11.0",
"core-js": "^2.6.11",
"express": "^4.15.2",
"rxjs": "^6.5.5",
"tslib": "^2.0.0",
"typescript-eslint-language-service": "^4.1.5",
"zone.js": "^0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "^14.1.0",
"@angular-eslint/builder": "^14.0.2",
"@angular-eslint/eslint-plugin": "^14.0.2",
"@angular-eslint/eslint-plugin-template": "^14.0.2",
"@angular-eslint/schematics": "^14.0.2",
"@angular-eslint/template-parser": "^14.0.2",
"@angular/cli": "^14.1.0",
"@angular/compiler-cli": "^14.1.0",
"@angular/language-service": "^14.1.0",
"@nguniversal/builders": "^14.0.3",
"@types/express": "^4.17.7",
"@types/node": "^12.12.54",
"@typescript-eslint/eslint-plugin": "4.28.2",
"@typescript-eslint/parser": "4.28.2",
"concurrently": "^6.0.0",
"cypress": "^10.2.0",
"eslint": "^7.26.0",
"ts-loader": "^6.2.2",
"ts-node": "^8.3.0",
"typescript": "~4.6.0",
"wait-on": "^5.2.1",
"webpack": "^5.61.0",
"webpack-cli": "^4.9.2"
}
}

View File

@@ -1,26 +0,0 @@
{
"compileOnSave": false,
"compilerOptions": {
"importHelpers": true,
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"module": "es2020",
"target": "es2020",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
],
"plugins": [
{
"name": "typescript-eslint-language-service"
}
]
}
}

View File

@@ -1,16 +0,0 @@
import { defineConfig } from 'cypress'
export default defineConfig({
video: false,
screenshotOnRunFailure: false,
e2e: {
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
setupNodeEvents(on, config) {
return require('./cypress/plugins/index.js')(on, config)
},
specPattern: './e2e/**/*.spec.ts',
baseUrl: 'http://localhost:4200/',
excludeSpecPattern: '**/examples/*',
},
})

View File

@@ -1,79 +0,0 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
Cypress.Commands.add('ionSwipeToGoBack', (complete = false, selector = 'ion-router-outlet') => {
const increment = complete ? 60 : 25;
cy.get(selector)
.first()
.trigger('mousedown', 0, 275, { which: 1, force: true })
.trigger('mousemove', increment * 1, 275, { which: 1, force: true })
.wait(50)
.trigger('mousemove', increment * 2, 275, { which: 1, force: true })
.wait(50)
.trigger('mousemove', increment * 3, 275, { which: 1, force: true })
.wait(50)
.trigger('mousemove', increment * 4, 275, { which: 1, force: true })
.wait(50)
.trigger('mouseup', increment * 4, 275, { which: 1, force: true });
cy.wait(150);
});
Cypress.Commands.add('testStack', (selector, expected) => {
cy.document().then((doc) => {
const children = Array.from(doc.querySelector(selector).children).map((el) => el.tagName.toLowerCase());
expect(children).to.deep.equal(expected);
});
});
Cypress.Commands.add('testLifeCycle', (selector, expected) => {
cy.get(`${selector} #ngOnInit`).invoke('text').should('equal', '1');
cy.get(`${selector} #ionViewWillEnter`).invoke('text').should('equal', expected.ionViewWillEnter.toString());
cy.get(`${selector} #ionViewDidEnter`).invoke('text').should('equal', expected.ionViewDidEnter.toString());
cy.get(`${selector} #ionViewWillLeave`).invoke('text').should('equal', expected.ionViewWillLeave.toString());
cy.get(`${selector} #ionViewDidLeave`).invoke('text').should('equal', expected.ionViewDidLeave.toString());
});
Cypress.Commands.add('ionPageVisible', (selector) => {
cy.get(selector)
.should('have.class', 'ion-page')
.should('not.have.class', 'ion-page-hidden')
.should('not.have.class', 'ion-page-invisible')
.should('have.length', 1);
});
Cypress.Commands.add('ionPageHidden', (selector) => {
cy.get(selector).should('have.class', 'ion-page').should('have.class', 'ion-page-hidden').should('have.length', 1);
});
Cypress.Commands.add('ionPageDoesNotExist', (selector) => {
cy.get(selector).should('not.exist');
});
Cypress.Commands.add('ionTabClick', (tabText) => {
// TODO: Figure out how to get rid of wait. It's a workaround for flakiness in CI.
cy.wait(250);
cy.contains('ion-tab-button', tabText).click({ force: true });
});

View File

@@ -1,19 +0,0 @@
describe('Accordion', () => {
beforeEach(() => {
cy.visit('/accordions');
});
it('should correctly expand on multiple modal opens', () => {
cy.get('#open-modal').click();
cy.get('ion-accordion:first-of-type').should('have.class', 'accordion-expanded');
cy.get('ion-accordion:last-of-type').should('not.have.class', 'accordion-expanded');
cy.get('#dismiss').click();
cy.get('#open-modal').click();
cy.get('ion-accordion:first-of-type').should('have.class', 'accordion-expanded');
cy.get('ion-accordion:last-of-type').should('not.have.class', 'accordion-expanded');
});
});

View File

@@ -1,60 +0,0 @@
describe('overlays - keepContentsMounted', () => {
describe('modal', () => {
it('should not mount component if false', () => {
cy.visit('/modal-inline');
cy.get('ion-modal ion-content').should('not.exist');
});
it('should mount component if true', () => {
cy.visit('/keep-contents-mounted');
cy.get('ion-modal ion-content').should('exist');
});
it('should keep component mounted after dismissing if true', () => {
cy.visit('/keep-contents-mounted');
cy.get('#open-modal').click();
cy.get('ion-modal ion-content').should('exist');
cy.get('ion-modal ion-button').click();
cy.get('ion-modal')
.should('not.be.visible')
.should('have.class', 'overlay-hidden');
cy.get('ion-modal ion-content').should('exist');
});
})
describe('popover', () => {
it('should not mount component if false', () => {
cy.visit('/popover-inline');
cy.get('ion-popover ion-content').should('not.exist');
});
it('should mount component if true', () => {
cy.visit('/keep-contents-mounted');
cy.get('ion-popover ion-content').should('exist');
});
it('should keep component mounted after dismissing if true', () => {
cy.visit('/keep-contents-mounted');
cy.get('#open-popover').click();
cy.get('ion-popover ion-content').should('exist');
cy.get('ion-popover ion-button').click();
cy.get('ion-popover')
.should('not.be.visible')
.should('have.class', 'overlay-hidden');
cy.get('ion-popover ion-content').should('exist');
});
});
});

View File

@@ -1,31 +0,0 @@
describe('Providers', () => {
beforeEach(() => {
cy.visit('/providers');
})
it('should load all providers', () => {
cy.get('#is-loaded').should('have.text', 'true');
cy.get('#is-ready').should('have.text', 'true');
cy.get('#is-paused').should('have.text', 'true');
cy.get('#is-resumed').should('have.text', 'true');
cy.get('#is-resized').should('have.text', 'true');
cy.get('#is-testing').should('have.text', 'false');
cy.get('#is-desktop').should('have.text', 'true');
cy.get('#is-mobile').should('have.text', 'false');
cy.get('#keyboard-height').should('have.text', '12345');
cy.get('#query-params').should('have.text', 'firstParam: null, firstParam: null');
});
it('should detect testing mode', () => {
cy.visit('/providers?ionic:_testing=true');
cy.get('#is-testing').should('have.text', 'true');
});
it('should get query params', () => {
cy.visit('/providers?firstParam=abc&secondParam=true');
cy.get('#query-params').should('have.text', 'firstParam: abc, firstParam: true');
})
});

View File

@@ -1,464 +0,0 @@
describe('Tabs', () => {
beforeEach(() => {
cy.visit('/tabs');
})
describe('entry url - /tabs', () => {
it('should redirect and load tab-account', () => {
testTabTitle('Tab 1 - Page 1');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1']);
testState(1, 'account');
});
it('should navigate between tabs and ionChange events should be dispatched', () => {
let tab = testTabTitle('Tab 1 - Page 1');
tab.find('.segment-changed').should('have.text', 'false');
cy.get('#tab-button-contact').click();
tab = testTabTitle('Tab 2 - Page 1');
tab.find('.segment-changed').should('have.text', 'false');
});
describe('when navigating between tabs', () => {
it('should emit ionTabsWillChange before setting the selected tab', () => {
cy.get('#ionTabsWillChangeCounter').should('have.text', '1');
cy.get('#ionTabsWillChangeEvent').should('have.text', 'account');
cy.get('#ionTabsWillChangeSelectedTab').should('have.text', '');
cy.get('#ionTabsDidChangeCounter').should('have.text', '1');
cy.get('#ionTabsDidChangeEvent').should('have.text', 'account');
cy.get('#ionTabsDidChangeSelectedTab').should('have.text', 'account');
cy.get('#tab-button-contact').click();
cy.get('#ionTabsWillChangeCounter').should('have.text', '2');
cy.get('#ionTabsWillChangeEvent').should('have.text', 'contact');
cy.get('#ionTabsWillChangeSelectedTab').should('have.text', 'account');
cy.get('#ionTabsDidChangeCounter').should('have.text', '2');
cy.get('#ionTabsDidChangeEvent').should('have.text', 'contact');
cy.get('#ionTabsDidChangeSelectedTab').should('have.text', 'contact');
})
});
it('should simulate stack + double tab click', () => {
let tab = getSelectedTab();
tab.find('#goto-tab1-page2').click();
testTabTitle('Tab 1 - Page 2 (1)');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab1-nested']);
testState(1, 'account');
// When you call find on tab above it changes the value of tab
// so we need to redefine it
tab = getSelectedTab();
tab.find('ion-back-button').should('be.visible');
cy.get('#tab-button-contact').click();
testTabTitle('Tab 2 - Page 1');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab1-nested', 'app-tabs-tab2']);
testState(2, 'contact');
cy.get('#tab-button-account').click();
testTabTitle('Tab 1 - Page 2 (1)');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab1-nested', 'app-tabs-tab2']);
testState(3, 'account');
tab = getSelectedTab();
tab.find('ion-back-button').should('be.visible');
cy.get('#tab-button-account').click();
testTabTitle('Tab 1 - Page 1');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab2']);
testState(3, 'account');
});
it('should simulate stack + back button click', () => {
const tab = getSelectedTab();
tab.find('#goto-tab1-page2').click();
testTabTitle('Tab 1 - Page 2 (1)');
testState(1, 'account');
cy.get('#tab-button-contact').click();
testTabTitle('Tab 2 - Page 1');
testState(2, 'contact');
cy.get('#tab-button-account').click();
testTabTitle('Tab 1 - Page 2 (1)');
testState(3, 'account');
cy.get('ion-back-button').click();
testTabTitle('Tab 1 - Page 1');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab2']);
testState(3, 'account');
});
it('should navigate deep then go home', () => {
const tab = getSelectedTab();
tab.find('#goto-tab1-page2').click();
cy.ionPageVisible('app-tabs-tab1-nested');
cy.ionPageHidden('app-tabs-tab1');
testTabTitle('Tab 1 - Page 2 (1)');
cy.get('#goto-next').click();
cy.ionPageVisible('app-tabs-tab1-nested:last-of-type');
cy.ionPageHidden('app-tabs-tab1-nested:first-of-type');
testTabTitle('Tab 1 - Page 2 (2)');
cy.get('#tab-button-contact').click();
cy.ionPageVisible('app-tabs-tab2');
cy.ionPageHidden('app-tabs-tab1-nested:last-of-type');
testTabTitle('Tab 2 - Page 1');
cy.get('#tab-button-account').click();
cy.ionPageVisible('app-tabs-tab1-nested:last-of-type');
cy.ionPageHidden('app-tabs-tab2');
testTabTitle('Tab 1 - Page 2 (2)');
cy.testStack('ion-tabs ion-router-outlet', [
'app-tabs-tab1',
'app-tabs-tab1-nested',
'app-tabs-tab1-nested',
'app-tabs-tab2'
]);
cy.get('#tab-button-account').click();
/**
* Wait for the leaving view to
* be unmounted otherwise testTabTitle
* may get the leaving view before it
* is unmounted.
*/
cy.ionPageVisible('app-tabs-tab1');
cy.ionPageDoesNotExist('app-tabs-tab1-nested');
testTabTitle('Tab 1 - Page 1');
cy.testStack('ion-tabs ion-router-outlet', [
'app-tabs-tab1',
'app-tabs-tab2'
]);
});
it('should switch tabs and go back', () => {
cy.get('#tab-button-contact').click();
const tab = testTabTitle('Tab 2 - Page 1');
tab.find('#goto-tab1-page1').click();
testTabTitle('Tab 1 - Page 1');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab2']);
});
it('should switch tabs and go to nested', () => {
cy.get('#tab-button-contact').click();
const tab = testTabTitle('Tab 2 - Page 1');
tab.find('#goto-tab1-page2').click();
testTabTitle('Tab 1 - Page 2 (1)');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab2', 'app-tabs-tab1-nested']);
});
it('should load lazy loaded tab', () => {
cy.get('#tab-button-lazy').click();
cy.ionPageVisible('app-tabs-tab3');
testTabTitle('Tab 3 - Page 1');
});
it('should use ion-back-button defaultHref', () => {
let tab = getSelectedTab();
tab.find('#goto-tab3-page2').click();
testTabTitle('Tab 3 - Page 2');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab3-nested']);
tab = getSelectedTab();
tab.find('ion-back-button').click();
testTabTitle('Tab 3 - Page 1');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab3']);
});
it('should preserve navigation extras when switching tabs', () => {
const expectUrlToContain = 'search=hello#fragment';
let tab = getSelectedTab();
tab.find('#goto-nested-page1-with-query-params').click();
testTabTitle('Tab 1 - Page 2 (1)');
testUrlContains(expectUrlToContain);
cy.get('#tab-button-contact').click();
testTabTitle('Tab 2 - Page 1');
cy.get('#tab-button-account').click();
tab = testTabTitle('Tab 1 - Page 2 (1)');
testUrlContains(expectUrlToContain);
});
it('should set root when clicking on an active tab to navigate to the root', () => {
const expectNestedTabUrlToContain = 'search=hello#fragment';
cy.url().then(url => {
const tab = getSelectedTab();
tab.find('#goto-nested-page1-with-query-params').click();
testTabTitle('Tab 1 - Page 2 (1)');
testUrlContains(expectNestedTabUrlToContain);
cy.get('#tab-button-account').click();
testTabTitle('Tab 1 - Page 1');
testUrlEquals(url);
})
});
})
describe('entry tab contains navigation extras', () => {
const expectNestedTabUrlToContain = 'search=hello#fragment';
const rootUrlParams = 'test=123#rootFragment';
const rootUrl = `/tabs/account?${rootUrlParams}`;
beforeEach(() => {
cy.visit(rootUrl);
})
it('should preserve root url navigation extras when clicking on an active tab to navigate to the root', () => {
const tab = getSelectedTab();
tab.find('#goto-nested-page1-with-query-params').click();
testTabTitle('Tab 1 - Page 2 (1)');
testUrlContains(expectNestedTabUrlToContain);
cy.get('#tab-button-account').click();
testTabTitle('Tab 1 - Page 1');
testUrlContains(rootUrl);
});
it('should preserve root url navigation extras when changing tabs', () => {
getSelectedTab();
cy.get('#tab-button-contact').click();
testTabTitle('Tab 2 - Page 1');
cy.get('#tab-button-account').click();
testTabTitle('Tab 1 - Page 1');
testUrlContains(rootUrl);
});
it('should navigate deep then go home and preserve navigation extras', () => {
let tab = getSelectedTab();
tab.find('#goto-tab1-page2').click();
cy.ionPageVisible('app-tabs-tab1-nested');
cy.ionPageHidden('app-tabs-tab1');
tab = testTabTitle('Tab 1 - Page 2 (1)');
tab.find('#goto-next').click();
cy.ionPageVisible('app-tabs-tab1-nested:last-of-type');
cy.ionPageHidden('app-tabs-tab1-nested:first-of-type');
testTabTitle('Tab 1 - Page 2 (2)');
cy.ionTabClick('Tab Two');
cy.ionPageVisible('app-tabs-tab2');
cy.ionPageHidden('app-tabs-tab1-nested:last-of-type');
testTabTitle('Tab 2 - Page 1');
cy.ionTabClick('Tab One');
cy.ionPageVisible('app-tabs-tab1-nested:last-of-type');
cy.ionPageHidden('app-tabs-tab2');
testTabTitle('Tab 1 - Page 2 (2)');
cy.ionTabClick('Tab One');
/**
* Wait for the leaving view to
* be unmounted otherwise testTabTitle
* may get the leaving view before it
* is unmounted.
*/
cy.ionPageVisible('app-tabs-tab1');
cy.ionPageDoesNotExist('app-tabs-tab1-nested');
testTabTitle('Tab 1 - Page 1');
testUrlContains(rootUrl);
});
})
describe('entry url - /tabs/account', () => {
beforeEach(() => {
cy.visit('/tabs/account');
});
it('should pop to previous view when leaving tabs outlet', () => {
cy.get('ion-title').should('contain.text', 'Tab 1 - Page 1');
cy.get('#goto-tab1-page2').click();
cy.get('ion-title').should('contain.text', 'Tab 1 - Page 2 (1)');
cy.get('#goto-global').click();
cy.get('ion-title').should('contain.text', 'Global Page');
cy.get('#goto-prev-pop').click();
cy.get('ion-title').should('contain.text', 'Tab 1 - Page 2 (1)');
cy.get('#goto-prev').click();
cy.get('ion-title').should('contain.text', 'Tab 1 - Page 1');
/**
* Verifies that when entering the tabs outlet directly,
* the navController.pop() method does not pop the previous view,
* when you are at the root of the tabs outlet.
*/
cy.get('#goto-previous-page').click();
cy.get('ion-title').should('contain.text', 'Tab 1 - Page 1');
});
});
describe('entry url - /', () => {
it('should pop to the root outlet from the tabs outlet', () => {
cy.visit('/');
cy.get('ion-title').should('contain.text', 'Test App');
cy.get('ion-item').contains('Tabs test').click();
cy.get('ion-title').should('contain.text', 'Tab 1 - Page 1');
cy.get('#goto-tab1-page2').click();
cy.get('ion-title').should('contain.text', 'Tab 1 - Page 2 (1)');
cy.get('#goto-global').click();
cy.get('ion-title').should('contain.text', 'Global Page');
cy.get('#goto-prev-pop').click();
cy.get('ion-title').should('contain.text', 'Tab 1 - Page 2 (1)');
cy.get('#goto-prev').click();
cy.get('ion-title').should('contain.text', 'Tab 1 - Page 1');
cy.get('#goto-previous-page').click();
cy.get('ion-title').should('contain.text', 'Test App');
});
});
describe('entry url - /tabs/account/nested/1', () => {
beforeEach(() => {
cy.visit('/tabs/account/nested/1');
})
it('should only display the back-button when there is a page in the stack', () => {
let tab = getSelectedTab();
tab.find('ion-back-button').should('not.be.visible');
testTabTitle('Tab 1 - Page 2 (1)');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1-nested']);
cy.get('#tab-button-account').click();
tab = testTabTitle('Tab 1 - Page 1');
tab.find('#goto-tab1-page2').click();
tab = testTabTitle('Tab 1 - Page 2 (1)');
tab.find('ion-back-button').should('be.visible');
});
it('should not reuse the same page', () => {
let tab = testTabTitle('Tab 1 - Page 2 (1)');
tab.find('#goto-next').click();
tab = testTabTitle('Tab 1 - Page 2 (2)');
tab.find('#goto-next').click();
tab = testTabTitle('Tab 1 - Page 2 (3)');
cy.testStack('ion-tabs ion-router-outlet', [
'app-tabs-tab1-nested',
'app-tabs-tab1-nested',
'app-tabs-tab1-nested'
]);
tab = getSelectedTab();
tab.find('ion-back-button').click();
tab = testTabTitle('Tab 1 - Page 2 (2)');
tab.find('ion-back-button').click();
tab = testTabTitle('Tab 1 - Page 2 (1)');
tab.find('ion-back-button').should('not.be.visible');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1-nested']);
});
})
describe('entry url - /tabs/lazy', () => {
beforeEach(() => {
cy.visit('/tabs/lazy');
});
it('should not display the back-button if coming from a different stack', () => {
let tab = testTabTitle('Tab 3 - Page 1');
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab3']);
tab = getSelectedTab();
tab.find('#goto-tab1-page2').click();
cy.testStack('ion-tabs ion-router-outlet', ['app-tabs-tab3', 'app-tabs-tab1-nested']);
tab = testTabTitle('Tab 1 - Page 2 (1)');
tab.find('ion-back-button').should('not.be.visible');
});
})
describe('enter url - /tabs/contact/one', () => {
beforeEach(() => {
cy.visit('/tabs/contact/one');
});
it('should return to correct tab after going to page in different outlet', () => {
const tab = getSelectedTab();
tab.find('#goto-nested-page1').click();
cy.testStack('app-nested-outlet ion-router-outlet', ['app-nested-outlet-page']);
const nestedOutlet = cy.get('app-nested-outlet');
nestedOutlet.find('ion-back-button').click();
testTabTitle('Tab 2 - Page 1');
});
})
})
function testTabTitle(title) {
const tab = getSelectedTab();
// Find is used to get a direct descendant instead of get
tab.find('ion-title').should('have.text', title);
return getSelectedTab();
}
function getSelectedTab() {
cy.get('ion-tabs ion-router-outlet > *:not(.ion-page-hidden)').should('have.length', 1);
return cy.get('ion-tabs ion-router-outlet > *:not(.ion-page-hidden)').first();
}
function testState(count, tab) {
cy.get('#tabs-state').should('have.text', `${count}.${tab}`);
}
function testUrlContains(urlFragment) {
cy.location().should((location) => {
expect(location.href).to.contain(urlFragment);
});
}
function testUrlEquals(url) {
cy.url().should('eq', url);
}

View File

@@ -1,11 +0,0 @@
describe('Virtual Scroll', () => {
beforeEach(() => {
cy.visit('/virtual-scroll');
cy.wait(30);
})
it('should open virtual-scroll', () => {
cy.get('ion-virtual-scroll > *').its('length').should('be.gt', 0);
});
});

View File

@@ -1,20 +0,0 @@
# Copy angular dist
rm -rf node_modules/@ionic/angular
cp -a ../../../dist node_modules/@ionic/angular
# Copy angular server
rm -rf node_modules/@ionic/angular-server
cp -a ../../../../packages/angular-server/dist node_modules/@ionic/angular-server
# # Copy core dist
rm -rf node_modules/@ionic/core
mkdir node_modules/@ionic/core
cp -a ../../../../core/css node_modules/@ionic/core/css
cp -a ../../../../core/dist node_modules/@ionic/core/dist
cp -a ../../../../core/hydrate node_modules/@ionic/core/hydrate
cp -a ../../../../core/loader node_modules/@ionic/core/loader
cp -a ../../../../core/package.json node_modules/@ionic/core/package.json
# # Copy ionicons
rm -rf node_modules/ionicons
cp -a ../../../../core/node_modules/ionicons node_modules/ionicons

View File

@@ -1,17 +0,0 @@
<ion-content>
<ion-button id="dismiss" (click)="modal.dismiss()">Dismiss Modal</ion-button>
<ion-accordion-group [value]="'a'">
<ion-accordion value="a">
<ion-item slot="header">
<ion-label>A</ion-label>
</ion-item>
<div slot="content">A content</div>
</ion-accordion>
<ion-accordion value="b">
<ion-item slot="header">
<ion-label>B</ion-label>
</ion-item>
<div slot="content">B content</div>
</ion-accordion>
</ion-accordion-group>
</ion-content>

View File

@@ -1,11 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-accordion-modal',
templateUrl: './accordion-modal.component.html',
})
export class AccordionModalComponent {
modal: HTMLIonModalElement;
constructor() {}
}

View File

@@ -1,13 +0,0 @@
<ion-header>
<ion-toolbar>
<ion-buttons>
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>
Accordion test
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-button id="open-modal" (click)="open()">Open Modal</ion-button>
</ion-content>

View File

@@ -1,22 +0,0 @@
import { Component } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { AccordionModalComponent } from './accordion-modal/accordion-modal.component';
@Component({
selector: 'app-accordion',
templateUrl: './accordion.component.html',
})
export class AccordionComponent {
constructor(
private modalCtrl: ModalController
) { }
async open() {
const modal = await this.modalCtrl.create({
component: AccordionModalComponent,
animated: false,
});
await modal.present();
}
}

View File

@@ -1,53 +0,0 @@
import { Component } from '@angular/core';
import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormControl } from '@angular/forms';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
})
export class FormComponent {
submitted = 'false';
profileForm: UntypedFormGroup;
outsideToggle = new UntypedFormControl(true);
constructor(fb: UntypedFormBuilder) {
this.profileForm = fb.group({
datetime: ['2010-08-20', Validators.required],
select: [undefined, Validators.required],
toggle: [false],
input: ['', Validators.required],
input2: ['Default Value'],
checkbox: [false],
range: [5, Validators.min(10)],
}, {
updateOn: typeof (window as any) !== 'undefined' && window.location.hash === '#blur' ? 'blur' : 'change'
});
}
setTouched() {
const formControl = this.profileForm.get('input');
formControl.markAsTouched();
}
onSubmit(_ev) {
this.submitted = 'true';
}
setValues() {
this.profileForm.patchValue({
datetime: '2010-08-20',
select: 'nes',
toggle: true,
input: 'Some value',
input2: 'Another values',
checkbox: true,
range: 50
});
}
markAllAsTouched() {
this.profileForm.markAllAsTouched();
}
}

View File

@@ -1,2 +0,0 @@
export * from './keep-contents-mounted.component';
export * from './keep-contents-mounted.module';

View File

@@ -1,16 +0,0 @@
import { NgModule } from "@angular/core";
import { RouterModule } from "@angular/router";
import { OverlayKeepContentsMounted } from ".";
@NgModule({
imports: [
RouterModule.forChild([
{
path: '',
component: OverlayKeepContentsMounted
}
])
],
exports: [RouterModule]
})
export class OverlayKeepContentsMountedRoutingModule { }

View File

@@ -1,22 +0,0 @@
<ion-content>
<ion-button id="open-modal" (click)="modal.present()">Open Modal</ion-button>
<ion-button id="open-popover" (click)="popover.present()">Open Popover</ion-button>
<ion-modal [keepContentsMounted]="true" #modal>
<ng-template>
<ion-content>
<ion-button (click)="modal.dismiss()">Dismiss</ion-button>
Modal Content
</ion-content>
</ng-template>
</ion-modal>
<ion-popover [keepContentsMounted]="true" #popover>
<ng-template>
<ion-content>
<ion-button (click)="popover.dismiss()">Dismiss</ion-button>
Popover Content
</ion-content>
</ng-template>
</ion-popover>
</ion-content>

View File

@@ -1,13 +0,0 @@
import { Component } from "@angular/core";
/**
* Validates that inline modals correctly mount
* inner components when keepContentsMounted is
* enabled.
*/
@Component({
selector: 'app-keep-contents-mounted',
templateUrl: 'keep-contents-mounted.component.html'
})
export class OverlayKeepContentsMounted {
}

View File

@@ -1,12 +0,0 @@
import { CommonModule } from "@angular/common";
import { NgModule } from "@angular/core";
import { IonicModule } from "@ionic/angular";
import { OverlayKeepContentsMountedRoutingModule } from "./keep-contents-mounted-routing.module";
import { OverlayKeepContentsMounted } from "./keep-contents-mounted.component";
@NgModule({
imports: [CommonModule, IonicModule, OverlayKeepContentsMountedRoutingModule],
declarations: [OverlayKeepContentsMounted],
exports: [OverlayKeepContentsMounted]
})
export class OverlayAutoMountModule { }

View File

@@ -1,70 +0,0 @@
import { Component, Input, NgZone, OnInit, Optional } from '@angular/core';
import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { ModalController, NavParams, IonNav, ViewWillLeave, ViewDidEnter, ViewDidLeave } from '@ionic/angular';
@Component({
selector: 'app-modal-example',
templateUrl: './modal-example.component.html',
})
export class ModalExampleComponent implements OnInit, ViewWillLeave, ViewDidEnter, ViewWillLeave, ViewDidLeave {
@Input() value: string;
form = new UntypedFormGroup({
select: new UntypedFormControl([])
});
valueFromParams: string;
onInit = 0;
willEnter = 0;
didEnter = 0;
willLeave = 0;
didLeave = 0;
modal: HTMLElement;
constructor(
private modalCtrl: ModalController,
@Optional() public nav: IonNav,
navParams: NavParams
) {
this.valueFromParams = navParams.get('prop');
}
ngOnInit() {
NgZone.assertInAngularZone();
this.onInit++;
}
ionViewWillEnter() {
if (this.onInit !== 1) {
throw new Error('ngOnInit was not called');
}
NgZone.assertInAngularZone();
this.willEnter++;
}
ionViewDidEnter() {
NgZone.assertInAngularZone();
this.didEnter++;
}
ionViewWillLeave() {
NgZone.assertInAngularZone();
this.willLeave++;
}
ionViewDidLeave() {
NgZone.assertInAngularZone();
this.didLeave++;
}
closeModal() {
this.modalCtrl.dismiss();
}
push() {
this.nav.push(ModalExampleComponent, {
'value': 'pushed!'
});
}
pop() {
this.nav.pop();
}
}

View File

@@ -1,20 +0,0 @@
<ion-button id="open-modal">Open Modal</ion-button>
<ul>
<li>
breakpointDidChange event count: <span id="breakpointDidChange">{{ breakpointDidChangeCounter }}</span>
</li>
</ul>
<ion-modal [animated]="false" trigger="open-modal" [breakpoints]="[0.1, 0.5, 1]" [initialBreakpoint]="0.5"
(ionBreakpointDidChange)="onBreakpointDidChange()">
<ng-template>
<ion-content>
<ion-list>
<ion-item *ngFor="let item of items">
<ion-label>{{ item }}</ion-label>
</ion-item>
</ion-list>
</ion-content>
</ng-template>
</ion-modal>

View File

@@ -1,13 +0,0 @@
<ion-button (click)="openPopover(popover)">Open Popover</ion-button>
<ion-popover #popover>
<ng-template>
<ion-content>
<ion-list>
<ion-item *ngFor="let item of items">
<ion-label>{{ item }}</ion-label>
</ion-item>
</ion-list>
</ion-content>
</ng-template>
</ion-popover>

View File

@@ -1,24 +0,0 @@
import { Component } from "@angular/core";
/**
* Validates that inline popovers will correctly display
* dynamic contents that are updated after the modal is
* display.
*/
@Component({
selector: 'app-popover-inline',
templateUrl: 'popover-inline.component.html'
})
export class PopoverInlineComponent {
items: string[] = [];
openPopover(popover: HTMLIonPopoverElement) {
popover.present();
setTimeout(() => {
this.items = ['A', 'B', 'C', 'D'];
}, 1000);
}
}

View File

@@ -1,16 +0,0 @@
import { NgModule } from "@angular/core";
import { RouterModule } from "@angular/router";
import { TabsGlobalComponent } from "./tabs-global.component";
@NgModule({
imports: [
RouterModule.forChild([
{
path: '',
component: TabsGlobalComponent
}
])
],
exports: [RouterModule]
})
export class TabsGlobalRoutingModule { }

View File

@@ -1,17 +0,0 @@
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>
Global Page
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-content>
<ion-button id="goto-prev-pop" (click)="navCtrl.pop()">Go To Previous</ion-button>
</ion-content>
</ion-content>

View File

@@ -1,17 +0,0 @@
import { Component } from "@angular/core";
import { NavController } from "@ionic/angular";
/**
* This component is used in conjunction with a tabs router-outlet,
* to validate the behavior of different routing APIs (e.g. NavController)
* when leaving and re-entering a router-outlet.
*/
@Component({
selector: 'app-tabs-global',
templateUrl: 'tabs-global.component.html'
})
export class TabsGlobalComponent {
constructor(public navCtrl: NavController) { }
}

View File

@@ -1,13 +0,0 @@
import { NgModule } from "@angular/core";
import { IonicModule } from "@ionic/angular";
import { TabsGlobalRoutingModule } from "./tabs-global-routing.module";
import { TabsGlobalComponent } from "./tabs-global.component";
@NgModule({
imports: [
IonicModule,
TabsGlobalRoutingModule
],
declarations: [TabsGlobalComponent]
})
export class TabsGlobalModule { }

View File

@@ -1,20 +0,0 @@
<ion-header>
<ion-toolbar>
<ion-title>Tab 1 - Page 2 ({{id}})</ion-title>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<h1>Welcome to NESTED PAGE {{id}}</h1>
<p>
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
<ion-button routerLink="/tabs/contact" id="goto-tab2-page1">Go to Tab 2 - Page 1</ion-button>
<ion-button routerLink="/tabs-global" id="goto-global">Go to Global Page</ion-button>
<ion-button routerLink="/tabs-global" id="goto-prev" (click)="navCtrl.pop()">Go to Previous Page (NavController).
</ion-button>
<ion-button routerLink="/tabs/account/nested/{{next()}}" id="goto-next">Go to Next</ion-button>
</p>
</ion-content>

View File

@@ -1,2 +0,0 @@
export * from './version-test.component';
export * from './version-test.module';

View File

@@ -1,16 +0,0 @@
import { NgModule } from "@angular/core";
import { RouterModule } from "@angular/router";
import { VersionTestComponent } from ".";
@NgModule({
imports: [
RouterModule.forChild([
{
path: '',
component: VersionTestComponent
}
])
],
exports: [RouterModule]
})
export class VersionTestRoutingModule { }

View File

@@ -1 +0,0 @@
Version-specific tests

View File

@@ -1,8 +0,0 @@
import { Component } from "@angular/core";
@Component({
selector: 'app-version-test',
templateUrl: 'version-test.component.html'
})
export class VersionTestComponent {
}

View File

@@ -1,12 +0,0 @@
import { CommonModule } from "@angular/common";
import { NgModule } from "@angular/core";
import { IonicModule } from "@ionic/angular";
import { VersionTestRoutingModule } from "./version-test-routing.module";
import { VersionTestComponent } from "./version-test.component";
@NgModule({
imports: [CommonModule, IonicModule, VersionTestRoutingModule],
declarations: [VersionTestComponent],
exports: [VersionTestComponent]
})
export class VersionTestModule { }

View File

@@ -1,33 +0,0 @@
#!/bin/bash
# The directory where the source
# for each specific application is.
APPS_DIR="apps"
# The directory where the
# base application logic is
BASE_DIR="base"
BUILD_DIR="build"
# The specific application
# we are building
APP_DIR="${1}"
# The full path to the specific application.
FULL_APP_DIR="${APPS_DIR}/${APP_DIR}/."
# The full path to the base application.
FULL_BASE_DIR="${BASE_DIR}/."
# The full path to the built application.
BUILD_APP_DIR="${BUILD_DIR}/${APP_DIR}/"
# Make the build directory if it does not already exist.
mkdir -p $BUILD_DIR
# First we need to copy the base application
cp -R $FULL_BASE_DIR $BUILD_APP_DIR
# Then we can copy the specific app which
# will override any files in the base application.
cp -R $FULL_APP_DIR $BUILD_APP_DIR

View File

@@ -140,9 +140,8 @@
}
}
},
"defaultProject": "test-app",
"cli": {
"schematicCollections": [
"@angular-eslint/schematics"
]
"defaultCollection": "@angular-eslint/schematics"
}
}

View File

@@ -0,0 +1,8 @@
{
"integrationFolder": "./e2e",
"testFiles": "**/*.spec.ts",
"baseUrl": "http://localhost:4200/",
"ignoreTestFiles": "**/examples/*",
"video": false,
"screenshotOnRunFailure": false
}

View File

@@ -0,0 +1,79 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
Cypress.Commands.add('ionSwipeToGoBack', (complete = false, selector = 'ion-router-outlet') => {
const increment = (complete) ? 60 : 25;
cy.get(selector)
.first()
.trigger('mousedown', 0, 275, { which: 1, force: true })
.trigger('mousemove', increment * 1, 275, { which: 1, force: true })
.wait(50)
.trigger('mousemove', increment * 2, 275, { which: 1, force: true })
.wait(50)
.trigger('mousemove', increment * 3, 275, { which: 1, force: true })
.wait(50)
.trigger('mousemove', increment * 4, 275, { which: 1, force: true })
.wait(50)
.trigger('mouseup', increment * 4, 275, { which: 1, force: true })
cy.wait(150);
})
Cypress.Commands.add('testStack', (selector, expected) => {
cy.document().then((doc) => {
const children = Array.from(
doc.querySelector(selector).children
).map(el => el.tagName.toLowerCase());
expect(children).to.deep.equal(expected);
})
})
Cypress.Commands.add('testLifeCycle', (selector, expected) => {
cy.get(`${selector} #ngOnInit`).invoke('text').should('equal', '1');
cy.get(`${selector} #ionViewWillEnter`).invoke('text').should('equal', expected.ionViewWillEnter.toString());
cy.get(`${selector} #ionViewDidEnter`).invoke('text').should('equal', expected.ionViewDidEnter.toString());
cy.get(`${selector} #ionViewWillLeave`).invoke('text').should('equal', expected.ionViewWillLeave.toString());
cy.get(`${selector} #ionViewDidLeave`).invoke('text').should('equal', expected.ionViewDidLeave.toString());
})
Cypress.Commands.add('ionPageVisible', (selector) => {
cy.get(selector)
.should('have.class', 'ion-page')
.should('not.have.class', 'ion-page-hidden')
.should('not.have.class', 'ion-page-invisible')
.should('have.length', 1)
})
Cypress.Commands.add('ionPageHidden', (selector) => {
cy.get(selector)
.should('have.class', 'ion-page')
.should('have.class', 'ion-page-hidden')
.should('have.length', 1)
})
Cypress.Commands.add('ionPageDoesNotExist', (selector) => {
cy.get(selector)
.should('not.exist')
});

Some files were not shown because too many files have changed in this diff Show More