React + MotionFiltros
Control segmentado
Una fila de opciones en la que una píldora de color se desliza hasta la que eliges.
Ajustes
3
Código
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 = ["Diseño", "Código", "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 para IA
Pégalo en ChatGPT, Claude o Cursor y adaptará el bloque a tu proyecto con estos ajustes, aunque no uses React.
Más en Filtros
Dónde usarlo
El control segmentado sirve para cambiar de vista, no para filtrar: «Mensual / Anual» en una página de precios, «Lista / Mapa» en un buscador de pisos o «Día / Semana / Mes» en un calendario. Como la píldora se desliza en lugar de saltar, se entiende qué ha cambiado. Tira de este segmented control cuando haya entre dos y cuatro opciones.
Con más de cuatro opciones se queda apretado, sobre todo en el móvil, así que recorta la lista o pasa a pestañas. Elige un color de acento con buen contraste, porque el texto seleccionado se vuelve blanco.