DataTable
Un tableau de données.
Il n'ordonne rien lui-même : à partir de quelques centaines de lignes, trier côté client veut dire les avoir toutes téléchargées. Le tri est une intention envoyée au serveur, et le tableau affiche ce qu'on lui rend.
La recherche fait exception, et seulement par défaut : sans onSearch, elle filtre les lignes déjà chargées — ce qui suffit tant que tout tient sur une page.
Installation
bash
sia-ui add data-tableOu par le paquet, sans rien copier :
tsx
import { DataTable, createTanStackRouterStorage, createUrlTableStorage, useDataTableQuery } from "@sia-ui/react-web";Props de DataTable
| Prop | Type | Défaut | Description |
|---|---|---|---|
* columns | DataTableColumn<T>[] | — | |
* data | T[] | — | |
actions | ReactNode | — | Actions globales, à droite. |
actionsDisplay | "icon" | "label" | icon | icon garde la colonne étroite sur un tableau déjà large. |
actionsHeader | ReactNode | — | |
bordered | boolean | true | |
can | (rule: PermissionRule) => boolean | — | Évalue les règles de permission des actions. |
caption | string | — | |
cardsBreakpoint | number | 768 | |
checkboxProps | Partial<Omit<CheckboxProps, "value" | "onValueChange" | "onClick" | "defaultChecked" | "onChange" | "disabled" | "checked" | "indeterminate">> | — | Les cases de sélection, en-tête comprise : taille, ton, classe. L'état coché, l'indétermination et le rappel sont calculés par le tableau ; le clic reste retenu pour ne pas déclencher onRowClick. |
className | string | — | |
confirmDialogProps | Partial<Omit<ConfirmDialogProps, "title" | "open" | "onOpenChange" | "tone" | "onConfirm">> | — | La confirmation d'une action : libellés par défaut, loading. Ce que déclare confirm sur l'action l'emporte ; le ton suit confirm.destructive, l'ouverture et la validation restent au tableau. |
defaultSelectedKeys | Key[] | — | |
defaultView | "table" | "cards" | table | |
density | "default" | "compact" | "comfortable" | default | |
description | ReactNode | — | |
empty | { title?: ReactNode; description?: ReactNode; action?: ReactNode; icon?: ReactNode; } | — | |
emptyStateProps | EmptyStateProps | — | L'état vide au complet : icône, compact, classe. Ce que déclare empty l'emporte sur les mêmes clés. |
error | ReactNode | — | |
errorStateProps | Partial<Omit<ErrorStateProps, "description" | "error">> | — | L'état d'erreur : titre, libellé du bouton, action, compact. Le message vient de error ; onRetry du tableau l'emporte s'il est fourni. |
getRowKey | (row: T, index: number) => Key | — | La clé d'une ligne. Sans elle, l'index — à éviter si les lignes bougent. |
inlineActionsLimit | number | 2 | Au-delà, les actions passent dans un menu. |
isRowSelectable | (row: T, index: number) => boolean | — | |
layout | "auto" | "fixed" | auto | |
loading | boolean | false | |
maxHeight | string | — | Hauteur du corps. Sans elle, stickyHeader n'a rien où se coller. |
onRetry | () => void | — | |
onRowClick | (row: T, index: number) => void | — | |
onSearch | (query: string) => void | — | Recherche déléguée. Fournie, le tableau cesse de filtrer lui-même. |
onSelectionChange | (keys: Key[], rows: T[]) => void | — | |
onSortChange | (field: string) => void | — | |
onViewChange | (view: DataTableView) => void | — | |
renderCard | (row: T, index: number) => ReactNode | — | Rendu complet d'une carte. Sans lui, elle est déduite des colonnes. |
responsive | boolean | true | Bascule en cartes sous le point de rupture. Actif par défaut : un tableau à sept colonnes est illisible sur un téléphone. |
rowActionButtonProps | Partial<Omit<ButtonProps, "children" | "onClick" | "disabled">> | — | Les boutons d'action à libellé : variante, taille, classe. Le clic, le libellé et l'état désactivé viennent de chaque RowAction. |
rowActionIconButtonProps | Partial<Omit<IconButtonProps, "icon" | "onClick" | "label" | "disabled">> | — | Les boutons d'action réduits à l'icône, déclencheur du menu « autres actions » compris. Une tooltip passée ici se fusionne avec celle de l'action, qui garde son libellé. |
rowActions | RowAction<T>[] | ((row: T, index: number) => RowAction<T>[]) | — | |
rowActionsMenuProps | Partial<Omit<DropdownMenuProps, "children" | "items" | "onSelect" | "open" | "defaultOpen">> | — | Le menu des actions qui ne tiennent pas en ligne : placement, décalage. Ni open ni defaultOpen : partagés par toutes les lignes, ils ouvriraient tous les menus à la fois. |
rowClassName | (row: T, index: number) => string | — | |
searchDelay | number | 0 | Millisecondes d'inactivité avant d'appeler onSearch. 0 — le défaut — l'appelle à chaque frappe, ce qui convient à un filtrage local. Pour une recherche serveur, 300 évite une requête par lettre ; Entrée et l'effacement déclenchent sans attendre. |
searchInputProps | Partial<Omit<SearchInputProps, "value" | "defaultValue" | "onValueChange" | "onSearch" | "searchDelay">> | — | Le champ de recherche : placeholder, libellés, clearable, classe. La valeur et les rappels restent au tableau — c'est lui qui filtre et qui temporise ; les déléguer ici ferait deux recherches concurrentes. |
searchKeys | string[] | — | Les clés sur lesquelles porte la recherche. Absente, aucun champ n'est affiché : un tableau sans champ déclaré n'a rien à chercher. Le filtrage est local, sur les lignes déjà chargées. |
searchPlaceholder | string | — | |
selectable | boolean | false | Ajoute une colonne de cases à cocher. Sur une liste paginée côté serveur, la case d'en-tête ne porte que sur la page affichée : le composant ne connaît pas les lignes qu'il n'a pas reçues, et prétendre « tout sélectionner » serait un mensonge. |
selectedKeys | Key[] | — | |
selectionActions | (context: { keys: Key[]; rows: T[]; clear: () => void; }) => ReactNode | — | Barre affichée dès qu'une ligne est cochée. |
showViewToggle | boolean | false | |
skeletonProps | SkeletonProps | — | Les blocs fantômes : rayon, classe, style. Leurs tailles ne sont que des défauts. |
skeletonRows | number | 5 | Lignes fantômes pendant le premier chargement. |
sort | { field: string; direction: "asc" | "desc"; } | — | |
stickyHeader | boolean | false | |
striped | boolean | false | Un fond alterné, une ligne sur deux. |
title | ReactNode | — | |
toolbar | ReactNode | — | Zone libre : filtres, sélecteur de période. |
view | "table" | "cards" | — |
Props de useDataTableQuery
Tri, filtres et pagination d'un tableau, synchronisés avec l'URL.
Le calcul vit dans @sia-ui/headless; il n'y a ici que le branchement sur la barre d'adresse, qui est la seule partie propre au navigateur.
| Prop | Type | Défaut | Description |
|---|---|---|---|
defaultState | TableQueryState | — | |
history | "push" | "replace" | — | Empile une entrée d'historique à chaque changement. |
prefix | string | — | Préfixe des clés, pour deux tableaux sur la même page. |
router | TanStackRouterLike | — | Le routeur TanStack Router de l'application. Raccourci de storage: createTanStackRouterStorage(router) ; history s'applique. |
serverParams | TableParamsMapping | — | Les noms des paramètres serveur — limit, sort + order… |
storage | TableQueryStorage | — | Un autre endroit où ranger l'état — le plus souvent le routeur. La barre d'adresse écrite directement passe sous le nez d'un routeur qui tient ses propres paramètres (TanStack Router, React Router) : il ne voit pas le changement, et le réécrit au prochain rendu. Fourni, ce stockage remplace celui de l'URL, et syncUrl / history sont ignorés. |
syncUrl | boolean | — | false garde l'état en mémoire — utile dans une modale. |
* obligatoire.
Voir aussi
- Le composant dans le catalogue — états, variantes, et bac à sable.
- La référence complète — tous les composants.