Organism
ReorderableList
Requiere <UIProvider> — Primeros pasos →
Instalación
Instala solo este componente (copia el código fuente a tu proyecto, sin dependencia npm)
npx orn-ui add reorderable-listO instala el paquete completo e impórtalo
pnpm add orn-ui
import { ReorderableList } from 'orn-ui/reorderable-list';Depende de:core (theme + icons)
Uso
- cuándo usarlo — Una lista corta y ya cargada que la gente reordena a mano: playlists, prioridades, orden custom.
- itemHeight — Obligatorio y fijo — el índice destino se calcula por distancia de arrastre, no midiendo layout.
- onReorder — Se dispara al soltar, con el arreglo ya reordenado; `data` en sí nunca se muta.
- disabled — Las filas siguen renderizando, solo deja de responder el arrastre — no hace falta una variante de solo lectura aparte.
Clip del demo todavía sin grabar — ver MEDIA.md
Variantes
Long-press a row and drag — the rows in between shift out of the way
<ReorderableList
data={data}
keyExtractor={(item) => item.id}
itemHeight={ITEM_HEIGHT}
onReorder={setData}
renderItem={(item, _index, dragging) => <Row name={item.name} dragging={dragging} />}
/>disabled — rows render but can’t be dragged
<ReorderableList
data={INITIAL}
keyExtractor={(item) => item.id}
itemHeight={ITEM_HEIGHT}
disabled
onReorder={() => {}}
renderItem={(item, _index, dragging) => <Row name={item.name} dragging={dragging} />}
/>Código completo del demo
const variants: VariantDef[] = [
{
label: 'Long-press a row and drag — the rows in between shift out of the way',
content: (
<ReorderableList
data={data}
keyExtractor={(item) => item.id}
itemHeight={ITEM_HEIGHT}
onReorder={setData}
renderItem={(item, _index, dragging) => <Row name={item.name} dragging={dragging} />}
/>
),
},
{
label: 'disabled — rows render but can’t be dragged',
content: (
<ReorderableList
data={INITIAL}
keyExtractor={(item) => item.id}
itemHeight={ITEM_HEIGHT}
disabled
onReorder={() => {}}
renderItem={(item, _index, dragging) => <Row name={item.name} dragging={dragging} />}
/>
),
},
];
return (
<>
<Caption style={{ marginBottom: 8 }}>Web preview doesn’t simulate touch drag — see the gif on this page.</Caption>
<VariantList variants={variants} />
</>
);Props
| Nombre | Tipo | Por defecto | Descripción |
|---|---|---|---|
data | T[] | — | — |
keyExtractor | (item: T, index: number) => string | — | — |
itemHeight | number | — | Alto fijo de cada fila: necesario para calcular el índice destino sin medir layout async. |
renderItem | (item: T, index: number, dragging: boolean) => ReactElement<unknown, string | JSXElementConstructor<any>> | — | — |
onReorder | (data: T[]) => void | — | Se llama al soltar, con el array ya reordenado. No muta `data`. |
onDragStart? | (index: number) => void | — | Empieza a arrastrar la fila `index`. Usalo para apagar el scroll del contenedor (`scrollEnabled={false}`) mientras dure: en iOS el `UIScrollView` padre cancela los toques sobre el contenido apenas arranca su gesto vertical, y sin esto el drag muere a los pocos píxeles. |
onDragEnd? | () => void | — | Termina el drag — al soltar o cancelar. Siempre corre si `onDragStart` corrió. |
disabled? | boolean | false | — |
style? | StyleProp<ViewStyle> | — | — |