Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ jobs:
strategy:
fail-fast: false
matrix:
apps: [ng16, ng17, ng18, ng19, ng20]
apps: [ng18, ng19, ng20, ng21]
needs: [build-angular, build-angular-server]
runs-on: ubuntu-latest
steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/stencil-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ jobs:
strategy:
fail-fast: false
matrix:
apps: [ng16, ng17, ng18, ng19, ng20]
apps: [ng18, ng19, ng20, ng21]
needs: [build-angular, build-angular-server]
runs-on: ubuntu-latest
steps:
Expand Down
87 changes: 87 additions & 0 deletions BREAKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ This is a comprehensive list of the breaking changes introduced in the major ver
- [Legacy Picker](#version-9x-legacy-picker)
- [Router Outlet](#version-9x-router-outlet)
- [Select](#version-9x-select)
- [Input and Searchbar](#version-9x-input-searchbar)
- [Framework Specific](#version-9x-framework-specific)
- [Angular](#version-9x-angular)
- [React](#version-9x-react)
- [Vue](#version-9x-vue)

Expand All @@ -31,7 +33,9 @@ This section details the desktop browser, JavaScript framework, and mobile platf
**Minimum JavaScript Framework Versions**
| Framework | Supported Version |
| --------- | --------------------- |
| Angular | 18+ |
| React | 18+ |
| Vue | 3.5+ |

<h2 id="version-9x-package-exports">Package Exports</h2>

Expand Down Expand Up @@ -97,8 +101,91 @@ The `ionChange` event on `ion-select` now only fires when the selected value act

Apps that relied on `ionChange` firing on every confirmation (for example, to detect overlay dismissal without a value change) should listen for `ionDismiss` instead, or use the `didDismiss` event on the underlying alert or action sheet.

<h4 id="version-9x-input-searchbar">Input and Searchbar</h4>

The `autocorrect` property on `ion-input` and `ion-searchbar` is now a `boolean` and defaults to `false`. It was previously typed as `'on' | 'off'` with a default of `'off'`. This resolves a type conflict introduced when TypeScript 5.9 added `autocorrect: boolean` to the DOM `HTMLElement` interface.

The string form no longer behaves the same way. Because an HTML attribute coerces to `true` for any non-empty string, `autocorrect="off"` now evaluates to `true` (autocorrect enabled). Migrate to the boolean property:

- Remove the attribute to keep autocorrect disabled (the default).
- Use a property binding to enable it: `[autocorrect]="true"` (Angular), `autocorrect={true}` (React), or `:autocorrect="true"` (Vue).

<h2 id="version-9x-framework-specific">Framework Specific</h2>

<h4 id="version-9x-angular">Angular</h4>

**Minimum Angular Version**

Ionic 9 requires Angular 18 or later. Angular 16 and 17 are no longer supported.

**Angular 21 Requires Explicit Zone Change Detection**

Angular 21 defaults `bootstrapModule()` and `bootstrapApplication()` to zoneless change detection. `zone.js` in your polyfills is ignored unless you opt back in explicitly, which surfaces as runtime `NG0909` errors and breaks change detection for asynchronous updates (modal and popover lifecycle, tab navigation, and anything depending on async-resolved state). Ionic 9 relies on zone-based change detection, so apps on Angular 21 must provide it explicitly.

Standalone bootstrap:

```diff
import { bootstrapApplication } from '@angular/platform-browser';
+ import { provideZoneChangeDetection } from '@angular/core';

bootstrapApplication(AppComponent, {
providers: [
+ provideZoneChangeDetection(),
// ...other providers
],
});
```

NgModule bootstrap:

```diff
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+ import { provideZoneChangeDetection } from '@angular/core';

platformBrowserDynamic()
- .bootstrapModule(AppModule)
+ .bootstrapModule(AppModule, {
+ applicationProviders: [provideZoneChangeDetection()],
+ })
.catch((err) => console.error(err));
```

Angular forbids `provideZoneChangeDetection()` inside an NgModule's `providers` array, so for NgModule apps it must be passed as `applicationProviders` on the `bootstrapModule()` call. This step is only required on Angular 21. Angular 18 through 20 are unaffected.

**TypeScript**

Ionic 9 supports TypeScript 5.4 or later, matching the minimum for Angular 18. Angular 21 requires TypeScript 5.9 or later per Angular's own requirements.

**Module Resolution**

`@ionic/angular` is now published with `exports`-based subpath resolution. Apps using TypeScript `moduleResolution: "node"` (classic) can fail to resolve subpaths such as `@ionic/angular/standalone`. Set `moduleResolution` to `"bundler"` (the default for `ng new` on Angular 17 and later). See [Package Exports](#version-9x-package-exports).

**CSS Imports No Longer Use the `~` Prefix**

Angular's current build pipeline no longer supports the webpack-loader `~` prefix in CSS `@import` statements:

```diff
- @import '~@ionic/angular/css/core.css';
+ @import '@ionic/angular/css/core.css';
```

**Narrowed Event Types**

The Angular output target no longer surfaces the narrow `*CustomEvent` types (such as `RefresherCustomEvent` and `ReorderEndCustomEvent`) through template type inference. Use `CustomEvent<*EventDetail>` and cast `event.target` at call sites that invoke methods on it:

```diff
- import { RefresherCustomEvent } from '@ionic/angular';
-
- onRefresh(event: RefresherCustomEvent) {
- event.target.complete();
- }
+ import type { RefresherEventDetail } from '@ionic/core';
+
+ onRefresh(event: CustomEvent<RefresherEventDetail>) {
+ (event.target as HTMLIonRefresherElement | null)?.complete();
+ }
```

<h4 id="version-9x-react">React</h4>

The `@ionic/react-router` package now requires React Router v6. React Router v5 is no longer supported.
Expand Down
6 changes: 3 additions & 3 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ ion-infinite-scroll-content,prop,loadingText,IonicSafeString | string | undefine
ion-input,scoped
ion-input,prop,autocapitalize,string,'off',false,false
ion-input,prop,autocomplete,"additional-name" | "address-level1" | "address-level2" | "address-level3" | "address-level4" | "address-line1" | "address-line2" | "address-line3" | "bday" | "bday-day" | "bday-month" | "bday-year" | "cc-additional-name" | "cc-csc" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-family-name" | "cc-given-name" | "cc-name" | "cc-number" | "cc-type" | "country" | "country-name" | "current-password" | "email" | "family-name" | "given-name" | "honorific-prefix" | "honorific-suffix" | "impp" | "language" | "name" | "new-password" | "nickname" | "off" | "on" | "one-time-code" | "organization" | "organization-title" | "photo" | "postal-code" | "sex" | "street-address" | "tel" | "tel-area-code" | "tel-country-code" | "tel-extension" | "tel-local" | "tel-national" | "transaction-amount" | "transaction-currency" | "url" | "username",'off',false,false
ion-input,prop,autocorrect,"off" | "on",'off',false,false
ion-input,prop,autocorrect,boolean,false,false,false
ion-input,prop,autofocus,boolean,false,false,false
ion-input,prop,clearInput,boolean,false,false,false
ion-input,prop,clearInputIcon,string | undefined,undefined,false,false
Expand Down Expand Up @@ -1542,7 +1542,7 @@ ion-searchbar,scoped
ion-searchbar,prop,animated,boolean,false,false,false
ion-searchbar,prop,autocapitalize,string,'off',false,false
ion-searchbar,prop,autocomplete,"additional-name" | "address-level1" | "address-level2" | "address-level3" | "address-level4" | "address-line1" | "address-line2" | "address-line3" | "bday" | "bday-day" | "bday-month" | "bday-year" | "cc-additional-name" | "cc-csc" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-family-name" | "cc-given-name" | "cc-name" | "cc-number" | "cc-type" | "country" | "country-name" | "current-password" | "email" | "family-name" | "given-name" | "honorific-prefix" | "honorific-suffix" | "impp" | "language" | "name" | "new-password" | "nickname" | "off" | "on" | "one-time-code" | "organization" | "organization-title" | "photo" | "postal-code" | "sex" | "street-address" | "tel" | "tel-area-code" | "tel-country-code" | "tel-extension" | "tel-local" | "tel-national" | "transaction-amount" | "transaction-currency" | "url" | "username",'off',false,false
ion-searchbar,prop,autocorrect,"off" | "on",'off',false,false
ion-searchbar,prop,autocorrect,boolean,false,false,false
ion-searchbar,prop,cancelButtonIcon,string,config.get('backButtonIcon', arrowBackSharp) as string,false,false
ion-searchbar,prop,cancelButtonText,string,'Cancel',false,false
ion-searchbar,prop,clearIcon,string | undefined,undefined,false,false
Expand Down Expand Up @@ -1779,7 +1779,7 @@ ion-spinner,css-prop,--color
ion-split-pane,shadow
ion-split-pane,prop,contentId,string | undefined,undefined,false,true
ion-split-pane,prop,disabled,boolean,false,false,false
ion-split-pane,prop,when,boolean | string,QUERY['lg'],false,false
ion-split-pane,prop,when,boolean | string,'(min-width: 992px)',false,false
ion-split-pane,event,ionSplitPaneVisible,{ visible: boolean; },true
ion-split-pane,css-prop,--border,ios
ion-split-pane,css-prop,--border,md
Expand Down
78 changes: 40 additions & 38 deletions core/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"loader/"
],
"dependencies": {
"@stencil/core": "4.43.0",
"@stencil/core": "^4.43.5",
"ionicons": "^8.0.13",
"tslib": "^2.1.0"
},
Expand All @@ -81,7 +81,7 @@
"@playwright/test": "^1.59.1",
"@rollup/plugin-node-resolve": "^8.4.0",
"@rollup/plugin-virtual": "^2.0.3",
"@stencil/angular-output-target": "^0.10.0",
"@stencil/angular-output-target": "^1.3.1",
"@stencil/react-output-target": "^1.5.2",
"@stencil/sass": "^3.0.9",
"@stencil/vue-output-target": "0.13.1",
Expand Down
Loading
Loading