Organism
List
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 listO instala el paquete completo e impórtalo
pnpm add orn-ui
import { List } from 'orn-ui/list';Uso
- cuándo usarlo — Cualquier lista de datos: resuelve carga, vacío y paginado para que cada pantalla no los reinvente.
- isLoading / isReady — `isLoading` es la carga de los datos; `isReady` es todo lo que la pantalla necesita antes de renderizar algo.
- emptyTitle / emptyDescription — Alimentan el EmptyState que muestra cuando no hay nada.
- onEndReached / isLoadingMore — Paginado: el callback carga, la bandera muestra el spinner del pie.
- ListComponent — `FlatList` por defecto; se cambia por FlashList sin tocar el resto.
Clip del demo todavía sin grabar — ver MEDIA.md
Variantes
Loaded
<List
data={DATA}
keyExtractor={(item) => item.id}
isLoading={false}
renderItem={({ item }) => (
<Card style={{ marginBottom: 8 }}>
<Body>{item.name}</Body>
</Card>
)}
/>Loading
<List data={[]} keyExtractor={(i: any) => i.id} isLoading loadingText="Fetching items..." renderItem={() => null} />Empty
<View style={{ flex: 1 }}>
<Button
title={showEmpty ? 'Reset' : 'Simulate empty result'}
variant="outline"
onPress={() => setShowEmpty((v) => !v)}
style={{ marginBottom: 12 }}
/>
<List
data={showEmpty ? [] : DATA.slice(0, 3)}
keyExtractor={(item: any) => item.id}
isLoading={false}
emptyTitle="No items"
emptyDescription="Try a different filter"
renderItem={({ item }: any) => (
<Card style={{ marginBottom: 8 }}>
<Body>{item.name}</Body>
</Card>
)}
/>
</View>Código completo del demo
const variants: VariantDef[] = [
{
label: 'Loaded',
content: (
<List
data={DATA}
keyExtractor={(item) => item.id}
isLoading={false}
renderItem={({ item }) => (
<Card style={{ marginBottom: 8 }}>
<Body>{item.name}</Body>
</Card>
)}
/>
),
},
{
label: 'Loading',
content: <List data={[]} keyExtractor={(i: any) => i.id} isLoading loadingText="Fetching items..." renderItem={() => null} />,
},
{
label: 'Empty',
content: (
<View style={{ flex: 1 }}>
<Button
title={showEmpty ? 'Reset' : 'Simulate empty result'}
variant="outline"
onPress={() => setShowEmpty((v) => !v)}
style={{ marginBottom: 12 }}
/>
<List
data={showEmpty ? [] : DATA.slice(0, 3)}
keyExtractor={(item: any) => item.id}
isLoading={false}
emptyTitle="No items"
emptyDescription="Try a different filter"
renderItem={({ item }: any) => (
<Card style={{ marginBottom: 8 }}>
<Body>{item.name}</Body>
</Card>
)}
/>
</View>
),
},
];
return <VariantList variants={variants} fill />;Props
| Nombre | Tipo | Por defecto | Descripción |
|---|---|---|---|
data | T[] | — | — |
keyExtractor | (item: T, index: number) => string | — | — |
renderItem | ListRenderItem<T> | — | — |
isLoading | boolean | — | Carga inicial: mientras es true y no hay datos, se muestran placeholders. |
isRefreshing? | boolean | false | Recarga con datos ya en pantalla (pull-to-refresh). |
isLoadingMore? | boolean | false | — |
isReady? | boolean | true | Controlado por quien lo consume: mientras es false, se muestra un spinner de pantalla completa. |
loadingText? | string | — | — |
loadingMoreText? | string | — | — |
skeletonCount? | number | 6 | Filas fantasma de la carga inicial. |
renderSkeletonItem? | () => ReactElement<unknown, string | JSXElementConstructor<any>> | — | Placeholder propio, para que calce con la forma real del ítem. |
onEndReached? | () => void | — | — |
onEndReachedThreshold? | number | 0.3 | — |
onRefresh? | () => void | — | — |
emptyTitle? | string | — | — |
emptyDescription? | string | — | — |
emptyIconName? | IconName | — | — |
ListHeaderComponent? | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentType<any> | — | — |
ListFooterComponent? | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentType<any> | — | — |
contentContainerStyle? | ViewStyle | — | — |
containerStyle? | ViewStyle | — | — |
ListComponent? | ComponentType<any> | FlatList | Componente de lista a usar (FlashList, etc). |
listProps? | Record<string, unknown> | — | — |