React + MotionFiltres
Contrôle segmenté
Une rangée d’options où une pastille colorée glisse jusqu’à celle que vous choisissez.
Réglages
3
Code
import { useId, useState } from "react";
import { motion } from "framer-motion";
const sizeMap = {
sm: { pad: "px-3 py-1.5", text: "text-xs" },
md: { pad: "px-4 py-2", text: "text-sm" },
lg: { pad: "px-5 py-2.5", text: "text-base" },
} as const;
interface SegmentedControlProps {
accent?: string;
size?: keyof typeof sizeMap;
options?: string[];
value?: string;
onChange?: (value: string) => void;
}
export default function SegmentedControl({
accent = "#0071e3",
size = "md",
options = ["Design", "Code", "Audio"],
value,
onChange,
}: SegmentedControlProps) {
const [internal, setInternal] = useState(options[0] ?? "");
const layoutId = useId();
const active = value ?? internal;
const current = options.includes(active) ? active : options[0];
const s = sizeMap[size];
const select = (o: string) => {
if (value === undefined) setInternal(o);
onChange?.(o);
};
return (
<div className="flex rounded-full bg-black/5 p-1 dark:bg-white/10">
{options.map((o) => (
<button
key={o}
type="button"
aria-pressed={current === o}
onClick={() => select(o)}
className={`relative rounded-full font-medium ${s.pad} ${s.text}`}
>
{current === o && (
<motion.span
layoutId={layoutId}
className="absolute inset-0 rounded-full"
style={{ backgroundColor: accent }}
transition={{ type: "spring", stiffness: 380, damping: 30 }}
/>
)}
<span
className="relative z-10"
style={{ color: current === o ? "#ffffff" : undefined }}
>
{o}
</span>
</button>
))}
</div>
);
}
Prompt pour l’IA
Collez-le dans ChatGPT, Claude ou Cursor : le bloc sera adapté à votre projet avec ces réglages, même sans React.
Plus dans Filtres
Où l’utiliser
Un contrôle segmenté sert à changer de vue, pas à filtrer : « Mensuel / Annuel » sur une page de tarifs, « Liste / Carte » dans une recherche immobilière ou « Jour / Semaine / Mois » dans un agenda. Comme la pastille glisse au lieu de sauter, on voit ce qui a changé. Pensez à ce segmented control dès qu’il y a deux à quatre choix.
Au-delà de quatre options, l’espace manque, surtout sur mobile : raccourcissez la liste ou passez à des onglets. Choisissez une couleur d’accent assez contrastée, car le libellé sélectionné passe en blanc.