Skip to content

docs(reorder): add new ionReorderStart, ionReorderMove, ionReorderEnd event playgrounds #4149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: feature-8.7
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
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 in the same or a new position, 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` a new 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
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love these section headings, but I decided to be consistent with how Range documents its events. If we want to change this I can update both components.


### 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 by removing their pointer from the screen. 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';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't like how range prefixes ion- in the directory names but I can update this if we want consistency.


<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
20 changes: 12 additions & 8 deletions plugins/docusaurus-plugin-ionic-component-api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,8 @@ module.exports = function (context, options) {
await generateMarkdownForVersion(version, npmTag, false);
}

let npmTag = 'latest';
if (currentVersion.banner === 'unreleased') {
npmTag = 'next';
} else if (currentVersion.path !== undefined) {
npmTag = currentVersion.path.slice(1);
}
// TODO: remove this before merging
let npmTag = '8.6.2-dev.11749759855.198287b7';
// Latest version
await generateMarkdownForVersion(currentVersion.path || currentVersion.label, npmTag, true);

Expand Down Expand Up @@ -145,7 +141,7 @@ ${properties
.map((prop) => {
const isDeprecated = prop.deprecation !== undefined;

const docs = isDeprecated ? `${prop.docs}\n_Deprecated_ ${prop.deprecation}` : prop.docs;
const docs = isDeprecated ? `${prop.docs}\n\n**_Deprecated_** — ${prop.deprecation}` : prop.docs;

return `
### ${prop.name} ${isDeprecated ? '(deprecated)' : ''}
Expand All @@ -170,7 +166,15 @@ function renderEvents({ events }) {
return `
| Name | Description | Bubbles |
| --- | --- | --- |
${events.map((event) => `| \`${event.event}\` | ${formatMultiline(event.docs)} | \`${event.bubbles}\` |`).join('\n')}`;
${events
.map((event) => {
const isDeprecated = event.deprecation !== undefined;
const docs = isDeprecated ? `${event.docs}\n\n**_Deprecated_** — ${event.deprecation}` : event.docs;
return `| \`${event.event}\` ${isDeprecated ? '**(deprecated)**' : ''} | ${formatMultiline(docs)} | \`${
event.bubbles
}\` |`;
})
.join('\n')}`;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions static/code/stackblitz/v8/angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"@angular/platform-browser": "^19.0.0",
"@angular/platform-browser-dynamic": "^19.0.0",
"@angular/router": "^19.0.0",
"@ionic/angular": "8.6.0",
"@ionic/core": "8.6.0",
"@ionic/angular": "8.6.2-dev.11749759855.198287b7",
"@ionic/core": "8.6.2-dev.11749759855.198287b7",
"ionicons": "8.0.9",
"rxjs": "^7.8.1",
"tslib": "^2.5.0",
Expand Down
4 changes: 2 additions & 2 deletions static/code/stackblitz/v8/html/index.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<html>

<head>
<link rel="stylesheet" type="text/css" href="https://cdn.skypack.dev/@ionic/core@8/css/core.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.skypack.dev/@ionic/core@8/css/ionic.bundle.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.skypack.dev/@ionic/core@8.6.2-dev.11749759855.198287b7/css/core.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.skypack.dev/@ionic/core@8.6.2-dev.11749759855.198287b7/css/ionic.bundle.css" />
</head>

<body>
Expand Down
4 changes: 2 additions & 2 deletions static/code/stackblitz/v8/html/index.withContent.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<html>

<head>
<link rel="stylesheet" type="text/css" href="https://cdn.skypack.dev/@ionic/core@8/css/core.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.skypack.dev/@ionic/core@8/css/ionic.bundle.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.skypack.dev/@ionic/core@8.6.2-dev.11749759855.198287b7/css/core.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.skypack.dev/@ionic/core@8.6.2-dev.11749759855.198287b7/css/ionic.bundle.css" />
</head>

<body>
Expand Down
2 changes: 1 addition & 1 deletion static/code/stackblitz/v8/html/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"dependencies": {
"@ionic/core": "8.6.0",
"@ionic/core": "8.6.2-dev.11749759855.198287b7",
"ionicons": "8.0.9"
}
}
4 changes: 2 additions & 2 deletions static/code/stackblitz/v8/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@ionic/react": "8.6.0",
"@ionic/react-router": "8.6.0",
"@ionic/react": "8.6.2-dev.11749759855.198287b7",
"@ionic/react-router": "8.6.2-dev.11749759855.198287b7",
"@types/node": "^22.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
Expand Down
4 changes: 2 additions & 2 deletions static/code/stackblitz/v8/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"preview": "vite preview"
},
"dependencies": {
"@ionic/vue": "8.6.0",
"@ionic/vue-router": "8.6.0",
"@ionic/vue": "8.6.2-dev.11749759855.198287b7",
"@ionic/vue-router": "8.6.2-dev.11749759855.198287b7",
"vue": "^3.2.25",
"vue-router": "4.5.1"
},
Expand Down
2 changes: 1 addition & 1 deletion static/demos/api/reorder/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
function toggleReorder() {
const reorderGroup = document.getElementById('reorder');
reorderGroup.disabled = !reorderGroup.disabled;
reorderGroup.addEventListener('ionItemReorder', ({ detail }) => {
reorderGroup.addEventListener('ionReorderEnd', ({ detail }) => {
detail.complete(true);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<ion-list>
<!-- The reorder gesture is disabled by default, enable it to drag and drop items -->
<!-- Casting $event to $any is a temporary fix for this bug https://github.com/ionic-team/ionic-framework/issues/24245 -->
<ion-reorder-group [disabled]="false" (ionItemReorder)="handleReorder($any($event))">
<ion-reorder-group [disabled]="false" (ionReorderEnd)="handleReorderEnd($any($event))">
<ion-item>
<ion-label> Item 1 </ion-label>
<ion-reorder slot="end"></ion-reorder>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
```ts
import { Component } from '@angular/core';
import {
ItemReorderEventDetail,
IonItem,
IonLabel,
IonList,
IonReorder,
IonReorderGroup,
ReorderEndCustomEvent,
} from '@ionic/angular/standalone';

