Composants
TabNav
Le rail de filtres piloté par l'URL des vues Forme (factures, clients…). Chaque onglet est un
lien portant un href complet ; la sélection suit
active, sans état interne. Un compteur optionnel s'affiche en
Badge.
TabList.onChange est un no-op, value = active.
En rendu serveur, tu passes active depuis le query param. Dans l'aperçu ci-dessous,
un linkComponent intercepte le clic (useState) pour rendre la démo manipulable.
Rail de filtres
import { TabNav } from "@forme-ch/ui/controls";
<TabNav
active={statut ?? "toutes"}
linkComponent={Link}
items={[
{ key: "toutes", label: "Toutes", count: 3303, href: "/admin/factures" },
{ key: "brouillon", label: "Brouillons", count: 1, href: "/admin/factures?statut=brouillon" },
{ key: "payees", label: "Payées", count: 2044, href: "/admin/factures?statut=payees" },
{ key: "impayees", label: "Impayées", count: null, href: "/admin/factures?statut=impayees" },
]}
/> Pleine largeur, sans filet
layout="fill" répartit les onglets ; hasDivider= retire le filet inférieur.
<TabNav
active={onglet}
layout="fill"
hasDivider={false}
linkComponent={Link}
items={[
{ key: "resume", label: "Résumé", href: "#resume" },
{ key: "activite", label: "Activité", href: "#activite" },
{ key: "documents", label: "Documents", href: "#documents" },
]}
/> Props
| Prop | Type | Défaut | Description |
|---|---|---|---|
items * | TabNavItem[] | — | Onglets : { key, label, count?, href, endContent? }. |
active * | string | — | Clé de l'onglet actif — doit matcher un item.key. |
ariaLabel | string | "Filtres" | Libellé a11y du rail d'onglets. |
hasDivider | boolean | true | Filet sous les onglets (rail de filtres Forme). |
size | "sm" | "md" | "lg" | "md" | Taille des cibles (alignée Button / TextField). |
layout | "hug" | "fill" | "hug" | Onglets ajustés au contenu (« hug ») ou répartis (« fill »). |
linkComponent | ElementType | <a> natif | Composant de lien (ex. next/link). Doit accepter href, className, style, children. |
TabNavItem
| Prop | Type | Défaut | Description |
|---|---|---|---|
key * | string | — | Clé de l'onglet (matche le query param ou la valeur « défaut »). |
label * | string | — | Libellé affiché. |
count | number | null | — | Compteur optionnel — omis ou null = pas de badge. |
href * | string | — | URL complète. L'appelant préserve les autres params. |
endContent | ReactNode | — | Contenu de fin custom (remplace le badge de compteur). |
Accessibilité
Renseigne ariaLabel pour nommer le rail (« Filtres factures »). Comme les
onglets sont de vrais liens, la navigation clavier et le retour arrière du navigateur fonctionnent
nativement. Le count est formaté fr-CH et rendu
en Badge neutre ; un endContent le remplace si fourni.
Le rail scrolle horizontalement sur mobile.
Do & Don't
✓ À faire
Piloter la sélection par l'URL et fournir un href complet par onglet. Passer next/link en linkComponent.
✕ À éviter
Gérer l'onglet actif par un état local en production (c'est un modèle URL). Confondre avec des onglets de contenu (panneaux) — ici ce sont des filtres/navigation.