Composant · Données
DataTable
StableTableau de données avec en-têtes triables, sélection et pagination intégrée.
Exemples
Services actifs
Tableau de base
| Search API | Platform | EU | 99.96 | Stable |
| Graph API | Platform | US | 99.71 | Stable |
| Chat Core | Chat | EU | 98.44 | Warning |
| Ingest | Data | EU | 97.88 | Stable |
| Billing | Finance | US | 99.12 | Stable |
| Streaming | Data | APAC | 95.05 | Degraded |
Format de ligne : ID, name, team, region, uptime, status
Voir le code (Svelte)
<DataTable
columns={[{"key":"name","label":"Service","sortable":true},{"key":"team","label":"Equipe","sortable":true},{"key":"region","label":"Région"},{"key":"uptime","label":"Disponibilité","align":"end","sortable":true,"width":"8rem"},{"key":"status","label":"Statut","align":"center"}]}
rows={[{"id":"api-search","name":"Search API","team":"Platform","region":"EU","uptime":99.96,"status":"Stable"},{"id":"api-graph","name":"Graph API","team":"Platform","region":"US","uptime":99.71,"status":"Stable"},{"id":"chat-core","name":"Chat Core","team":"Chat","region":"EU","uptime":98.44,"status":"Warning"},{"id":"ingest","name":"Ingest","team":"Data","region":"EU","uptime":97.88,"status":"Stable"},{"id":"billing","name":"Billing","team":"Finance","region":"US","uptime":99.12,"status":"Stable"},{"id":"stream","name":"Streaming","team":"Data","region":"APAC","uptime":95.05,"status":"Degraded"}]}
caption="Services actifs"
size="sm"
/>
<p>
<strong>Format de ligne :</strong>
<code>ID, name, team, region, uptime, status</code>
</p>Selection + pagination
Tableau paginé
| Search API | Platform | EU | 99.96 | Stable |
| Graph API | Platform | US | 99.71 | Stable |
| Chat Core | Chat | EU | 98.44 | Warning |
Voir le code (Svelte)
<DataTable
caption="Selection + pagination"
columns={[{"key":"name","label":"Service","sortable":true},{"key":"team","label":"Equipe","sortable":true},{"key":"region","label":"Région"},{"key":"uptime","label":"Disponibilité","align":"end","sortable":true,"width":"8rem"},{"key":"status","label":"Statut","align":"center"}]}
rows={[{"id":"api-search","name":"Search API","team":"Platform","region":"EU","uptime":99.96,"status":"Stable"},{"id":"api-graph","name":"Graph API","team":"Platform","region":"US","uptime":99.71,"status":"Stable"},{"id":"chat-core","name":"Chat Core","team":"Chat","region":"EU","uptime":98.44,"status":"Warning"},{"id":"ingest","name":"Ingest","team":"Data","region":"EU","uptime":97.88,"status":"Stable"},{"id":"billing","name":"Billing","team":"Finance","region":"US","uptime":99.12,"status":"Stable"},{"id":"stream","name":"Streaming","team":"Data","region":"APAC","uptime":95.05,"status":"Degraded"}]}
size="md"
pageSize={3}
previousLabel="Précédent"
nextLabel="Suivant"
/>Le tri par en-tête, la sélection multiple et le clic de ligne sont interactifs dans l'implémentation Svelte du DataTable ; cet aperçu est figé sur le sous-ensemble commun aux trois frameworks (colonnes, lignes, légende, taille, pagination).
Mise en forme conditionnelle
Décorations sémantiques
| Search API | Platform | EU | 99.96 tendance positive | Stable |
| Graph API | Platform | US | 99.71 | Stable |
| Chat Core | Chat | EU | 98.44 avertissement | Warning avertissement |
| Ingest | Data | EU | 97.88 | Stable |
| Billing | Finance | US | 99.12 information | Stable |
| Streaming | Data | APAC | 95.05 tendance négative | Degraded tendance négative |
Voir le code (Svelte)
<DataTable
caption="Mise en forme conditionnelle"
columns={[{"key":"name","label":"Service","sortable":true},{"key":"team","label":"Equipe","sortable":true},{"key":"region","label":"Région"},{"key":"uptime","label":"Disponibilité","align":"end","sortable":true,"width":"8rem"},{"key":"status","label":"Statut","align":"center"}]}
rows={[{"id":"api-search","name":"Search API","team":"Platform","region":"EU","uptime":99.96,"status":"Stable"},{"id":"api-graph","name":"Graph API","team":"Platform","region":"US","uptime":99.71,"status":"Stable"},{"id":"chat-core","name":"Chat Core","team":"Chat","region":"EU","uptime":98.44,"status":"Warning"},{"id":"ingest","name":"Ingest","team":"Data","region":"EU","uptime":97.88,"status":"Stable"},{"id":"billing","name":"Billing","team":"Finance","region":"US","uptime":99.12,"status":"Stable"},{"id":"stream","name":"Streaming","team":"Data","region":"APAC","uptime":95.05,"status":"Degraded"}]}
size="sm"
decorations={{"api-search":{"uptime":{"intent":"positive","icon":"trending-up"}},"chat-core":{"uptime":{"intent":"warning","icon":"triangle-alert"},"status":{"intent":"warning"}},"stream":{"uptime":{"intent":"negative","icon":"trending-down"},"status":{"intent":"negative"}},"billing":{"uptime":{"intent":"info","icon":"info"}}}}
/>La prop `decorations` (rowId → colId → { intent, icon }) applique un fond teinté accessible issu des tokens feedback (mêmes que Badge / Alert) et une icône lucide. L'intention n'est jamais signalée par la seule couleur : un texte lecteur d'écran et un `title` décrivent l'intent. Le moteur de règles (seuils, comparaisons) vit côté dataviz-core ; le DS ne fait que rendre la sortie.
API
| Prop | Type | Default |
|---|---|---|
columns | DataTableColumn[] | requis |
rows | DataTableRow[] | requis |
decorations | Record<string, Record<string, CellDecoration>> | optionnel |
caption | string | optionnel |
size | "sm" | "md" | "lg" | "md" |
selectable | "none" | "single" | "multiple" | "none" |
selectedIds | string[] ($bindable) | [] |
onSelectionChange | (ids: string[]) => void (React / Vue) | optionnel |
sortable | boolean | true |
sortBy | DataTableSort | null ($bindable) | null |
onSortChange | (sortBy: DataTableSort | null) => void (React / Vue) | optionnel |
pageSize | number | désactivé |
page | number ($bindable) | 1 |
onPageChange | (page: number) => void (React / Vue) | optionnel |
onRowClick | (row: DataTableRow) => void | optionnel |
selectAllLabel | string | "Select all rows" |
selectRowLabel | string | "Select row" |
previousLabel | string | "Previous" |
nextLabel | string | "Next" |
paginationLabel | string | "Pagination" |
rangeLabel | (range: { start: number; end: number; total: number }) => string | ({ start, end, total }) => "start-end of total" |
emptyLabel | string | "No data" |
class | string | optionnel |
Pour piloter l’état depuis le parent : Svelte utilise des props $bindable (selectedIds, sortBy, page), tandis que React et Vue
utilisent le couple prop contrôlée + callback
(onSelectionChange, onSortChange, onPageChange).
Les cellules sont triables par défaut si sortable reste vrai; une
colonne triable bascule ascending → descending → sans
tri. Les lignes disposent d’un état cliquable quand onRowClick est
fourni.
Notes d’usage
- Le tri est géré localement via `sortBy` (aucune source de vérité externe imposée).
- `selectable="multiple"` ajoute la colonne de cases à cocher et active la sélection groupée.
- Quand `pageSize` est fourni, la pagination se calcule côté composant; `page` peut être bindé pour contrôler l’état externe.
- Chaque ligne doit fournir un `id` stable et unique; il sert à l’identifiant d’accessibilité et de sélection.
Tokens utilisés
--st-component-dataTable-border--st-component-dataTable-captionText--st-component-dataTable-headerBackground--st-component-dataTable-rowBackground--st-component-dataTable-rowHoverBackground--st-component-dataTable-text--st-component-dataTable-radius--st-component-pagination-background--st-component-pagination-border--st-component-pagination-text--st-component-pagination-radius--st-component-control-focusRing--st-component-control-hoverBackground--st-component-control-hoverBorder--st-semantic-action-primary--st-semantic-border-subtle--st-semantic-surface-subtle--st-semantic-surface-default--st-semantic-text-secondary