Aller au contenu
Design system

Composants · data

Données & tableaux

Le statut est toujours visible, les montants toujours avec leur devise et en chiffres tabulaires, les négatifs signalés par le signe et la couleur. Chaque document montre ses documents liés.

  • StatusBadge
  • Badge
  • Tag
  • MoneyText
  • QuantityText
  • DateText
  • PercentText
  • Card
  • Avatar
  • AvatarGroup
  • DataTable
  • RowActionsMenu
  • Pagination
  • FilterBar
  • DescriptionList
  • Timeline
  • DocumentFlow
  • TreeTable
  • PlanningGrid
  • MatchingGrid

Statuts et étiquettes

StatusBadge — les 27 statuts de documents

Quand l’utiliser : Afficher le statut d’un document partout où il apparaît (en-tête, tableau, carte). Le dictionnaire commun garantit le même libellé et le même ton dans tous les modules ; un module peut le compléter via dictionary.

  • Brouillondraft
  • À validerpending_approval
  • Approuvéapproved
  • Refusérejected
  • Confirméconfirmed
  • En coursin_progress
  • Partiellement reçupartially_received
  • Partiellement livrépartially_delivered
  • Reçureceived
  • Livrédelivered
  • Facturéinvoiced
  • Partiellement payépartially_paid
  • Payépaid
  • En retardoverdue
  • Annulécancelled
  • Extournéreversed
  • Comptabiliséposted
  • Clôturéclosed
  • Verrouillélocked
  • Bloquéblocked
  • En quarantainequarantine
  • Libéréreleased
  • Planifiéplanned
  • Lancéreleased_mo
  • Suspendususpended
  • Terminécompleted
  • Archivéarchived
ConfirméConfirméConfirméEn peséeSoldée
La pastille colorée n’est jamais le seul indice : le libellé est toujours affiché. Tailles sm, md, lg.
Afficher le code
<StatusBadge status="pending_approval" />                     // À valider
<StatusBadge status="quarantine" size="sm" />
<StatusBadge status="weighing" dictionary={{ weighing: { label: 'En pesée', tone: 'info' } }} />

Badge et Tag

Quand l’utiliser : Badge : information catégorielle courte non statutaire (type d’article, rôle, nouveauté). Tag : étiquette libre, éventuellement retirable (segments clients, mots-clés).

neutralinfosuccesswarningdangerspecialprimary
Matière premièreProduit finiSuivi par lotNouveau
GrossisteOuagadougouPaiement 30 jLivraison incluseVerrouillé
Afficher le code
<Badge tone="special" icon={<Wheat />}>Matière première</Badge>
<Tag onRemove={() => remove('Grossiste')}>Grossiste</Tag>

Valeurs formatées

MoneyText, QuantityText, PercentText, DateText

Quand l’utiliser : Toujours afficher une valeur métier avec son composant de formatage : montant en unités mineures avec devise, quantité avec unité, pourcentage depuis une fraction, date au format local du site.

Montant de commande
18 750 000 F CFA
Avoir (négatif)
−1 125 000 F CFA
Variation CA (delta)
+15 150 000 F CFA
Sans devise
94 800 000
En euros
12 500,50 EUR
Valeur absente
—
Stock paddy TS2
412 850 kg
Écart d’inventaire
-12,5 sac
Rendement usinage
63,4 %
Production vs mois préc.
+7,4 %
Heures d’arrêt (inversé)
−34,1 %
Date
Date et heure
Relative
Afficher le code
<MoneyText value="18750000" currency="XOF" />                     // 18 750 000 F CFA
<MoneyText value="-1125000" currency="XOF" />                     // −1 125 000 F CFA (rouge)
<MoneyText value="15150000" currency="XOF" tone="delta" signDisplay="exceptZero" />
<QuantityText value="412850" unit="kg" />
<PercentText value={0.088} delta showIcon />
<DateText value="2026-10-13T09:42:00Z" mode="relative" />

Tableau de données

DataTable s’appuie sur TanStack Table : colonnes ColumnDef, meta.align pour les nombres, meta.rowLink pour la cellule qui porte le lien.

DataTable — commandes clients

