Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e9cc2a9
docs(reorder): add new ionReorderStart, ionReorderMove, ionReorderEnd…
brandyscarney Jun 23, 2025
b3dd3f3
docs(components): remove legacy syntax sections from all form control…
kkindrai Jul 25, 2025
4f75fd8
chore(deps): update dependency vite to v7.0.6 (#4216)
renovate[bot] Jul 28, 2025
69b87fb
chore(deps): update dependency vite to v7.0.6 (#4215)
renovate[bot] Jul 28, 2025
751ca7e
chore(deps): update dependency vue to v3.5.18 (#4217)
renovate[bot] Jul 28, 2025
2f858c8
chore(deps): update dependency vue-tsc to v3.0.4 (#4218)
renovate[bot] Jul 28, 2025
070d69e
docs(layout): update css utilities to include new classes and improve…
brandyscarney Jul 30, 2025
8112113
docs(datetime): add border property to highlightedDates examples (#4220)
brandyscarney Jul 30, 2025
f8de8aa
docs(angular): add injection token docs (#4221)
ShaneK Jul 30, 2025
c9f4754
merge feature-8.7
brandyscarney Jul 30, 2025
54a3cb2
docs(playgrounds): add back migration examples for JP docs (#4225)
brandyscarney Jul 31, 2025
613d75c
chore(deps): update ionic to v8.7.0 (#4223)
renovate[bot] Jul 31, 2025
f4a7449
chore(deps): update dependency @vitejs/plugin-vue to v6.0.1 (#4224)
renovate[bot] Jul 31, 2025
2a77aed
docs(radio): add example for wrapping label text
soundproofboot Jul 31, 2025
4e03158
docs(radio): update wrapping example to include ion-text-wrap utility…
soundproofboot Aug 6, 2025
3a4b4ed
docs(radio): small updates for wrapping demo
brandyscarney Aug 8, 2025
69a4d2c
docs(radio): copy example to v7 docs
brandyscarney Aug 8, 2025
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
177 changes: 177 additions & 0 deletions docs/angular/injection-tokens.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
---
title: Angular Injection Tokens
sidebar_label: Injection Tokens
---

<head>
<title>Angular Injection Tokens | Access Ionic Elements via Dependency Injection</title>
<meta
name="description"
content="Learn how to use Ionic's Angular injection tokens to access Ionic elements through Angular's dependency injection system for more streamlined component interactions."
/>
</head>

Ionic provides Angular injection tokens that allow you to access Ionic elements through Angular's dependency injection system. This provides a more Angular-idiomatic way to interact with Ionic components programmatically.

## Benefits

Using injection tokens provides several advantages:

- **Type Safety**: Full TypeScript support with proper typing for the modal element
- **Angular Integration**: Works seamlessly with Angular's dependency injection system
- **Simplified Code**: Eliminates the need for `ViewChild` queries or manual element references
- **Better Testing**: Easier to mock and test components that use injection tokens

## IonModalToken

The `IonModalToken` injection token allows you to inject a reference to the current modal element directly into your Angular components. This is particularly useful when you need to programmatically control modal behavior, listen to modal events, or access modal properties.

Starting in `@ionic/angular` v8.7.0, you can use this injection token to streamline modal interactions in your Angular applications.

### Basic Usage

To use the `IonModalToken`, inject it into your component's constructor:

```tsx
import { Component, inject } from '@angular/core';
import { IonButton, IonContent, IonHeader, IonModalToken, IonTitle, IonToolbar } from '@ionic/angular/standalone';

@Component({
selector: 'app-modal',
template: `
<ion-header>
<ion-toolbar>
<ion-title>Modal Content</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<p>This is modal content</p>
<ion-button (click)="closeModal()">Close Modal</ion-button>
</ion-content>
`,
imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonButton],
})
export class ModalComponent {
private modalToken = inject(IonModalToken);

closeModal() {
this.modalToken.dismiss();
}
}
```

### Listening to Modal Events

You can use the injected modal reference to listen to modal lifecycle events:

```tsx
import { Component, inject, OnInit } from '@angular/core';
import { IonButton, IonContent, IonHeader, IonModalToken, IonTitle, IonToolbar } from '@ionic/angular/standalone';

@Component({
selector: 'app-modal',
template: `
<ion-header>
<ion-toolbar>
<ion-title>Modal with Events</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<p>Check the console for modal events</p>
<ion-button (click)="closeModal()">Close</ion-button>
</ion-content>
`,
imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonButton],
})
export class ModalComponent implements OnInit {
private modalToken = inject(IonModalToken);

ngOnInit() {
this.modalToken.addEventListener('ionModalWillDismiss', (event) => {
console.log('Modal will dismiss:', event.detail);
});

this.modalToken.addEventListener('ionModalDidDismiss', (event) => {
console.log('Modal did dismiss:', event.detail);
});
}

closeModal() {
this.modalToken.dismiss({ result: 'closed by button' });
}
}
```

### Accessing Modal Properties

The injected modal reference provides access to all modal properties and methods:

```tsx
import { Component, inject, OnInit } from '@angular/core';
import { IonButton, IonContent, IonHeader, IonModalToken, IonTitle, IonToolbar } from '@ionic/angular/standalone';

@Component({
selector: 'app-modal',
template: `
<ion-header>
<ion-toolbar>
<ion-title>Modal Properties</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<p>Modal ID: {{ modalId }}</p>
<ion-button (click)="toggleBackdropDismiss()"> Toggle Backdrop Dismiss: {{ backdropDismiss }} </ion-button>
</ion-content>
`,
imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonButton],
})
export class ModalComponent implements OnInit {
private modalToken = inject(IonModalToken);

modalId = '';
backdropDismiss = true;

ngOnInit() {
this.modalId = this.modalToken.id || 'No ID';
this.backdropDismiss = this.modalToken.backdropDismiss;
}

toggleBackdropDismiss() {
this.backdropDismiss = !this.backdropDismiss;
this.modalToken.backdropDismiss = this.backdropDismiss;
}
}
```

### Opening a Modal with Injection Token Content

When opening a modal that uses the injection token, you can pass the component directly to the modal controller:

```tsx
import { Component, inject } from '@angular/core';
import { IonContent, IonButton, ModalController } from '@ionic/angular/standalone';
import { ModalComponent } from './modal.component';

@Component({
selector: 'app-home',
template: `
<ion-content>
<ion-button (click)="openModal()">Open Modal</ion-button>
</ion-content>
`,
})
export class HomePage {
private modalController = inject(ModalController);

async openModal() {
const myModal = await this.modalController.create({
component: ModalComponent,
componentProps: {
// Any props you want to pass to the modal content
},
});

await myModal.present();
}
}
```
26 changes: 1 addition & 25 deletions docs/api/checkbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import Justify from '@site/static/usage/v8/checkbox/justify/index.md';
import Indeterminate from '@site/static/usage/v8/checkbox/indeterminate/index.md';

<Indeterminate />

## Links inside of Labels

Checkbox labels can sometimes be accompanied with links. These links can provide more information related to the checkbox. However, clicking the link should not check the checkbox. To achieve this, we can use [stopPropagation](https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation) to prevent the click event from bubbling. When using this approach, the rest of the label still remains clickable.
Expand Down Expand Up @@ -114,30 +114,6 @@ interface CheckboxCustomEvent<T = any> extends CustomEvent {
}
```

## Migrating from Legacy Checkbox Syntax

A simpler checkbox syntax was introduced in Ionic 7.0. This new syntax reduces the boilerplate required to setup a checkbox, resolves accessibility issues, and improves the developer experience.

Developers can perform this migration one checkbox at a time. While developers can continue using the legacy syntax, we recommend migrating as soon as possible.

### Using the Modern Syntax

Using the modern syntax involves removing the `ion-label` and passing the label directly inside of `ion-checkbox`. The placement of the label can be configured using the `labelPlacement` property on `ion-checkbox`. The way the label and the control are packed on a line can be controlled using the `justify` property on `ion-checkbox`.

import Migration from '@site/static/usage/v8/checkbox/migration/index.md';

<Migration />


:::note
In past versions of Ionic, `ion-item` was required for `ion-checkbox` to function properly. Starting in Ionic 7.0, `ion-checkbox` should only be used in an `ion-item` when the item is placed in an `ion-list`. Additionally, `ion-item` is no longer required for `ion-checkbox` to function properly.
:::

### Using the Legacy Syntax

Ionic uses heuristics to detect if an app is using the modern checkbox syntax. In some instances, it may be preferable to continue using the legacy syntax. Developers can set the `legacy` property on `ion-checkbox` to `true` to force that instance of the checkbox to use the legacy syntax.


## Properties
<Props />

Expand Down
22 changes: 0 additions & 22 deletions docs/api/input.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,28 +188,6 @@ import CSSProps from '@site/static/usage/v8/input/theming/css-properties/index.m

<CSSProps />

## Migrating from Legacy Input Syntax

A simpler input syntax was introduced in Ionic 7.0. This new syntax reduces the boilerplate required to setup an input, resolves accessibility issues, and improves the developer experience.

Developers can perform this migration one input at a time. While developers can continue using the legacy syntax, we recommend migrating as soon as possible.

### Using the Modern Syntax

Using the modern syntax involves three steps:

1. Remove `ion-label` and use the `label` property on `ion-input` instead. The placement of the label can be configured using the `labelPlacement` property on `ion-input`.
2. Move input-specific properties from `ion-item` on to `ion-input`. This includes the `counter`, `counterFormatter`, `fill`, and `shape` properties.
3. Remove usages of the `helper` and `error` slots on `ion-item` and use the `helperText` and `errorText` properties on `ion-input` instead.

import Migration from '@site/static/usage/v8/input/migration/index.md';

<Migration />

### Using the Legacy Syntax

Ionic uses heuristics to detect if an app is using the modern input syntax. In some instances, it may be preferable to continue using the legacy syntax. Developers can set the `legacy` property on `ion-input` to `true` to force that instance of the input to use the legacy syntax.

## Interfaces

### InputChangeEventDetail
Expand Down
33 changes: 8 additions & 25 deletions docs/api/radio.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ import LabelPlacement from '@site/static/usage/v8/radio/label-placement/index.md

<LabelPlacement />

## Label Wrapping

Regardless of label placement, long text will not wrap by default. If the width of the radio is constrained, overflowing text will be truncated with an ellipsis. You can enable text wrapping by adding the `ion-text-wrap` class to a wrapper around the radio text or styling the `label` shadow part using the `::part()` selector.

import LabelWrap from '@site/static/usage/v8/radio/label-wrap/index.md';

<LabelWrap />

## Object Value References

By default, the radio group uses strict equality (`===`) to determine if an option is selected. This can be overridden by providing a property name or a function to the `compareWith` property.
Expand Down Expand Up @@ -107,31 +115,6 @@ import CSSParts from '@site/static/usage/v8/radio/theming/css-shadow-parts/index

<CSSParts />

## Migrating from Legacy Radio Syntax

A simpler radio syntax was introduced in Ionic 7.0. This new syntax reduces the boilerplate required to setup an radio, resolves accessibility issues, and improves the developer experience.

Developers can perform this migration one radio at a time. While developers can continue using the legacy syntax, we recommend migrating as soon as possible.

### Using the Modern Syntax

Using the modern syntax involves removing the `ion-label` and passing the label directly inside of `ion-radio`. The placement of the label can be configured using the `labelPlacement` property on `ion-radio`. The way the label and the control are packed on a line can be controlled using the `justify` property on `ion-radio`.

import Migration from '@site/static/usage/v8/radio/migration/index.md';

<Migration />


:::note
In past versions of Ionic, `ion-item` was required for `ion-radio` to function properly. Starting in Ionic 7.0, `ion-radio` should only be used in an `ion-item` when the item is placed in an `ion-list`. Additionally, `ion-item` is no longer required for `ion-radio` to function properly.
:::

### Using the Legacy Syntax

Ionic uses heuristics to detect if an app is using the modern radio syntax. In some instances, it may be preferable to continue using the legacy syntax. Developers can set the `legacy` property on `ion-radio` to `true` to force that instance of the radio to use the legacy syntax.



## Properties
<Props />

Expand Down
26 changes: 0 additions & 26 deletions docs/api/range.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,32 +128,6 @@ import CSSParts from '@site/static/usage/v8/range/theming/css-shadow-parts/index

<CSSParts />

## Migrating from Legacy Range Syntax

A simpler range syntax was introduced in Ionic 7.0. This new syntax reduces the boilerplate required to setup an range, resolves accessibility issues, and improves the developer experience.

Developers can perform this migration one range at a time. While developers can continue using the legacy syntax, we recommend migrating as soon as possible.

### Using the Modern Syntax

Using the modern syntax involves removing the `ion-label` and passing the label to `ion-range` using the `label` property. The placement of the label can be configured using the `labelPlacement` property.

If custom HTML is needed for the label, it can be passed directly inside the `ion-range` using the `label` slot instead.

import Migration from '@site/static/usage/v8/range/migration/index.md';

<Migration />


:::note
In past versions of Ionic, `ion-item` was required for `ion-range` to function properly. Starting in Ionic 7.0, `ion-range` should only be used in an `ion-item` when the item is placed in an `ion-list`. Additionally, `ion-item` is no longer required for `ion-range` to function properly.
:::

### Using the Legacy Syntax

Ionic uses heuristics to detect if an app is using the modern range syntax. In some instances, it may be preferable to continue using the legacy syntax. Developers can set the `legacy` property on `ion-range` to `true` to force that instance of the range to use the legacy syntax.


## Interfaces

### RangeChangeEventDetail
Expand Down
Loading