mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix(reorder-group): add children fallback for framework compatibility (#30593)
Issue number: resolves #30592 --------- ## What is the current behavior? Reorder group is failing for Angular, React & Vue due to the change from `children` to `__children`. ## What is the new behavior? - Fallback to `children` if `__children` is undefined. - Adds an e2e test for Angular (depends on https://github.com/ionic-team/ionic-framework/pull/30594) - Tasks have been created to migrate and add e2e tests for the other frameworks ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information Dev build: `8.7.2-dev.11754087334.1815cf22` --------- Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
This commit is contained in:
@@ -153,7 +153,7 @@ export class ReorderGroup implements ComponentInterface {
|
||||
const heights = this.cachedHeights;
|
||||
heights.length = 0;
|
||||
const el = this.el;
|
||||
const children: any = el.__children;
|
||||
const children: any = el.__children || el.children;
|
||||
if (!children || children.length === 0) {
|
||||
return;
|
||||
}
|
||||
@@ -259,7 +259,7 @@ export class ReorderGroup implements ComponentInterface {
|
||||
private completeReorder(listOrReorder?: boolean | any[]): any {
|
||||
const selectedItemEl = this.selectedItemEl;
|
||||
if (selectedItemEl && this.state === ReorderGroupState.Complete) {
|
||||
const children: any = this.el.__children;
|
||||
const children: any = this.el.__children || this.el.children;
|
||||
const len = children.length;
|
||||
const toIndex = this.lastToIndex;
|
||||
const fromIndex = indexForItem(selectedItemEl);
|
||||
@@ -309,7 +309,7 @@ export class ReorderGroup implements ComponentInterface {
|
||||
/********* DOM WRITE ********* */
|
||||
private reorderMove(fromIndex: number, toIndex: number) {
|
||||
const itemHeight = this.selectedItemHeight;
|
||||
const children: any = this.el.__children;
|
||||
const children: any = this.el.__children || this.el.children;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const style = (children[i] as any).style;
|
||||
let value = '';
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@playwright/test';
|
||||
import { dragElementBy } from '../../utils/drag-utils';
|
||||
|
||||
test.describe('reorder-group: angular standalone', () => {
|
||||
test('should reorder the items', async ({ page }) => {
|
||||
await page.goto('/standalone/reorder-group');
|
||||
|
||||
// Get initial order
|
||||
const initialItems = await page.locator('ion-item').allTextContents();
|
||||
expect(initialItems).toEqual(['Item 1', 'Item 2', 'Item 3']);
|
||||
|
||||
const reorderGroup = page.locator('ion-reorder-group');
|
||||
|
||||
// Drag the first item down to move it to the end (below Item 3)
|
||||
await dragElementBy(reorderGroup.locator('ion-reorder').first(), page, 0, 300);
|
||||
|
||||
// Wait for the reorder to complete
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Verify the new order - Item 1 should now be at the end
|
||||
const finalItems = await page.locator('ion-item').allTextContents();
|
||||
expect(finalItems).toEqual(['Item 2', 'Item 3', 'Item 1']);
|
||||
});
|
||||
});
|
||||
@@ -19,6 +19,7 @@ export const routes: Routes = [
|
||||
{ path: 'providers', loadComponent: () => import('../providers/providers.component').then(c => c.ProvidersComponent) },
|
||||
{ path: 'overlay-controllers', loadComponent: () => import('../overlay-controllers/overlay-controllers.component').then(c => c.OverlayControllersComponent) },
|
||||
{ path: 'button', loadComponent: () => import('../button/button.component').then(c => c.ButtonComponent) },
|
||||
{ path: 'reorder-group', loadComponent: () => import('../reorder-group/reorder-group.component').then(c => c.ReorderGroupComponent) },
|
||||
{ path: 'icon', loadComponent: () => import('../icon/icon.component').then(c => c.IconComponent) },
|
||||
{ path: 'split-pane', redirectTo: '/standalone/split-pane/inbox', pathMatch: 'full' },
|
||||
{
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
Icon Test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/standalone/reorder-group">
|
||||
<ion-label>
|
||||
Reorder Group Test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<ion-list>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { IonItem, IonLabel, IonReorder, IonReorderGroup } from '@ionic/angular/standalone';
|
||||
import { ReorderEndCustomEvent } from "@ionic/angular";
|
||||
|
||||
@Component({
|
||||
selector: 'app-reorder-group',
|
||||
template: `
|
||||
<ion-reorder-group disabled="false" (ionReorderEnd)="onReorderEnd($event)">
|
||||
<ion-item>
|
||||
<ion-reorder slot="end"></ion-reorder>
|
||||
<ion-label>Item 1</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-reorder slot="end"></ion-reorder>
|
||||
<ion-label>Item 2</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-reorder slot="end"></ion-reorder>
|
||||
<ion-label>Item 3</ion-label>
|
||||
</ion-item>
|
||||
</ion-reorder-group>
|
||||
`,
|
||||
standalone: true,
|
||||
imports: [IonItem, IonLabel, IonReorder, IonReorderGroup]
|
||||
})
|
||||
export class ReorderGroupComponent {
|
||||
onReorderEnd(event: ReorderEndCustomEvent) {
|
||||
if (event.detail.from !== event.detail.to) {
|
||||
console.log('ionReorderEnd: Dragged from index', event.detail.from, 'to', event.detail.to);
|
||||
} else {
|
||||
console.log('ionReorderEnd: No position change occurred');
|
||||
}
|
||||
|
||||
event.detail.complete();
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import IonPopoverNested from './pages/overlay-components/IonPopoverNested';
|
||||
import KeepContentsMounted from './pages/overlay-components/KeepContentsMounted';
|
||||
import OverlayComponents from './pages/overlay-components/OverlayComponents';
|
||||
import OverlayHooks from './pages/overlay-hooks/OverlayHooks';
|
||||
import ReorderGroup from './pages/ReorderGroup';
|
||||
|
||||
setupIonicReact();
|
||||
|
||||
@@ -67,6 +68,7 @@ const App: React.FC = () => (
|
||||
<Route path="/tabs-direct-navigation" component={TabsDirectNavigation} />
|
||||
<Route path="/icons" component={Icons} />
|
||||
<Route path="/inputs" component={Inputs} />
|
||||
<Route path="/reorder-group" component={ReorderGroup} />
|
||||
</IonRouterOutlet>
|
||||
</IonReactRouter>
|
||||
</IonApp>
|
||||
|
||||
@@ -46,6 +46,9 @@ const Main: React.FC<MainProps> = () => {
|
||||
<IonItem routerLink="/inputs">
|
||||
<IonLabel>Inputs</IonLabel>
|
||||
</IonItem>
|
||||
<IonItem routerLink="/reorder-group">
|
||||
<IonLabel>Reorder Group</IonLabel>
|
||||
</IonItem>
|
||||
</IonList>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
|
||||
58
packages/react/test/base/src/pages/ReorderGroup.tsx
Normal file
58
packages/react/test/base/src/pages/ReorderGroup.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
IonBackButton,
|
||||
IonButtons,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonItem,
|
||||
IonLabel,
|
||||
IonPage,
|
||||
IonReorder,
|
||||
IonReorderGroup,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
} from '@ionic/react';
|
||||
import type { ReorderEndCustomEvent } from '@ionic/react';
|
||||
|
||||
const ReorderGroup: React.FC = () => {
|
||||
const onReorderEnd = (event: ReorderEndCustomEvent) => {
|
||||
if (event.detail.from !== event.detail.to) {
|
||||
console.log('ionReorderEnd: Dragged from index', event.detail.from, 'to', event.detail.to);
|
||||
} else {
|
||||
console.log('ionReorderEnd: No position change occurred');
|
||||
}
|
||||
|
||||
event.detail.complete();
|
||||
};
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonHeader>
|
||||
<IonToolbar>
|
||||
<IonButtons slot="start">
|
||||
<IonBackButton></IonBackButton>
|
||||
</IonButtons>
|
||||
<IonTitle>Reorder Group</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent>
|
||||
<IonReorderGroup disabled={false} onIonReorderEnd={onReorderEnd}>
|
||||
<IonItem>
|
||||
<IonReorder slot="end"></IonReorder>
|
||||
<IonLabel>Item 1</IonLabel>
|
||||
</IonItem>
|
||||
<IonItem>
|
||||
<IonReorder slot="end"></IonReorder>
|
||||
<IonLabel>Item 2</IonLabel>
|
||||
</IonItem>
|
||||
<IonItem>
|
||||
<IonReorder slot="end"></IonReorder>
|
||||
<IonLabel>Item 3</IonLabel>
|
||||
</IonItem>
|
||||
</IonReorderGroup>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default ReorderGroup;
|
||||
@@ -86,6 +86,10 @@ const routes: Array<RouteRecordRaw> = [
|
||||
path: '/components/range',
|
||||
component: () => import('@/views/Range.vue')
|
||||
},
|
||||
{
|
||||
path: '/reorder-group',
|
||||
component: () => import('@/views/ReorderGroup.vue')
|
||||
},
|
||||
{
|
||||
path: '/nested',
|
||||
component: () => import('@/views/RouterOutlet.vue'),
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
<ion-item router-link="/navigation" id="navigation">
|
||||
<ion-label>Navigation</ion-label>
|
||||
</ion-item>
|
||||
<ion-item router-link="/reorder-group">
|
||||
<ion-label>Reorder Group</ion-label>
|
||||
</ion-item>
|
||||
<ion-item router-link="/routing" id="routing">
|
||||
<ion-label>Routing</ion-label>
|
||||
</ion-item>
|
||||
|
||||
78
packages/vue/test/base/src/views/ReorderGroup.vue
Normal file
78
packages/vue/test/base/src/views/ReorderGroup.vue
Normal file
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<ion-page>
|
||||
<ion-header :translucent="true">
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Reorder Group</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content :fullscreen="true">
|
||||
<ion-reorder-group :disabled="false" @ion-reorder-end="onReorderEnd">
|
||||
<ion-item>
|
||||
<ion-reorder slot="end"></ion-reorder>
|
||||
<ion-label>Item 1</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-reorder slot="end"></ion-reorder>
|
||||
<ion-label>Item 2</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-reorder slot="end"></ion-reorder>
|
||||
<ion-label>Item 3</ion-label>
|
||||
</ion-item>
|
||||
</ion-reorder-group>
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
IonButtons,
|
||||
IonBackButton,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonItem,
|
||||
IonLabel,
|
||||
IonPage,
|
||||
IonReorder,
|
||||
IonReorderGroup,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
} from "@ionic/vue";
|
||||
import { defineComponent } from "vue";
|
||||
import type { ReorderEndCustomEvent } from "@ionic/vue";
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
IonButtons,
|
||||
IonBackButton,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonItem,
|
||||
IonLabel,
|
||||
IonPage,
|
||||
IonReorder,
|
||||
IonReorderGroup,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
},
|
||||
setup() {
|
||||
const onReorderEnd = (event: ReorderEndCustomEvent) => {
|
||||
if (event.detail.from !== event.detail.to) {
|
||||
console.log('ionReorderEnd: Dragged from index', event.detail.from, 'to', event.detail.to);
|
||||
} else {
|
||||
console.log('ionReorderEnd: No position change occurred');
|
||||
}
|
||||
|
||||
event.detail.complete();
|
||||
};
|
||||
|
||||
return {
|
||||
onReorderEnd,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user