Skip to content
Merged
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
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();
}
}
```
54 changes: 49 additions & 5 deletions docs/api/reorder-group.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,71 @@ import Slots from '@ionic-internal/component-api/v8/reorder-group/slots.md';
import EncapsulationPill from '@components/page/api/EncapsulationPill';


The reorder group is a container for items using the [reorder](./reorder) component. When the user drags an item and drops it in a new position, the `ionItemReorder` event is dispatched. A handler for this event should be implemented that calls the `complete` method.
The reorder group is a container for items using the [reorder](./reorder) component. When the user drags an item and drops it, the `ionReorderEnd` event is dispatched. A handler for this event should be implemented that calls the `complete` method.

The `detail` property of the `ionItemReorder` event includes all of the relevant information about the reorder operation, including the `from` and `to` indexes. In the context of reordering, an item moves `from` an index `to` a new index. For example usage of the reorder group, see the [reorder](./reorder) documentation.
The `detail` property of the `ionReorderEnd` event includes all of the relevant information about the reorder operation, including the `from` and `to` indexes. In the context of reordering, an item moves `from` an index `to` an index. For example usage of the reorder group, see the [reorder](./reorder) documentation.


## Interfaces

### ItemReorderEventDetail
### ReorderMoveEventDetail

```typescript
interface ItemReorderEventDetail {
interface ReorderMoveEventDetail {
from: number;
to: number;
}
```

### ReorderEndEventDetail

```typescript
interface ReorderEndEventDetail {
from: number;
to: number;
complete: (data?: boolean | any[]) => any;
}
```

### ItemReorderCustomEvent
### ReorderMoveCustomEvent

While not required, this interface can be used in place of the `CustomEvent` interface for stronger typing with Ionic events emitted from this component.

```typescript
interface ReorderMoveCustomEvent extends CustomEvent {
detail: ReorderMoveEventDetail;
target: HTMLIonReorderGroupElement;
}

```

### ReorderEndCustomEvent

While not required, this interface can be used in place of the `CustomEvent` interface for stronger typing with Ionic events emitted from this component.

```typescript
interface ReorderEndCustomEvent extends CustomEvent {
detail: ReorderEndEventDetail;
target: HTMLIonReorderGroupElement;
}
```

### ItemReorderEventDetail (deprecated)

**_Deprecated_** — Use the `ionReorderEnd` event with `ReorderEndEventDetail` instead.

```typescript
interface ItemReorderEventDetail {
from: number;
to: number;
complete: (data?: boolean | any[]) => any;
}
```

### ItemReorderCustomEvent (deprecated)

**_Deprecated_** — Use the `ionReorderEnd` event with `ReorderEndCustomEvent` instead.

```typescript
interface ItemReorderCustomEvent extends CustomEvent {
detail: ItemReorderEventDetail;
Expand Down
25 changes: 24 additions & 1 deletion docs/api/reorder.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import EncapsulationPill from '@components/page/api/EncapsulationPill';

Reorder is a component that allows an item to be dragged to change its order within a group of items. It must be used within a [reorder group](./reorder-group) to provide a visual drag and drop interface.

The reorder is the anchor used to drag and drop the items. Once the reorder is complete, the `ionItemReorder` event will be dispatched from the reorder group and the `complete` method needs to be called.
The reorder is the anchor used to drag and drop the items. Once the reorder is complete, the `ionReorderEnd` event will be dispatched from the reorder group and the `complete` method needs to be called.


## Basic Usage
Expand Down Expand Up @@ -73,6 +73,29 @@ import UpdatingData from '@site/static/usage/v8/reorder/updating-data/index.md';

<UpdatingData />

## Event Handling

### Using `ionReorderStart` and `ionReorderEnd`

The `ionReorderStart` event is emitted when the user begins a reorder gesture. This event fires when the user taps and holds an item, before any movement occurs. This is useful for preparing the UI for the reorder operation, such as hiding certain elements or updating the visual state of items. For example, icons in list items can be hidden while they are being dragged and shown again when the reorder is complete.

The `ionReorderEnd` event is emitted when the user completes the reorder gesture. This occurs when the user releases the item they are dragging, for example by lifting their finger on a touch screen or releasing the mouse button. The event includes the `from` and `to` indices of the item, as well as the `complete` method that should be called to finalize the reorder operation. The `from` index will always be the position of the item when the gesture started, while the `to` index will be its final position. This event will fire even if no items have changed position, in which case the `from` and `to` indices will be the same.

import ReorderStartEndEvents from '@site/static/usage/v8/reorder/reorder-start-end-events/index.md';

<ReorderStartEndEvents />

### Using `ionReorderMove`

The `ionReorderMove` event is emitted continuously during the reorder gesture as the user drags an item. The event includes the `from` and `to` indices of the item. Unlike `ionReorderEnd`, the `from` index in this event represents the last known position of the item (which updates as the item moves), while the `to` index represents its current position. If the item has not changed position since the last event, the `from` and `to` indices will be the same. This event is useful for tracking position changes during the drag operation. For example, the ranking or numbering of items can be updated in real-time as they are being dragged to maintain a logical ascending order.

:::warning
Do not call the `complete` method during the `ionReorderMove` event as it can break the gesture.
:::

import ReorderMoveEvent from '@site/static/usage/v8/reorder/reorder-move-event/index.md';

<ReorderMoveEvent />

## Usage with Virtual Scroll

Expand Down
Loading
Loading