70 lines
2.7 KiB
TypeScript
70 lines
2.7 KiB
TypeScript
|
|
// SkeletonTableFooter.tsx
|
|||
|
|
|
|||
|
|
/** Skeleton del footer de paginación, imita DataTablePagination */
|
|||
|
|
export function SkeletonDataTableFooter({
|
|||
|
|
pageIndex = 0,
|
|||
|
|
pageSize = 10,
|
|||
|
|
totalItems = 0,
|
|||
|
|
}: {
|
|||
|
|
pageIndex?: number; // 0-based
|
|||
|
|
pageSize?: number;
|
|||
|
|
totalItems?: number;
|
|||
|
|
}) {
|
|||
|
|
// Cálculo de rango (1-based visual)
|
|||
|
|
const start = totalItems > 0 ? pageIndex * pageSize + 1 : 0;
|
|||
|
|
const end = totalItems > 0 ? Math.min(start + pageSize - 1, totalItems) : 0;
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div
|
|||
|
|
role="status"
|
|||
|
|
aria-busy="true"
|
|||
|
|
className="flex items-center justify-between border-t border-border px-4 py-3 bg-background"
|
|||
|
|
>
|
|||
|
|
{/* Izquierda: rango visible */}
|
|||
|
|
<div className="flex flex-col sm:flex-row items-center gap-4 flex-1 text-sm text-muted-foreground">
|
|||
|
|
<span aria-live="polite">
|
|||
|
|
{/* Texto real + shimmer leve para coherencia visual */}
|
|||
|
|
{`Mostrando ${start}–${end} de ${totalItems} registros`}
|
|||
|
|
</span>
|
|||
|
|
|
|||
|
|
{/* 'Filas por página' + trigger del select simulado */}
|
|||
|
|
<div className="flex items-center gap-2">
|
|||
|
|
<span>Filas por página</span>
|
|||
|
|
<div
|
|||
|
|
className="h-8 w-20 rounded bg-foreground/10 animate-pulse motion-reduce:animate-none"
|
|||
|
|
aria-hidden
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* Derecha: controles de paginación simulados */}
|
|||
|
|
<div className="flex items-center gap-2">
|
|||
|
|
{/* Primera */}
|
|||
|
|
<div
|
|||
|
|
className="h-8 w-8 rounded-md bg-foreground/10 animate-pulse motion-reduce:animate-none"
|
|||
|
|
aria-hidden
|
|||
|
|
/>
|
|||
|
|
{/* Anterior */}
|
|||
|
|
<div
|
|||
|
|
className="h-8 w-8 rounded-md bg-foreground/10 animate-pulse motion-reduce:animate-none"
|
|||
|
|
aria-hidden
|
|||
|
|
/>
|
|||
|
|
{/* Indicador de página */}
|
|||
|
|
<div className="h-5 w-28 rounded bg-foreground/10 animate-pulse motion-reduce:animate-none" />
|
|||
|
|
{/* Siguiente */}
|
|||
|
|
<div
|
|||
|
|
className="h-8 w-8 rounded-md bg-foreground/10 animate-pulse motion-reduce:animate-none"
|
|||
|
|
aria-hidden
|
|||
|
|
/>
|
|||
|
|
{/* Última */}
|
|||
|
|
<div
|
|||
|
|
className="h-8 w-8 rounded-md bg-foreground/10 animate-pulse motion-reduce:animate-none"
|
|||
|
|
aria-hidden
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<span className="sr-only">Loading pagination…</span>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|