Compare commits

..

3 Commits

Author SHA1 Message Date
Liam DeBeasi
65c94b16d5 add custom anim support to nav outlet 2023-06-09 14:37:38 -04:00
Liam DeBeasi
fb0b0ae46e add modal sample 2023-06-09 12:39:38 -04:00
Liam DeBeasi
a3bc83a1e6 poc using animations with any lib 2023-06-09 09:27:55 -04:00
4966 changed files with 37458 additions and 75259 deletions

33
.github/CODEOWNERS vendored
View File

@@ -11,15 +11,13 @@
# In each subsection folders are ordered first by depth, then alphabetically.
# This should make it easy to add new rules without breaking existing ones.
* @ionic-team/framework
# Frameworks
## Angular
/packages/angular/ @sean-perkins @thetaPC
/packages/angular-server @sean-perkins @thetaPC
/packages/angular/test @thetaPC
/angular/ @sean-perkins
/packages/angular-server @sean-perkins
/angular/test
## React
@@ -30,23 +28,19 @@
## Vue
/packages/vue/ @liamdebeasi @thetaPC
/packages/vue-router/ @liamdebeasi @thetaPC
/packages/vue/test/ @thetaPC
/packages/vue-router/__tests__ @thetaPC
/packages/vue/ @liamdebeasi
/packages/vue-router/ @liamdebeasi
/packages/vue/test/
/packages/vue-router/__tests__
# Components
/core/src/components/accordion/ @liamdebeasi
/core/src/components/accordion-group/ @liamdebeasi
/core/src/components/checkbox/ @amandaejohnston
/core/src/components/datetime/ @liamdebeasi @amandaejohnston @sean-perkins
/core/src/components/datetime-button/ @liamdebeasi
/core/src/components/item/ @brandyscarney
/core/src/components/menu/ @amandaejohnston
/core/src/components/menu-toggle/ @amandaejohnston
@@ -56,19 +50,9 @@
/core/src/components/picker-internal/ @liamdebeasi
/core/src/components/picker-column-internal/ @liamdebeasi
/core/src/components/radio/ @amandaejohnston
/core/src/components/radio-group/ @amandaejohnston
/core/src/components/refresher/ @liamdebeasi
/core/src/components/refresher-content/ @liamdebeasi
/core/src/components/searchbar/ @brandyscarney
/core/src/components/segment/ @brandyscarney
/core/src/components/segment-button/ @brandyscarney
/core/src/components/skeleton-text/ @brandyscarney
# Utilities
/core/src/utils/animation/ @liamdebeasi
@@ -80,6 +64,3 @@
/core/src/utils/sanitization/ @liamdebeasi
/core/src/utils/tap-click/ @liamdebeasi
/core/src/utils/transition/ @liamdebeasi
/core/src/css/ @brandyscarney
/core/src/themes/ @brandyscarney

View File