Quand l’utiliser : Toute liste de documents ou de référentiel : tri, sélection et actions en masse, colonnes configurables, densité, actions de ligne, ligne cliquable par un vrai lien, totaux en pied et cartes sur mobile (< 768 px : réduisez la fenêtre).

État simulé :
  • Ville : Ouagadougou
  • CMD-2026-00428Brouillon
    Grossiste Démo Tampouy · Ouagadougou
    9 950 000 F CFA
  • CMD-2026-00424in_preparation
    Supérette Démo Gounghin · Ouagadougou
    704 000 F CFA
  • CMD-2026-00425in_preparation
    Grossiste Démo Kossodo · Ouagadougou
    9 375 000 F CFA
  • CMD-2026-00421Payé
    Grossiste Démo Kossodo · Ouagadougou
    18 750 000 F CFA
  • CMD-2026-00417Facturé
    Grossiste Démo Kossodo · Ouagadougou
    21 000 000 F CFA

Le bouton « Filtres » ajoute ou retire le filtre Ville = Ouagadougou.

Cliquez un en-tête pour trier (tri côté « serveur » simulé, avant pagination). Cochez des lignes pour voir la barre d’actions groupées. Menu « Colonnes » et bouton de densité à droite de la barre d’outils.
Afficher le code
<DataTable
  caption="Commandes clients" columns={columns} data={rows} getRowId={(r) => r.id}
  sorting={sorting} onSortingChange={setSorting} manualSorting
  enableRowSelection bulkActions={(selected, clear) => <Button size="sm">Exporter ({selected.length})</Button>}
  rowActions={(r) => [{ label: 'Dupliquer' }, { label: 'Annuler…', danger: true, separatorBefore: true }]}
  getRowHref={(r) => `/sales/orders/${r.id}`} getRowLabel={(r) => r.number}
  enableDensityToggle defaultColumnVisibility={{ deliveryDate: false }}
  toolbar={<FilterBar search={<SearchInput … />} chips={chips} onRemoveChip={…} onReset={reset} />}
  renderMobileCard={(r) => <OrderCard order={r} />}
  empty={<EmptyState variant="no-results" size="sm" onResetFilters={reset} />}
  footer={<Pagination variant="pages" page={page} pageCount={pageCount} onPageChange={setPage} … />}
/>

// Colonne numérique : alignée à droite, chiffres tabulaires, total en pied
{ id: 'amount', accessorFn: (r) => Number(r.amount), header: 'Montant', meta: { align: 'right' },
  cell: ({ row }) => <MoneyText value={row.original.amount} currency="XOF" />,
  footer: ({ table }) => <MoneyText value={sumOf(table)} currency="XOF" /> }

FilterBar

Quand l’utiliser : Au-dessus d’une liste : recherche, bouton « Filtres » (panneau ou tiroir), vues enregistrées, filtres actifs en puces retirables et « Réinitialiser ». Les filtres vivent dans l’URL.

  • Statut : À valider, Confirmé
  • Site : Usine de Di
  • Période : 01/10/2026 – 13/10/2026
Afficher le code
<FilterBar
  search={<SearchInput placeholder="Rechercher…" size="sm" />}
  onFiltersClick={openFilters}
  savedViews={<Button size="sm" variant="ghost">Mes vues</Button>}
  actions={<Button size="sm">Exporter</Button>}
  chips={[{ id: 'status', label: 'Statut', value: 'À valider, Confirmé' }]}
  onRemoveChip={(id) => removeFilter(id)} onReset={resetFilters}
/>

RowActionsMenu

Quand l’utiliser : Menu « ⋯ » d’une ligne ou d’une carte. Utilisé automatiquement par DataTable (prop rowActions) ; disponible seul pour une liste personnalisée.

  • CMD-2026-00428Grossiste Démo TampouyBrouillon
  • CMD-2026-00427Distribution Céréales DémoÀ valider
  • CMD-2026-00426Alimentation Démo SahelPartiellement livré

Libellé accessible propre à chaque ligne.

Afficher le code
<RowActionsMenu label="Actions sur CMD-2026-00421" actions={[
  { label: 'Ouvrir' }, { label: 'Dupliquer' },
  { label: 'Annuler…', danger: true, separatorBefore: true },
]} />

Pagination

