Tableau
Un tableau HTML sémantique destiné aux factures, aux listes administratives et aux grilles tarifaires — lignes bordées, en-têtes en gras et ombre néobrutaliste marquée.
import {
Table,
TableBody,Le composant table habille les éléments de tableau natifs du HTML — <table>, <thead>, <tbody>, <th>, <td>, <caption> — sans bibliothèque de primitives en dessous ; les variantes Radix et Base livrent le même fichier. La recette néobrutaliste au programme : bordure épaisse et ombre franche autour du tableau entier, cellules d’en-tête dans la police de titres, et séparateurs de lignes de 2px.
À privilégier dans ces cas :
- Factures et commandes — des lignes d’articles avec une ligne
TableFooterpour le total. - Listes d’administration — utilisateurs, clés API, abonnements, avec un menu déroulant d’actions par ligne.
- Grilles tarifaires et comparatives — des matrices de fonctionnalités où les en-têtes de colonnes portent le sens.
Installation#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/table.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/table.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/table.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/table.json
Copiez-collez le code suivant dans votre projet.
"use client"
import * as React from "react"
import { cn } from "@/lib/utils"
function Table({ className, ...props }: React.ComponentProps<"table">) {
return (
<div
data-slot="table-container"
className="relative w-full overflow-x-auto rounded border-2 shadow-md"
>
<table
data-slot="table"
className={cn("w-full caption-bottom text-sm", className)}
{...props}
/>
</div>
)
}
function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
return (
<thead
data-slot="table-header"
className={cn("[&_tr]:border-b-2", className)}
{...props}
/>
)
}
function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
return (
<tbody
data-slot="table-body"
className={cn("[&_tr:last-child]:border-0", className)}
{...props}
/>
)
}
function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
return (
<tfoot
data-slot="table-footer"
className={cn(
"border-t-2 bg-muted/50 font-medium [&>tr]:last:border-b-0",
className
)}
{...props}
/>
)
}
function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
return (
<tr
data-slot="table-row"
className={cn(
"border-b-2 transition-colors hover:bg-accent has-aria-expanded:bg-accent data-[state=selected]:bg-accent",
className
)}
{...props}
/>
)
}
function TableHead({ className, ...props }: React.ComponentProps<"th">) {
return (
<th
data-slot="table-head"
className={cn(
"h-10 bg-muted px-2 text-left align-middle font-head font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
className
)}
{...props}
/>
)
}
function TableCell({ className, ...props }: React.ComponentProps<"td">) {
return (
<td
data-slot="table-cell"
className={cn(
"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
className
)}
{...props}
/>
)
}
function TableCaption({
className,
...props
}: React.ComponentProps<"caption">) {
return (
<caption
data-slot="table-caption"
className={cn("mt-4 text-sm text-muted-foreground", className)}
{...props}
/>
)
}
export {
Table,
TableHeader,
TableBody,
TableFooter,
TableHead,
TableRow,
TableCell,
TableCaption,
}
Adaptez les chemins d’import à la configuration de votre projet.
Utilisation#
import {
Table,
TableBody,
TableCaption,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"<Table>
<TableCaption>A list of your recent invoices.</TableCaption>
<TableHeader>
<TableRow>
<TableHead className="w-[100px]">Invoice</TableHead>
<TableHead>Status</TableHead>
<TableHead>Method</TableHead>
<TableHead className="text-right">Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell className="font-medium">INV001</TableCell>
<TableCell>Paid</TableCell>
<TableCell>Credit Card</TableCell>
<TableCell className="text-right">$250.00</TableCell>
</TableRow>
</TableBody>
</Table>Composition#
Utilisez la composition suivante pour construire un Table :
Table
├── TableCaption
├── TableHeader
│ └── TableRow
│ ├── TableHead
│ ├── TableHead
│ ├── TableHead
│ └── TableHead
├── TableBody
│ ├── TableRow
│ │ ├── TableCell
│ │ ├── TableCell
│ │ ├── TableCell
│ │ └── TableCell
│ └── TableRow
│ ├── TableCell
│ ├── TableCell
│ ├── TableCell
│ └── TableCell
└── TableFooterExemples#
Pied de tableau#
Utilisez le composant <TableFooter /> pour ajouter un pied de tableau.
import {
Table,
TableBody,Actions#
Un tableau qui présente des actions pour chaque ligne à l’aide d’un composant <DropdownMenu />.
import { MoreHorizontalIcon } from "lucide-react"
import { Button } from "@/components/ui/button"Data Table#
Vous pouvez utiliser le composant <Table /> pour construire des tableaux de données plus complexes. Associez-le à @tanstack/react-table pour créer des tableaux avec tri, filtrage et pagination.
Consultez la documentation Data Table pour en savoir plus.
Vous pouvez aussi voir un exemple de tableau de données dans la démo Tasks.
RTL#
Pour activer le RTL dans Neobrutalism, consultez le guide de configuration RTL.
"use client"
import * as React from "react"Accessibilité#
Rendre des éléments de tableau natifs offre aux lecteurs d’écran l’annonce du tableau, la navigation par lignes et colonnes et l’association des en-têtes, sans le moindre câblage ARIA. Nommez chaque tableau avec TableCaption et réservez TableHead aux véritables cellules d’en-tête. Le conteneur de défilement n’est pas focalisable, donc les utilisateurs au clavier seul ne peuvent pas faire défiler un tableau qui déborde — si des tableaux larges sont probables, ajoutez tabIndex={0}, role="region" et un aria-label au div conteneur dans votre copie du composant.