@@ -2,10 +2,10 @@
- [Button States](#button-states)
* [Component Structure](#component-structure)
* [Activated](#activated)
* [Disabled](#disabled)
* [Focused](#focused)
* [Hover](#hover)
* [Activated](#activated)
* [Ripple Effect](#ripple-effect)
* [Example Components](#example-components)
* [References](#references)
@@ -21,7 +21,7 @@
## Button States
Any component that renders a button should have the following states: [`disabled`](#disabled), [`focused`](#focused), [`hover`](#hover), [`activated`](#activated). It should also have a [Ripple Effect](#ripple-effect) component added for Material Design.
Any component that renders a button should have the following states: [`activated`](#activated), [`disabled`](#disabled), [`focused`](#focused), [`hover`](#hover). It should also have a [Ripple Effect](#ripple-effect) component added for Material Design.
### Component Structure
@@ -89,6 +89,73 @@ The following styles should be set for the CSS to work properly. Note that the `
```
### Activated
The activated state should be enabled for elements with actions on "press". It usually changes the opacity or background of an element.
> Make sure the component has the correct [component structure](#component-structure) before continuing.
#### JavaScript
The `ion-activatable` class needs to be set on an element that can be activated:
```jsx
render() {
return (
<Host class='ion-activatable'>
<slot></slot>
</Host>
);
}
```
Once that is done, the element will get the `ion-activated` class added on press.
In addition to setting that class, `ion-activatable-instant` can be set in order to have an instant press with no delay:
```jsx
<Host class='ion-activatable ion-activatable-instant'>
```
#### CSS
```css
/**
* @prop --color-activated: Color of the button when pressed
* @prop --background-activated: Background of the button when pressed
* @prop --background-activated-opacity: Opacity of the background when pressed
*/
```
Style the `ion-activated` class based on the spec for that element:
```scss
:host(.ion-activated) .button-native {
color: var(--color-activated);
&::after {
background: var(--background-activated);
opacity: var(--background-activated-opacity);
}
}
```
> Order is important! Activated should be after the focused & hover states.
#### User Customization
Setting the activated state on the `::after` pseudo-element allows the user to customize the activated state without knowing what the default opacity is set at. A user can customize in the following ways to have a solid red background on press, or they can leave out `--background-activated-opacity` and the button will use the default activated opacity to match the spec.
```css
ion-button {
--background-activated: red;
--background-activated-opacity: 1;
}
```
### Disabled
The disabled state should be set via prop on all components that render a native button. Setting a disabled state will change the opacity or color of the button and remove click events from firing.
@@ -125,8 +192,7 @@ render() {
}
```
> [!NOTE]
> If the class being added was for `ion-back-button` it would be `back-button-disabled`.
> Note: if the class being added was for `ion-back-button` it would be `back-button-disabled`.
#### CSS
@@ -144,18 +210,10 @@ The following CSS _at the bare minimum_ should be added for the disabled class,
TODO
### Focused
The focused state should be enabled for elements with actions when tabbed to via the keyboard. This will only work inside of an `ion-app`. It usually changes the opacity or background of an element.
> [!WARNING]
> Do not use `:focus` because that will cause the focus to apply even when an element is tapped (because the element is now focused). Instead, we only want the focus state to be shown when it makes sense which is what the `.ion-focusable` utility mentioned below does.
> [!NOTE]
> The [`:focus-visible`](https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible) pseudo-class mostly does the same thing as our JavaScript-driven utility. However, it does not work well with Shadow DOM components as the element that receives focus is typically inside of the Shadow DOM, but we usually want to set the `:focus-visible` state on the host so we can style other parts of the component. Using other combinations such as `:has(:focus-visible)` does not work because `:has` does not pierce the Shadow DOM (as that would leak implementation details about the Shadow DOM contents). `:focus-within` does work with the Shadow DOM, but that has the same problem as `:focus` that was mentioned before. Unfortunately, a [`:focus-visible-within` pseudo-class does not exist yet](https://github.com/WICG/focus-visible/issues/151).
> [!IMPORTANT]
> Make sure the component has the correct [component structure](#component-structure) before continuing.
#### JavaScript
@@ -165,7 +223,7 @@ The `ion-focusable` class needs to be set on an element that can be focused:
```jsx
render() {
return (
<Host class="ion-focusable">
<Host class='ion-focusable'>
<slot></slot>
</Host>
);
@@ -200,8 +258,7 @@ Style the `ion-focused` class based on the spec for that element:
}
```
> [!IMPORTANT]
> Order matters! Focused should be **before** the activated and hover states.
> Order is important! Focused should be after the activated and before the hover state.
#### User Customization
@@ -220,10 +277,6 @@ ion-button {
The [hover state](https://developer.mozilla.org/en-US/docs/Web/CSS/:hover) happens when a user moves their cursor on top of an element without pressing on it. It should not happen on mobile, only on desktop devices that support hover.
> [!NOTE]
> Some Android devices [incorrectly report their inputs](https://issues.chromium.org/issues/40855702) which can result in certain devices receiving hover events when they should not.
> [!IMPORTANT]
> Make sure the component has the correct [component structure](#component-structure) before continuing.
#### CSS
@@ -254,8 +307,7 @@ Style the `:hover` based on the spec for that element:
}
```
> [!IMPORTANT]
> Order matters! Hover should be **before** the activated state.
> Order is important! Hover should be before the activated state.
#### User Customization
@@ -270,79 +322,6 @@ ion-button {
```
### Activated
The activated state should be enabled for elements with actions on "press". It usually changes the opacity or background of an element.
> [!WARNING]
>`:active` should not be used here as it is not received on mobile Safari unless the element has a `touchstart` listener (which we don't necessarily want to have to add to every element). From [Safari Web Content Guide](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/AdjustingtheTextSize/AdjustingtheTextSize.html):
>
>> On iOS, mouse events are sent so quickly that the down or active state is never received. Therefore, the `:active` pseudo state is triggered only when there is a touch event set on the HTML element
> [!IMPORTANT]
> Make sure the component has the correct [component structure](#component-structure) before continuing.
#### JavaScript
The `ion-activatable` class needs to be set on an element that can be activated:
```jsx
render() {
return (
<Host class="ion-activatable">
<slot></slot>
</Host>
);
}
```
Once that is done, the element will get the `ion-activated` class added on press after a small delay. This delay exists so that the active state does not show up when an activatable element is tapped while scrolling.
In addition to setting that class, `ion-activatable-instant` can be set in order to have an instant press with no delay:
```jsx
<Host class="ion-activatable ion-activatable-instant">
```
#### CSS
```css
/**
* @prop --color-activated: Color of the button when pressed
* @prop --background-activated: Background of the button when pressed
* @prop --background-activated-opacity: Opacity of the background when pressed
*/
```
Style the `ion-activated` class based on the spec for that element:
```scss
:host(.ion-activated) .button-native {
color: var(--color-activated);
&::after {
background: var(--background-activated);
opacity: var(--background-activated-opacity);
}
}
```
> [!IMPORTANT]
> Order matters! Activated should be **after** the focused & hover states.
#### User Customization
Setting the activated state on the `::after` pseudo-element allows the user to customize the activated state without knowing what the default opacity is set at. A user can customize in the following ways to have a solid red background on press, or they can leave out `--background-activated-opacity` and the button will use the default activated opacity to match the spec.
```css
ion-button {
--background-activated: red;
--background-activated-opacity: 1;
}
```
### Ripple Effect
The ripple effect should be added to elements for Material Design. It *requires* the `ion-activatable` class to be set on the parent element to work, and relative positioning on the parent.

View File

@@ -163,7 +163,7 @@ npm i
npm run build
npm pack --pack-destination ~
cd ../packages/angular
cd ../angular
npm i
npm run sync
npm run build
@@ -295,7 +295,7 @@ See [Ionic's E2E testing guide](../core/src/utils/test/playwright/docs/README.md
#### Modifying Files
1. Locate the files inside the relevant root directory:
- Angular: [`/packages/angular/src`](/packages/angular/src)
- Angular: [`/angular/src`](/angular/src)
- React: [`/packages/react/src`](/packages/react/src)
- Vue: [`/packages/vue/src`](/packages/vue/src)
2. Make your changes to the files. If the change is overly complex or out of the ordinary, add comments so we can understand the changes.
@@ -311,7 +311,7 @@ See [Ionic's E2E testing guide](../core/src/utils/test/playwright/docs/README.md
##### Previewing in this repository
Follow the steps in the test directory for each framework:
- Angular: [`/packages/angular/test`](/packages/angular/test/README.md)
- Angular: [`/angular/test`](/angular/test/README.md)
- React: [`/packages/react/test`](/packages/react/test/README.md)
- Vue: [`/packages/vue/test`](/packages/vue/test/README.md)
@@ -322,7 +322,7 @@ Follow the steps to [preview changes in core](#preview-changes).
#### Lint Changes
1. Run `npm run lint` to lint the TypeScript in the relevant directory:
- Angular: [`/packages/angular/src`](/packages/angular/src)
- Angular: [`/angular/src`](/angular/src)
- React: [`/packages/react/src`](/packages/react/src)
- Vue: [`/packages/vue/src`](/packages/vue/src)
2. If there are lint errors, run `npm run lint.fix` to automatically fix any errors. Repeat step 1 to ensure the errors have been fixed, and manually fix them if not.
@@ -330,7 +330,7 @@ Follow the steps to [preview changes in core](#preview-changes).
#### Modifying Tests
1. Locate the e2e test to modify inside the relevant test app directory:
- Angular: [`/packages/angular/test/base/e2e/src`](/packages/angular/test/base/e2e/src)
- Angular: [`/angular/test/base/e2e/src`](/angular/test/base/e2e/src)
- React: [`/packages/react/test/base/tests/e2e/specs`](/packages/react/test/base/tests/e2e/specs)
- Vue: [`/packages/vue/test/base/tests/e2e/specs`](/packages/vue/test/base/tests/e2e/specs)
2. If a test exists, modify the test by adding an example to reproduce the problem fixed or feature added.

View File

@@ -20,10 +20,12 @@ body:
id: affected-versions
attributes:
label: Ionic Framework Version
description: Which version(s) of Ionic Framework does this issue impact? [Ionic Framework 1.x to 6.x are no longer supported](https://ionicframework.com/docs/reference/support#framework-maintenance-and-support-status). For extended support, considering visiting [Ionic's Enterprise offering](https://ionic.io/enterprise).
description: Which version(s) of Ionic Framework does this issue impact? For Ionic Framework 1.x issues, please use https://github.com/ionic-team/ionic-v1. For Ionic Framework 2.x and 3.x issues, please use https://github.com/ionic-team/ionic-v3.
options:
- v4.x
- v5.x
- v6.x
- v7.x
- v8.x (Beta)
- Nightly
multiple: true
validations:
@@ -49,11 +51,11 @@ body:
id: steps-to-reproduce
attributes:
label: Steps to Reproduce
description: Explain the steps required to reproduce this issue.
description: Please explain the steps required to duplicate this issue.
placeholder: |
1. Go to '...'
2. Click on '...'
3. Observe: '...'
1.
2.
3.
validations:
required: true
@@ -61,15 +63,8 @@ body:
id: reproduction-url
attributes:
label: Code Reproduction URL
description: |
Reproduce this issue in a blank [Ionic Framework starter application](https://ionicframework.com/start#basics) or a Stackblitz example.
You can use the Stackblitz button available on any of the [component playgrounds](https://ionicframework.com/docs/components) to open an editable example. Remember to save your changes to obtain a link to copy.
Reproductions cases must be minimal and focused around the specific problem you are experiencing. This is the best way to ensure this issue is triaged quickly. Issues without a code reproduction may be closed if the Ionic Team cannot reproduce the issue you are reporting.
description: Please reproduce this issue in a blank Ionic Framework starter application and provide a link to the repo. Try out our [Getting Started Wizard](https://ionicframework.com/start#basics) to quickly spin up an Ionic Framework starter app. This is the best way to ensure this issue is triaged quickly. Issues without a code reproduction may be closed if the Ionic Team cannot reproduce the issue you are reporting.
placeholder: https://github.com/...
validations:
required: true
- type: textarea
id: ionic-info

View File

@@ -1,4 +1,4 @@
Issue number: resolves #
Issue number: #
---------
@@ -21,12 +21,7 @@ Issue number: resolves #
- [ ] Yes
- [ ] No
<!--
If this introduces a breaking change:
1. Describe the impact and migration path for existing applications below.
2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging. See https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#footer for more information.
-->
<!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. -->
## Other information

16
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/core"
schedule:
interval: "daily"
versioning-strategy: increase
allow:
- dependency-name: "@playwright/test"
- dependency-name: "@axe-core/playwright"
- dependency-name: "@stencil/angular-output-target"
- dependency-name: "@stencil/core"
- dependency-name: "@stencil/react-output-target"
- dependency-name: "@stencil/sass"
- dependency-name: "@stencil/vue-output-target"
- dependency-name: "ionicons"

15
.github/labeler.yml vendored
View File

@@ -6,17 +6,16 @@
# https://github.com/actions/labeler
'package: core':
- changed-files:
- any-glob-to-any-file: ['core/**/*']
- core/**/*
'package: angular':
- changed-files:
- any-glob-to-any-file: ['packages/angular/**/*', 'packages/angular-*/**/*']
- angular/**/*
- packages/angular-*/**/*
'package: react':
- changed-files:
- any-glob-to-any-file: ['packages/react/**/*', 'packages/react-*/**/*']
- packages/react/**/*
- packages/react-*/**/*
'package: vue':
- changed-files:
- any-glob-to-any-file: ['packages/vue/**/*', 'packages/vue-*/**/*']
- packages/vue/**/*
- packages/vue-*/**/*

View File

@@ -3,9 +3,9 @@ description: 'Build Ionic Angular Server'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- name: Install Angular Server Dependencies
run: npm ci

View File

@@ -3,9 +3,9 @@ description: 'Build Ionic Angular'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
@@ -14,25 +14,25 @@ runs:
- name: Install Angular Dependencies
run: npm ci
shell: bash
working-directory: ./packages/angular
working-directory: ./angular
- name: Sync
run: npm run sync
shell: bash
working-directory: ./packages/angular
working-directory: ./angular
- name: Lint
run: npm run lint
shell: bash
working-directory: ./packages/angular
working-directory: ./angular
- name: Build
run: npm run build
shell: bash
working-directory: ./packages/angular
working-directory: ./angular
- name: Check Diff
run: git diff --exit-code
shell: bash
working-directory: ./packages/angular
working-directory: ./angular
- uses: ./.github/workflows/actions/upload-archive
with:
name: ionic-angular
output: ./packages/angular/AngularBuild.zip
paths: ./packages/angular/dist
output: ./angular/AngularBuild.zip
paths: ./angular/dist

View File

@@ -8,10 +8,10 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- name: Install Dependencies
run: npm ci
@@ -22,7 +22,7 @@ runs:
run: npm i @stencil/core@${{ inputs.stencil-version }}
shell: bash
- name: Build Core
run: npm run build -- --ci --debug --verbose
run: npm run build -- --ci
working-directory: ./core
shell: bash
- uses: ./.github/workflows/actions/upload-archive

View File

@@ -1,28 +1,16 @@
name: 'Build Ionic Core'
description: 'Build Ionic Core'
inputs:
ionicons-version:
description: 'The NPM tag of ionicons to install.'
type: string
required: false
runs:
using: 'composite'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- name: Install Dependencies
run: npm install
working-directory: ./core
shell: bash
# If an Ionicons version was specified install that.
# Otherwise just use the version defined in the package.json.
- name: Install Ionicons Version
if: inputs.ionicons-version != ''
run: npm install ionicons@${{ inputs.ionicons-version }}
working-directory: ./core
shell: bash
- name: Build Core
run: npm run build -- --ci
working-directory: ./core

View File

@@ -3,9 +3,9 @@ description: 'Build Ionic React Router'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core

View File

@@ -3,9 +3,9 @@ description: 'Build Ionic React'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core

View File

@@ -3,9 +3,9 @@ description: 'Builds Ionic Vue Router'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core

View File

@@ -3,9 +3,9 @@ description: 'Build Ionic Vue'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core

View File

@@ -10,10 +10,10 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v3
with:
name: ${{ inputs.name }}
path: ${{ inputs.path }}
- name: Extract Archive
- name: Exract Archive
run: unzip -q -o ${{ inputs.path }}/${{ inputs.filename }}
shell: bash

View File

@@ -19,24 +19,18 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
# Provenance requires npm 9.5.0+
node-version: 16.x
- name: Install latest npm
run: npm install -g npm@latest
shell: bash
# This ensures the local version of Lerna is installed
# and that we do not use the global Lerna version
- name: Install root dependencies
run: npm ci
shell: bash
- name: Install Dependencies
run: npx lerna bootstrap --include-dependencies --scope ${{ inputs.scope }} --ignore-scripts -- --legacy-peer-deps
run: lerna bootstrap --include-dependencies --scope ${{ inputs.scope }} --ignore-scripts -- --legacy-peer-deps
shell: bash
working-directory: ${{ inputs.working-directory }}
- name: Update Version
run: npx lerna version ${{ inputs.version }} --yes --exact --no-changelog --no-push --no-git-tag-version --preid=${{ inputs.preid }}
run: lerna version ${{ inputs.version }} --yes --exact --no-changelog --no-push --no-git-tag-version --preid=${{ inputs.preid }}
shell: bash
working-directory: ${{ inputs.working-directory }}
- name: Run Build

View File

@@ -6,9 +6,9 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18
node-version: 16
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
@@ -27,16 +27,16 @@ runs:
- name: Create Test App
run: ./build.sh ${{ inputs.app }}
shell: bash
working-directory: ./packages/angular/test
working-directory: ./angular/test
- name: Install Dependencies
run: npm install
shell: bash
working-directory: ./packages/angular/test/build/${{ inputs.app }}
working-directory: ./angular/test/build/${{ inputs.app }}
- name: Sync Built Changes
run: npm run sync
shell: bash
working-directory: ./packages/angular/test/build/${{ inputs.app }}
working-directory: ./angular/test/build/${{ inputs.app }}
- name: Run Tests
run: npm run test
shell: bash
working-directory: ./packages/angular/test/build/${{ inputs.app }}
working-directory: ./angular/test/build/${{ inputs.app }}

View File

@@ -3,9 +3,9 @@ description: 'Test Core Clean Build'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- uses: ./.github/workflows/actions/download-archive
with:
@@ -13,15 +13,6 @@ runs:
path: ./core
filename: CoreBuild.zip
- name: Check Diff
run: |
git diff --exit-code || {
echo -e "\033[1;31m⚠ Error: Differences Detected ⚠️\033[0m"
echo -e "\033[1;31mThere are uncommitted changes between the build outputs from CI and your branch.\033[0m"
echo -e "\033[1;31mPlease ensure you have followed these steps:\033[0m"
echo -e "\033[1;31m1. Run 'npm run build' locally to generate the latest build output.\033[0m"
echo -e "\033[1;31m2. Commit and push all necessary changes to your branch.\033[0m"
echo -e "\033[1;31m3. Compare and validate the differences before proceeding.\033[0m"
exit 1
}
run: git diff --exit-code
shell: bash
working-directory: ./core

View File

@@ -3,9 +3,9 @@ description: 'Test Core Lint'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- name: Install Dependencies
run: npm ci
working-directory: ./core

View File

@@ -7,27 +7,25 @@ inputs:
description: 'Playwright total number of test shards (ex: 4)'
update:
description: 'Whether or not to update the reference snapshots'
component:
description: 'The component to update the reference snapshots'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
path: ./core
filename: CoreBuild.zip
- name: Install Dependencies
run: npm install
- name: Install Playwright Dependencies
run: npm install && npx playwright install && npx playwright install-deps
shell: bash
working-directory: ./core
- name: Test
if: inputs.update != 'true'
run: npm run test.e2e.docker.ci ${{ inputs.component }} -- --shard=${{ inputs.shard }}/${{ inputs.totalShards }}
run: npm run test.e2e -- --shard=${{ inputs.shard }}/${{ inputs.totalShards }}
shell: bash
working-directory: ./core
- name: Test and Update
@@ -49,7 +47,7 @@ runs:
# which is why we not using the upload-archive
# composite step here.
run: |
npm run test.e2e.docker.ci ${{ inputs.component }} -- --shard=${{ inputs.shard }}/${{ inputs.totalShards }} --update-snapshots
npm run test.e2e -- --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
@@ -62,7 +60,7 @@ runs:
working-directory: ./core
- name: Archive Updated Screenshots
if: inputs.update == 'true' && steps.test-and-update.outputs.hasUpdatedScreenshots == 'true'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: updated-screenshots-${{ inputs.shard }}-${{ inputs.totalShards }}
path: UpdatedScreenshots-${{ inputs.shard }}-${{ inputs.totalShards }}.zip

View File

@@ -1,23 +1,15 @@
name: 'Test Core Spec'
description: 'Test Core Spec'
inputs:
stencil-version:
description: 'The NPM tag of @stencil/core to install.'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- name: Install Dependencies
run: npm ci
run: npm install
working-directory: ./core
shell: bash
- name: Install Stencil ${{ inputs.stencil-version }}
run: npm install @stencil/core@${{ inputs.stencil-version }}
shell: bash
working-directory: ./core
if: ${{ inputs.stencil-version != '' }}
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core

View File

@@ -6,9 +6,9 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core

View File

@@ -6,9 +6,9 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core

View File

@@ -6,9 +6,9 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 16.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core

View File

@@ -7,10 +7,10 @@ on:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 18.x
- uses: actions/download-artifact@v4
node-version: 16.x
- uses: actions/download-artifact@v3
with:
path: ./artifacts
- name: Extract Archives
@@ -25,30 +25,17 @@ runs:
# Configure user as Ionitron
# and push only the changed .png snapshots
# to the remote branch.
# Non-Linux screenshots are in .gitignore
# Screenshots are in .gitignore
# to prevent local screenshots from getting
# pushed to Git.
# pushed to Git. As a result, we need --force
# here so that CI generated screenshots can
# get added to git. Screenshot ground truths
# should only be added via this CI process.
run: |
git config user.name ionitron
git config user.email hi@ionicframework.com
# This adds an empty entry for new
# screenshot files so we can track them with
# git diff
git add src/\*.png -N
if git diff --exit-code; then
echo -e "\033[1;31m⚠ Error: No new screenshots generated ⚠️\033[0m"
echo -e "\033[1;31mThis means that there were zero visual diffs when running screenshot tests.\033[0m"
echo -e "\033[1;31mMake sure you have pushed any code changes that would result in visual diffs.\033[0m"
exit 1
else
# This actually adds the contents
# of the screenshots (including new ones)
git add src/\*.png
git commit -m "chore(): add updated snapshots"
git push
fi
git add src/\*.png --force
git commit -m "chore(): add updated snapshots"
git push
shell: bash
working-directory: ./core

View File

@@ -13,7 +13,7 @@ runs:
- name: Create Archive
run: zip -q -r ${{ inputs.output }} ${{ inputs.paths }}
shell: bash
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v3
with:
name: ${{ inputs.name }}
path: ${{ inputs.output }}

View File

@@ -1,18 +0,0 @@
name: Assign issues to triage
on:
issues:
types: [opened]
jobs:
auto-assign:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: 'Auto-assign issue'
uses: pozil/auto-assign-issue@edee9537367a8fbc625d27f9e10aa8bad47b8723 # v1.13.0
with:
assignees: liamdebeasi, sean-perkins, brandyscarney, amandaejohnston, mapsandapps, thetaPC
numOfAssignee: 1
allowSelfAssign: false

View File

@@ -4,12 +4,6 @@ on:
pull_request:
branches: [ '**' ]
merge_group:
workflow_dispatch:
inputs:
ionicons_npm_release_tag:
required: false
type: string
description: What version of ionicons should be pulled from NPM? Use this if you want to test a custom version of Ionicons with Ionic.
# When pushing a new commit we should
# cancel the previous test run to not
@@ -22,30 +16,28 @@ jobs:
build-core:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-core
with:
ionicons-version: ${{ inputs.ionicons_npm_release_tag }}
test-core-clean-build:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-clean-build
test-core-lint:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-lint
test-core-spec:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-spec
test-core-screenshot:
@@ -62,7 +54,7 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-screenshot
with:
shard: ${{ matrix.shard }}
@@ -90,14 +82,14 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-vue
build-vue-router:
needs: [build-vue]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-vue-router
test-vue-e2e:
@@ -108,7 +100,7 @@ jobs:
needs: [build-vue, build-vue-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-vue-e2e
with:
app: ${{ matrix.apps }}
@@ -126,25 +118,25 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-angular
build-angular-server:
needs: [build-core]
needs: [build-angular]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-angular-server
test-angular-e2e:
strategy:
fail-fast: false
matrix:
apps: [ng14, ng15, ng16, ng17]
apps: [ng14, ng15, ng16]
needs: [build-angular, build-angular-server]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-angular-e2e
with:
app: ${{ matrix.apps }}
@@ -162,14 +154,14 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-react
build-react-router:
needs: [build-react]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-react-router
test-react-router-e2e:
@@ -180,7 +172,7 @@ jobs:
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-react-router-e2e
with:
app: ${{ matrix.apps }}
@@ -202,7 +194,7 @@ jobs:
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-react-e2e
with:
app: ${{ matrix.apps }}

View File

@@ -14,8 +14,8 @@ jobs:
permissions:
security-events: write
steps:
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v3
- uses: actions/checkout@v3
- uses: github/codeql-action/init@v2
with:
languages: javascript
- uses: github/codeql-action/analyze@v3
- uses: github/codeql-action/analyze@v2

View File

@@ -9,7 +9,7 @@ jobs:
outputs:
dev-hash: ${{ steps.create-dev-hash.outputs.DEV_HASH }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
# 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

View File

@@ -13,7 +13,7 @@ jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v5
- uses: actions/labeler@main
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
sync-labels: true

View File

@@ -12,7 +12,7 @@ jobs:
outputs:
nightly-hash: ${{ steps.create-nightly-hash.outputs.NIGHTLY_HASH }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
# 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
@@ -37,3 +37,45 @@ jobs:
version: ${{ needs.create-nightly-hash.outputs.nightly-hash }}
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
finalize-release:
needs: [create-nightly-hash, release-ionic]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
token: ${{ secrets.IONITRON_TOKEN }}
fetch-depth: 0
- name: Configure Identity
# Commits from github-actions do not
# trigger other GitHub Actions. As a result,
# we publish releases from Ionitron instead
# so actions run when merging the release branch
# back into main.
run: |
git config user.name ionitron
git config user.email hi@ionicframework.com
shell: bash
- name: Checkout Nightly Branch
# There are branch protection rules for our version
# branches (i.e. "6.2.x"), so we cannot name the branch
# the nightly hash as it would fall under the protection
# rule. As a result, we prefix "tmp-" to the branch.
run: |
git checkout -b tmp-${{ needs.create-nightly-hash.outputs.nightly-hash }}
git push origin tmp-${{ needs.create-nightly-hash.outputs.nightly-hash }}
shell: bash
- name: Create GitHub Release
run: lerna version ${{ needs.create-nightly-hash.outputs.nightly-hash }} --yes --force-publish='*' --conventional-commits --conventional-prerelease --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 tmp-${{ needs.create-nightly-hash.outputs.nightly-hash }}
git push origin --delete tmp-${{ needs.create-nightly-hash.outputs.nightly-hash }}
shell: bash

View File

@@ -22,7 +22,7 @@ jobs:
release-core:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/publish-npm
with:
scope: '@ionic/core'
@@ -48,7 +48,7 @@ jobs:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Restore @ionic/docs built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -68,7 +68,7 @@ jobs:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -81,21 +81,21 @@ jobs:
tag: ${{ inputs.tag }}
version: ${{ inputs.version }}
preid: ${{ inputs.preid }}
working-directory: 'packages/angular'
working-directory: 'angular'
folder: './dist'
token: ${{ secrets.NPM_TOKEN }}
- name: Cache Built @ionic/angular
uses: ./.github/workflows/actions/upload-archive
with:
name: ionic-angular
output: packages/angular/AngularBuild.zip
paths: packages/angular/dist
output: ./angular/AngularBuild.zip
paths: ./angular/dist
release-react:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -121,7 +121,7 @@ jobs:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -144,16 +144,22 @@ jobs:
paths: packages/vue/dist packages/vue/css
release-angular-server:
needs: [release-core]
needs: [release-angular]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
path: ./core
filename: CoreBuild.zip
- name: Restore @ionic/angular built cache
uses: ./.github/workflows/actions/download-archive
with:
name: ionic-angular
path: ./angular
filename: AngularBuild.zip
- uses: ./.github/workflows/actions/publish-npm
with:
scope: '@ionic/angular-server'
@@ -168,7 +174,7 @@ jobs:
needs: [release-react]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -194,7 +200,7 @@ jobs:
needs: [release-vue]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:

View File

@@ -50,7 +50,7 @@ jobs:
needs: [release-ionic]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
with:
token: ${{ secrets.IONITRON_TOKEN }}
fetch-depth: 0
@@ -69,45 +69,16 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
update-package-lock:
# This needs to run after finalize-release
# because we also push to the repo in that
# job. If these jobs ran in parallel then it is
# possible for them to push at the same time.
needs: [finalize-release]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Pull the latest version of the reference
# branch instead of the revision that triggered
# the workflow otherwise we won't get the commit
# created in the previous job and this next job
# will fail.
with:
ref: ${{ github.ref }}
- name: Configure Identity
# Commits from github-actions do not
# trigger other GitHub Actions. As a result,
# we push from Ionitron instead so actions
# run when merging the release branch
# back into main.
run: |
git config user.name ionitron
git config user.email hi@ionicframework.com
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"
git add .
git commit -m "chore(): update package lock files"
git push
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"
git add .
git commit -m "chore(): update package lock files"
git push
shell: bash
purge-cdn-cache:
needs: [release-ionic]

View File

@@ -8,12 +8,7 @@ on:
# at 6:00 UTC (6:00 am UTC)
- cron: '00 06 * * 1-5'
workflow_dispatch:
inputs:
npm_release_tag:
required: true
type: string
description: What version should be pulled from NPM?
default: nightly
# allows for manual invocations in the GitHub UI
# When pushing a new commit we should
# cancel the previous test run to not
@@ -26,33 +21,31 @@ jobs:
build-core-with-stencil-nightly:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-core-stencil-prerelease
with:
stencil-version: ${{ inputs.npm_release_tag || 'nightly' }}
stencil-version: nightly
test-core-clean-build:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-clean-build
test-core-lint:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-lint
test-core-spec:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-spec
with:
stencil-version: ${{ inputs.npm_release_tag || 'nightly' }}
test-core-screenshot:
strategy:
@@ -72,7 +65,7 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-screenshot
with:
shard: ${{ matrix.shard }}
@@ -100,14 +93,14 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-vue
build-vue-router:
needs: [build-vue]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-vue-router
test-vue-e2e:
@@ -118,7 +111,7 @@ jobs:
needs: [build-vue, build-vue-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-vue-e2e
with:
app: ${{ matrix.apps }}
@@ -136,25 +129,25 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-angular
build-angular-server:
needs: [build-core-with-stencil-nightly]
needs: [build-angular]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-angular-server
test-angular-e2e:
strategy:
fail-fast: false
matrix:
apps: [ng16, ng17]
apps: [ng12, ng13, ng14, ng15]
needs: [build-angular, build-angular-server]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-angular-e2e
with:
app: ${{ matrix.apps }}
@@ -172,14 +165,14 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-react
build-react-router:
needs: [build-react]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-react-router
test-react-router-e2e:
@@ -190,7 +183,7 @@ jobs:
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-react-router-e2e
with:
app: ${{ matrix.apps }}
@@ -212,7 +205,7 @@ jobs:
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-react-e2e
with:
app: ${{ matrix.apps }}

220
.github/workflows/stencil-v4.yml vendored Normal file
View File

@@ -0,0 +1,220 @@
# This workflow is intended to run against the `HEAD` of Stencil's primary branch.
# See https://github.com/ionic-team/stencil for contents of the repository
name: 'Stencil v4 Build'
on:
schedule:
# Run every Monday-Friday
# at 6:00 UTC (6:00 am UTC)
- cron: '00 06 * * 1-5'
workflow_dispatch:
# allows for manual invocations in the GitHub UI
# 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: false
jobs:
build-core-with-stencil-v4:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-core-stencil-prerelease
with:
stencil-version: v4-next
test-core-clean-build:
needs: [build-core-with-stencil-v4]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-clean-build
test-core-lint:
needs: [build-core-with-stencil-v4]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-lint
test-core-spec:
needs: [build-core-with-stencil-v4]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-spec
test-core-screenshot:
strategy:
# This ensures that all screenshot shard
# failures are reported so the dev can
# review everything at once.
fail-fast: false
matrix:
# Divide the tests into n buckets
# and run those buckets in parallel.
# To increase the number of shards,
# 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]
needs: [build-core-with-stencil-v4]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-screenshot
with:
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-with-stencil-v4]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-vue
build-vue-router:
needs: [build-vue]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- 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@v3
- 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-with-stencil-v4]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-angular
build-angular-server:
needs: [build-angular]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-angular-server
test-angular-e2e:
strategy:
fail-fast: false
matrix:
apps: [ng12, ng13, ng14, ng15]
needs: [build-angular, build-angular-server]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- 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-with-stencil-v4]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-react
build-react-router:
needs: [build-react]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-react-router
test-react-router-e2e:
strategy:
fail-fast: false
matrix:
apps: [reactrouter5]
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-react-router-e2e
with:
app: ${{ matrix.apps }}
verify-test-react-router-e2e:
if: ${{ always() }}
needs: test-react-router-e2e
runs-on: ubuntu-latest
steps:
- name: Check build matrix status
if: ${{ needs.test-react-router-e2e.result != 'success' }}
run: exit 1
test-react-e2e:
strategy:
fail-fast: false
matrix:
apps: [react17, react18]
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-react-e2e
with:
app: ${{ matrix.apps }}
verify-test-react-e2e:
if: ${{ always() }}
needs: test-react-e2e
runs-on: ubuntu-latest
steps:
- name: Check build matrix status
if: ${{ needs.test-react-e2e.result != 'success' }}
run: exit 1

View File

@@ -2,31 +2,12 @@ name: 'Update Reference Screenshots'
on:
workflow_dispatch:
inputs:
# Screenshots can be updated for all components or specified component(s).
# If the `component` variable is set, then the test has the option to
# - run all the instances of the specified component(s) in the `src/components` folder
# -- For example: if the `component` value is "item", then the following command will be: `npm run test.e2e item`
# - run the specified file path
# -- For example: if the `component` value is "src/components/item/test/basic", then the following command will be: `npm run test.e2e src/components/item/test/basic`
# - run multiple specified components based on the space-separated value
# -- For example: if the `component` value is "item basic", then the following command will be: `npm run test.e2e item basic`
# -- For example: if the `component` value is "src/components/item/test/basic src/components/item/test/a11y", then the following command will be: `npm run test.e2e src/components/item/test/basic src/components/item/test/a11y`
#
# If the `component` variable is not set, then the test will run all the instances of the components in the `src/components` folder.
# - For example: `npm run test.e2e`
#
# More common options can be found at the Playwright Command line page: https://playwright.dev/docs/test-cli
component:
description: 'What component(s) should be updated? (leave blank to update all or use a space-separated list for multiple components)'
required: false
default: ''
jobs:
build-core:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/build-core
test-core-screenshot:
@@ -47,19 +28,18 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: ./.github/workflows/actions/test-core-screenshot
with:
shard: ${{ matrix.shard }}
totalShards: ${{ matrix.totalShards }}
update: true
component: ${{ inputs.component }}
update-reference-screenshots:
runs-on: ubuntu-latest
needs: [test-core-screenshot]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
# Normally, we could just push with the
# default GITHUB_TOKEN, but that will
# not cause the build workflow

15
.gitignore vendored
View File

@@ -68,20 +68,11 @@ core/www/
# playwright
core/test-results/
core/playwright-report/
# ground truths generated outside of docker should not be committed to the repo
core/**/*-snapshots/*
# new ground truths should only be generated inside of docker which will result in -linux.png screenshots
!core/**/*-snapshots/*-linux.png
# these files are going to be different per-developer environment so do not add them to the repo
core/docker-display.txt
core/docker-display-volume.txt
core/**/*-snapshots
# angular
packages/angular/css/
packages/angular/test/build/
angular/css/
angular/test/build/
.angular/
# vue

View File

@@ -4,7 +4,7 @@
"enabled": false
},
"pullRequests": {
"enabled": false
"enabled": true
}
}
}

View File

@@ -3,700 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [7.8.1](https://github.com/ionic-team/ionic-framework/compare/v7.8.0...v7.8.1) (2024-03-20)
### Bug Fixes
* **datetime:** wheel picker shows consistently in overlays ([#29147](https://github.com/ionic-team/ionic-framework/issues/29147)) ([19c1bc1](https://github.com/ionic-team/ionic-framework/commit/19c1bc16cbc6725463890382365203824b7fd353)), closes [#26234](https://github.com/ionic-team/ionic-framework/issues/26234)
* **header:** iOS headers in MD app are not hidden ([#29164](https://github.com/ionic-team/ionic-framework/issues/29164)) ([fdfecd3](https://github.com/ionic-team/ionic-framework/commit/fdfecd32c33c41cf202d3b30c073bfb1b077e2d6)), closes [#28867](https://github.com/ionic-team/ionic-framework/issues/28867)
* **react:** avoid definitely typed errors with @types/react@18 ([#29182](https://github.com/ionic-team/ionic-framework/issues/29182)) ([58d217d](https://github.com/ionic-team/ionic-framework/commit/58d217d0cf6b716da855c71c169fb1870d4067d3)), closes [#29178](https://github.com/ionic-team/ionic-framework/issues/29178)
### Performance Improvements
* **datetime:** calendar body shows immediately in modal on ios ([#29163](https://github.com/ionic-team/ionic-framework/issues/29163)) ([f759776](https://github.com/ionic-team/ionic-framework/commit/f75977699dae5aeea3d97d4318377633e935afb9)), closes [#24542](https://github.com/ionic-team/ionic-framework/issues/24542)
# [7.8.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.5...v7.8.0) (2024-03-13)
### Features
* **datetime:** formatOptions property for Datetime ([#29065](https://github.com/ionic-team/ionic-framework/issues/29065)) ([7cdbc1b](https://github.com/ionic-team/ionic-framework/commit/7cdbc1b5ad004e17a7c51363653e0e67f50e6860))
* **searchbar:** autocapitalize, dir, lang, maxlength, and minlength are inherited to native input ([#29098](https://github.com/ionic-team/ionic-framework/issues/29098)) ([a0a77f7](https://github.com/ionic-team/ionic-framework/commit/a0a77f799df0732d9f7182f15866035a3ce5a1eb)), closes [#27606](https://github.com/ionic-team/ionic-framework/issues/27606)
## [7.7.5](https://github.com/ionic-team/ionic-framework/compare/v7.7.4...v7.7.5) (2024-03-13)
### Bug Fixes
* **angular:** add ionNavWillChange and ionNavDidChange types for nav ([#29122](https://github.com/ionic-team/ionic-framework/issues/29122)) ([85b9d5c](https://github.com/ionic-team/ionic-framework/commit/85b9d5c35f626ffc273d220549b0126ddc1f7e4b)), closes [#29114](https://github.com/ionic-team/ionic-framework/issues/29114)
* **checkbox:** set aria-checked of indeterminate checkbox to 'mixed' ([#29115](https://github.com/ionic-team/ionic-framework/issues/29115)) ([b2d636f](https://github.com/ionic-team/ionic-framework/commit/b2d636f14dcd33313f6604cfd4a64b542c831b34))
* **overlay:** do not hide overlay if toast is presented ([#29140](https://github.com/ionic-team/ionic-framework/issues/29140)) ([c0f5e5e](https://github.com/ionic-team/ionic-framework/commit/c0f5e5ebc0c9d45d71e10e09903b00b3ba8e6bba)), closes [#29139](https://github.com/ionic-team/ionic-framework/issues/29139)
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
### Bug Fixes
* **modal:** ariaLabel and role are inherited when set via htmlAttributes ([#29099](https://github.com/ionic-team/ionic-framework/issues/29099)) ([de13633](https://github.com/ionic-team/ionic-framework/commit/de13633a182d963876434db773aa346833f956fd))
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
### Bug Fixes
* **label:** do not grow when in end slot ([#29036](https://github.com/ionic-team/ionic-framework/issues/29036)) ([1fc4b76](https://github.com/ionic-team/ionic-framework/commit/1fc4b76f5940b38fd89e19561d6b4738dfb8ae5d)), closes [#29033](https://github.com/ionic-team/ionic-framework/issues/29033)
* **overlays:** focus is returned to last focus element when focusing toast ([#28950](https://github.com/ionic-team/ionic-framework/issues/28950)) ([2ed0ada](https://github.com/ionic-team/ionic-framework/commit/2ed0ada9237b3f4dbf5959746ce2d1744936eebe)), closes [#28261](https://github.com/ionic-team/ionic-framework/issues/28261)
## [7.7.2](https://github.com/ionic-team/ionic-framework/compare/v7.7.1...v7.7.2) (2024-02-14)
### Bug Fixes
* **overlays:** do not return focus if application has already moved focus manually ([#28850](https://github.com/ionic-team/ionic-framework/issues/28850)) ([a016670](https://github.com/ionic-team/ionic-framework/commit/a016670a8a46e101d23235b17bc8a2081fb992eb)), closes [#28849](https://github.com/ionic-team/ionic-framework/issues/28849)
* **overlays:** ensure that only topmost overlay is announced by screen readers ([#28997](https://github.com/ionic-team/ionic-framework/issues/28997)) ([ba4ba61](https://github.com/ionic-team/ionic-framework/commit/ba4ba6161c1a6c67f7804b07f49c64ac9ad2b14c)), closes [#23472](https://github.com/ionic-team/ionic-framework/issues/23472)
* **popover:** render arrow above backdrop ([#28986](https://github.com/ionic-team/ionic-framework/issues/28986)) ([0a8964d](https://github.com/ionic-team/ionic-framework/commit/0a8964d30c76218fe62f7f4aed4f81df7bb80cd0)), closes [#28985](https://github.com/ionic-team/ionic-framework/issues/28985)
## [7.7.1](https://github.com/ionic-team/ionic-framework/compare/v7.7.0...v7.7.1) (2024-02-07)
### Bug Fixes
* **action-sheet:** iOS dismiss animation respects safe area ([#28915](https://github.com/ionic-team/ionic-framework/issues/28915)) ([7449fb4](https://github.com/ionic-team/ionic-framework/commit/7449fb4fed4048f5d01ba068dc6f8e2d7727e95d)), closes [#28541](https://github.com/ionic-team/ionic-framework/issues/28541)
* **overlays:** tear down animations after dismiss ([#28907](https://github.com/ionic-team/ionic-framework/issues/28907)) ([950fa40](https://github.com/ionic-team/ionic-framework/commit/950fa40c5597c81d5cbaeb9276b09adfea5e79fb)), closes [#28352](https://github.com/ionic-team/ionic-framework/issues/28352)
* **react:** route with redirect will mount page ([#28961](https://github.com/ionic-team/ionic-framework/issues/28961)) ([5777ce2](https://github.com/ionic-team/ionic-framework/commit/5777ce258119d2715b1326cdc103bd4ad7612bd1)), closes [#28838](https://github.com/ionic-team/ionic-framework/issues/28838)
* **select:** popover can be scrolled ([#28965](https://github.com/ionic-team/ionic-framework/issues/28965)) ([35ab6b4](https://github.com/ionic-team/ionic-framework/commit/35ab6b4816bd627239de8d8b25ce0c86db8c74b4)), closes [#28963](https://github.com/ionic-team/ionic-framework/issues/28963)
# [7.7.0](https://github.com/ionic-team/ionic-framework/compare/v7.6.7...v7.7.0) (2024-01-31)
### Features
* add experimental hardware back button support in browsers ([#28705](https://github.com/ionic-team/ionic-framework/issues/28705)) ([658d1ca](https://github.com/ionic-team/ionic-framework/commit/658d1caccd530350843b85c0e24544ec27dd9eb4)), closes [#28703](https://github.com/ionic-team/ionic-framework/issues/28703)
## [7.6.7](https://github.com/ionic-team/ionic-framework/compare/v7.6.6...v7.6.7) (2024-01-31)
### Bug Fixes
* **accordion:** prevent opening of readonly accordion using keyboard ([#28865](https://github.com/ionic-team/ionic-framework/issues/28865)) ([e10f49c](https://github.com/ionic-team/ionic-framework/commit/e10f49c43daa11fe7deb5a9b9bfd34897542b6b1)), closes [#28344](https://github.com/ionic-team/ionic-framework/issues/28344)
* **action-sheet, alert, toast:** button roles autocomplete with available options ([#27940](https://github.com/ionic-team/ionic-framework/issues/27940)) ([f6fc22b](https://github.com/ionic-team/ionic-framework/commit/f6fc22bba60388701b80a9421510e3d843d39e9e)), closes [#27965](https://github.com/ionic-team/ionic-framework/issues/27965)
* **item:** ensure button focus state on property change ([#28892](https://github.com/ionic-team/ionic-framework/issues/28892)) ([bf7922c](https://github.com/ionic-team/ionic-framework/commit/bf7922c8b37b32dbf90650cb74a2e77bedf0c118)), closes [#28525](https://github.com/ionic-team/ionic-framework/issues/28525)
* **item:** only default slot content wraps ([#28773](https://github.com/ionic-team/ionic-framework/issues/28773)) ([9448783](https://github.com/ionic-team/ionic-framework/commit/9448783bb19b187f867054c86d215e3dc97952c1)), closes [#28769](https://github.com/ionic-team/ionic-framework/issues/28769)
## [7.6.6](https://github.com/ionic-team/ionic-framework/compare/v7.6.5...v7.6.6) (2024-01-24)
### Bug Fixes
* **alert:** remove border-right on ios stacked buttons ([#28821](https://github.com/ionic-team/ionic-framework/issues/28821)) ([ad65824](https://github.com/ionic-team/ionic-framework/commit/ad65824722da0eed90ef9e595b743754bfd360b8))
* **datetime:** do not animate to new value when multiple values in different months are set ([#28847](https://github.com/ionic-team/ionic-framework/issues/28847)) ([9262f7d](https://github.com/ionic-team/ionic-framework/commit/9262f7da15969706039e9d5f11ef5c7bd73ced0d)), closes [#28602](https://github.com/ionic-team/ionic-framework/issues/28602)
* **datetime:** enter closes keyboard when typing time ([#28848](https://github.com/ionic-team/ionic-framework/issues/28848)) ([c47a16d](https://github.com/ionic-team/ionic-framework/commit/c47a16d6c3c57f56b053727dd10ead0bfe547e50)), closes [#28325](https://github.com/ionic-team/ionic-framework/issues/28325)
* **menu:** improve reliability of main content not being scrollable when menu opens ([#28829](https://github.com/ionic-team/ionic-framework/issues/28829)) ([9603a4d](https://github.com/ionic-team/ionic-framework/commit/9603a4de363d2b42622ff3585cd6e4787d9581d1)), closes [#28399](https://github.com/ionic-team/ionic-framework/issues/28399)
* **popover:** content inside of popover scrolls correctly ([#28861](https://github.com/ionic-team/ionic-framework/issues/28861)) ([10c38d0](https://github.com/ionic-team/ionic-framework/commit/10c38d0354e61e20bec9a313de84b22c3b85c323)), closes [#28455](https://github.com/ionic-team/ionic-framework/issues/28455)
* **segment:** setting value via binding updates button state ([#28837](https://github.com/ionic-team/ionic-framework/issues/28837)) ([0847c2a](https://github.com/ionic-team/ionic-framework/commit/0847c2ac2c52b5fa6d30e381685d6cbf7a41231a)), closes [#28816](https://github.com/ionic-team/ionic-framework/issues/28816)
* **select:** click handlers on slotted content fire ([#28839](https://github.com/ionic-team/ionic-framework/issues/28839)) ([aed7a03](https://github.com/ionic-team/ionic-framework/commit/aed7a03532b88628a4358c8cbae1a1cbb861462b)), closes [#28818](https://github.com/ionic-team/ionic-framework/issues/28818)
* **vue:** tabs and parameterized routes work with latest vue ([#28846](https://github.com/ionic-team/ionic-framework/issues/28846)) ([5bc4399](https://github.com/ionic-team/ionic-framework/commit/5bc439961fda2c595666e67688fdd1b8ff4dd0bf)), closes [#28774](https://github.com/ionic-team/ionic-framework/issues/28774)
## [7.6.5](https://github.com/ionic-team/ionic-framework/compare/v7.6.4...v7.6.5) (2024-01-17)
### Bug Fixes
* **angular:** add old IonBackButtonDelegate import ([#28831](https://github.com/ionic-team/ionic-framework/issues/28831)) ([fb77353](https://github.com/ionic-team/ionic-framework/commit/fb7735397ed53323dd93a172407117228610b929)), closes [#28827](https://github.com/ionic-team/ionic-framework/issues/28827)
* **list:** remove uneeded border radius from items in inset list ([#28830](https://github.com/ionic-team/ionic-framework/issues/28830)) ([dbaaa5b](https://github.com/ionic-team/ionic-framework/commit/dbaaa5bd9f43b8ba589b3f9c4b4204d2f203ef18))
## [7.6.4](https://github.com/ionic-team/ionic-framework/compare/v7.6.3...v7.6.4) (2024-01-10)
### Bug Fixes
* **input:** slotted buttons are clickable ([#28772](https://github.com/ionic-team/ionic-framework/issues/28772)) ([4ccc150](https://github.com/ionic-team/ionic-framework/commit/4ccc150edff4e3f33f453343aedb081d920b2f90)), closes [#28762](https://github.com/ionic-team/ionic-framework/issues/28762)
## [7.6.3](https://github.com/ionic-team/ionic-framework/compare/v7.6.2...v7.6.3) (2024-01-03)
### Bug Fixes
* **datetime:** selected today button renders correctly on ios ([#28740](https://github.com/ionic-team/ionic-framework/issues/28740)) ([2f99aea](https://github.com/ionic-team/ionic-framework/commit/2f99aeae6f71d5ffd1880f2c549227ecf71becf3))
* **nav, router-outlet:** ios page transition does not cover menu on larger screens ([#28745](https://github.com/ionic-team/ionic-framework/issues/28745)) ([878eec6](https://github.com/ionic-team/ionic-framework/commit/878eec6ea21d76586466d01e13e5e842e69eaceb)), closes [#28737](https://github.com/ionic-team/ionic-framework/issues/28737)
* **radio-group:** radio disabled prop can be undefined ([#28712](https://github.com/ionic-team/ionic-framework/issues/28712)) ([75ffeee](https://github.com/ionic-team/ionic-framework/commit/75ffeee933ae353d2601670178896116c81923e0)), closes [#28677](https://github.com/ionic-team/ionic-framework/issues/28677)
* **refresher:** native ios refresher works on iPadOS ([#28620](https://github.com/ionic-team/ionic-framework/issues/28620)) ([e522601](https://github.com/ionic-team/ionic-framework/commit/e5226016a0f0b066a7bd7fc9997f905d3b87fbc4)), closes [#28617](https://github.com/ionic-team/ionic-framework/issues/28617)
## [7.6.2](https://github.com/ionic-team/ionic-framework/compare/v7.6.1...v7.6.2) (2023-12-19)
### Bug Fixes
* **input, textarea, select:** reduce padding on slotted buttons ([#28676](https://github.com/ionic-team/ionic-framework/issues/28676)) ([516b844](https://github.com/ionic-team/ionic-framework/commit/516b84475e5d78060f35fa2c4821efc712536353))
* **item:** label does not expand indefinitely ([#28700](https://github.com/ionic-team/ionic-framework/issues/28700)) ([bc51dd0](https://github.com/ionic-team/ionic-framework/commit/bc51dd05cf036656980de584d2367db46054f774))
* **refresher:** mode property can be used in typescript ([#28717](https://github.com/ionic-team/ionic-framework/issues/28717)) ([7ce1031](https://github.com/ionic-team/ionic-framework/commit/7ce1031c177487649c2a698664ec98f10d9002b9)), closes [#28716](https://github.com/ionic-team/ionic-framework/issues/28716)
## [7.6.1](https://github.com/ionic-team/ionic-framework/compare/v7.6.0...v7.6.1) (2023-12-13)
### Bug Fixes
* **datetime:** prefer wheel sets working value on confirmation ([#28520](https://github.com/ionic-team/ionic-framework/issues/28520)) ([e886e3f](https://github.com/ionic-team/ionic-framework/commit/e886e3ff2fcb8a3586a62881c5fc848f3074235d)), closes [#25839](https://github.com/ionic-team/ionic-framework/issues/25839)
* **input, textarea:** clearOnInput ignores key modifiers ([#28639](https://github.com/ionic-team/ionic-framework/issues/28639)) ([8f7d87c](https://github.com/ionic-team/ionic-framework/commit/8f7d87c6803b1600a3ca21785df0e9bac49f74a3)), closes [#28633](https://github.com/ionic-team/ionic-framework/issues/28633)
* **menu:** allow styling of the box shadow and transform when visible inside of a split pane ([#28691](https://github.com/ionic-team/ionic-framework/issues/28691)) ([8ee23d2](https://github.com/ionic-team/ionic-framework/commit/8ee23d20d5cc7419ce15f047b92d2f826d3eb681)), closes [#21530](https://github.com/ionic-team/ionic-framework/issues/21530)
* **react:** avoid type collision with @types/react@18.2.43 and greater ([#28687](https://github.com/ionic-team/ionic-framework/issues/28687)) ([92f1b86](https://github.com/ionic-team/ionic-framework/commit/92f1b8627a240c93891205f75adcb5ce3d46596d))
* **react:** replacing route uses new route direction and animation ([#28671](https://github.com/ionic-team/ionic-framework/issues/28671)) ([a17b963](https://github.com/ionic-team/ionic-framework/commit/a17b9631829c36c2daf1d5227f5afa69f99f8743)), closes [#24260](https://github.com/ionic-team/ionic-framework/issues/24260)
* **react:** use custom animation when going back after a replace ([#28674](https://github.com/ionic-team/ionic-framework/issues/28674)) ([fc88613](https://github.com/ionic-team/ionic-framework/commit/fc88613fefa019a3b695a2c6e10c85cd3ce79ae8)), closes [#28673](https://github.com/ionic-team/ionic-framework/issues/28673)
# [7.6.0](https://github.com/ionic-team/ionic-framework/compare/v7.5.8...v7.6.0) (2023-12-06)
### Bug Fixes
* **angular,vue:** range form value updates while dragging knob ([#28422](https://github.com/ionic-team/ionic-framework/issues/28422)) ([0854a11](https://github.com/ionic-team/ionic-framework/commit/0854a11a25759d0201eae66c96a62fe138d486f8)), closes [#28256](https://github.com/ionic-team/ionic-framework/issues/28256)
* **animation:** add stronger types to Animation interface ([#28334](https://github.com/ionic-team/ionic-framework/issues/28334)) ([4a088d5](https://github.com/ionic-team/ionic-framework/commit/4a088d5d612ab0387064d388b37d46cdf15cf1ff))
* **animation:** progressEnd coercion is reset before onFinish ([#28394](https://github.com/ionic-team/ionic-framework/issues/28394)) ([eae8162](https://github.com/ionic-team/ionic-framework/commit/eae8162d0dc2e0bd7a9d56a3662a8e5f5d142b72)), closes [#28393](https://github.com/ionic-team/ionic-framework/issues/28393)
* **infinite-scroll:** remaining in threshold after ionInfinite can trigger event again on scroll ([#28569](https://github.com/ionic-team/ionic-framework/issues/28569)) ([8c235fd](https://github.com/ionic-team/ionic-framework/commit/8c235fd30c50f317de1f37f69068507aa0979068)), closes [#18071](https://github.com/ionic-team/ionic-framework/issues/18071)
* **item:** allow item to grow when it is used in a flex container ([#28594](https://github.com/ionic-team/ionic-framework/issues/28594)) ([1c1b567](https://github.com/ionic-team/ionic-framework/commit/1c1b567279dee44da70bb9b90c129946c9043987))
* **item:** wrap elements and label contents when the font size increases or the elements do not fit ([#28146](https://github.com/ionic-team/ionic-framework/issues/28146)) ([6438e3e](https://github.com/ionic-team/ionic-framework/commit/6438e3e919c665569b731a2d74fe1547b4f3c1cc))
* **select:** do not collapse to width: 0 when placed in flex container ([#28631](https://github.com/ionic-team/ionic-framework/issues/28631)) ([e71e7a0](https://github.com/ionic-team/ionic-framework/commit/e71e7a069000db8738abc304758de64286817442))
* **toast:** add swipeGesture to ToastOptions ([#28518](https://github.com/ionic-team/ionic-framework/issues/28518)) ([4ad6df6](https://github.com/ionic-team/ionic-framework/commit/4ad6df67f01cebce30d4da46c7541c4b14c5d4a4))
### Features
* **checkbox:** add shadow part for label ([#28604](https://github.com/ionic-team/ionic-framework/issues/28604)) ([f9f5654](https://github.com/ionic-team/ionic-framework/commit/f9f5654ab0e920bf97089fbabfb9eedbcf6fe8ae)), closes [#28300](https://github.com/ionic-team/ionic-framework/issues/28300)
* **input, textarea, select:** add start and end slots ([#28583](https://github.com/ionic-team/ionic-framework/issues/28583)) ([357b8b2](https://github.com/ionic-team/ionic-framework/commit/357b8b2beb29b95d53ef043af349067be1d32658)), closes [#26297](https://github.com/ionic-team/ionic-framework/issues/26297)
* **radio-group:** add compareWith property ([#28452](https://github.com/ionic-team/ionic-framework/issues/28452)) ([0ae327f](https://github.com/ionic-team/ionic-framework/commit/0ae327f0e09cd97d705f2d3051c215034381e226))
* **radio:** add shadow part for label ([#28607](https://github.com/ionic-team/ionic-framework/issues/28607)) ([b757970](https://github.com/ionic-team/ionic-framework/commit/b757970d23e87c59aa883ecb1bfa9b66bcae8de2)), closes [#28300](https://github.com/ionic-team/ionic-framework/issues/28300)
* **range:** expose label wrapper as shadow part ([#28601](https://github.com/ionic-team/ionic-framework/issues/28601)) ([52ed2bf](https://github.com/ionic-team/ionic-framework/commit/52ed2bf63777c764f57bb4c3a5d4a127bff46c50))
* **toast:** add swipe to dismiss functionality ([#28442](https://github.com/ionic-team/ionic-framework/issues/28442)) ([30c21aa](https://github.com/ionic-team/ionic-framework/commit/30c21aab3ed40d73c28e7d60d0952d8891b0a9d3)), closes [#21769](https://github.com/ionic-team/ionic-framework/issues/21769)
* **toggle:** expose label wrapper as shadow part ([#28585](https://github.com/ionic-team/ionic-framework/issues/28585)) ([a34188f](https://github.com/ionic-team/ionic-framework/commit/a34188f7dbec4a16e4f2043ed3dc096e337725a7))
Note: Text inside of `ion-item` can now wrap to resolve accessibility issues related to readability. We recommend evaluating your application to account for text wrapping.
## [7.5.8](https://github.com/ionic-team/ionic-framework/compare/v7.5.7...v7.5.8) (2023-12-06)
### Bug Fixes
* **angular:** add missing menu controller methods ([#28618](https://github.com/ionic-team/ionic-framework/issues/28618)) ([7871b56](https://github.com/ionic-team/ionic-framework/commit/7871b56eccfe63326b6dd4b56ade3b3afd444fce)), closes [#20053](https://github.com/ionic-team/ionic-framework/issues/20053)
* **overlays:** trigger is configured on load ([#28526](https://github.com/ionic-team/ionic-framework/issues/28526)) ([a3cd204](https://github.com/ionic-team/ionic-framework/commit/a3cd204f616606ccffc35082655e55fdfb19fe28)), closes [#28524](https://github.com/ionic-team/ionic-framework/issues/28524)
* **react:** router creates new view instances of parameterized routes ([#28616](https://github.com/ionic-team/ionic-framework/issues/28616)) ([1705d06](https://github.com/ionic-team/ionic-framework/commit/1705d064cc041e99f432a27207f3aab7fa62c778)), closes [#26524](https://github.com/ionic-team/ionic-framework/issues/26524)
* **vue:** nav component accepts kebab-case component properties ([#28615](https://github.com/ionic-team/ionic-framework/issues/28615)) ([60303aa](https://github.com/ionic-team/ionic-framework/commit/60303aad23f823488afc8f8824e9c72e3ab86acc)), closes [#28611](https://github.com/ionic-team/ionic-framework/issues/28611)
## [7.5.7](https://github.com/ionic-team/ionic-framework/compare/v7.5.6...v7.5.7) (2023-11-29)
### Bug Fixes
* **alert:** date inputs render correctly in mobile safari ([#28495](https://github.com/ionic-team/ionic-framework/issues/28495)) ([b833f0e](https://github.com/ionic-team/ionic-framework/commit/b833f0e826ddd261230e2e29b70e2dc884d8cb04)), closes [#28494](https://github.com/ionic-team/ionic-framework/issues/28494)
* **datetime:** allow disabling datetime with prefer-wheel ([#28511](https://github.com/ionic-team/ionic-framework/issues/28511)) ([01130e1](https://github.com/ionic-team/ionic-framework/commit/01130e12e1d73bbf558da9d4dffd7122822ff39c))
## [7.5.6](https://github.com/ionic-team/ionic-framework/compare/v7.5.5...v7.5.6) (2023-11-21)
### Bug Fixes
* **alert:** match MD spec on tablet ([#28501](https://github.com/ionic-team/ionic-framework/issues/28501)) ([6a2be9f](https://github.com/ionic-team/ionic-framework/commit/6a2be9fa3c12a893d98dc139a1575a6e7e3c7c26)), closes [#23977](https://github.com/ionic-team/ionic-framework/issues/23977)
* **angular:** ng add @ionic/angular in standalone projects ([#28523](https://github.com/ionic-team/ionic-framework/issues/28523)) ([c07312e](https://github.com/ionic-team/ionic-framework/commit/c07312e5ed931f6f825ccf083c9dead9fa815843)), closes [#28514](https://github.com/ionic-team/ionic-framework/issues/28514)
* **angular:** overlays are defined when using standalone controllers ([#28560](https://github.com/ionic-team/ionic-framework/issues/28560)) ([9453132](https://github.com/ionic-team/ionic-framework/commit/9453132aa8952b4adfa1326e61138b329e254f76)), closes [#28385](https://github.com/ionic-team/ionic-framework/issues/28385)
* **datetime:** updating value with min scrolls to new value ([#28549](https://github.com/ionic-team/ionic-framework/issues/28549)) ([388d19e](https://github.com/ionic-team/ionic-framework/commit/388d19e04f83f85abd4602adb04cc71ac575764a)), closes [#28548](https://github.com/ionic-team/ionic-framework/issues/28548)
## [7.5.5](https://github.com/ionic-team/ionic-framework/compare/v7.5.4...v7.5.5) (2023-11-15)
### Bug Fixes
* **accordion-group:** correct accordion is open on load ([#28510](https://github.com/ionic-team/ionic-framework/issues/28510)) ([a000dd2](https://github.com/ionic-team/ionic-framework/commit/a000dd2c0b65be8ab5b2ad19f2748fbca13d5085)), closes [#28506](https://github.com/ionic-team/ionic-framework/issues/28506)
* **action-sheet:** adjust height for safe area with scrollable options ([#28504](https://github.com/ionic-team/ionic-framework/issues/28504)) ([900267e](https://github.com/ionic-team/ionic-framework/commit/900267eb36c36f2af63435f6b46acca52b3bdab7)), closes [#27777](https://github.com/ionic-team/ionic-framework/issues/27777)
* **header:** collapsible large title does not flicker when collapse prop not reflected ([#28472](https://github.com/ionic-team/ionic-framework/issues/28472)) ([8227b0e](https://github.com/ionic-team/ionic-framework/commit/8227b0ee6d5250e122a34a83c644f8a74fbbafd5)), closes [#28466](https://github.com/ionic-team/ionic-framework/issues/28466)
* **item-divider:** apply safe area to proper side regardless of direction ([#28420](https://github.com/ionic-team/ionic-framework/issues/28420)) ([4513e0c](https://github.com/ionic-team/ionic-framework/commit/4513e0c6b066d4990800c707e1d97f69c8fcfb0c))
* **radio-group:** emit value change on componentDidLoad ([#28488](https://github.com/ionic-team/ionic-framework/issues/28488)) ([73b8bfd](https://github.com/ionic-team/ionic-framework/commit/73b8bfde3f060490958c10f58d0f68de80cb957f)), closes [#28356](https://github.com/ionic-team/ionic-framework/issues/28356)
* **searchbar:** cancel icon aligns with back button ([#28478](https://github.com/ionic-team/ionic-framework/issues/28478)) ([c053fd9](https://github.com/ionic-team/ionic-framework/commit/c053fd9c68d9b1add1335db80be962215946a0b1)), closes [#28468](https://github.com/ionic-team/ionic-framework/issues/28468)
## [7.5.4](https://github.com/ionic-team/ionic-framework/compare/v7.5.3...v7.5.4) (2023-11-08)
### Bug Fixes
* **inputs:** remove invalid legacy warnings in input, textarea, and select ([#28484](https://github.com/ionic-team/ionic-framework/issues/28484)) ([c765dcb](https://github.com/ionic-team/ionic-framework/commit/c765dcbac4148762768d8c2bea9103e7d38c510b))
* **item:** apply safe area to proper side regardless of direction ([#28403](https://github.com/ionic-team/ionic-framework/issues/28403)) ([ed040b0](https://github.com/ionic-team/ionic-framework/commit/ed040b09e9cbd4246864e690542132defc6a6578))
* **list:** remove border from last item with item-sliding ([#28439](https://github.com/ionic-team/ionic-framework/issues/28439)) ([cafafcc](https://github.com/ionic-team/ionic-framework/commit/cafafcc9d166ef536dcb73edd522c8f2a0fb95b6)), closes [#28435](https://github.com/ionic-team/ionic-framework/issues/28435)
## [7.5.3](https://github.com/ionic-team/ionic-framework/compare/v7.5.2...v7.5.3) (2023-11-01)
### Bug Fixes
* **alert:** long words wrap to next line ([#28408](https://github.com/ionic-team/ionic-framework/issues/28408)) ([34257d6](https://github.com/ionic-team/ionic-framework/commit/34257d681e9034b0a001aa45e17222f3aab5ed76)), closes [#28406](https://github.com/ionic-team/ionic-framework/issues/28406)
* **angular:** inputs on standalone form controls are reactive ([#28434](https://github.com/ionic-team/ionic-framework/issues/28434)) ([3b6e631](https://github.com/ionic-team/ionic-framework/commit/3b6e6318bf94125b3f8305b4d072a5945ceb3730)), closes [#28431](https://github.com/ionic-team/ionic-framework/issues/28431)
* **angular:** NavController works with nested outlets ([#28421](https://github.com/ionic-team/ionic-framework/issues/28421)) ([90acad1](https://github.com/ionic-team/ionic-framework/commit/90acad1837b117542830ec0083389a35c5b4ee76)), closes [#28417](https://github.com/ionic-team/ionic-framework/issues/28417)
* **angular:** run platform subscriptions inside zone ([#28404](https://github.com/ionic-team/ionic-framework/issues/28404)) ([a4b303e](https://github.com/ionic-team/ionic-framework/commit/a4b303e1338a35756a9cf7f67508d24d2f8537a2)), closes [#19539](https://github.com/ionic-team/ionic-framework/issues/19539)
* **angular:** standalone form components do not error when multiple are used ([#28423](https://github.com/ionic-team/ionic-framework/issues/28423)) ([89698b3](https://github.com/ionic-team/ionic-framework/commit/89698b338fb05cde427c98720c238d2365abdaa7)), closes [#28418](https://github.com/ionic-team/ionic-framework/issues/28418)
* **datetime:** allow calendar navigation in readonly mode; disallow keyboard navigation when disabled ([#28336](https://github.com/ionic-team/ionic-framework/issues/28336)) ([f6a6877](https://github.com/ionic-team/ionic-framework/commit/f6a6877044a6d912a92aab00c3c78897da09415d)), closes [#28121](https://github.com/ionic-team/ionic-framework/issues/28121)
* **input, textarea, select:** use consistent sizes ([#28390](https://github.com/ionic-team/ionic-framework/issues/28390)) ([b31ecbb](https://github.com/ionic-team/ionic-framework/commit/b31ecbbfe8deb87604686d752e92e672dd9b277a)), closes [#28388](https://github.com/ionic-team/ionic-framework/issues/28388)
* **list-header:** apply safe area to proper side regardless of direction ([#28371](https://github.com/ionic-team/ionic-framework/issues/28371)) ([f99d530](https://github.com/ionic-team/ionic-framework/commit/f99d5305fb4b1607b42e34a0b7653d8e1b5bf23f))
* **segment:** avoid scrolling webkit bug ([#28376](https://github.com/ionic-team/ionic-framework/issues/28376)) ([8e2f818](https://github.com/ionic-team/ionic-framework/commit/8e2f81867175e9980e6d072b0a4414baae571223)), closes [#28373](https://github.com/ionic-team/ionic-framework/issues/28373)
* **tab-bar:** apply safe area to proper side regardless of direction ([#28372](https://github.com/ionic-team/ionic-framework/issues/28372)) ([d47b7e7](https://github.com/ionic-team/ionic-framework/commit/d47b7e750310ceb2f2c7ecfda8343923ff8d564a))
## [7.5.2](https://github.com/ionic-team/ionic-framework/compare/v7.5.1...v7.5.2) (2023-10-25)
### Bug Fixes
* **alert, action-sheet:** show scrollbar for long list of options ([#28369](https://github.com/ionic-team/ionic-framework/issues/28369)) ([60f3d65](https://github.com/ionic-team/ionic-framework/commit/60f3d6579498ebad75c4f5163fca3947ac2dadff)), closes [#18487](https://github.com/ionic-team/ionic-framework/issues/18487)
* **angular:** remove form control side effects ([#28359](https://github.com/ionic-team/ionic-framework/issues/28359)) ([82d6309](https://github.com/ionic-team/ionic-framework/commit/82d6309ef1675c0a6e767e87c23f166d84579d8f)), closes [#28358](https://github.com/ionic-team/ionic-framework/issues/28358)
* **fab:** apply safe area in positioning to proper side regardless of direction ([#28377](https://github.com/ionic-team/ionic-framework/issues/28377)) ([331c08a](https://github.com/ionic-team/ionic-framework/commit/331c08aad542de158e53ed351705d4c396bb4e90))
* **input, searchbar, textarea:** ensure nativeInput is always available ([#28362](https://github.com/ionic-team/ionic-framework/issues/28362)) ([2b015b2](https://github.com/ionic-team/ionic-framework/commit/2b015b22144e306444f2bf30ace0b5cc7e32a710)), closes [#28283](https://github.com/ionic-team/ionic-framework/issues/28283)
* **menu:** menu no longer disappears with multiple split panes ([#28370](https://github.com/ionic-team/ionic-framework/issues/28370)) ([5a30082](https://github.com/ionic-team/ionic-framework/commit/5a30082546cb19eb98128ca9091b35094841d4f2)), closes [#18683](https://github.com/ionic-team/ionic-framework/issues/18683) [#15538](https://github.com/ionic-team/ionic-framework/issues/15538) [#22341](https://github.com/ionic-team/ionic-framework/issues/22341)
* **rtl:** allow :host to use rtl() ([#28353](https://github.com/ionic-team/ionic-framework/issues/28353)) ([6b7d288](https://github.com/ionic-team/ionic-framework/commit/6b7d288536307fcb49231dca66ab938b389ea85e))
## [7.5.1](https://github.com/ionic-team/ionic-framework/compare/v7.5.0...v7.5.1) (2023-10-18)
### Bug Fixes
* **angular:** do not create duplicate menuController instances ([#28343](https://github.com/ionic-team/ionic-framework/issues/28343)) ([fa78676](https://github.com/ionic-team/ionic-framework/commit/fa78676d57eb80655ee9447ffa07dcfdae0c6b2a)), closes [#28337](https://github.com/ionic-team/ionic-framework/issues/28337)
* **angular:** export missing lifecycle interfaces for standalone package ([#28346](https://github.com/ionic-team/ionic-framework/issues/28346)) ([dd93e0b](https://github.com/ionic-team/ionic-framework/commit/dd93e0b2689511f3145606f4dbb2c30dcf4c2950)), closes [/github.com/ionic-team/ionic-angular-standalone-codemods/pull/13/files/baa37ef1e3e8ba773b693db280542efba815482a#r1356414362](https://github.com//github.com/ionic-team/ionic-angular-standalone-codemods/pull/13/files/baa37ef1e3e8ba773b693db280542efba815482a/issues/r1356414362)
* **react:** cleanup functions are execute for lifecycle hooks ([#28319](https://github.com/ionic-team/ionic-framework/issues/28319)) ([1ba9973](https://github.com/ionic-team/ionic-framework/commit/1ba9973857503c6e47cb225b77a5b89e0a9d2718)), closes [#28186](https://github.com/ionic-team/ionic-framework/issues/28186)
* **react:** lifecycle events are removed on page unmount ([#28316](https://github.com/ionic-team/ionic-framework/issues/28316)) ([f14a59c](https://github.com/ionic-team/ionic-framework/commit/f14a59c5e0670ed7cc9ce1a73a087a5af13266e2))
* **title:** large title transition supports dynamic font scaling ([#28290](https://github.com/ionic-team/ionic-framework/issues/28290)) ([fe47594](https://github.com/ionic-team/ionic-framework/commit/fe47594dc0bbb047f0bade144cf07b084fbeef5e)), closes [#28351](https://github.com/ionic-team/ionic-framework/issues/28351)
# [7.5.0](https://github.com/ionic-team/ionic-framework/compare/v7.4.4...v7.5.0) (2023-10-11)
### Bug Fixes
* **alert:** stop Enter keypress for checkboxes ([#28279](https://github.com/ionic-team/ionic-framework/issues/28279)) ([72b3899](https://github.com/ionic-team/ionic-framework/commit/72b389993df4b0dc392262a106d7949e176b13af))
* **select:** use correct aria-haspopup value ([#28265](https://github.com/ionic-team/ionic-framework/issues/28265)) ([01167fc](https://github.com/ionic-team/ionic-framework/commit/01167fc185db9bbb45b3a4086aff98008a76af2c))
* **toast:** toast does not warn when positionAnchor is undefined ([#28312](https://github.com/ionic-team/ionic-framework/issues/28312)) ([c37b3d8](https://github.com/ionic-team/ionic-framework/commit/c37b3d8bf4b440506fdc96455a532c6316e5673d))
### Features
* **a11y:** add dynamic font scaling ([#28314](https://github.com/ionic-team/ionic-framework/issues/28314)) ([f806781](https://github.com/ionic-team/ionic-framework/commit/f8067819eeb577db163bf3e0f95fc73064d62b8a)), closes [#24638](https://github.com/ionic-team/ionic-framework/issues/24638) [#18592](https://github.com/ionic-team/ionic-framework/issues/18592)
* **angular, react, vue, core:** export openURL utility ([#28295](https://github.com/ionic-team/ionic-framework/issues/28295)) ([6da82aa](https://github.com/ionic-team/ionic-framework/commit/6da82aab816b28bfc174f7634ded1fc1e06502ab)), closes [#27911](https://github.com/ionic-team/ionic-framework/issues/27911)
* **angular:** ship Ionic components as Angular standalone components ([#28311](https://github.com/ionic-team/ionic-framework/issues/28311)) ([57e2476](https://github.com/ionic-team/ionic-framework/commit/57e247637005b10f0d21d5ac5f5232bcb1908301))
* **datetime:** add support for h11 and h24 hour formats ([#28219](https://github.com/ionic-team/ionic-framework/issues/28219)) ([597bc3f](https://github.com/ionic-team/ionic-framework/commit/597bc3f085c5ff1451c73d0cf4d7d664943e712f)), closes [#23750](https://github.com/ionic-team/ionic-framework/issues/23750)
* **toast:** allow custom positioning relative to specific element ([#28248](https://github.com/ionic-team/ionic-framework/issues/28248)) ([897ff6f](https://github.com/ionic-team/ionic-framework/commit/897ff6f7493d8d7e4ab22c6ae59de066b43ce682)), closes [#17499](https://github.com/ionic-team/ionic-framework/issues/17499)
## [7.4.4](https://github.com/ionic-team/ionic-framework/compare/v7.4.3...v7.4.4) (2023-10-11)
### Bug Fixes
* **animation:** play method resolves when animation is stopped ([#28264](https://github.com/ionic-team/ionic-framework/issues/28264)) ([e6031fb](https://github.com/ionic-team/ionic-framework/commit/e6031fbef0698dac0a346cd6202c47f2abf54f95))
* **checkbox, radio, toggle:** disabled elements are not interactive ([#28294](https://github.com/ionic-team/ionic-framework/issues/28294)) ([c70432e](https://github.com/ionic-team/ionic-framework/commit/c70432e6934bcf1d570e1f7cf671c52d2bb52a8b)), closes [#28293](https://github.com/ionic-team/ionic-framework/issues/28293)
* **content:** fullscreen offset is computed correctly with tab bar ([#28245](https://github.com/ionic-team/ionic-framework/issues/28245)) ([7375dd6](https://github.com/ionic-team/ionic-framework/commit/7375dd6abafdf7457f23deb53ad5f016456a6af2)), closes [#21130](https://github.com/ionic-team/ionic-framework/issues/21130)
* **core:** allow fullscreen scroll content to flow outside container for translucent tab bar ([#28246](https://github.com/ionic-team/ionic-framework/issues/28246)) ([b297529](https://github.com/ionic-team/ionic-framework/commit/b297529afc4b93a93f7eaecd31dd5a88a3de5f4e)), closes [#17676](https://github.com/ionic-team/ionic-framework/issues/17676)
* **core:** swipe to go back gesture has priority over other horizontal swipe gestures ([#28304](https://github.com/ionic-team/ionic-framework/issues/28304)) ([d5f0c77](https://github.com/ionic-team/ionic-framework/commit/d5f0c776dfb5cb40b8119c596805dad3adb621e0)), closes [#28303](https://github.com/ionic-team/ionic-framework/issues/28303)
* **header:** collapsible large title main header does not flicker on load ([#28277](https://github.com/ionic-team/ionic-framework/issues/28277)) ([3259da0](https://github.com/ionic-team/ionic-framework/commit/3259da0de181c8f82c38d9de13733213c77d398f)), closes [#27060](https://github.com/ionic-team/ionic-framework/issues/27060)
* **menu:** do not error if disabled or swipeGesture is changed mid-animation ([#28268](https://github.com/ionic-team/ionic-framework/issues/28268)) ([a169044](https://github.com/ionic-team/ionic-framework/commit/a1690441e5bcee8176da32700de6f9e3fde9635e)), closes [#20092](https://github.com/ionic-team/ionic-framework/issues/20092) [#19676](https://github.com/ionic-team/ionic-framework/issues/19676) [#19000](https://github.com/ionic-team/ionic-framework/issues/19000)
* **segment:** scroll to active segment-button on first load ([#28276](https://github.com/ionic-team/ionic-framework/issues/28276)) ([1167a93](https://github.com/ionic-team/ionic-framework/commit/1167a9325fb930b6c727bc26889f5488d9620062)), closes [#28096](https://github.com/ionic-team/ionic-framework/issues/28096)
## [7.4.3](https://github.com/ionic-team/ionic-framework/compare/v7.4.2...v7.4.3) (2023-10-04)
### Bug Fixes
* **fab-button:** position is correct with custom sizes ([#28195](https://github.com/ionic-team/ionic-framework/issues/28195)) ([eb41b55](https://github.com/ionic-team/ionic-framework/commit/eb41b556b57c97139b9c36dc3e3be3711d8afaca)), closes [#22564](https://github.com/ionic-team/ionic-framework/issues/22564)
* **range:** knob positions are correct on initial render with custom elements build ([#28257](https://github.com/ionic-team/ionic-framework/issues/28257)) ([ac2c8e6](https://github.com/ionic-team/ionic-framework/commit/ac2c8e6c22da4d0d8224def24ddef56ee9d26246)), closes [#25444](https://github.com/ionic-team/ionic-framework/issues/25444)
## [7.4.2](https://github.com/ionic-team/ionic-framework/compare/v7.4.1...v7.4.2) (2023-09-27)
### Bug Fixes
* **react:** Nav unmounts component while invoking popTo or popToRoot ([#27821](https://github.com/ionic-team/ionic-framework/issues/27821)) ([0edcb2c](https://github.com/ionic-team/ionic-framework/commit/0edcb2cd85133ae8c304c53c37ca829e5fbad447)), closes [#27798](https://github.com/ionic-team/ionic-framework/issues/27798)
* **title:** large title uses custom font on transition ([#28231](https://github.com/ionic-team/ionic-framework/issues/28231)) ([71a7af0](https://github.com/ionic-team/ionic-framework/commit/71a7af0f52fe62937b1dea1ca2739e78801a2a6d))
## [7.4.1](https://github.com/ionic-team/ionic-framework/compare/v7.4.0...v7.4.1) (2023-09-20)
### Bug Fixes
* **overlays:** correctly re-add root to accessibility tree ([#28183](https://github.com/ionic-team/ionic-framework/issues/28183)) ([81714d4](https://github.com/ionic-team/ionic-framework/commit/81714d45bd97f0ba91729959b60a0dc1d1d06533)), closes [#28180](https://github.com/ionic-team/ionic-framework/issues/28180)
* **radio,toggle,checkbox,select:** padded space is clickable in items ([#28136](https://github.com/ionic-team/ionic-framework/issues/28136)) ([5b7e422](https://github.com/ionic-team/ionic-framework/commit/5b7e422dc0bfd4d58fb31f62715af47e62dabb57)), closes [#27169](https://github.com/ionic-team/ionic-framework/issues/27169)
* **range:** knob is not cut off in item with modern syntax ([#28199](https://github.com/ionic-team/ionic-framework/issues/28199)) ([0104d89](https://github.com/ionic-team/ionic-framework/commit/0104d899270d73e16f2850a5fd7d2ba25a9e7ef0)), closes [#27199](https://github.com/ionic-team/ionic-framework/issues/27199)
* **scroll-assist:** improve input scroll accuracy with native resizing ([#28169](https://github.com/ionic-team/ionic-framework/issues/28169)) ([b5c736f](https://github.com/ionic-team/ionic-framework/commit/b5c736f5ac829efebedf3256ddf77ab3daa7a5f6)), closes [#22940](https://github.com/ionic-team/ionic-framework/issues/22940)
* **scroll-assist:** re-run when keyboard changes ([#28174](https://github.com/ionic-team/ionic-framework/issues/28174)) ([3f06da4](https://github.com/ionic-team/ionic-framework/commit/3f06da4cfc0d59c658e17e09ccb1ea28a29339f9)), closes [#22940](https://github.com/ionic-team/ionic-framework/issues/22940)
# [7.4.0](https://github.com/ionic-team/ionic-framework/compare/v7.3.4...v7.4.0) (2023-09-14)
### Bug Fixes
* **datetime:** scroll to newly selected date when value changes ([#27806](https://github.com/ionic-team/ionic-framework/issues/27806)) ([32244fb](https://github.com/ionic-team/ionic-framework/commit/32244fbdd1931e59a9e3cedd2b143c8ee7d01459)), closes [#26391](https://github.com/ionic-team/ionic-framework/issues/26391)
* **many:** add correct scale to stacked labels ([#28163](https://github.com/ionic-team/ionic-framework/issues/28163)) ([8cb8786](https://github.com/ionic-team/ionic-framework/commit/8cb878669e53bad25bbe2787826b6d02d292848a))
* **range:** add correct margin in item ([#28161](https://github.com/ionic-team/ionic-framework/issues/28161)) ([1d2b867](https://github.com/ionic-team/ionic-framework/commit/1d2b867f2207d366e355265b081bc9aabe31ce7e))
### Features
* **checkbox, radio, toggle, range:** stacked labels for form controls ([#28075](https://github.com/ionic-team/ionic-framework/issues/28075)) ([e6c7bb6](https://github.com/ionic-team/ionic-framework/commit/e6c7bb60e7e61c965f45e2bf3e3bd16f5125ad56))
* **datetime:** add disabled part ([#28134](https://github.com/ionic-team/ionic-framework/issues/28134)) ([cd8d509](https://github.com/ionic-team/ionic-framework/commit/cd8d5091a133804ac97d0394354dcf7cd73d9355))
* **datetime:** add parts for calendar day, active, and today ([#27641](https://github.com/ionic-team/ionic-framework/issues/27641)) ([79b005d](https://github.com/ionic-team/ionic-framework/commit/79b005da704c2ce481e1e3bc4d24cdba06a36d04)), closes [#25340](https://github.com/ionic-team/ionic-framework/issues/25340)
* export TransitionOptions interface and getIonPageElement ([#28140](https://github.com/ionic-team/ionic-framework/issues/28140)) ([19f3bb2](https://github.com/ionic-team/ionic-framework/commit/19f3bb23fd5587848fc41a744ca46ef5985c04d2)), closes [#28137](https://github.com/ionic-team/ionic-framework/issues/28137)
## [7.3.4](https://github.com/ionic-team/ionic-framework/compare/v7.3.3...v7.3.4) (2023-09-13)
### Bug Fixes
* **menu:** remove app dir from safe area padding ([#28123](https://github.com/ionic-team/ionic-framework/issues/28123)) ([e0542a7](https://github.com/ionic-team/ionic-framework/commit/e0542a7867871fa45a7fe6a4986e7de633063b4b))
## [7.3.3](https://github.com/ionic-team/ionic-framework/compare/v7.3.2...v7.3.3) (2023-09-06)
### Bug Fixes
* **modal:** swipe to dismiss resets status bar style ([#28110](https://github.com/ionic-team/ionic-framework/issues/28110)) ([176585f](https://github.com/ionic-team/ionic-framework/commit/176585f446b04a6a0cedab2e09417637dbfc78ee)), closes [#28105](https://github.com/ionic-team/ionic-framework/issues/28105)
* **overlays:** prevent overlays from getting stuck open ([#28069](https://github.com/ionic-team/ionic-framework/issues/28069)) ([584e9d3](https://github.com/ionic-team/ionic-framework/commit/584e9d3be220343451c2d4b9bf90658ecd530de1)), closes [#27200](https://github.com/ionic-team/ionic-framework/issues/27200)
* **popover:** dynamic width popover is positioned correctly ([#28072](https://github.com/ionic-team/ionic-framework/issues/28072)) ([2a80eb6](https://github.com/ionic-team/ionic-framework/commit/2a80eb6bd0b16a9dab9bea600bb7f935d25c0e1b)), closes [#27190](https://github.com/ionic-team/ionic-framework/issues/27190) [#24780](https://github.com/ionic-team/ionic-framework/issues/24780)
* **react:** overlay content is shown with hook ([#28109](https://github.com/ionic-team/ionic-framework/issues/28109)) ([7b551fd](https://github.com/ionic-team/ionic-framework/commit/7b551fd54b9e16a2538e5b82a13d72b3007fa045)), closes [#28102](https://github.com/ionic-team/ionic-framework/issues/28102)
* **textarea:** cols property is respected ([#28081](https://github.com/ionic-team/ionic-framework/issues/28081)) ([6d4eabc](https://github.com/ionic-team/ionic-framework/commit/6d4eabcc1046c28c1abf69a8bda3e06f80cf3f8f)), closes [#22142](https://github.com/ionic-team/ionic-framework/issues/22142)
## [7.3.2](https://github.com/ionic-team/ionic-framework/compare/v7.3.1...v7.3.2) (2023-08-30)
### Bug Fixes
* **datetime:** gracefully handle invalid min/max ([#28054](https://github.com/ionic-team/ionic-framework/issues/28054)) ([01fc9b4](https://github.com/ionic-team/ionic-framework/commit/01fc9b45116f7ad6ddc56c7fb1535dec798c2b3a)), closes [#28041](https://github.com/ionic-team/ionic-framework/issues/28041)
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
### Bug Fixes
* **angular:** ionTabsWillChange is fired before tab activation ([#27991](https://github.com/ionic-team/ionic-framework/issues/27991)) ([bbfb8f8](https://github.com/ionic-team/ionic-framework/commit/bbfb8f81a61475d7e73b63743db5d6a0cd979d21)), closes [#27212](https://github.com/ionic-team/ionic-framework/issues/27212)
* **input, textarea:** clearOnEdit does not clear when pressing Tab ([#28005](https://github.com/ionic-team/ionic-framework/issues/28005)) ([444acc1](https://github.com/ionic-team/ionic-framework/commit/444acc1f1bca348b62dfb398067cc087529f67f1)), closes [#27746](https://github.com/ionic-team/ionic-framework/issues/27746)
* **react:** avoid multiple invocations of onDidDismiss and onWillPresent ([#28020](https://github.com/ionic-team/ionic-framework/issues/28020)) ([0ac3df3](https://github.com/ionic-team/ionic-framework/commit/0ac3df3f378bdefc3a927adc798ebd9ec7a54fee)), closes [#28010](https://github.com/ionic-team/ionic-framework/issues/28010)
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
### Bug Fixes
* **alert:** radio and checkbox labels wrap to next line ([#27898](https://github.com/ionic-team/ionic-framework/issues/27898)) ([0d3127a](https://github.com/ionic-team/ionic-framework/commit/0d3127ad09df3c914a8c254f14931de5ca3beb31)), closes [#17269](https://github.com/ionic-team/ionic-framework/issues/17269)
### Features
* **action-sheet:** add htmlAttributes property for passing attributes to buttons ([#27863](https://github.com/ionic-team/ionic-framework/issues/27863)) ([5ce4ec0](https://github.com/ionic-team/ionic-framework/commit/5ce4ec0439e4f31aba31062fd8af4a2ad792a54f))
* **alert:** add htmlAttributes property for passing attributes to buttons ([#27862](https://github.com/ionic-team/ionic-framework/issues/27862)) ([06be0e5](https://github.com/ionic-team/ionic-framework/commit/06be0e511164ebdaa6af9a3747d0585260c030a9))
* **toast:** add htmlAttributes property for passing attributes to buttons ([#27855](https://github.com/ionic-team/ionic-framework/issues/27855)) ([9a68588](https://github.com/ionic-team/ionic-framework/commit/9a685882b7085d911ff09eedacc367629e32348a))
* **toast:** add shadow part for cancel button ([#27921](https://github.com/ionic-team/ionic-framework/issues/27921)) ([e9faf54](https://github.com/ionic-team/ionic-framework/commit/e9faf54d0a7409521706ce9c8b0d26f3fbe9ba41)), closes [#27920](https://github.com/ionic-team/ionic-framework/issues/27920)
## [7.2.4](https://github.com/ionic-team/ionic-framework/compare/v7.2.3...v7.2.4) (2023-08-16)
### Bug Fixes
* **tap-click:** do not error in document-less environment ([#27972](https://github.com/ionic-team/ionic-framework/issues/27972)) ([28bd4ba](https://github.com/ionic-team/ionic-framework/commit/28bd4ba720bb77d5f5c48cd7a45e0015daddc9dd))
* **title:** large title aligns with ios spec ([#27969](https://github.com/ionic-team/ionic-framework/issues/27969)) ([8fa12fc](https://github.com/ionic-team/ionic-framework/commit/8fa12fc88857df27a1ca11249f0085e100fe1474)), closes [#27966](https://github.com/ionic-team/ionic-framework/issues/27966)
## [7.2.3](https://github.com/ionic-team/ionic-framework/compare/v7.2.2...v7.2.3) (2023-08-09)
### Bug Fixes
* **button:** hidden button is added when form is set async ([#27955](https://github.com/ionic-team/ionic-framework/issues/27955)) ([e9fa300](https://github.com/ionic-team/ionic-framework/commit/e9fa30002bd5dec4f2f56a15c84eec1b3e794942)), closes [#27952](https://github.com/ionic-team/ionic-framework/issues/27952)
* **datetime:** changing months work if partially visible ([#27917](https://github.com/ionic-team/ionic-framework/issues/27917)) ([eb19c28](https://github.com/ionic-team/ionic-framework/commit/eb19c289d6581639f6df7aff002bebdf2b27d31c)), closes [#27913](https://github.com/ionic-team/ionic-framework/issues/27913)
* **item-sliding:** account for options added before watcher ([#27915](https://github.com/ionic-team/ionic-framework/issues/27915)) ([a0b3ef0](https://github.com/ionic-team/ionic-framework/commit/a0b3ef02af718e232246515bb873ad8c090fa55d)), closes [#27910](https://github.com/ionic-team/ionic-framework/issues/27910)
* **many:** overlays present if isOpen is true on load ([#27933](https://github.com/ionic-team/ionic-framework/issues/27933)) ([a0e6ac6](https://github.com/ionic-team/ionic-framework/commit/a0e6ac6013552c5e3acdde33575d4aaf4d4c0bda)), closes [#27928](https://github.com/ionic-team/ionic-framework/issues/27928)
* **modal:** setCurrentBreakpoint respects animated prop ([#27924](https://github.com/ionic-team/ionic-framework/issues/27924)) ([da55ab9](https://github.com/ionic-team/ionic-framework/commit/da55ab949ef1894738da5a6241176089b7a2b6e3)), closes [#27923](https://github.com/ionic-team/ionic-framework/issues/27923)
* **nav:** improve reliability of swipe back gesture when quickly swiping back ([#27904](https://github.com/ionic-team/ionic-framework/issues/27904)) ([9500769](https://github.com/ionic-team/ionic-framework/commit/9500769f114d180613f0340b1a328b5e631b7188)), closes [#27893](https://github.com/ionic-team/ionic-framework/issues/27893)
* **tab-button:** update event type interface on React ([#27950](https://github.com/ionic-team/ionic-framework/issues/27950)) ([1cf1eca](https://github.com/ionic-team/ionic-framework/commit/1cf1eca00239f3e98854466116e42f9a2e7b4590)), closes [#27949](https://github.com/ionic-team/ionic-framework/issues/27949)
## [7.2.2](https://github.com/ionic-team/ionic-framework/compare/v7.2.1...v7.2.2) (2023-08-02)
### Bug Fixes
* **datetime-button:** render correct text when passing partial date values ([#27816](https://github.com/ionic-team/ionic-framework/issues/27816)) ([bd1910b](https://github.com/ionic-team/ionic-framework/commit/bd1910ba69348877ad5f99d9db2b59d06693b91e)), closes [#27797](https://github.com/ionic-team/ionic-framework/issues/27797)
* **input, textarea:** input does not block floating label ([#27870](https://github.com/ionic-team/ionic-framework/issues/27870)) ([f14c440](https://github.com/ionic-team/ionic-framework/commit/f14c440d6321ef9f168b272338e5cd21cab384ef)), closes [#27812](https://github.com/ionic-team/ionic-framework/issues/27812)
* **item-options:** use correct safe area padding ([#27853](https://github.com/ionic-team/ionic-framework/issues/27853)) ([0b8f1bc](https://github.com/ionic-team/ionic-framework/commit/0b8f1bc7dd4170a2a8c9ed3aede173dd489b25ea))
* **radio:** radios can be focused and are announced with group ([#27817](https://github.com/ionic-team/ionic-framework/issues/27817)) ([ba2f49b](https://github.com/ionic-team/ionic-framework/commit/ba2f49b8a460520d20ac198db800ea2d9e5b015f)), closes [#27438](https://github.com/ionic-team/ionic-framework/issues/27438)
* **react, vue:** custom animations are used when going back ([#27895](https://github.com/ionic-team/ionic-framework/issues/27895)) ([824033f](https://github.com/ionic-team/ionic-framework/commit/824033f1d4b4a3e5d4c6a978a39e5bb1f33b5bb4)), closes [#27873](https://github.com/ionic-team/ionic-framework/issues/27873)
* **select:** popover uses modern form syntax ([#27818](https://github.com/ionic-team/ionic-framework/issues/27818)) ([0c117cf](https://github.com/ionic-team/ionic-framework/commit/0c117cfe7f383b7c7837d27de5a6eee12ddd6c2f)), closes [#27071](https://github.com/ionic-team/ionic-framework/issues/27071) [#27786](https://github.com/ionic-team/ionic-framework/issues/27786)
## [7.2.1](https://github.com/ionic-team/ionic-framework/compare/v7.2.0...v7.2.1) (2023-07-26)
### Bug Fixes
* **item-sliding:** buttons are not interactive on close ([#27829](https://github.com/ionic-team/ionic-framework/issues/27829)) ([6e4919c](https://github.com/ionic-team/ionic-framework/commit/6e4919caff90fc60988e5cc85ad7161844eb5b51)), closes [#22722](https://github.com/ionic-team/ionic-framework/issues/22722)
* **modal:** body background is reset with inline card modals ([#27835](https://github.com/ionic-team/ionic-framework/issues/27835)) ([38626d9](https://github.com/ionic-team/ionic-framework/commit/38626d96809d1c6be523ea62a4fac1dec73ee891)), closes [#27830](https://github.com/ionic-team/ionic-framework/issues/27830)
# [7.2.0](https://github.com/ionic-team/ionic-framework/compare/v7.1.4...v7.2.0) (2023-07-19)
### Features
* **angular:** support binding routing data to component inputs ([#27694](https://github.com/ionic-team/ionic-framework/issues/27694)) ([90f4124](https://github.com/ionic-team/ionic-framework/commit/90f41243d9404caaad99076965b7cd649ddf7f33)), closes [#27476](https://github.com/ionic-team/ionic-framework/issues/27476)
* **button:** allow button to increase in height when text wraps ([#27547](https://github.com/ionic-team/ionic-framework/issues/27547)) ([6fe716f](https://github.com/ionic-team/ionic-framework/commit/6fe716fd1320935632854e5d4f741b57801bda92))
* **searchbar:** add name property ([#27737](https://github.com/ionic-team/ionic-framework/issues/27737)) ([7131037](https://github.com/ionic-team/ionic-framework/commit/71310372c94862342d607007ece127340df92a8c)), closes [#27675](https://github.com/ionic-team/ionic-framework/issues/27675)
## [7.1.4](https://github.com/ionic-team/ionic-framework/compare/v7.1.3...v7.1.4) (2023-07-19)
### Bug Fixes
* **angular:** menu button is enabled with Angular Universal builds ([#27814](https://github.com/ionic-team/ionic-framework/issues/27814)) ([2cf1a0b](https://github.com/ionic-team/ionic-framework/commit/2cf1a0bcae7d766aa25951c53470876f9569906c)), closes [#27524](https://github.com/ionic-team/ionic-framework/issues/27524) [#22206](https://github.com/ionic-team/ionic-framework/issues/22206)
* **button:** submit form when pressing enter key ([#27790](https://github.com/ionic-team/ionic-framework/issues/27790)) ([b78af75](https://github.com/ionic-team/ionic-framework/commit/b78af7598f19ca5e1b440ddc0091a62d86321066)), closes [#19368](https://github.com/ionic-team/ionic-framework/issues/19368)
* **radio, checkbox, toggle:** add top and bottom margins when in ion-item ([#27788](https://github.com/ionic-team/ionic-framework/issues/27788)) ([35f0ec5](https://github.com/ionic-team/ionic-framework/commit/35f0ec581a55e0cb080f0793fb94d3e424c06d4d)), closes [#27498](https://github.com/ionic-team/ionic-framework/issues/27498)
* safari no longer adjusts text in landscape ([#27787](https://github.com/ionic-team/ionic-framework/issues/27787)) ([66584b0](https://github.com/ionic-team/ionic-framework/commit/66584b03d0b33507170f954009998c72fb3f7755)), closes [#27782](https://github.com/ionic-team/ionic-framework/issues/27782)
* **textarea:** stacked/floating textarea size is correct on safari ([#27766](https://github.com/ionic-team/ionic-framework/issues/27766)) ([2cb7013](https://github.com/ionic-team/ionic-framework/commit/2cb701395487c6a0304400f6b821659ae6def820)), closes [#27345](https://github.com/ionic-team/ionic-framework/issues/27345)
## [7.1.3](https://github.com/ionic-team/ionic-framework/compare/v7.1.2...v7.1.3) (2023-07-12)
### Bug Fixes
* avoid unresolved import warning on stencil apps ([#27765](https://github.com/ionic-team/ionic-framework/issues/27765)) ([2085025](https://github.com/ionic-team/ionic-framework/commit/2085025644f075e63d04bece56eca4f2beeadbb6)), closes [#27762](https://github.com/ionic-team/ionic-framework/issues/27762)
* **overlays:** first button is not focused on backdrop tap ([#27774](https://github.com/ionic-team/ionic-framework/issues/27774)) ([82c568b](https://github.com/ionic-team/ionic-framework/commit/82c568b8c8e1e9934e1928452aa5216619290e7b)), closes [#27773](https://github.com/ionic-team/ionic-framework/issues/27773)
## [7.1.2](https://github.com/ionic-team/ionic-framework/compare/v7.1.1...v7.1.2) (2023-07-06)
### Bug Fixes
* **back-button:** show correct background on focus + hover with ios ([#27723](https://github.com/ionic-team/ionic-framework/issues/27723)) ([db9a001](https://github.com/ionic-team/ionic-framework/commit/db9a0010df3c7fd0fcd0dbcd8c4ad3b30d022b5c)), closes [#27722](https://github.com/ionic-team/ionic-framework/issues/27722)
* **nav:** root component is mounted with root params ([#27676](https://github.com/ionic-team/ionic-framework/issues/27676)) ([1f06be4](https://github.com/ionic-team/ionic-framework/commit/1f06be4a31965f2a949b4866a585aee6af0af29d)), closes [#27146](https://github.com/ionic-team/ionic-framework/issues/27146)
## [7.1.1](https://github.com/ionic-team/ionic-framework/compare/v7.1.0...v7.1.1) (2023-06-26)
### Bug Fixes
* **textarea:** autogrow resizes correctly ([#27691](https://github.com/ionic-team/ionic-framework/issues/27691)) ([f263611](https://github.com/ionic-team/ionic-framework/commit/f263611260c465bfeefc2db7b1ea04bfa5b54303)), closes [#27688](https://github.com/ionic-team/ionic-framework/issues/27688)
# [7.1.0](https://github.com/ionic-team/ionic-framework/compare/v7.0.14...v7.1.0) (2023-06-21)
### Bug Fixes
* **angular:** tabs supports conditional slot bindings ([#27582](https://github.com/ionic-team/ionic-framework/issues/27582)) ([d20bea5](https://github.com/ionic-team/ionic-framework/commit/d20bea561c362eacd250cdedbc9b79159eb2c95f)), closes [#19484](https://github.com/ionic-team/ionic-framework/issues/19484)
* **datetime:** ascending order for years ([#27551](https://github.com/ionic-team/ionic-framework/issues/27551)) ([2098806](https://github.com/ionic-team/ionic-framework/commit/209880622a4600f88c4878e82975ad0492bd55db)), closes [#27422](https://github.com/ionic-team/ionic-framework/issues/27422)
* import paths ([d10509f](https://github.com/ionic-team/ionic-framework/commit/d10509f84099515f62c895dcd736cc387e382bde))
* **select:** hide notch cutout if no visible label provided ([#27649](https://github.com/ionic-team/ionic-framework/issues/27649)) ([606a892](https://github.com/ionic-team/ionic-framework/commit/606a892e400a531cac5c413dc7492a54ae0e1fea))
### Features
* **datetime:** add part for month/year button ([#27618](https://github.com/ionic-team/ionic-framework/issues/27618)) ([d44422e](https://github.com/ionic-team/ionic-framework/commit/d44422e224374804010746a12f398d3c0d6a9f2c)), closes [#26596](https://github.com/ionic-team/ionic-framework/issues/26596)
* **datetime:** add shadow parts and CSS variables for styling wheel pickers ([#27529](https://github.com/ionic-team/ionic-framework/issues/27529)) ([f2c1845](https://github.com/ionic-team/ionic-framework/commit/f2c1845fba11d8273331c601052f0f34457b6649)), closes [#25945](https://github.com/ionic-team/ionic-framework/issues/25945)
* **input:** add experimental label slot ([#27650](https://github.com/ionic-team/ionic-framework/issues/27650)) ([a45395c](https://github.com/ionic-team/ionic-framework/commit/a45395cc02b2617b80e6c2389fa745e7c20540fc)), closes [#27061](https://github.com/ionic-team/ionic-framework/issues/27061)
* **range:** add label prop ([#27408](https://github.com/ionic-team/ionic-framework/issues/27408)) ([368add2](https://github.com/ionic-team/ionic-framework/commit/368add2a5ca3820a1f9623c96d29bcccfa693fdc))
* return if the pop on NavController was successful ([#27404](https://github.com/ionic-team/ionic-framework/issues/27404)) ([e80f0b2](https://github.com/ionic-team/ionic-framework/commit/e80f0b240968de0d642463e95a35adf8dbffd2e1)), closes [#27403](https://github.com/ionic-team/ionic-framework/issues/27403)
* **segment, segment-button:** update segment value property to accept numbers ([#27222](https://github.com/ionic-team/ionic-framework/issues/27222)) ([ec95ae5](https://github.com/ionic-team/ionic-framework/commit/ec95ae5cd38e3d2b9ec9fdbc9e237fa1241f7a4e)), closes [#27221](https://github.com/ionic-team/ionic-framework/issues/27221)
* **segment:** display segment as a grid and add an ellipsis to overflowing text in a segment button ([#27457](https://github.com/ionic-team/ionic-framework/issues/27457)) ([448e63f](https://github.com/ionic-team/ionic-framework/commit/448e63fef0aca603214cb357dec37e1db2a0f052)), closes [#16532](https://github.com/ionic-team/ionic-framework/issues/16532)
* **select:** add label slot ([#27545](https://github.com/ionic-team/ionic-framework/issues/27545)) ([af92cb2](https://github.com/ionic-team/ionic-framework/commit/af92cb28c8819c88b40192b5dcbafedc1eb2064a)), closes [#26838](https://github.com/ionic-team/ionic-framework/issues/26838)
* **select:** add props to customize toggle icons ([#27648](https://github.com/ionic-team/ionic-framework/issues/27648)) ([95e28b6](https://github.com/ionic-team/ionic-framework/commit/95e28b6629843af7dce62f20bc8e31adfb391990)), closes [#17248](https://github.com/ionic-team/ionic-framework/issues/17248)
* **select:** expose container and label as CSS parts ([#27541](https://github.com/ionic-team/ionic-framework/issues/27541)) ([5c10f88](https://github.com/ionic-team/ionic-framework/commit/5c10f88b2eb4d869966ea9a6d1db34185cefe676)), closes [#27112](https://github.com/ionic-team/ionic-framework/issues/27112)
* **textarea:** add experimental label slot ([#27677](https://github.com/ionic-team/ionic-framework/issues/27677)) ([8bcd9e8](https://github.com/ionic-team/ionic-framework/commit/8bcd9e8b35f252a4efaec7a7be7d69a70beefa9f)), closes [#27061](https://github.com/ionic-team/ionic-framework/issues/27061)
## [7.0.14](https://github.com/ionic-team/ionic-framework/compare/v7.0.13...v7.0.14) (2023-06-15)
### Bug Fixes
* **keyboard:** keyboard events emit correctly when Capacitor is available but the Keyboard plugin is not ([#27655](https://github.com/ionic-team/ionic-framework/issues/27655)) ([7a38a00](https://github.com/ionic-team/ionic-framework/commit/7a38a006a94f1240d93102f2f42bbfc4d76a679e)), closes [#27654](https://github.com/ionic-team/ionic-framework/issues/27654)
* **toast:** allow color for translucent toast ([#27652](https://github.com/ionic-team/ionic-framework/issues/27652)) ([d555375](https://github.com/ionic-team/ionic-framework/commit/d555375c146639b32e85c57a8cdd4d52313ef4cf)), closes [#27567](https://github.com/ionic-team/ionic-framework/issues/27567)
## [7.0.13](https://github.com/ionic-team/ionic-framework/compare/v7.0.12...v7.0.13) (2023-06-14)
### Bug Fixes
* **react:** onDoubleClick fires on components ([#27611](https://github.com/ionic-team/ionic-framework/issues/27611)) ([3e191df](https://github.com/ionic-team/ionic-framework/commit/3e191df3dd43dcdd5a5f717166d4db9834340a2b)), closes [#21320](https://github.com/ionic-team/ionic-framework/issues/21320)
## [7.0.12](https://github.com/ionic-team/ionic-framework/compare/v7.0.11...v7.0.12) (2023-06-08)

View File

@@ -55,7 +55,7 @@
| Project | Package | Version | Downloads| Links |
| ------- | ------- | ------- | -------- |:-----:|
| **Core** | [`@ionic/core`](https://www.npmjs.com/package/@ionic/core) | [![version](https://img.shields.io/npm/v/@ionic/core/latest.svg)](https://www.npmjs.com/package/@ionic/core) | <a href="https://www.npmjs.com/package/@ionic/core" target="_blank"><img src="https://img.shields.io/npm/dm/@ionic/core.svg" alt="NPM Downloads" /></a> | [`README.md`](core/README.md)
| **Angular** | [`@ionic/angular`](https://www.npmjs.com/package/@ionic/angular) | [![version](https://img.shields.io/npm/v/@ionic/angular/latest.svg)](https://www.npmjs.com/package/@ionic/angular) | <a href="https://www.npmjs.com/package/@ionic/angular" target="_blank"><img src="https://img.shields.io/npm/dm/@ionic/angular.svg" alt="NPM Downloads" /></a> | [`README.md`](packages/angular/README.md)
| **Angular** | [`@ionic/angular`](https://www.npmjs.com/package/@ionic/angular) | [![version](https://img.shields.io/npm/v/@ionic/angular/latest.svg)](https://www.npmjs.com/package/@ionic/angular) | <a href="https://www.npmjs.com/package/@ionic/angular" target="_blank"><img src="https://img.shields.io/npm/dm/@ionic/angular.svg" alt="NPM Downloads" /></a> | [`README.md`](angular/README.md)
| **Vue** | [`@ionic/vue`](https://www.npmjs.com/package/@ionic/vue) | [![version](https://img.shields.io/npm/v/@ionic/vue/latest.svg)](https://www.npmjs.com/package/@ionic/vue) | <a href="https://www.npmjs.com/package/@ionic/vue" target="_blank"><img src="https://img.shields.io/npm/dm/@ionic/vue.svg" alt="NPM Downloads" /></a> | [`README.md`](packages/vue/README.md)
| **React** | [`@ionic/react`](https://www.npmjs.com/package/@ionic/react) | [![version](https://img.shields.io/npm/v/@ionic/react/latest.svg)](https://www.npmjs.com/package/@ionic/react) | <a href="https://www.npmjs.com/package/@ionic/react" target="_blank"><img src="https://img.shields.io/npm/dm/@ionic/react.svg" alt="NPM Downloads" /></a> |[`README.md`](packages/react/README.md)

6
angular/.prettierignore Normal file
View File

@@ -0,0 +1,6 @@
dist
scripts
test
src/directives/proxies.ts
src/directives/proxies-list.ts
src/directives/angular-component-lib/utils.ts

View File

@@ -3,452 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [7.8.1](https://github.com/ionic-team/ionic-framework/compare/v7.8.0...v7.8.1) (2024-03-20)
**Note:** Version bump only for package @ionic/angular
# [7.8.0](https://github.com/ionic-team/ionic-framework/compare/v7.7.5...v7.8.0) (2024-03-13)
### Features
* **datetime:** formatOptions property for Datetime ([#29065](https://github.com/ionic-team/ionic-framework/issues/29065)) ([7cdbc1b](https://github.com/ionic-team/ionic-framework/commit/7cdbc1b5ad004e17a7c51363653e0e67f50e6860))
* **searchbar:** autocapitalize, dir, lang, maxlength, and minlength are inherited to native input ([#29098](https://github.com/ionic-team/ionic-framework/issues/29098)) ([a0a77f7](https://github.com/ionic-team/ionic-framework/commit/a0a77f799df0732d9f7182f15866035a3ce5a1eb)), closes [#27606](https://github.com/ionic-team/ionic-framework/issues/27606)
## [7.7.5](https://github.com/ionic-team/ionic-framework/compare/v7.7.4...v7.7.5) (2024-03-13)
### Bug Fixes
* **angular:** add ionNavWillChange and ionNavDidChange types for nav ([#29122](https://github.com/ionic-team/ionic-framework/issues/29122)) ([85b9d5c](https://github.com/ionic-team/ionic-framework/commit/85b9d5c35f626ffc273d220549b0126ddc1f7e4b)), closes [#29114](https://github.com/ionic-team/ionic-framework/issues/29114)
## [7.7.4](https://github.com/ionic-team/ionic-framework/compare/v7.7.3...v7.7.4) (2024-03-06)
**Note:** Version bump only for package @ionic/angular
## [7.7.3](https://github.com/ionic-team/ionic-framework/compare/v7.7.2...v7.7.3) (2024-02-21)
**Note:** Version bump only for package @ionic/angular
## [7.7.2](https://github.com/ionic-team/ionic-framework/compare/v7.7.1...v7.7.2) (2024-02-14)
**Note:** Version bump only for package @ionic/angular
## [7.7.1](https://github.com/ionic-team/ionic-framework/compare/v7.7.0...v7.7.1) (2024-02-07)
**Note:** Version bump only for package @ionic/angular
# [7.7.0](https://github.com/ionic-team/ionic-framework/compare/v7.6.7...v7.7.0) (2024-01-31)
**Note:** Version bump only for package @ionic/angular
## [7.6.7](https://github.com/ionic-team/ionic-framework/compare/v7.6.6...v7.6.7) (2024-01-31)
**Note:** Version bump only for package @ionic/angular
## [7.6.6](https://github.com/ionic-team/ionic-framework/compare/v7.6.5...v7.6.6) (2024-01-24)
**Note:** Version bump only for package @ionic/angular
## [7.6.5](https://github.com/ionic-team/ionic-framework/compare/v7.6.4...v7.6.5) (2024-01-17)
### Bug Fixes
* **angular:** add old IonBackButtonDelegate import ([#28831](https://github.com/ionic-team/ionic-framework/issues/28831)) ([fb77353](https://github.com/ionic-team/ionic-framework/commit/fb7735397ed53323dd93a172407117228610b929)), closes [#28827](https://github.com/ionic-team/ionic-framework/issues/28827)
## [7.6.4](https://github.com/ionic-team/ionic-framework/compare/v7.6.3...v7.6.4) (2024-01-10)
**Note:** Version bump only for package @ionic/angular
## [7.6.3](https://github.com/ionic-team/ionic-framework/compare/v7.6.2...v7.6.3) (2024-01-03)
**Note:** Version bump only for package @ionic/angular
## [7.6.2](https://github.com/ionic-team/ionic-framework/compare/v7.6.1...v7.6.2) (2023-12-19)
### Bug Fixes
* **refresher:** mode property can be used in typescript ([#28717](https://github.com/ionic-team/ionic-framework/issues/28717)) ([7ce1031](https://github.com/ionic-team/ionic-framework/commit/7ce1031c177487649c2a698664ec98f10d9002b9)), closes [#28716](https://github.com/ionic-team/ionic-framework/issues/28716)
## [7.6.1](https://github.com/ionic-team/ionic-framework/compare/v7.6.0...v7.6.1) (2023-12-13)
**Note:** Version bump only for package @ionic/angular
# [7.6.0](https://github.com/ionic-team/ionic-framework/compare/v7.5.8...v7.6.0) (2023-12-06)
### Bug Fixes
* **angular,vue:** range form value updates while dragging knob ([#28422](https://github.com/ionic-team/ionic-framework/issues/28422)) ([0854a11](https://github.com/ionic-team/ionic-framework/commit/0854a11a25759d0201eae66c96a62fe138d486f8)), closes [#28256](https://github.com/ionic-team/ionic-framework/issues/28256)
### Features
* **radio-group:** add compareWith property ([#28452](https://github.com/ionic-team/ionic-framework/issues/28452)) ([0ae327f](https://github.com/ionic-team/ionic-framework/commit/0ae327f0e09cd97d705f2d3051c215034381e226))
* **toast:** add swipe to dismiss functionality ([#28442](https://github.com/ionic-team/ionic-framework/issues/28442)) ([30c21aa](https://github.com/ionic-team/ionic-framework/commit/30c21aab3ed40d73c28e7d60d0952d8891b0a9d3)), closes [#21769](https://github.com/ionic-team/ionic-framework/issues/21769)
## [7.5.8](https://github.com/ionic-team/ionic-framework/compare/v7.5.7...v7.5.8) (2023-12-06)
### Bug Fixes
* **angular:** add missing menu controller methods ([#28618](https://github.com/ionic-team/ionic-framework/issues/28618)) ([7871b56](https://github.com/ionic-team/ionic-framework/commit/7871b56eccfe63326b6dd4b56ade3b3afd444fce)), closes [#20053](https://github.com/ionic-team/ionic-framework/issues/20053)
## [7.5.7](https://github.com/ionic-team/ionic-framework/compare/v7.5.6...v7.5.7) (2023-11-29)
**Note:** Version bump only for package @ionic/angular
## [7.5.6](https://github.com/ionic-team/ionic-framework/compare/v7.5.5...v7.5.6) (2023-11-21)
### Bug Fixes
* **angular:** ng add @ionic/angular in standalone projects ([#28523](https://github.com/ionic-team/ionic-framework/issues/28523)) ([c07312e](https://github.com/ionic-team/ionic-framework/commit/c07312e5ed931f6f825ccf083c9dead9fa815843)), closes [#28514](https://github.com/ionic-team/ionic-framework/issues/28514)
* **angular:** overlays are defined when using standalone controllers ([#28560](https://github.com/ionic-team/ionic-framework/issues/28560)) ([9453132](https://github.com/ionic-team/ionic-framework/commit/9453132aa8952b4adfa1326e61138b329e254f76)), closes [#28385](https://github.com/ionic-team/ionic-framework/issues/28385)
## [7.5.5](https://github.com/ionic-team/ionic-framework/compare/v7.5.4...v7.5.5) (2023-11-15)
**Note:** Version bump only for package @ionic/angular
## [7.5.4](https://github.com/ionic-team/ionic-framework/compare/v7.5.3...v7.5.4) (2023-11-08)
**Note:** Version bump only for package @ionic/angular
## [7.5.3](https://github.com/ionic-team/ionic-framework/compare/v7.5.2...v7.5.3) (2023-11-01)
### Bug Fixes
* **angular:** inputs on standalone form controls are reactive ([#28434](https://github.com/ionic-team/ionic-framework/issues/28434)) ([3b6e631](https://github.com/ionic-team/ionic-framework/commit/3b6e6318bf94125b3f8305b4d072a5945ceb3730)), closes [#28431](https://github.com/ionic-team/ionic-framework/issues/28431)
* **angular:** NavController works with nested outlets ([#28421](https://github.com/ionic-team/ionic-framework/issues/28421)) ([90acad1](https://github.com/ionic-team/ionic-framework/commit/90acad1837b117542830ec0083389a35c5b4ee76)), closes [#28417](https://github.com/ionic-team/ionic-framework/issues/28417)
* **angular:** run platform subscriptions inside zone ([#28404](https://github.com/ionic-team/ionic-framework/issues/28404)) ([a4b303e](https://github.com/ionic-team/ionic-framework/commit/a4b303e1338a35756a9cf7f67508d24d2f8537a2)), closes [#19539](https://github.com/ionic-team/ionic-framework/issues/19539)
* **angular:** standalone form components do not error when multiple are used ([#28423](https://github.com/ionic-team/ionic-framework/issues/28423)) ([89698b3](https://github.com/ionic-team/ionic-framework/commit/89698b338fb05cde427c98720c238d2365abdaa7)), closes [#28418](https://github.com/ionic-team/ionic-framework/issues/28418)
## [7.5.2](https://github.com/ionic-team/ionic-framework/compare/v7.5.1...v7.5.2) (2023-10-25)
### Bug Fixes
* **angular:** remove form control side effects ([#28359](https://github.com/ionic-team/ionic-framework/issues/28359)) ([82d6309](https://github.com/ionic-team/ionic-framework/commit/82d6309ef1675c0a6e767e87c23f166d84579d8f)), closes [#28358](https://github.com/ionic-team/ionic-framework/issues/28358)
## [7.5.1](https://github.com/ionic-team/ionic-framework/compare/v7.5.0...v7.5.1) (2023-10-18)
### Bug Fixes
* **angular:** do not create duplicate menuController instances ([#28343](https://github.com/ionic-team/ionic-framework/issues/28343)) ([fa78676](https://github.com/ionic-team/ionic-framework/commit/fa78676d57eb80655ee9447ffa07dcfdae0c6b2a)), closes [#28337](https://github.com/ionic-team/ionic-framework/issues/28337)
* **angular:** export missing lifecycle interfaces for standalone package ([#28346](https://github.com/ionic-team/ionic-framework/issues/28346)) ([dd93e0b](https://github.com/ionic-team/ionic-framework/commit/dd93e0b2689511f3145606f4dbb2c30dcf4c2950)), closes [/github.com/ionic-team/ionic-angular-standalone-codemods/pull/13/files/baa37ef1e3e8ba773b693db280542efba815482a#r1356414362](https://github.com//github.com/ionic-team/ionic-angular-standalone-codemods/pull/13/files/baa37ef1e3e8ba773b693db280542efba815482a/issues/r1356414362)
# [7.5.0](https://github.com/ionic-team/ionic-framework/compare/v7.4.4...v7.5.0) (2023-10-11)
### Features
* **angular, react, vue, core:** export openURL utility ([#28295](https://github.com/ionic-team/ionic-framework/issues/28295)) ([6da82aa](https://github.com/ionic-team/ionic-framework/commit/6da82aab816b28bfc174f7634ded1fc1e06502ab)), closes [#27911](https://github.com/ionic-team/ionic-framework/issues/27911)
* **angular:** ship Ionic components as Angular standalone components ([#28311](https://github.com/ionic-team/ionic-framework/issues/28311)) ([57e2476](https://github.com/ionic-team/ionic-framework/commit/57e247637005b10f0d21d5ac5f5232bcb1908301))
* **toast:** allow custom positioning relative to specific element ([#28248](https://github.com/ionic-team/ionic-framework/issues/28248)) ([897ff6f](https://github.com/ionic-team/ionic-framework/commit/897ff6f7493d8d7e4ab22c6ae59de066b43ce682)), closes [#17499](https://github.com/ionic-team/ionic-framework/issues/17499)
## [7.4.4](https://github.com/ionic-team/ionic-framework/compare/v7.4.3...v7.4.4) (2023-10-11)
**Note:** Version bump only for package @ionic/angular
## [7.4.3](https://github.com/ionic-team/ionic-framework/compare/v7.4.2...v7.4.3) (2023-10-04)
**Note:** Version bump only for package @ionic/angular
## [7.4.2](https://github.com/ionic-team/ionic-framework/compare/v7.4.1...v7.4.2) (2023-09-27)
**Note:** Version bump only for package @ionic/angular
## [7.4.1](https://github.com/ionic-team/ionic-framework/compare/v7.4.0...v7.4.1) (2023-09-20)
**Note:** Version bump only for package @ionic/angular
# [7.4.0](https://github.com/ionic-team/ionic-framework/compare/v7.3.4...v7.4.0) (2023-09-14)
### Features
* **checkbox, radio, toggle, range:** stacked labels for form controls ([#28075](https://github.com/ionic-team/ionic-framework/issues/28075)) ([e6c7bb6](https://github.com/ionic-team/ionic-framework/commit/e6c7bb60e7e61c965f45e2bf3e3bd16f5125ad56))
* export TransitionOptions interface and getIonPageElement ([#28140](https://github.com/ionic-team/ionic-framework/issues/28140)) ([19f3bb2](https://github.com/ionic-team/ionic-framework/commit/19f3bb23fd5587848fc41a744ca46ef5985c04d2)), closes [#28137](https://github.com/ionic-team/ionic-framework/issues/28137)
## [7.3.4](https://github.com/ionic-team/ionic-framework/compare/v7.3.3...v7.3.4) (2023-09-13)
**Note:** Version bump only for package @ionic/angular
## [7.3.3](https://github.com/ionic-team/ionic-framework/compare/v7.3.2...v7.3.3) (2023-09-06)
**Note:** Version bump only for package @ionic/angular
## [7.3.2](https://github.com/ionic-team/ionic-framework/compare/v7.3.1...v7.3.2) (2023-08-30)
**Note:** Version bump only for package @ionic/angular
## [7.3.1](https://github.com/ionic-team/ionic-framework/compare/v7.3.0...v7.3.1) (2023-08-23)
### Bug Fixes
* **angular:** ionTabsWillChange is fired before tab activation ([#27991](https://github.com/ionic-team/ionic-framework/issues/27991)) ([bbfb8f8](https://github.com/ionic-team/ionic-framework/commit/bbfb8f81a61475d7e73b63743db5d6a0cd979d21)), closes [#27212](https://github.com/ionic-team/ionic-framework/issues/27212)
# [7.3.0](https://github.com/ionic-team/ionic-framework/compare/v7.2.4...v7.3.0) (2023-08-16)
**Note:** Version bump only for package @ionic/angular
## [7.2.4](https://github.com/ionic-team/ionic-framework/compare/v7.2.3...v7.2.4) (2023-08-16)
**Note:** Version bump only for package @ionic/angular
## [7.2.3](https://github.com/ionic-team/ionic-framework/compare/v7.2.2...v7.2.3) (2023-08-09)
**Note:** Version bump only for package @ionic/angular
## [7.2.2](https://github.com/ionic-team/ionic-framework/compare/v7.2.1...v7.2.2) (2023-08-02)
**Note:** Version bump only for package @ionic/angular
## [7.2.1](https://github.com/ionic-team/ionic-framework/compare/v7.2.0...v7.2.1) (2023-07-26)
**Note:** Version bump only for package @ionic/angular
# [7.2.0](https://github.com/ionic-team/ionic-framework/compare/v7.1.4...v7.2.0) (2023-07-19)
### Features
* **angular:** support binding routing data to component inputs ([#27694](https://github.com/ionic-team/ionic-framework/issues/27694)) ([90f4124](https://github.com/ionic-team/ionic-framework/commit/90f41243d9404caaad99076965b7cd649ddf7f33)), closes [#27476](https://github.com/ionic-team/ionic-framework/issues/27476)
* **searchbar:** add name property ([#27737](https://github.com/ionic-team/ionic-framework/issues/27737)) ([7131037](https://github.com/ionic-team/ionic-framework/commit/71310372c94862342d607007ece127340df92a8c)), closes [#27675](https://github.com/ionic-team/ionic-framework/issues/27675)
## [7.1.4](https://github.com/ionic-team/ionic-framework/compare/v7.1.3...v7.1.4) (2023-07-19)
**Note:** Version bump only for package @ionic/angular
## [7.1.3](https://github.com/ionic-team/ionic-framework/compare/v7.1.2...v7.1.3) (2023-07-12)
**Note:** Version bump only for package @ionic/angular
## [7.1.2](https://github.com/ionic-team/ionic-framework/compare/v7.1.1...v7.1.2) (2023-07-06)
**Note:** Version bump only for package @ionic/angular
## [7.1.1](https://github.com/ionic-team/ionic-framework/compare/v7.1.0...v7.1.1) (2023-06-26)
**Note:** Version bump only for package @ionic/angular
# [7.1.0](https://github.com/ionic-team/ionic-framework/compare/v7.0.14...v7.1.0) (2023-06-21)
### Bug Fixes
* **angular:** tabs supports conditional slot bindings ([#27582](https://github.com/ionic-team/ionic-framework/issues/27582)) ([d20bea5](https://github.com/ionic-team/ionic-framework/commit/d20bea561c362eacd250cdedbc9b79159eb2c95f)), closes [#19484](https://github.com/ionic-team/ionic-framework/issues/19484)
### Features
* **range:** add label prop ([#27408](https://github.com/ionic-team/ionic-framework/issues/27408)) ([368add2](https://github.com/ionic-team/ionic-framework/commit/368add2a5ca3820a1f9623c96d29bcccfa693fdc))
* return if the pop on NavController was successful ([#27404](https://github.com/ionic-team/ionic-framework/issues/27404)) ([e80f0b2](https://github.com/ionic-team/ionic-framework/commit/e80f0b240968de0d642463e95a35adf8dbffd2e1)), closes [#27403](https://github.com/ionic-team/ionic-framework/issues/27403)
* **segment, segment-button:** update segment value property to accept numbers ([#27222](https://github.com/ionic-team/ionic-framework/issues/27222)) ([ec95ae5](https://github.com/ionic-team/ionic-framework/commit/ec95ae5cd38e3d2b9ec9fdbc9e237fa1241f7a4e)), closes [#27221](https://github.com/ionic-team/ionic-framework/issues/27221)
* **segment:** display segment as a grid and add an ellipsis to overflowing text in a segment button ([#27457](https://github.com/ionic-team/ionic-framework/issues/27457)) ([448e63f](https://github.com/ionic-team/ionic-framework/commit/448e63fef0aca603214cb357dec37e1db2a0f052)), closes [#16532](https://github.com/ionic-team/ionic-framework/issues/16532)
* **select:** add props to customize toggle icons ([#27648](https://github.com/ionic-team/ionic-framework/issues/27648)) ([95e28b6](https://github.com/ionic-team/ionic-framework/commit/95e28b6629843af7dce62f20bc8e31adfb391990)), closes [#17248](https://github.com/ionic-team/ionic-framework/issues/17248)
## [7.0.14](https://github.com/ionic-team/ionic-framework/compare/v7.0.13...v7.0.14) (2023-06-15)
**Note:** Version bump only for package @ionic/angular
## [7.0.13](https://github.com/ionic-team/ionic-framework/compare/v7.0.12...v7.0.13) (2023-06-14)
**Note:** Version bump only for package @ionic/angular
## [7.0.12](https://github.com/ionic-team/ionic-framework/compare/v7.0.11...v7.0.12) (2023-06-08)
**Note:** Version bump only for package @ionic/angular

View File

@@ -52,23 +52,3 @@ $ npx schematics @ionic/angular:ng-add
You'll now be able to add ionic components to a vanilla Angular app setup.
## Project Structure
**common**
This is where logic that is shared between lazy loaded and standalone components live. For example, the lazy loaded IonPopover and standalone IonPopover components extend from a base IonPopover implementation that exists in this directory.
**Note:** This directory exposes internal APIs and is only accessed in the `standalone` and `src` submodules. Ionic developers should never import directly from `@ionic/angular/common`. Instead, they should import from `@ionic/angular` or `@ionic/angular/standalone`.
**standalone**
This is where the standalone component implementations live. It was added as a separate entry point to avoid any lazy loaded logic from accidentally being pulled in to the final build. Having a separate directory allows the lazy loaded implementation to remain accessible from `@ionic/angular` for backwards compatibility.
Ionic developers can access this by importing from `@ionic/angular/standalone`.
**src**
This is where the lazy loaded component implementations live.
Ionic developers can access this by importing from `@ionic/angular`.

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular",
"version": "7.8.1",
"version": "7.0.12",
"description": "Angular specific wrappers for @ionic/core",
"keywords": [
"ionic",
@@ -26,8 +26,8 @@
"scripts": {
"build": "npm run clean && npm run build.ng && npm run build.core && npm run clean-generated",
"build.core": "node scripts/build-core.js",
"build.link": "npm run build && node scripts/link-copy.js",
"build.ng": "ng-packagr -p ng-package.json -c tsconfig.json",
"build.watch": "npm run build.ng -- --watch",
"clean": "node scripts/clean.js",
"clean-generated": "node ./scripts/clean-generated.js",
"lint": "npm run eslint && npm run prettier -- --write --cache",
@@ -47,7 +47,7 @@
}
},
"dependencies": {
"@ionic/core": "^7.8.1",
"@ionic/core": "^7.0.12",
"ionicons": "^7.0.0",
"jsonc-parser": "^3.0.0",
"tslib": "^2.3.0"
@@ -60,12 +60,11 @@
"zone.js": ">=0.11.0"
},
"devDependencies": {
"@angular-devkit/core": "^17.0.0",
"@angular-devkit/schematics": "^17.0.0",
"@angular-devkit/core": "^14.0.0",
"@angular-devkit/schematics": "^14.0.0",
"@angular-eslint/eslint-plugin": "^14.0.0",
"@angular-eslint/eslint-plugin-template": "^14.0.0",
"@angular-eslint/template-parser": "^14.0.0",
"@angular/cli": "^14.0.0",
"@angular/common": "^14.0.0",
"@angular/compiler": "^14.0.0",
"@angular/compiler-cli": "^14.0.0",
@@ -76,7 +75,7 @@
"@angular/router": "^14.0.0",
"@ionic/eslint-config": "^0.3.0",
"@ionic/prettier-config": "^2.0.0",
"@schematics/angular": "^17.0.0",
"@schematics/angular": "^14.0.0",
"@types/node": "12.12.5",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",

21
angular/scripts/README.md Normal file
View File

@@ -0,0 +1,21 @@
# Local @ionic/angular test/testapp development
1. `npm install` at the root of `angular`
2. `npm run build.dev` to build local `@ionic/angular` and `@ionic/core`
3. `cd test/testapp` to the test app
4. `npm install` in the test app directory
5. `npm run serve` copies packages and serve the app (see package.json for more options)
6. [http://localhost:4200/](http://localhost:4200/)
# npm link local development
`npm link` doesn't work as expected due to the `devDependency` on `@angular/core`. This is the work around...
npm run build.link ../ionic-conference-app
When the command above is ran from the `angular` directory, it will build `@ionic/angular` and copy the `dist` directory to the correct location of another local project. In the example above, the end result is that it copies the `dist` directory to `../ionic-conference-app/node_modules/@ionic/angular/dist`. The path given should be relative to the root of this mono repo.
## package.json note
The `package.json` file in this directory references __Ionic 3__ and is in here to get GitHub to properly show the Used By counts on the repo. __Do not remove it!__

View File

@@ -5,7 +5,7 @@ const spawn = require('child_process').spawn;
const typescriptPath = path.join(__dirname, '..', 'node_modules', '.bin');
function copyCSS() {
const src = path.join(__dirname, '..', '..', '..', 'core', 'css');
const src = path.join(__dirname, '..', '..', 'core', 'css');
const dst = path.join(__dirname, '..','dist', 'css');
fs.removeSync(dst);

40
angular/scripts/link-copy.js vendored Normal file
View File

@@ -0,0 +1,40 @@
const fs = require('fs-extra');
const path = require('path');
let prjDir = process.argv[2];
if (!prjDir) {
throw new Error('local path required as last argument to "npm run build.link" command');
}
prjDir = path.join(__dirname, '../../../', prjDir);
copyPackage(prjDir, 'angular');
copyPackage(prjDir, 'core');
function copyPackage(prjDir, pkgName) {
const prjDest = path.join(prjDir, 'node_modules', '@ionic', pkgName);
const pkgSrcDir = path.join(__dirname, '..', '..', pkgName);
const pkgSrcDist = path.join(pkgSrcDir, 'dist');
const pkgJsonPath = path.join(pkgSrcDir, 'package.json');
const pkgJson = require(pkgJsonPath);
// make sure this local project exists
fs.emptyDirSync(prjDest);
pkgJson.files.push('package.json');
pkgJson.files.forEach(f => {
const src = path.join(pkgSrcDir, f);
const dest = path.join(prjDest, f);
console.log('copying:', src, 'to', dest);
fs.copySync(src, dest);
});
const prjReadme = path.join(prjDest, 'README.md');
console.log('readme:', prjReadme);
fs.writeFileSync(prjReadme, '@ionic/' + pkgName + ' copied from ' + pkgSrcDir + ', ' + new Date());
}

View File

@@ -6,7 +6,7 @@ set -e
rm -f *.tgz
# Pack @ionic/core
npm pack ../../core
npm pack ../core
# Install Dependencies
npm install *.tgz --no-save

View File

@@ -1,9 +1,11 @@
import { NgZone } from '@angular/core';
import type { Config, IonicWindow } from '@ionic/angular/common';
import { raf } from '@ionic/angular/common';
import { setupConfig } from '@ionic/core';
import { applyPolyfills, defineCustomElements } from '@ionic/core/loader';
import { Config } from './providers/config';
import { IonicWindow } from './types/interfaces';
import { raf } from './util/util';
// TODO(FW-2827): types
export const appInitialize = (config: Config, doc: Document, zone: NgZone) => {

View File

@@ -12,14 +12,6 @@ export const proxyInputs = (Cmp: any, inputs: string[]) => {
set(val: any) {
this.z.runOutsideAngular(() => (this.el[item] = val));
},
/**
* In the event that proxyInputs is called
* multiple times re-defining these inputs
* will cause an error to be thrown. As a result
* we set configurable: true to indicate these
* properties can be changed.
*/
configurable: true,
});
});
};

View File

@@ -1,6 +1,7 @@
import { Directive, HostListener, ElementRef, Injector } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ValueAccessor, setIonicClasses } from '@ionic/angular/common';
import { ValueAccessor, setIonicClasses } from './value-accessor';
@Directive({
selector: 'ion-checkbox,ion-toggle',
@@ -18,8 +19,8 @@ export class BooleanValueAccessorDirective extends ValueAccessor {
}
writeValue(value: boolean): void {
this.elementRef.nativeElement.checked = this.lastValue = value;
setIonicClasses(this.elementRef);
this.el.nativeElement.checked = this.lastValue = value;
setIonicClasses(this.el);
}
@HostListener('ionChange', ['$event.target'])

View File

@@ -1,6 +1,7 @@
import { Directive, HostListener, ElementRef, Injector } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ValueAccessor } from '@ionic/angular/common';
import { ValueAccessor } from './value-accessor';
@Directive({
selector: 'ion-input[type=number]',

View File

@@ -1,6 +1,7 @@
import { ElementRef, Injector, Directive, HostListener } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ValueAccessor } from '@ionic/angular/common';
import { ValueAccessor } from './value-accessor';
@Directive({
/* tslint:disable-next-line:directive-selector */
@@ -18,12 +19,9 @@ export class RadioValueAccessorDirective extends ValueAccessor {
super(injector, el);
}
// TODO(FW-2827): type (HTMLIonRadioElement and HTMLElement are both missing `checked`)
@HostListener('ionSelect', ['$event.target'])
_handleIonSelect(el: any): void {
/**
* The `el` type is any to access the `checked` state property
* that is not exposed on the type interface.
*/
this.handleValueChange(el, el.checked);
}
}

View File

@@ -1,10 +1,11 @@
import { ElementRef, Injector, Directive, HostListener } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ValueAccessor } from '@ionic/angular/common';
import { ValueAccessor } from './value-accessor';
@Directive({
/* tslint:disable-next-line:directive-selector */
selector: 'ion-select, ion-radio-group, ion-segment, ion-datetime',
selector: 'ion-range, ion-select, ion-radio-group, ion-segment, ion-datetime',
providers: [
{
provide: NG_VALUE_ACCESSOR,
@@ -20,7 +21,12 @@ export class SelectValueAccessorDirective extends ValueAccessor {
@HostListener('ionChange', ['$event.target'])
_handleChangeEvent(
el: HTMLIonSelectElement | HTMLIonRadioGroupElement | HTMLIonSegmentElement | HTMLIonDatetimeElement
el:
| HTMLIonRangeElement
| HTMLIonSelectElement
| HTMLIonRadioGroupElement
| HTMLIonSegmentElement
| HTMLIonDatetimeElement
): void {
this.handleValueChange(el, el.value);
}

View File

@@ -1,10 +1,10 @@
import { ElementRef, Injector, Directive, HostListener } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ValueAccessor } from '@ionic/angular/common';
// TODO(FW-5495): rename class since range isn't a text component
import { ValueAccessor } from './value-accessor';
@Directive({
selector: 'ion-input:not([type=number]),ion-textarea,ion-searchbar,ion-range',
selector: 'ion-input:not([type=number]),ion-textarea,ion-searchbar',
providers: [
{
provide: NG_VALUE_ACCESSOR,
@@ -19,9 +19,7 @@ export class TextValueAccessorDirective extends ValueAccessor {
}
@HostListener('ionInput', ['$event.target'])
_handleInputEvent(
el: HTMLIonInputElement | HTMLIonTextareaElement | HTMLIonSearchbarElement | HTMLIonRangeElement
): void {
_handleInputEvent(el: HTMLIonInputElement | HTMLIonTextareaElement | HTMLIonSearchbarElement): void {
this.handleValueChange(el, el.value);
}
}

View File

@@ -2,7 +2,7 @@ import { AfterViewInit, ElementRef, Injector, OnDestroy, Directive, HostListener
import { ControlValueAccessor, NgControl } from '@angular/forms';
import { Subscription } from 'rxjs';
import { raf } from '../../utils/util';
import { raf } from '../../util/util';
// TODO(FW-2827): types
@@ -17,11 +17,11 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
protected lastValue: any;
private statusChanges?: Subscription;
constructor(protected injector: Injector, protected elementRef: ElementRef) {}
constructor(protected injector: Injector, protected el: ElementRef) {}
writeValue(value: any): void {
this.elementRef.nativeElement.value = this.lastValue = value;
setIonicClasses(this.elementRef);
this.el.nativeElement.value = this.lastValue = value;
setIonicClasses(this.el);
}
/**
@@ -38,20 +38,20 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
* @param value The new value of the control.
*/
handleValueChange(el: HTMLElement, value: any): void {
if (el === this.elementRef.nativeElement) {
if (el === this.el.nativeElement) {
if (value !== this.lastValue) {
this.lastValue = value;
this.onChange(value);
}
setIonicClasses(this.elementRef);
setIonicClasses(this.el);
}
}
@HostListener('ionBlur', ['$event.target'])
_handleBlurEvent(el: any): void {
if (el === this.elementRef.nativeElement) {
if (el === this.el.nativeElement) {
this.onTouched();
setIonicClasses(this.elementRef);
setIonicClasses(this.el);
}
}
@@ -64,7 +64,7 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
}
setDisabledState(isDisabled: boolean): void {
this.elementRef.nativeElement.disabled = isDisabled;
this.el.nativeElement.disabled = isDisabled;
}
ngOnDestroy(): void {
@@ -87,7 +87,7 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
// Listen for changes in validity, disabled, or pending states
if (ngControl.statusChanges) {
this.statusChanges = ngControl.statusChanges.subscribe(() => setIonicClasses(this.elementRef));
this.statusChanges = ngControl.statusChanges.subscribe(() => setIonicClasses(this.el));
}
/**
@@ -102,7 +102,7 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
const oldFn = formControl[method].bind(formControl);
formControl[method] = (...params: any[]) => {
oldFn(...params);
setIonicClasses(this.elementRef);
setIonicClasses(this.el);
};
}
});
@@ -129,7 +129,7 @@ export const setIonicClasses = (element: ElementRef): void => {
const getClasses = (element: HTMLElement) => {
const classList = element.classList;
const classes: string[] = [];
const classes = [];
for (let i = 0; i < classList.length; i++) {
const item = classList.item(i);
if (item !== null && startsWith(item, 'ng-')) {

View File

@@ -0,0 +1,41 @@
import { Directive, HostListener, Input, Optional } from '@angular/core';
import { AnimationBuilder } from '@ionic/core';
import { Config } from '../../providers/config';
import { NavController } from '../../providers/nav-controller';
import { IonRouterOutlet } from './ion-router-outlet';
@Directive({
selector: 'ion-back-button',
})
export class IonBackButtonDelegateDirective {
@Input()
defaultHref: string | undefined | null;
@Input()
routerAnimation?: AnimationBuilder;
constructor(
@Optional() private routerOutlet: IonRouterOutlet,
private navCtrl: NavController,
private config: Config
) {}
/**
* @internal
*/
@HostListener('click', ['$event'])
onClick(ev: Event): void {
const defaultHref = this.defaultHref || this.config.get('backButtonDefaultHref');
if (this.routerOutlet?.canGoBack()) {
this.navCtrl.setDirection('back', undefined, undefined, this.routerAnimation);
this.routerOutlet.pop();
ev.preventDefault();
} else if (defaultHref != null) {
this.navCtrl.navigateBack(defaultHref, { animation: this.routerAnimation });
ev.preventDefault();
}
}
}

View File

@@ -15,23 +15,18 @@ import {
Output,
SkipSelf,
EnvironmentInjector,
Input,
InjectionToken,
Injectable,
reflectComponentType,
} from '@angular/core';
import type { Provider } from '@angular/core';
import { OutletContext, Router, ActivatedRoute, ChildrenOutletContexts, PRIMARY_OUTLET, Data } from '@angular/router';
import { componentOnReady } from '@ionic/core/components';
import type { AnimationBuilder } from '@ionic/core/components';
import { Observable, BehaviorSubject, Subscription, combineLatest, of } from 'rxjs';
import { componentOnReady } from '@ionic/core';
import { Observable, BehaviorSubject } from 'rxjs';
import { distinctUntilChanged, filter, switchMap } from 'rxjs/operators';
import { AnimationBuilder } from '../../ionic-core';
import { Config } from '../../providers/config';
import { NavController } from '../../providers/nav-controller';
import { StackController } from './stack-controller';
import { RouteView, StackDidChangeEvent, StackWillChangeEvent, getUrl, isTabSwitch } from './stack-utils';
import { RouteView, getUrl } from './stack-utils';
// TODO(FW-2827): types
@@ -44,34 +39,24 @@ import { RouteView, StackDidChangeEvent, StackWillChangeEvent, getUrl, isTabSwit
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class IonRouterOutlet implements OnDestroy, OnInit {
nativeEl: HTMLIonRouterOutletElement;
activatedView: RouteView | null = null;
tabsPrefix: string | undefined;
private activated: ComponentRef<any> | null = null;
activatedView: RouteView | null = null;
private _activatedRoute: ActivatedRoute | null = null;
private _swipeGesture?: boolean;
private name: string;
private stackCtrl: StackController;
// Maintain map of activated route proxies for each component instance
private proxyMap = new WeakMap<any, ActivatedRoute>();
// Keep the latest activated route in a subject for the proxy routes to switch map to
private currentActivatedRoute$ = new BehaviorSubject<{ component: any; activatedRoute: ActivatedRoute } | null>(null);
private activated: ComponentRef<any> | null = null;
/** @internal */
get activatedComponentRef(): ComponentRef<any> | null {
return this.activated;
}
private _activatedRoute: ActivatedRoute | null = null;
/**
* The name of the outlet
*/
@Input() name = PRIMARY_OUTLET;
/** @internal */
@Output() stackWillChange = new EventEmitter<StackWillChangeEvent>();
/** @internal */
@Output() stackDidChange = new EventEmitter<StackDidChangeEvent>();
tabsPrefix: string | undefined;
@Output() stackEvents = new EventEmitter<any>();
// eslint-disable-next-line @angular-eslint/no-output-rename
@Output('activate') activateEvents = new EventEmitter<any>();
// eslint-disable-next-line @angular-eslint/no-output-rename
@@ -80,9 +65,6 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
private parentContexts = inject(ChildrenOutletContexts);
private location = inject(ViewContainerRef);
private environmentInjector = inject(EnvironmentInjector);
private inputBinder = inject(INPUT_BINDER, { optional: true });
/** @nodoc */
readonly supportsBindingToComponentInputs = true;
// Ionic providers
private config = inject(Config);
@@ -127,7 +109,6 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
ngOnDestroy(): void {
this.stackCtrl.destroy();
this.inputBinder?.unsubscribeFromRouteData(this);
}
getContext(): OutletContext | null {
@@ -294,8 +275,6 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
this.currentActivatedRoute$.next({ component: cmpRef.instance, activatedRoute });
}
this.inputBinder?.bindActivatedRouteToOutletComponent(this);
this.activatedView = enteringView;
/**
@@ -309,16 +288,9 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
*/
this.navCtrl.setTopOutlet(this);
const leavingView = this.stackCtrl.getActiveView();
this.stackWillChange.emit({
enteringView,
tabSwitch: isTabSwitch(enteringView, leavingView),
});
this.stackCtrl.setActive(enteringView).then((data) => {
this.activateEvents.emit(cmpRef.instance);
this.stackDidChange.emit(data);
this.stackEvents.emit(data);
});
}
@@ -443,98 +415,3 @@ class OutletInjector implements Injector {
return this.parent.get(token, notFoundValue);
}
}
// TODO: FW-4785 - Remove this once Angular 15 support is dropped
const INPUT_BINDER = new InjectionToken<RoutedComponentInputBinder>('');
/**
* Injectable used as a tree-shakable provider for opting in to binding router data to component
* inputs.
*
* The RouterOutlet registers itself with this service when an `ActivatedRoute` is attached or
* activated. When this happens, the service subscribes to the `ActivatedRoute` observables (params,
* queryParams, data) and sets the inputs of the component using `ComponentRef.setInput`.
* Importantly, when an input does not have an item in the route data with a matching key, this
* input is set to `undefined`. If it were not done this way, the previous information would be
* retained if the data got removed from the route (i.e. if a query parameter is removed).
*
* The `RouterOutlet` should unregister itself when destroyed via `unsubscribeFromRouteData` so that
* the subscriptions are cleaned up.
*/
@Injectable()
class RoutedComponentInputBinder {
private outletDataSubscriptions = new Map<IonRouterOutlet, Subscription>();
bindActivatedRouteToOutletComponent(outlet: IonRouterOutlet): void {
this.unsubscribeFromRouteData(outlet);
this.subscribeToRouteData(outlet);
}
unsubscribeFromRouteData(outlet: IonRouterOutlet): void {
this.outletDataSubscriptions.get(outlet)?.unsubscribe();
this.outletDataSubscriptions.delete(outlet);
}
private subscribeToRouteData(outlet: IonRouterOutlet) {
const { activatedRoute } = outlet;
const dataSubscription = combineLatest([activatedRoute.queryParams, activatedRoute.params, activatedRoute.data])
.pipe(
switchMap(([queryParams, params, data], index) => {
data = { ...queryParams, ...params, ...data };
// Get the first result from the data subscription synchronously so it's available to
// the component as soon as possible (and doesn't require a second change detection).
if (index === 0) {
return of(data);
}
// Promise.resolve is used to avoid synchronously writing the wrong data when
// two of the Observables in the `combineLatest` stream emit one after
// another.
return Promise.resolve(data);
})
)
.subscribe((data) => {
// Outlet may have been deactivated or changed names to be associated with a different
// route
if (
!outlet.isActivated ||
!outlet.activatedComponentRef ||
outlet.activatedRoute !== activatedRoute ||
activatedRoute.component === null
) {
this.unsubscribeFromRouteData(outlet);
return;
}
const mirror = reflectComponentType(activatedRoute.component);
if (!mirror) {
this.unsubscribeFromRouteData(outlet);
return;
}
for (const { templateName } of mirror.inputs) {
outlet.activatedComponentRef.setInput(templateName, data[templateName]);
}
});
this.outletDataSubscriptions.set(outlet, dataSubscription);
}
}
export const provideComponentInputBinding = (): Provider => {
return {
provide: INPUT_BINDER,
useFactory: componentInputBindingFactory,
deps: [Router],
};
};
function componentInputBindingFactory(router?: Router) {
/**
* We cast the router to any here, since the componentInputBindingEnabled
* property is not available until Angular v16.
*/
if ((router as any)?.componentInputBindingEnabled) {
return new RoutedComponentInputBinder();
}
return null;
}

View File

@@ -1,70 +1,62 @@
import {
AfterContentChecked,
AfterContentInit,
Directive,
ElementRef,
EventEmitter,
HostListener,
Output,
ViewChild,
} from '@angular/core';
import { Component, ContentChild, EventEmitter, HostListener, Output, ViewChild } from '@angular/core';
import { NavController } from '../../providers/nav-controller';
import { IonTabBar } from '../proxies';
import { StackDidChangeEvent, StackWillChangeEvent } from './stack-utils';
import { IonRouterOutlet } from './ion-router-outlet';
import { StackEvent } from './stack-utils';
@Directive({
@Component({
selector: 'ion-tabs',
template: `<ng-content select="[slot=top]"></ng-content>
<div class="tabs-inner">
<ion-router-outlet #outlet tabs="true" (stackEvents)="onPageSelected($event)"></ion-router-outlet>
</div>
<ng-content></ng-content>`,
styles: [
`
:host {
display: flex;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
flex-direction: column;
width: 100%;
height: 100%;
contain: layout size style;
}
.tabs-inner {
position: relative;
flex: 1;
contain: layout size style;
}
`,
],
})
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class IonTabs implements AfterContentInit, AfterContentChecked {
/**
* Note: These must be redeclared on each child class since it needs
* access to generated components such as IonRouterOutlet and IonTabBar.
*/
outlet: any;
tabBar: any;
tabBars: any;
// eslint-disable-next-line @angular-eslint/component-class-suffix
export class IonTabs {
@ViewChild('outlet', { read: IonRouterOutlet, static: false }) outlet: IonRouterOutlet;
@ContentChild(IonTabBar, { static: false }) tabBar: IonTabBar | undefined;
@ViewChild('tabsInner', { read: ElementRef, static: true }) tabsInner: ElementRef<HTMLDivElement>;
/**
* Emitted before the tab view is changed.
*/
@Output() ionTabsWillChange = new EventEmitter<{ tab: string }>();
/**
* Emitted after the tab view is changed.
*/
@Output() ionTabsDidChange = new EventEmitter<{ tab: string }>();
private tabBarSlot = 'bottom';
constructor(private navCtrl: NavController) {}
ngAfterContentInit(): void {
this.detectSlotChanges();
}
ngAfterContentChecked(): void {
this.detectSlotChanges();
}
/**
* @internal
*/
onStackWillChange({ enteringView, tabSwitch }: StackWillChangeEvent): void {
const stackId = enteringView.stackId;
if (tabSwitch && stackId !== undefined) {
onPageSelected(detail: StackEvent): void {
const stackId = detail.enteringView.stackId;
if (detail.tabSwitch && stackId !== undefined) {
this.ionTabsWillChange.emit({ tab: stackId });
}
}
/**
* @internal
*/
onStackDidChange({ enteringView, tabSwitch }: StackDidChangeEvent): void {
const stackId = enteringView.stackId;
if (tabSwitch && stackId !== undefined) {
if (this.tabBar) {
this.tabBar.selectedTab = stackId;
}
@@ -145,48 +137,4 @@ export class IonTabs implements AfterContentInit, AfterContentChecked {
getSelected(): string | undefined {
return this.outlet.getActiveStackId();
}
/**
* Detects changes to the slot attribute of the tab bar.
*
* If the slot attribute has changed, then the tab bar
* should be relocated to the new slot position.
*/
private detectSlotChanges(): void {
this.tabBars.forEach((tabBar: any) => {
// el is a protected attribute from the generated component wrapper
const currentSlot = tabBar.el.getAttribute('slot');
if (currentSlot !== this.tabBarSlot) {
this.tabBarSlot = currentSlot;
this.relocateTabBar();
}
});
}
/**
* Relocates the tab bar to the new slot position.
*/
private relocateTabBar(): void {
/**
* `el` is a protected attribute from the generated component wrapper.
* To avoid having to manually create the wrapper for tab bar, we
* cast the tab bar to any and access the protected attribute.
*/
const tabBar = (this.tabBar as any).el as HTMLElement;
if (this.tabBarSlot === 'top') {
/**
* A tab bar with a slot of "top" should be inserted
* at the top of the container.
*/
this.tabsInner.nativeElement.before(tabBar);
} else {
/**
* A tab bar with a slot of "bottom" or without a slot
* should be inserted at the end of the container.
*/
this.tabsInner.nativeElement.after(tabBar);
}
}
}

View File

@@ -0,0 +1,40 @@
import { ElementRef, Injector, Directive, EnvironmentInjector } from '@angular/core';
import { AngularDelegate } from '../../providers/angular-delegate';
import { ProxyCmp, proxyOutputs } from '../angular-component-lib/utils';
@ProxyCmp({
inputs: ['animated', 'animation', 'root', 'rootParams', 'swipeGesture'],
methods: [
'push',
'insert',
'insertPages',
'pop',
'popTo',
'popToRoot',
'removeIndex',
'setRoot',
'setPages',
'getActive',
'getByIndex',
'canGoBack',
'getPrevious',
],
})
@Directive({
selector: 'ion-nav',
})
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class NavDelegate {
protected el: HTMLElement;
constructor(
ref: ElementRef,
environmentInjector: EnvironmentInjector,
injector: Injector,
angularDelegate: AngularDelegate
) {
this.el = ref.nativeElement;
ref.nativeElement.delegate = angularDelegate.create(environmentInjector, injector);
proxyOutputs(this, this.el, ['ionNavDidChange', 'ionNavWillChange']);
}
}

View File

@@ -1,7 +1,7 @@
import { LocationStrategy } from '@angular/common';
import { ElementRef, OnChanges, OnInit, Directive, HostListener, Input, Optional } from '@angular/core';
import { Router, RouterLink } from '@angular/router';
import type { AnimationBuilder, RouterDirection } from '@ionic/core/components';
import { AnimationBuilder, RouterDirection } from '@ionic/core';
import { NavController } from '../../providers/nav-controller';

View File

@@ -1,14 +1,14 @@
import { Location } from '@angular/common';
import { ComponentRef, NgZone } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import type { AnimationBuilder, RouterDirection } from '@ionic/core/components';
import { AnimationBuilder, RouterDirection } from '@ionic/core';
import { bindLifecycleEvents } from '../../providers/angular-delegate';
import { NavController } from '../../providers/nav-controller';
import {
RouteView,
StackDidChangeEvent,
StackEvent,
computeStackId,
destroyView,
getUrl,
@@ -61,7 +61,7 @@ export class StackController {
return view;
}
setActive(enteringView: RouteView): Promise<StackDidChangeEvent> {
setActive(enteringView: RouteView): Promise<StackEvent> {
const consumeResult = this.navCtrl.consumeTransition();
let { direction, animation, animationBuilder } = consumeResult;
const leavingView = this.activeView;
@@ -224,13 +224,6 @@ export class StackController {
return this.activeView ? this.activeView.stackId : undefined;
}
/**
* @internal
*/
getActiveView(): RouteView | undefined {
return this.activeView;
}
hasRunningTask(): boolean {
return this.runningTask !== undefined;
}

View File

@@ -1,6 +1,6 @@
import { ComponentRef } from '@angular/core';
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router';
import type { AnimationBuilder, NavDirection, RouterDirection } from '@ionic/core/components';
import { AnimationBuilder, NavDirection, RouterDirection } from '@ionic/core';
export const insertView = (views: RouteView[], view: RouteView, direction: RouterDirection): RouteView[] => {
if (direction === 'root') {
@@ -79,23 +79,10 @@ export const destroyView = (view: RouteView | undefined): void => {
}
};
export interface StackWillChangeEvent {
enteringView: RouteView;
/**
* `true` if the event is trigged as a result of a switch
* between tab navigation stacks.
*/
tabSwitch: boolean;
}
export interface StackDidChangeEvent {
export interface StackEvent {
enteringView: RouteView;
direction: RouterDirection;
animation: NavDirection | undefined;
/**
* `true` if the event is trigged as a result of a switch
* between tab navigation stacks.
*/
tabSwitch: boolean;
}

View File

@@ -1,15 +1,17 @@
/* eslint-disable */
/* tslint:disable */
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ContentChild,
Directive,
ElementRef,
EventEmitter,
NgZone,
TemplateRef,
} from '@angular/core';
import type { Components, ModalBreakpointChangeEventDetail } from '@ionic/core/components';
import { ProxyCmp, proxyOutputs } from '../utils/proxy';
import { ProxyCmp, proxyOutputs } from '../angular-component-lib/utils';
import { Components, ModalBreakpointChangeEventDetail } from '@ionic/core';
export declare interface IonModal extends Components.IonModal {
/**
@@ -33,7 +35,7 @@ export declare interface IonModal extends Components.IonModal {
*/
ionBreakpointDidChange: EventEmitter<CustomEvent<ModalBreakpointChangeEventDetail>>;
/**
* Emitted after the modal has presented. Shorthand for ionModalDidPresent.
* Emitted after the modal has presented. Shorthand for ionModalWillDismiss.
*/
didPresent: EventEmitter<CustomEvent>;
/**
@@ -49,61 +51,65 @@ export declare interface IonModal extends Components.IonModal {
*/
didDismiss: EventEmitter<CustomEvent>;
}
const MODAL_INPUTS = [
'animated',
'keepContentsMounted',
'backdropBreakpoint',
'backdropDismiss',
'breakpoints',
'canDismiss',
'cssClass',
'enterAnimation',
'event',
'handle',
'handleBehavior',
'initialBreakpoint',
'isOpen',
'keyboardClose',
'leaveAnimation',
'mode',
'presentingElement',
'showBackdrop',
'translucent',
'trigger',
];
const MODAL_METHODS = [
'present',
'dismiss',
'onDidDismiss',
'onWillDismiss',
'setCurrentBreakpoint',
'getCurrentBreakpoint',
];
@ProxyCmp({
inputs: MODAL_INPUTS,
methods: MODAL_METHODS,
inputs: [
'animated',
'keepContentsMounted',
'backdropBreakpoint',
'backdropDismiss',
'breakpoints',
'canDismiss',
'cssClass',
'enterAnimation',
'event',
'handle',
'handleBehavior',
'initialBreakpoint',
'isOpen',
'keyboardClose',
'leaveAnimation',
'mode',
'presentingElement',
'showBackdrop',
'translucent',
'trigger',
],
methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss', 'setCurrentBreakpoint', 'getCurrentBreakpoint'],
})
/**
* @Component extends from @Directive
* so by defining the inputs here we
* do not need to re-define them for the
* lazy loaded popover.
*/
@Directive({
@Component({
selector: 'ion-modal',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: MODAL_INPUTS,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `<div class="ion-delegate-host ion-page" *ngIf="isCmpOpen || keepContentsMounted">
<ng-container [ngTemplateOutlet]="template"></ng-container>
</div>`,
inputs: [
'animated',
'keepContentsMounted',
'backdropBreakpoint',
'backdropDismiss',
'breakpoints',
'canDismiss',
'cssClass',
'enterAnimation',
'event',
'handle',
'handleBehavior',
'initialBreakpoint',
'isOpen',
'keyboardClose',
'leaveAnimation',
'mode',
'presentingElement',
'showBackdrop',
'translucent',
'trigger',
],
})
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class IonModal {
// TODO(FW-2827): type
@ContentChild(TemplateRef, { static: false }) template: TemplateRef<any>;
isCmpOpen = false;
isCmpOpen: boolean = false;
protected el: HTMLElement;

View File

@@ -1,16 +1,17 @@
/* eslint-disable */
/* tslint:disable */
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ContentChild,
Directive,
ElementRef,
EventEmitter,
NgZone,
TemplateRef,
} from '@angular/core';
import type { Components } from '@ionic/core/components';
import { ProxyCmp, proxyOutputs } from '../utils/proxy';
import { ProxyCmp, proxyOutputs } from '../angular-component-lib/utils';
import { Components } from '@ionic/core';
export declare interface IonPopover extends Components.IonPopover {
/**
* Emitted after the popover has presented.
@@ -29,7 +30,7 @@ export declare interface IonPopover extends Components.IonPopover {
*/
ionPopoverDidDismiss: EventEmitter<CustomEvent>;
/**
* Emitted after the popover has presented. Shorthand for ionPopoverDidPresent.
* Emitted after the popover has presented. Shorthand for ionPopoverWillDismiss.
*/
didPresent: EventEmitter<CustomEvent>;
/**
@@ -45,54 +46,63 @@ export declare interface IonPopover extends Components.IonPopover {
*/
didDismiss: EventEmitter<CustomEvent>;
}
const POPOVER_INPUTS = [
'alignment',
'animated',
'arrow',
'keepContentsMounted',
'backdropDismiss',
'cssClass',
'dismissOnSelect',
'enterAnimation',
'event',
'isOpen',
'keyboardClose',
'leaveAnimation',
'mode',
'showBackdrop',
'translucent',
'trigger',
'triggerAction',
'reference',
'size',
'side',
];
const POPOVER_METHODS = ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'];
@ProxyCmp({
inputs: POPOVER_INPUTS,
methods: POPOVER_METHODS,
inputs: [
'alignment',
'animated',
'arrow',
'keepContentsMounted',
'backdropDismiss',
'cssClass',
'dismissOnSelect',
'enterAnimation',
'event',
'isOpen',
'keyboardClose',
'leaveAnimation',
'mode',
'showBackdrop',
'translucent',
'trigger',
'triggerAction',
'reference',
'size',
'side',
],
methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'],
})
/**
* @Component extends from @Directive
* so by defining the inputs here we
* do not need to re-define them for the
* lazy loaded popover.
*/
@Directive({
@Component({
selector: 'ion-popover',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: POPOVER_INPUTS,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `<ng-container [ngTemplateOutlet]="template" *ngIf="isCmpOpen || keepContentsMounted"></ng-container>`,
inputs: [
'alignment',
'animated',
'arrow',
'keepContentsMounted',
'backdropDismiss',
'cssClass',
'dismissOnSelect',
'enterAnimation',
'event',
'isOpen',
'keyboardClose',
'leaveAnimation',
'mode',
'showBackdrop',
'translucent',
'trigger',
'triggerAction',
'reference',
'size',
'side',
],
})
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class IonPopover {
// TODO(FW-2827): type
@ContentChild(TemplateRef, { static: false }) template: TemplateRef<any>;
isCmpOpen = false;
isCmpOpen: boolean = false;
protected el: HTMLElement;

View File

@@ -8,6 +8,7 @@ export const DIRECTIVES = [
d.IonAlert,
d.IonApp,
d.IonAvatar,
d.IonBackButton,
d.IonBackdrop,
d.IonBadge,
d.IonBreadcrumb,
@@ -49,6 +50,7 @@ export const DIRECTIVES = [
d.IonMenu,
d.IonMenuButton,
d.IonMenuToggle,
d.IonNav,
d.IonNavLink,
d.IonNote,
d.IonPicker,

View File

@@ -230,6 +230,28 @@ export class IonAvatar {
export declare interface IonAvatar extends Components.IonAvatar {}
@ProxyCmp({
inputs: ['color', 'defaultHref', 'disabled', 'icon', 'mode', 'routerAnimation', 'text', 'type']
})
@Component({
selector: 'ion-back-button',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['color', 'defaultHref', 'disabled', 'icon', 'mode', 'routerAnimation', 'text', 'type'],
})
export class IonBackButton {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
}
export declare interface IonBackButton extends Components.IonBackButton {}
@ProxyCmp({
inputs: ['stopPropagation', 'tappable', 'visible']
})
@@ -507,14 +529,14 @@ export declare interface IonCardTitle extends Components.IonCardTitle {}
@ProxyCmp({
inputs: ['alignment', 'checked', 'color', 'disabled', 'indeterminate', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value']
inputs: ['checked', 'color', 'disabled', 'indeterminate', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value']
})
@Component({
selector: 'ion-checkbox',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['alignment', 'checked', 'color', 'disabled', 'indeterminate', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value'],
inputs: ['checked', 'color', 'disabled', 'indeterminate', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value'],
})
export class IonCheckbox {
protected el: HTMLElement;
@@ -635,7 +657,7 @@ Set `scrollEvents` to `true` to enable.
@ProxyCmp({
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'formatOptions', 'highlightedDates', 'hourCycle', 'hourValues', 'isDateEnabled', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'multiple', 'name', 'preferWheel', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'titleSelectedDatesFormatter', 'value', 'yearValues'],
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'highlightedDates', 'hourCycle', 'hourValues', 'isDateEnabled', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'multiple', 'name', 'preferWheel', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'titleSelectedDatesFormatter', 'value', 'yearValues'],
methods: ['confirm', 'reset', 'cancel']
})
@Component({
@@ -643,7 +665,7 @@ Set `scrollEvents` to `true` to enable.
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'formatOptions', 'highlightedDates', 'hourCycle', 'hourValues', 'isDateEnabled', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'multiple', 'name', 'preferWheel', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'titleSelectedDatesFormatter', 'value', 'yearValues'],
inputs: ['cancelText', 'clearText', 'color', 'dayValues', 'disabled', 'doneText', 'firstDayOfWeek', 'highlightedDates', 'hourCycle', 'hourValues', 'isDateEnabled', 'locale', 'max', 'min', 'minuteValues', 'mode', 'monthValues', 'multiple', 'name', 'preferWheel', 'presentation', 'readonly', 'showClearButton', 'showDefaultButtons', 'showDefaultTimeLabel', 'showDefaultTitle', 'size', 'titleSelectedDatesFormatter', 'value', 'yearValues'],
})
export class IonDatetime {
protected el: HTMLElement;
@@ -980,9 +1002,8 @@ import type { InputChangeEventDetail as IIonInputInputChangeEventDetail } from '
export declare interface IonInput extends Components.IonInput {
/**
* The `ionInput` event is fired each time the user modifies the input's value.
Unlike the `ionChange` event, the `ionInput` event is fired for each alteration
to the input's value. This typically happens for each keystroke as the user types.
* The `ionInput` event fires when the `value` of an `<ion-input>` element
has been changed.
For elements that accept text input (`type=text`, `type=tel`, etc.), the interface
is [`InputEvent`](https://developer.mozilla.org/en-US/docs/Web/API/InputEvent); for others,
@@ -991,9 +1012,9 @@ the input is cleared on edit, the type is `null`.
*/
ionInput: EventEmitter<CustomEvent<IIonInputInputInputEventDetail>>;
/**
* The `ionChange` event is fired when the user modifies the input's value.
Unlike the `ionInput` event, the `ionChange` event is only fired when changes
are committed, not as the user types.
* The `ionChange` event is fired for `<ion-input>` elements when the user
modifies the element's value. Unlike the `ionInput` event, the `ionChange`
event is not necessarily fired for each alteration to an element's value.
Depending on the way the users interacts with the element, the `ionChange`
event fires at a different moment:
@@ -1373,6 +1394,39 @@ export class IonMenuToggle {
export declare interface IonMenuToggle extends Components.IonMenuToggle {}
@ProxyCmp({
inputs: ['animated', 'animation', 'root', 'rootParams', 'swipeGesture'],
methods: ['push', 'insert', 'insertPages', 'pop', 'popTo', 'popToRoot', 'removeIndex', 'setRoot', 'setPages', 'getActive', 'getByIndex', 'canGoBack', 'getPrevious']
})
@Component({
selector: 'ion-nav',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['animated', 'animation', 'root', 'rootParams', 'swipeGesture'],
})
export class IonNav {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionNavWillChange', 'ionNavDidChange']);
}
}
export declare interface IonNav extends Components.IonNav {
/**
* Event fired when the nav will change components
*/
ionNavWillChange: EventEmitter<CustomEvent<void>>;
/**
* Event fired when the nav has changed components
*/
ionNavDidChange: EventEmitter<CustomEvent<void>>;
}
@ProxyCmp({
inputs: ['component', 'componentProps', 'routerAnimation', 'routerDirection']
})
@@ -1503,14 +1557,14 @@ export declare interface IonProgressBar extends Components.IonProgressBar {}
@ProxyCmp({
inputs: ['alignment', 'color', 'disabled', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value']
inputs: ['color', 'disabled', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value']
})
@Component({
selector: 'ion-radio',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['alignment', 'color', 'disabled', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value'],
inputs: ['color', 'disabled', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value'],
})
export class IonRadio {
protected el: HTMLElement;
@@ -1535,14 +1589,14 @@ export declare interface IonRadio extends Components.IonRadio {
@ProxyCmp({
inputs: ['allowEmptySelection', 'compareWith', 'name', 'value']
inputs: ['allowEmptySelection', 'name', 'value']
})
@Component({
selector: 'ion-radio-group',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['allowEmptySelection', 'compareWith', 'name', 'value'],
inputs: ['allowEmptySelection', 'name', 'value'],
})
export class IonRadioGroup {
protected el: HTMLElement;
@@ -1565,14 +1619,14 @@ export declare interface IonRadioGroup extends Components.IonRadioGroup {
@ProxyCmp({
inputs: ['activeBarStart', 'color', 'debounce', 'disabled', 'dualKnobs', 'label', 'labelPlacement', 'legacy', 'max', 'min', 'mode', 'name', 'pin', 'pinFormatter', 'snaps', 'step', 'ticks', 'value']
inputs: ['activeBarStart', 'color', 'debounce', 'disabled', 'dualKnobs', 'labelPlacement', 'legacy', 'max', 'min', 'mode', 'name', 'pin', 'pinFormatter', 'snaps', 'step', 'ticks', 'value']
})
@Component({
selector: 'ion-range',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['activeBarStart', 'color', 'debounce', 'disabled', 'dualKnobs', 'label', 'labelPlacement', 'legacy', 'max', 'min', 'mode', 'name', 'pin', 'pinFormatter', 'snaps', 'step', 'ticks', 'value'],
inputs: ['activeBarStart', 'color', 'debounce', 'disabled', 'dualKnobs', 'labelPlacement', 'legacy', 'max', 'min', 'mode', 'name', 'pin', 'pinFormatter', 'snaps', 'step', 'ticks', 'value'],
})
export class IonRange {
protected el: HTMLElement;
@@ -1626,7 +1680,7 @@ mouse drag, touch gesture, or keyboard interaction.
@ProxyCmp({
inputs: ['closeDuration', 'disabled', 'mode', 'pullFactor', 'pullMax', 'pullMin', 'snapbackDuration'],
inputs: ['closeDuration', 'disabled', 'pullFactor', 'pullMax', 'pullMin', 'snapbackDuration'],
methods: ['complete', 'cancel', 'getProgress']
})
@Component({
@@ -1634,7 +1688,7 @@ mouse drag, touch gesture, or keyboard interaction.
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['closeDuration', 'disabled', 'mode', 'pullFactor', 'pullMax', 'pullMin', 'snapbackDuration'],
inputs: ['closeDuration', 'disabled', 'pullFactor', 'pullMax', 'pullMin', 'snapbackDuration'],
})
export class IonRefresher {
protected el: HTMLElement;
@@ -1788,7 +1842,7 @@ export declare interface IonRow extends Components.IonRow {}
@ProxyCmp({
inputs: ['animated', 'autocapitalize', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'enterkeyhint', 'inputmode', 'maxlength', 'minlength', 'mode', 'name', 'placeholder', 'searchIcon', 'showCancelButton', 'showClearButton', 'spellcheck', 'type', 'value'],
inputs: ['animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'enterkeyhint', 'inputmode', 'mode', 'placeholder', 'searchIcon', 'showCancelButton', 'showClearButton', 'spellcheck', 'type', 'value'],
methods: ['setFocus', 'getInputElement']
})
@Component({
@@ -1796,7 +1850,7 @@ export declare interface IonRow extends Components.IonRow {}
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['animated', 'autocapitalize', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'enterkeyhint', 'inputmode', 'maxlength', 'minlength', 'mode', 'name', 'placeholder', 'searchIcon', 'showCancelButton', 'showClearButton', 'spellcheck', 'type', 'value'],
inputs: ['animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'enterkeyhint', 'inputmode', 'mode', 'placeholder', 'searchIcon', 'showCancelButton', 'showClearButton', 'spellcheck', 'type', 'value'],
})
export class IonSearchbar {
protected el: HTMLElement;
@@ -1900,7 +1954,7 @@ export declare interface IonSegmentButton extends Components.IonSegmentButton {}
@ProxyCmp({
inputs: ['cancelText', 'color', 'compareWith', 'disabled', 'expandedIcon', 'fill', 'interface', 'interfaceOptions', 'justify', 'label', 'labelPlacement', 'legacy', 'mode', 'multiple', 'name', 'okText', 'placeholder', 'selectedText', 'shape', 'toggleIcon', 'value'],
inputs: ['cancelText', 'color', 'compareWith', 'disabled', 'fill', 'interface', 'interfaceOptions', 'justify', 'label', 'labelPlacement', 'legacy', 'mode', 'multiple', 'name', 'okText', 'placeholder', 'selectedText', 'shape', 'value'],
methods: ['open']
})
@Component({
@@ -1908,7 +1962,7 @@ export declare interface IonSegmentButton extends Components.IonSegmentButton {}
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['cancelText', 'color', 'compareWith', 'disabled', 'expandedIcon', 'fill', 'interface', 'interfaceOptions', 'justify', 'label', 'labelPlacement', 'legacy', 'mode', 'multiple', 'name', 'okText', 'placeholder', 'selectedText', 'shape', 'toggleIcon', 'value'],
inputs: ['cancelText', 'color', 'compareWith', 'disabled', 'fill', 'interface', 'interfaceOptions', 'justify', 'label', 'labelPlacement', 'legacy', 'mode', 'multiple', 'name', 'okText', 'placeholder', 'selectedText', 'shape', 'value'],
})
export class IonSelect {
protected el: HTMLElement;
@@ -2132,15 +2186,17 @@ import type { TextareaInputEventDetail as IIonTextareaTextareaInputEventDetail }
export declare interface IonTextarea extends Components.IonTextarea {
/**
* The `ionChange` event is fired when the user modifies the textarea's value.
Unlike the `ionInput` event, the `ionChange` event is fired when
the element loses focus after its value has been modified.
* The `ionChange` event is fired for `<ion-textarea>` elements when the user
modifies the element's value. Unlike the `ionInput` event, the `ionChange`
event is not necessarily fired for each alteration to an element's value.
The `ionChange` event is fired when the element loses focus after its value
has been modified.
*/
ionChange: EventEmitter<CustomEvent<IIonTextareaTextareaChangeEventDetail>>;
/**
* The `ionInput` event is fired each time the user modifies the textarea's value.
Unlike the `ionChange` event, the `ionInput` event is fired for each alteration
to the textarea's value. This typically happens for each keystroke as the user types.
* The `ionInput` event fires when the `value` of an `<ion-textarea>` element
has been changed.
When `clearOnEdit` is enabled, the `ionInput` event will be fired when
the user clears the textarea by performing a keydown event.
@@ -2201,7 +2257,7 @@ export declare interface IonTitle extends Components.IonTitle {}
@ProxyCmp({
inputs: ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'isOpen', 'keyboardClose', 'layout', 'leaveAnimation', 'message', 'mode', 'position', 'positionAnchor', 'swipeGesture', 'translucent', 'trigger'],
inputs: ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'isOpen', 'keyboardClose', 'layout', 'leaveAnimation', 'message', 'mode', 'position', 'translucent', 'trigger'],
methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss']
})
@Component({
@@ -2209,7 +2265,7 @@ export declare interface IonTitle extends Components.IonTitle {}
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'isOpen', 'keyboardClose', 'layout', 'leaveAnimation', 'message', 'mode', 'position', 'positionAnchor', 'swipeGesture', 'translucent', 'trigger'],
inputs: ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'isOpen', 'keyboardClose', 'layout', 'leaveAnimation', 'message', 'mode', 'position', 'translucent', 'trigger'],
})
export class IonToast {
protected el: HTMLElement;
@@ -2264,14 +2320,14 @@ Shorthand for ionToastDidDismiss.
@ProxyCmp({
inputs: ['alignment', 'checked', 'color', 'disabled', 'enableOnOffLabels', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value']
inputs: ['checked', 'color', 'disabled', 'enableOnOffLabels', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value']
})
@Component({
selector: 'ion-toggle',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['alignment', 'checked', 'color', 'disabled', 'enableOnOffLabels', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value'],
inputs: ['checked', 'color', 'disabled', 'enableOnOffLabels', 'justify', 'labelPlacement', 'legacy', 'mode', 'name', 'value'],
})
export class IonToggle {
protected el: HTMLElement;

View File

@@ -5,45 +5,41 @@ export { RadioValueAccessorDirective as RadioValueAccessor } from './directives/
export { SelectValueAccessorDirective as SelectValueAccessor } from './directives/control-value-accessors/select-value-accessor';
export { TextValueAccessorDirective as TextValueAccessor } from './directives/control-value-accessors/text-value-accessor';
export { IonTabs } from './directives/navigation/ion-tabs';
export { IonBackButton } from './directives/navigation/ion-back-button';
// TODO FW-5889
export { IonBackButton as IonBackButtonDelegate } from './directives/navigation/ion-back-button';
export { IonNav } from './directives/navigation/ion-nav';
export { IonBackButtonDelegateDirective as IonBackButtonDelegate } from './directives/navigation/ion-back-button';
export { NavDelegate } from './directives/navigation/nav-delegate';
export { IonRouterOutlet } from './directives/navigation/ion-router-outlet';
export {
RouterLinkDelegateDirective as RouterLinkDelegate,
RouterLinkWithHrefDelegateDirective as RouterLinkWithHrefDelegate,
} from './directives/navigation/router-link-delegate';
export { NavParams } from './directives/navigation/nav-params';
export { IonModal } from './directives/overlays/modal';
export { IonPopover } from './directives/overlays/popover';
export * from './directives/proxies';
export * from './directives/validators';
// PROVIDERS
export {
DomController,
NavController,
Config,
Platform,
AngularDelegate,
NavParams,
IonicRouteStrategy,
ViewWillEnter,
ViewWillLeave,
ViewDidEnter,
ViewDidLeave,
} from '@ionic/angular/common';
export { AlertController } from './providers/alert-controller';
export { AnimationController } from './providers/animation-controller';
export { AngularDelegate } from './providers/angular-delegate';
export { ActionSheetController } from './providers/action-sheet-controller';
export { GestureController } from './providers/gesture-controller';
export { AlertController } from './providers/alert-controller';
export { LoadingController } from './providers/loading-controller';
export { MenuController } from './providers/menu-controller';
export { ModalController } from './providers/modal-controller';
export { PickerController } from './providers/picker-controller';
export { ModalController } from './providers/modal-controller';
export { Platform } from './providers/platform';
export { PopoverController } from './providers/popover-controller';
export { ToastController } from './providers/toast-controller';
export { NavController } from './providers/nav-controller';
export { DomController } from './providers/dom-controller';
export { Config } from './providers/config';
export { AnimationController } from './providers/animation-controller';
export { GestureController } from './providers/gesture-controller';
// ROUTER STRATEGY
export { IonicRouteStrategy } from './util/ionic-router-reuse-strategy';
// TYPES
export * from './types/ionic-lifecycle-hooks';
// PACKAGE MODULE
export { IonicModule } from './ionic-module';
@@ -58,7 +54,6 @@ export {
getPlatforms,
isPlatform,
getTimeGivenProgression,
getIonPageElement,
// TYPES
Animation,
AnimationBuilder,
@@ -122,7 +117,6 @@ export {
SearchbarInputEventDetail,
SegmentChangeEventDetail,
SegmentCustomEvent,
SegmentValue,
SelectChangeEventDetail,
SelectCustomEvent,
TabsCustomEvent,
@@ -133,6 +127,4 @@ export {
ToastLayout,
ToggleChangeEventDetail,
ToggleCustomEvent,
TransitionOptions,
openURL,
} from '@ionic/core';

View File

@@ -1,6 +1,5 @@
import { CommonModule, DOCUMENT } from '@angular/common';
import { ModuleWithProviders, APP_INITIALIZER, NgModule, NgZone } from '@angular/core';
import { ConfigToken, AngularDelegate, provideComponentInputBinding } from '@ionic/angular/common';
import { IonicConfig } from '@ionic/core';
import { appInitialize } from './app-initialize';
@@ -11,10 +10,10 @@ import {
SelectValueAccessorDirective,
TextValueAccessorDirective,
} from './directives/control-value-accessors';
import { IonBackButton } from './directives/navigation/ion-back-button';
import { IonNav } from './directives/navigation/ion-nav';
import { IonBackButtonDelegateDirective } from './directives/navigation/ion-back-button';
import { IonRouterOutlet } from './directives/navigation/ion-router-outlet';
import { IonTabs } from './directives/navigation/ion-tabs';
import { NavDelegate } from './directives/navigation/nav-delegate';
import {
RouterLinkDelegateDirective,
RouterLinkWithHrefDelegateDirective,
@@ -22,7 +21,8 @@ import {
import { IonModal } from './directives/overlays/modal';
import { IonPopover } from './directives/overlays/popover';
import { DIRECTIVES } from './directives/proxies-list';
import { IonMaxValidator, IonMinValidator } from './directives/validators';
import { AngularDelegate } from './providers/angular-delegate';
import { ConfigToken } from './providers/config';
import { ModalController } from './providers/modal-controller';
import { PopoverController } from './providers/popover-controller';
@@ -44,14 +44,10 @@ const DECLARATIONS = [
// navigation
IonTabs,
IonRouterOutlet,
IonBackButton,
IonNav,
IonBackButtonDelegateDirective,
NavDelegate,
RouterLinkDelegateDirective,
RouterLinkWithHrefDelegateDirective,
// validators
IonMinValidator,
IonMaxValidator,
];
@NgModule({
@@ -75,7 +71,6 @@ export class IonicModule {
multi: true,
deps: [ConfigToken, DOCUMENT, NgZone],
},
provideComponentInputBinding(),
],
};
}

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { OverlayBaseController } from '@ionic/angular/common';
import type { ActionSheetOptions } from '@ionic/core';
import { actionSheetController } from '@ionic/core';
import { ActionSheetOptions, actionSheetController } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable({
providedIn: 'root',

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { OverlayBaseController } from '@ionic/angular/common';
import type { AlertOptions } from '@ionic/core';
import { alertController } from '@ionic/core';
import { AlertOptions, alertController } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable({
providedIn: 'root',

View File

@@ -16,7 +16,7 @@ import {
LIFECYCLE_WILL_ENTER,
LIFECYCLE_WILL_LEAVE,
LIFECYCLE_WILL_UNLOAD,
} from '@ionic/core/components';
} from '@ionic/core';
import { NavParams } from '../directives/navigation/nav-params';

View File

@@ -1,6 +1,5 @@
import { Injectable } from '@angular/core';
import { createAnimation, getTimeGivenProgression } from '@ionic/core';
import type { Animation } from '@ionic/core';
import { Animation, createAnimation, getTimeGivenProgression } from '@ionic/core';
@Injectable({
providedIn: 'root',

View File

@@ -1,5 +1,5 @@
import { Injectable, InjectionToken } from '@angular/core';
import type { Config as CoreConfig, IonicConfig } from '@ionic/core/components';
import { Config as CoreConfig, IonicConfig } from '@ionic/core';
import { IonicWindow } from '../types/interfaces';

View File

@@ -1,6 +1,5 @@
import { Injectable, NgZone } from '@angular/core';
import type { Gesture, GestureConfig } from '@ionic/core';
import { createGesture } from '@ionic/core';
import { NgZone, Injectable } from '@angular/core';
import { Gesture, GestureConfig, createGesture } from '@ionic/core';
@Injectable({
providedIn: 'root',

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { OverlayBaseController } from '@ionic/angular/common';
import type { LoadingOptions } from '@ionic/core';
import { loadingController } from '@ionic/core';
import { LoadingOptions, loadingController } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable({
providedIn: 'root',

View File

@@ -1,15 +1,17 @@
import type { MenuControllerI, AnimationBuilder, MenuI, Animation } from '@ionic/core/components';
export class MenuController implements MenuControllerI {
constructor(private menuController: MenuControllerI) {}
import { Injectable } from '@angular/core';
import { menuController } from '@ionic/core';
@Injectable({
providedIn: 'root',
})
export class MenuController {
/**
* Programmatically open the Menu.
* @param [menuId] Optionally get the menu by its id, or side.
* @return returns a promise when the menu is fully opened
*/
open(menuId?: string): Promise<boolean> {
return this.menuController.open(menuId);
return menuController.open(menuId);
}
/**
@@ -20,7 +22,7 @@ export class MenuController implements MenuControllerI {
* @return returns a promise when the menu is fully closed
*/
close(menuId?: string): Promise<boolean> {
return this.menuController.close(menuId);
return menuController.close(menuId);
}
/**
@@ -30,7 +32,7 @@ export class MenuController implements MenuControllerI {
* @return returns a promise when the menu has been toggled
*/
toggle(menuId?: string): Promise<boolean> {
return this.menuController.toggle(menuId);
return menuController.toggle(menuId);
}
/**
@@ -42,7 +44,7 @@ export class MenuController implements MenuControllerI {
* @return Returns the instance of the menu, which is useful for chaining.
*/
enable(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement | undefined> {
return this.menuController.enable(shouldEnable, menuId);
return menuController.enable(shouldEnable, menuId);
}
/**
@@ -52,7 +54,7 @@ export class MenuController implements MenuControllerI {
* @return Returns the instance of the menu, which is useful for chaining.
*/
swipeGesture(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement | undefined> {
return this.menuController.swipeGesture(shouldEnable, menuId);
return menuController.swipeGesture(shouldEnable, menuId);
}
/**
@@ -61,7 +63,7 @@ export class MenuController implements MenuControllerI {
* If the menuId is not specified, it returns true if ANY menu is currenly open.
*/
isOpen(menuId?: string): Promise<boolean> {
return this.menuController.isOpen(menuId);
return menuController.isOpen(menuId);
}
/**
@@ -69,7 +71,7 @@ export class MenuController implements MenuControllerI {
* @return Returns true if the menu is currently enabled, otherwise false.
*/
isEnabled(menuId?: string): Promise<boolean> {
return this.menuController.isEnabled(menuId);
return menuController.isEnabled(menuId);
}
/**
@@ -82,48 +84,20 @@ export class MenuController implements MenuControllerI {
* @return Returns the instance of the menu if found, otherwise `null`.
*/
get(menuId?: string): Promise<HTMLIonMenuElement | undefined> {
return this.menuController.get(menuId);
return menuController.get(menuId);
}
/**
* @return Returns the instance of the menu already opened, otherwise `null`.
*/
getOpen(): Promise<HTMLIonMenuElement | undefined> {
return this.menuController.getOpen();
return menuController.getOpen();
}
/**
* @return Returns an array of all menu instances.
*/
getMenus(): Promise<HTMLIonMenuElement[]> {
return this.menuController.getMenus();
}
registerAnimation(name: string, animation: AnimationBuilder): void {
return this.menuController.registerAnimation(name, animation);
}
isAnimating(): Promise<boolean> {
return this.menuController.isAnimating();
}
_getOpenSync(): HTMLIonMenuElement | undefined {
return this.menuController._getOpenSync();
}
_createAnimation(type: string, menuCmp: MenuI): Promise<Animation> {
return this.menuController._createAnimation(type, menuCmp);
}
_register(menu: MenuI): void {
return this.menuController._register(menu);
}
_unregister(menu: MenuI): void {
return this.menuController._unregister(menu);
}
_setOpen(menu: MenuI, shouldOpen: boolean, animated: boolean): Promise<boolean> {
return this.menuController._setOpen(menu, shouldOpen, animated);
return menuController.getMenus();
}
}

View File

@@ -1,7 +1,9 @@
import { Injector, Injectable, EnvironmentInjector, inject } from '@angular/core';
import { AngularDelegate, OverlayBaseController } from '@ionic/angular/common';
import type { ModalOptions } from '@ionic/core';
import { modalController } from '@ionic/core';
import { ModalOptions, modalController } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
import { AngularDelegate } from './angular-delegate';
@Injectable()
export class ModalController extends OverlayBaseController<ModalOptions, HTMLIonModalElement> {

View File

@@ -1,9 +1,9 @@
import { Location } from '@angular/common';
import { Injectable, Optional } from '@angular/core';
import { NavigationExtras, Router, UrlSerializer, UrlTree, NavigationStart } from '@angular/router';
import type { AnimationBuilder, NavDirection, RouterDirection } from '@ionic/core/components';
import { AnimationBuilder, NavDirection, RouterDirection } from '@ionic/core';
import { IonRouterOutlet } from '../directives/navigation/router-outlet';
import { IonRouterOutlet } from '../directives/navigation/ion-router-outlet';
import { Platform } from './platform';
@@ -131,21 +131,17 @@ export class NavController {
*
* It recursively finds the top active `ion-router-outlet` and calls `pop()`.
* This is the recommended way to go back when you are using `ion-router-outlet`.
*
* Resolves to `true` if it was able to pop.
*/
async pop(): Promise<boolean> {
async pop(): Promise<void> {
let outlet = this.topOutlet;
while (outlet) {
if (await outlet.pop()) {
return true;
break;
} else {
outlet = outlet.parentOutlet;
}
}
return false;
}
/**

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { OverlayBaseController } from '@ionic/angular/common';
import type { PickerOptions } from '@ionic/core';
import { pickerController } from '@ionic/core';
import { PickerOptions, pickerController } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable({
providedIn: 'root',

View File

@@ -1,7 +1,6 @@
import { DOCUMENT } from '@angular/common';
import { NgZone, Inject, Injectable } from '@angular/core';
import { getPlatforms, isPlatform } from '@ionic/core/components';
import type { BackButtonEventDetail, KeyboardEventDetail, Platforms } from '@ionic/core/components';
import { BackButtonEventDetail, KeyboardEventDetail, Platforms, getPlatforms, isPlatform } from '@ionic/core';
import { Subscription, Subject } from 'rxjs';
// TODO(FW-2827): types
@@ -23,13 +22,13 @@ export class Platform {
/**
* @hidden
*/
backButton = new Subject<BackButtonEventDetail>() as BackButtonEmitter;
backButton: BackButtonEmitter = new Subject<BackButtonEventDetail>() as any;
/**
* The keyboardDidShow event emits when the
* on-screen keyboard is presented.
*/
keyboardDidShow = new Subject<KeyboardEventDetail>();
keyboardDidShow = new Subject<KeyboardEventDetail>() as any;
/**
* The keyboardDidHide event emits when the
@@ -68,12 +67,12 @@ export class Platform {
});
};
proxyEvent(this.pause, doc, 'pause', zone);
proxyEvent(this.resume, doc, 'resume', zone);
proxyEvent(this.backButton, doc, 'ionBackButton', zone);
proxyEvent(this.resize, this.win, 'resize', zone);
proxyEvent(this.keyboardDidShow, this.win, 'ionKeyboardDidShow', zone);
proxyEvent(this.keyboardDidHide, this.win, 'ionKeyboardDidHide', zone);
proxyEvent(this.pause, doc, 'pause');
proxyEvent(this.resume, doc, 'resume');
proxyEvent(this.backButton, doc, 'ionBackButton');
proxyEvent(this.resize, this.win, 'resize');
proxyEvent(this.keyboardDidShow, this.win, 'ionKeyboardDidShow');
proxyEvent(this.keyboardDidHide, this.win, 'ionKeyboardDidHide');
let readyResolve: (value: string) => void;
this._readyPromise = new Promise((res) => {
@@ -262,20 +261,12 @@ const readQueryParam = (url: string, key: string) => {
return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null;
};
const proxyEvent = <T>(emitter: Subject<T>, el: EventTarget, eventName: string, zone: NgZone) => {
const proxyEvent = <T>(emitter: Subject<T>, el: EventTarget, eventName: string) => {
if (el) {
el.addEventListener(eventName, (ev) => {
/**
* `zone.run` is required to make sure that we are running inside the Angular zone
* at all times. This is necessary since an app that has Capacitor will
* override the `document.addEventListener` with its own implementation.
* The override causes the event to no longer be in the Angular zone.
*/
zone.run(() => {
// ?? cordova might emit "null" events
const value = ev != null ? (ev as any).detail : undefined;
emitter.next(value);
});
// ?? cordova might emit "null" events
const value = ev != null ? (ev as any).detail : undefined;
emitter.next(value);
});
}
};

View File

@@ -1,8 +1,11 @@
import { Injector, inject, EnvironmentInjector } from '@angular/core';
import { AngularDelegate, OverlayBaseController } from '@ionic/angular/common';
import type { PopoverOptions } from '@ionic/core';
import { popoverController } from '@ionic/core';
import { Injector, Injectable, inject, EnvironmentInjector } from '@angular/core';
import { PopoverOptions, popoverController } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
import { AngularDelegate } from './angular-delegate';
@Injectable()
export class PopoverController extends OverlayBaseController<PopoverOptions, HTMLIonPopoverElement> {
private angularDelegate = inject(AngularDelegate);
private injector = inject(Injector);

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { OverlayBaseController } from '@ionic/angular/common';
import type { ToastOptions } from '@ionic/core';
import { toastController } from '@ionic/core';
import { ToastOptions, toastController } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable({
providedIn: 'root',

View File

@@ -0,0 +1,6 @@
/* Ionic Variables and Theming. */
/* This is just a placeholder file For more info, please see: */
/* https://ionicframework.com/docs/theming/basics */
/* To quickly generate your own theme, check out the color generator */
/* https://ionicframework.com/docs/theming/color-generator */

View File

@@ -12,19 +12,10 @@ import {
url,
} from '@angular-devkit/schematics';
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
import { addRootProvider } from '@schematics/angular/utility';
import { getWorkspace } from '@schematics/angular/utility/workspace';
import { addIonicModuleImportToNgModule } from '../utils/ast';
import {
addArchitectBuilder,
addAsset,
addCli,
addSchematics,
addStyle,
getDefaultAngularAppName,
} from './../utils/config';
import { addModuleImportToRootModule } from './../utils/ast';
import { addArchitectBuilder, addAsset, addStyle, getDefaultAngularAppName } from './../utils/config';
import { addPackageToPackageJson } from './../utils/package';
import { Schema as IonAddOptions } from './schema';
@@ -42,53 +33,9 @@ function addIonicAngularToolkitToPackageJson(): Rule {
};
}
/**
* Adds the @ionic/angular-toolkit schematics and cli configuration to the project's `angular.json` file.
* @param projectName The name of the project.
*/
function addIonicAngularToolkitToAngularJson(): Rule {
return (host: Tree) => {
addCli(host, '@ionic/angular-toolkit');
addSchematics(host, '@ionic/angular-toolkit:component', {
styleext: 'scss',
});
addSchematics(host, '@ionic/angular-toolkit:page', {
styleext: 'scss',
});
return host;
};
}
/**
* Adds the `IonicModule.forRoot()` usage to the project's `AppModule`.
* If the project does not use modules this will operate as a noop.
* @param projectSourceRoot The source root path of the project.
*/
function addIonicAngularModuleToAppModule(projectSourceRoot: Path): Rule {
return (host: Tree) => {
const appModulePath = `${projectSourceRoot}/app/app.module.ts`;
if (host.exists(appModulePath)) {
addIonicModuleImportToNgModule(host, appModulePath);
}
return host;
};
}
/**
* Adds the `provideIonicAngular` usage to the project's app config.
* If the project does not use an app config this will operate as a noop.
* @param projectName The name of the project.
* @param projectSourceRoot The source root path of the project.
*/
function addProvideIonicAngular(projectName: string, projectSourceRoot: Path): Rule {
return (host: Tree) => {
const appConfig = `${projectSourceRoot}/app/app.config.ts`;
if (host.exists(appConfig)) {
return addRootProvider(
projectName,
({ code, external }) => code`${external('provideIonicAngular', '@ionic/angular/standalone')}({})`
);
}
addModuleImportToRootModule(host, projectSourceRoot, 'IonicModule.forRoot()', '@ionic/angular');
return host;
};
}
@@ -116,49 +63,15 @@ function addIonicStyles(projectName: string, projectSourceRoot: Path): Rule {
};
}
function addIonicons(projectName: string, projectSourceRoot: Path): Rule {
function addIonicons(projectName: string): Rule {
return (host: Tree) => {
const hasAppModule = host.exists(`${projectSourceRoot}/app/app.module.ts`);
if (hasAppModule) {
/**
* Add Ionicons to the `angular.json` file only if the project
* is using the lazy build of `@ionic/angular` with modules.
*/
const ioniconsGlob = {
glob: '**/*.svg',
input: 'node_modules/ionicons/dist/ionicons/svg',
output: './svg',
};
addAsset(host, projectName, 'build', ioniconsGlob);
addAsset(host, projectName, 'test', ioniconsGlob);
}
return host;
};
}
function addIonicConfig(projectSourceRoot: string): Rule {
return (host: Tree) => {
const ionicConfig = 'ionic.config.json';
if (!host.exists(ionicConfig)) {
const hasAppModule = host.exists(`${projectSourceRoot}/app/app.module.ts`);
const type = hasAppModule ? 'angular' : 'angular-standalone';
host.create(
ionicConfig,
JSON.stringify(
{
name: 'ionic-app',
app_id: '',
type,
integrations: {},
},
null,
2
)
);
}
const ioniconsGlob = {
glob: '**/*.svg',
input: 'node_modules/ionicons/dist/ionicons/svg',
output: './svg',
};
addAsset(host, projectName, 'build', ioniconsGlob);
addAsset(host, projectName, 'test', ioniconsGlob);
return host;
};
}
@@ -216,13 +129,10 @@ export default function ngAdd(options: IonAddOptions): Rule {
// @ionic/angular
addIonicAngularToPackageJson(),
addIonicAngularToolkitToPackageJson(),
addIonicAngularToolkitToAngularJson(),
addIonicAngularModuleToAppModule(sourcePath),
addProvideIonicAngular(options.project, sourcePath),
addIonicBuilder(options.project),
addIonicStyles(options.project, sourcePath),
addIonicons(options.project, sourcePath),
addIonicConfig(sourcePath),
addIonicons(options.project),
mergeWith(rootTemplateSource),
// install freshly added dependencies
installNodeDeps(),

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