Quand l’utiliser : Sous un tableau. Par numéros de page quand le total est connu ; par curseur (précédent / suivant) pour les grands volumes paginés côté serveur.

Afficher le code
<Pagination variant="pages" page={page} pageCount={25} onPageChange={setPage} total={1240} rangeStart={101} rangeEnd={150} />
<Pagination hasPrevious={…} hasNext={…} onPrevious={…} onNext={…} rangeStart={1} rangeEnd={50} />

Cartes et fiches

Card, Avatar et AvatarGroup

Quand l’utiliser : Card regroupe un contenu autonome (tuile, résumé, bloc de fiche) ; avec href, toute la carte est cliquable via un vrai lien porté par le titre. Avatar identifie une personne (photo ou initiales).

Grossiste Démo Kossodo

Client depuis 2019 · Ouagadougou

Encours
39 750 000 F CFA
Commandes 2026
14

CMD-2026-00421

Carte cliquable (lien)

Confirmé18 750 000 F CFA

Équipe de quart

Usine de Di · quart du matin

ADAwa DémoDirectrice industrielle
IDMDPD
IDMDPD+2
Afficher le code
<Card title="Grossiste Démo Kossodo" description="Client depuis 2019" actions={<RowActionsMenu actions={…} label="Actions" />}
      footer={<Button size="sm">Voir la fiche</Button>}>…</Card>
<Card href="/sales/orders/so-421" title="CMD-2026-00421" variant="outlined">…</Card>
<AvatarGroup people={[{ name: 'Awa Démo' }, { name: 'Issa Démo' }, …]} max={3} />

DescriptionList

Quand l’utiliser : Bloc de propriétés d’une fiche (en-tête de document, onglet Informations). stacked (libellé au-dessus) sur plusieurs colonnes, inline (libellé à gauche) dans un panneau étroit.

Client
Grossiste Démo TampouyCLI-00041
Date de commande
Livraison prévue
Montant HT
9 950 000 F CFA
Statut
Brouillon
Commercial
Issa Démo
Référence client
—
Adresse de livraison
Zone industrielle de Kossodo, lot 14, Ouagadougou
Afficher le code
<DescriptionList columns={3} items={[
  { label: 'Client', value: 'Grossiste Démo Kossodo' },
  { label: 'Montant', value: <MoneyText value="18750000" currency="XOF" /> },
  { label: 'Adresse de livraison', value: '…', span: 'full' },
]} />

Historique

Timeline (ActivityFeed)

Quand l’utiliser : Historique d’un document ou flux d’activité : qui a fait quoi, quand, et quelles valeurs ont changé (ancienne → nouvelle). Les actions système sont signalées comme telles.

  1. Système a émis et comptabilisé la facture FAC-2026-00377 ·

  2. Issa Démo a validé l’expédition BL-2026-00388 ·

  3. Mariam Démo a libéré le lot RB25-261013-01 ·

  4. Paul Démo a modifié la limite de crédit de Comptoir Démo du Centre ·

    • Limite de crédit :5 000 000 F CFAremplacé par8 000 000 F CFA
  1. Mariam Démo a mis le lot en quarantaine ·

    Humidité mesurée à 15,8 % : séchage complémentaire demandé.
  2. Système a créé le lot RB25-261012-04 ·

Afficher le code
<Timeline events={[
  { id: 'a1', actor: { name: 'Issa Démo' }, action: 'a validé la livraison BL-2026-00388', date: '2026-10-13T09:42:00Z' },
  { id: 'a4', actor: { name: 'Paul Démo' }, action: 'a modifié la limite de crédit', date: '…',
    changes: [{ field: 'Limite de crédit', from: '5 000 000 F CFA', to: '8 000 000 F CFA' }] },
]} timeZone="Africa/Ouagadougou" />

Flux de documents

DocumentFlow — Devis → Commande → BL → Facture → Paiement

Quand l’utiliser : Dans l’en-tête ou l’onglet « Documents liés » de chaque document : la chaîne complète, le document courant mis en évidence, chaque étape cliquable, les étapes futures grisées.

