diff --git a/apps/web/src/components/dashboard/KpiCard.tsx b/apps/web/src/components/dashboard/KpiCard.tsx index 50ec6c1..3f41caa 100644 --- a/apps/web/src/components/dashboard/KpiCard.tsx +++ b/apps/web/src/components/dashboard/KpiCard.tsx @@ -15,7 +15,8 @@ import { cn } from "@/lib/utils"; * - On laisse l'utilisateur déclarer l'intent. */ type KpiCardProps = { - label: string; + /** Texte ou node — accepte un GlossaryTerm si la métrique a une définition. */ + label: React.ReactNode; value: string; delta?: string; /** Sens du delta affiché (sert juste à colorer subtilement). Default neutral. */ diff --git a/apps/web/src/components/ui/GlossaryTerm.tsx b/apps/web/src/components/ui/GlossaryTerm.tsx new file mode 100644 index 0000000..724a5a1 --- /dev/null +++ b/apps/web/src/components/ui/GlossaryTerm.tsx @@ -0,0 +1,80 @@ +import * as TooltipPrimitive from "@radix-ui/react-tooltip"; +import { Asterisk } from "lucide-react"; +import { cn } from "@/lib/utils"; + +/** + * Term wrapper — affiche un terme avec une petite astérisque cliquable/hoverable + * qui révèle sa définition. Pour le glossaire métier (DSO, LME, mise en demeure…). + * + * Pas de tooltip natif (`title=`) parce qu'il s'affiche en gris système et + * casse la DA. Radix Tooltip est déjà dans la stack pour Dialog, on en + * profite ici. + */ +type GlossaryTermProps = { + /** Le mot/expression visible (ex. "DSO moyen"). */ + children: React.ReactNode; + /** Définition affichée dans le tooltip. */ + definition: React.ReactNode; + /** Côté du tooltip (défaut bottom). */ + side?: "top" | "right" | "bottom" | "left"; + /** Classe sur le wrapper. */ + className?: string; + /** Position de l'astérisque (défaut : after = à droite). */ + marker?: "before" | "after"; +}; + +export function GlossaryTerm({ + children, + definition, + side = "bottom", + className, + marker = "after", +}: GlossaryTermProps) { + const star = ( +