@@ -2,6 +2,7 @@ import { cn } from 'cn'
22import { AlertTriangleIcon , RefreshCwIcon } from 'lucide-react'
33
44import { Button } from '@/components/ui/button'
5+ import { LineaEsqueleto } from '@/components/states'
56import { Skeleton } from '@/components/ui/skeleton'
67import {
78 Table ,
@@ -65,7 +66,7 @@ interface Props<T> {
6566 cargando : boolean
6667 error ?: unknown
6768 onReintentar ?: ( ) => void
68- /** Segun la causa: no tener nada no es lo mismo que no encontrar . */
69+ /** `EmptyState` sin marco; distinto sin datos que sin coincidencias . */
6970 vacio : React . ReactNode
7071 /** Filas del esqueleto: las de la carga anterior o la pagina entera. */
7172 filasEsperadas ?: number
@@ -134,7 +135,7 @@ export function DataTable<T>({
134135 </ TableRow >
135136 ) : datos . length === 0 ? (
136137 < TableRow className = "hover:bg-transparent" >
137- < TableCell colSpan = { columnas . length } className = "py-12 text-center " >
138+ < TableCell colSpan = { columnas . length } className = "p-0 " >
138139 { vacio }
139140 </ TableCell >
140141 </ TableRow >
@@ -167,23 +168,15 @@ export function DataTable<T>({
167168 { cargando ? (
168169 < ul className = "grid gap-3 sm:grid-cols-2 xl:grid-cols-3" >
169170 { Array . from ( { length : Math . min ( huesos , 6 ) } , ( _ , indice ) => (
170- < li key = { indice } className = "rounded-lg border p-4" >
171- < Skeleton className = "h-5 w-2/5" />
172- < div className = "mt-4 grid grid-cols-2 gap-3" >
173- < Skeleton className = "h-4 w-full" />
174- < Skeleton className = "h-4 w-2/3" />
175- < Skeleton className = "h-4 w-3/4" />
176- < Skeleton className = "h-4 w-1/2" />
177- </ div >
178- </ li >
171+ < TarjetaEsqueleto key = { indice } columnas = { columnas } />
179172 ) ) }
180173 </ ul >
181174 ) : error ? (
182175 < div className = "rounded-lg border p-4" >
183176 < AvisoDeError error = { error } onReintentar = { onReintentar } />
184177 </ div >
185178 ) : datos . length === 0 ? (
186- < div className = "rounded-lg border px-6 py-12 text-center " > { vacio } </ div >
179+ < div className = "rounded-lg border" > { vacio } </ div >
187180 ) : (
188181 < ul className = "grid gap-3 sm:grid-cols-2 xl:grid-cols-3" >
189182 { datos . map ( ( fila , indice ) => (
@@ -241,6 +234,32 @@ function TarjetaDeFila<T>({
241234 )
242235}
243236
237+ /** Forma de `TarjetaDeFila`: sin salto al cargar. */
238+ function TarjetaEsqueleto < T > ( { columnas } : { columnas : Columna < T > [ ] } ) {
239+ const titulo = columnas . find ( ( columna ) => columna . rol === 'titulo' ) ?? columnas [ 0 ]
240+ const resto = columnas . filter (
241+ ( columna ) => columna !== titulo && columna . rol !== 'acciones' ,
242+ )
243+
244+ return (
245+ < li className = "rounded-lg border p-4" aria-hidden >
246+ < LineaEsqueleto className = "w-2/5" />
247+ < dl className = "mt-4 grid grid-cols-2 gap-x-4 gap-y-3" >
248+ { resto . map ( ( columna ) => (
249+ < div key = { columna . key } >
250+ < dt className = "text-muted-foreground text-[11px] tracking-[0.12em] uppercase" >
251+ { columna . header }
252+ </ dt >
253+ < dd className = "mt-1" >
254+ < LineaEsqueleto className = "w-3/4" />
255+ </ dd >
256+ </ div >
257+ ) ) }
258+ </ dl >
259+ </ li >
260+ )
261+ }
262+
244263function CeldaEsqueleto < T > ( { columna } : { columna : Columna < T > } ) {
245264 if ( columna . rol === 'acciones' ) {
246265 return (
0 commit comments