Afficher le code
<DocumentFlow currentId="cmd" steps={[
  { id: 'dev', type: 'Devis', number: 'DEV-2026-00198', status: 'approved', date: '2026-10-08', href: '…' },
  { id: 'cmd', type: 'Commande', number: 'CMD-2026-00421', status: 'confirmed', href: '/sales/orders/so-421' },
  { id: 'bl', type: 'Livraison', number: 'BL-2026-00388', status: 'partially_delivered' },
  { id: 'fac', type: 'Facture', pending: true },
  { id: 'pay', type: 'Paiement', pending: true },
]} />

Arborescences, plannings et rapprochements

Grilles spécialisées construites sur les mêmes conventions que DataTable : légende accessible, chiffres tabulaires, montants en bigint.

TreeTable — arborescence avec sous-totaux

Quand l’utiliser : Données hiérarchiques à plusieurs niveaux : plan comptable, nomenclature, organigramme, budget par rubrique. Les colonnes aggregate cumulent les montants (bigint) des descendants.

Comptes de trésorerie et soldes
CompteSolde
52 — Banques
85 650 000 F CFA
5251 — Comptes à terme
25 000 000 F CFA
Total88 140 000 F CFA
Motif ARIA treegrid : ↑ ↓ lignes, → déplie, ← replie ou remonte au parent, Entrée active la ligne. Le pied affiche le total général.
Afficher le code
<TreeTable caption="Trésorerie" rows={accounts} getRowId={(a) => a.id} getChildren={(a) => a.children}
  defaultExpanded="all" showExpandControls
  columns={[
    { id: 'label', header: 'Compte', cell: (a) => a.label },
    { id: 'balance', header: 'Solde', align: 'end', aggregate: true, value: (a) => a.balance, format: (v) => formatMoney(v, 'XOF') },
  ]} />

PlanningGrid — ressources × jours

Quand l’utiliser : Planning des congés, roulements d’équipes, présence : une ligne par ressource, une colonne par jour. Le code court porte le sens, la couleur le renforce.

Planning des congés — équipe de démonstration, octobre 2026
SalariéL05 5 octobreM06 6 octobreM07 7 octobreJ08 8 octobreV09 9 octobreS10 10 octobreD11 11 octobreL12 12 octobreM13 13 octobre, aujourd'huiM14 14 octobreJ15 15 octobre, Fête de démonstrationV16 16 octobreS17 17 octobreD18 18 octobre
Awa DémoOpératrice décortiqueuseCA Congé annuelCA Congé annuel
Issa ExempleConducteur de ligneAM Absence maladieFOR Formation sécurité
Mariam FictiveMagasinièreAI Absence injustifiéeCA Congé annuel (en attente)CA Congé annuel (en attente)
Présents33222333223333
  • CACongé annuel
  • CADemande en attente
  • AMAbsence maladie
  • AIAbsence injustifiée
  • FORFormation
Première colonne et en-tête figés, défilement horizontal limité au conteneur, week-ends et fériés grisés, jour courant repéré. Pointillés : en attente ; liseré : anomalie.
Afficher le code
<PlanningGrid caption="Planning des congés" days={isoDateRange('2026-10-05', '2026-10-18')} rows={rows}
  holidays={[{ date: '2026-10-15', label: 'Fête de démonstration' }]} today="2026-10-13"
  legend={[{ code: 'CA', label: 'Congé annuel', tone: 'primary' }, …]} />

MatchingGrid — rapprochement de deux listes

Quand l’utiliser : Pointer des éléments de part et d’autre jusqu’à l’équilibre : lignes de relevé ↔ écritures (mode equal), lettrage débit ↔ crédit (mode zeroSum).

Relevé bancaire

0 sélectionnée · 0 F CFA

Écritures comptables

0 sélectionnée · 0 F CFA
Sélectionnez des lignes de part et d’autre.
Totaux des sélections et écart annoncés aux lecteurs d’écran ; l’action « Rapprocher » n’est activée que si la sélection est équilibrée (tolérance configurable).
Afficher le code
<MatchingGrid currency="XOF"
  left={{ title: 'Relevé bancaire', items: statementLines }}
  right={{ title: 'Écritures comptables', items: bookEntries }}
  actions={({ balanced, clear }) => <Button disabled={!balanced} onClick={clear}>Rapprocher</Button>} />