@Component({
Expand All @@ -16,14 +16,14 @@ import {
imports: [IonItem, IonLabel, IonList, IonReorder, IonReorderGroup],
})
export class ExampleComponent {
handleReorder(event: CustomEvent<ItemReorderEventDetail>) {
handleReorderEnd(event: ReorderEndCustomEvent) {
// The `from` and `to` properties contain the index of the item
// when the drag started and ended, respectively
console.log('Dragged from index', event.detail.from, 'to', event.detail.to);

// Finish the reorder and position the item in the DOM based on
// where the gesture ended. This method can also be called directly
// by the reorder group
// by the reorder group.
event.detail.complete();
}
}
Expand Down
16 changes: 11 additions & 5 deletions static/usage/v8/reorder/basic/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@
<title>Reorder</title>
<link rel="stylesheet" href="../../common.css" />
<script src="../../common.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@8/dist/ionic/ionic.esm.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@8/css/ionic.bundle.css" />
<script
type="module"
src="https://cdn.jsdelivr.net/npm/@ionic/[email protected]/dist/ionic/ionic.esm.js"
></script>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@ionic/[email protected]/css/ionic.bundle.css"
/>

<style>
ion-list {
width: 100%;
width: 300px;
}
</style>
</head>
Expand Down Expand Up @@ -56,14 +62,14 @@
<script>
const reorderGroup = document.querySelector('ion-reorder-group');

reorderGroup.addEventListener('ionItemReorder', ({ detail }) => {
reorderGroup.addEventListener('ionReorderEnd', ({ detail }) => {
// The `from` and `to` properties contain the index of the item
// when the drag started and ended, respectively
console.log('Dragged from index', detail.from, 'to', detail.to);

// Finish the reorder and position the item in the DOM based on
// where the gesture ended. This method can also be called directly
// by the reorder group
// by the reorder group.
detail.complete();
});
</script>
Expand Down
4 changes: 2 additions & 2 deletions static/usage/v8/reorder/basic/javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@
<script>
const reorderGroup = document.querySelector('ion-reorder-group');

reorderGroup.addEventListener('ionItemReorder', ({ detail }) => {
reorderGroup.addEventListener('ionReorderEnd', ({ detail }) => {
// The `from` and `to` properties contain the index of the item
// when the drag started and ended, respectively
console.log('Dragged from index', detail.from, 'to', detail.to);

// Finish the reorder and position the item in the DOM based on
// where the gesture ended. This method can also be called directly
// by the reorder group
// by the reorder group.
detail.complete();
});
</script>
Expand Down
8 changes: 4 additions & 4 deletions static/usage/v8/reorder/basic/react.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
```tsx
import React from 'react';
import { IonItem, IonLabel, IonList, IonReorder, IonReorderGroup, ItemReorderEventDetail } from '@ionic/react';
import { IonItem, IonLabel, IonList, IonReorder, IonReorderGroup, ReorderEndCustomEvent } from '@ionic/react';

function Example() {
function handleReorder(event: CustomEvent<ItemReorderEventDetail>) {
function handleReorderEnd(event: ReorderEndCustomEvent) {
// The `from` and `to` properties contain the index of the item
// when the drag started and ended, respectively
console.log('Dragged from index', event.detail.from, 'to', event.detail.to);

// Finish the reorder and position the item in the DOM based on
// where the gesture ended. This method can also be called directly
// by the reorder group
// by the reorder group.
event.detail.complete();
}

return (
<IonList>
{/* The reorder gesture is disabled by default, enable it to drag and drop items */}
<IonReorderGroup disabled={false} onIonItemReorder={handleReorder}>
<IonReorderGroup disabled={false} onIonReorderEnd={handleReorderEnd}>
<IonItem>
<IonLabel>Item 1</IonLabel>
<IonReorder slot="end"></IonReorder>
Expand Down
10 changes: 5 additions & 5 deletions static/usage/v8/reorder/basic/vue.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<template>
<ion-list>
<!-- The reorder gesture is disabled by default, enable it to drag and drop items -->
<ion-reorder-group :disabled="false" @ionItemReorder="handleReorder($event)">
<ion-reorder-group :disabled="false" @ionReorderEnd="handleReorderEnd($event)">
<ion-item>
<ion-label> Item 1 </ion-label>
<ion-reorder slot="end"></ion-reorder>
Expand Down Expand Up @@ -32,24 +32,24 @@
</template>

<script lang="ts">
import { IonItem, IonLabel, IonList, IonReorder, IonReorderGroup } from '@ionic/vue';
import { IonItem, IonLabel, IonList, IonReorder, IonReorderGroup, ReorderEndCustomEvent } from '@ionic/vue';
import { defineComponent } from 'vue';

export default defineComponent({
components: { IonItem, IonLabel, IonList, IonReorder, IonReorderGroup },
setup() {
const handleReorder = (event: CustomEvent) => {
const handleReorderEnd = (event: ReorderEndCustomEvent) => {
// The `from` and `to` properties contain the index of the item
// when the drag started and ended, respectively
console.log('Dragged from index', event.detail.from, 'to', event.detail.to);

// Finish the reorder and position the item in the DOM based on
// where the gesture ended. This method can also be called directly
// by the reorder group
// by the reorder group.
event.detail.complete();
};

return { handleReorder };
return { handleReorderEnd };
},
});
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<ion-list>
<!-- The reorder gesture is disabled by default, enable it to drag and drop items -->
<!-- Casting $event to $any is a temporary fix for this bug https://github.com/ionic-team/ionic-framework/issues/24245 -->
<ion-reorder-group [disabled]="false" (ionItemReorder)="handleReorder($any($event))">
<ion-reorder-group [disabled]="false" (ionReorderEnd)="handleReorderEnd($any($event))">
<ion-item>
<ion-label> Item 1 </ion-label>
<ion-reorder slot="end">
Expand Down
Loading