React + MotionNavegación
Pestañas segmentadas iOS
Un carril gris suave por el que una píldora blanca con una sombra ligera se desliza hasta la sección que eliges.
Ajustes
3
Código
import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
const spring = { type: "spring" as const, stiffness: 300, damping: 30 };
const OPTIONS = ["Estancias", "Experiencias", "Servicios"];
interface SegmentedControlProps {
count?: number;
}
export default function SegmentedControl({ count = 3 }: SegmentedControlProps) {
const options = OPTIONS.slice(0, count);
const [active, setActive] = useState(0);
return (
<div className="flex rounded-full bg-black/5 p-1 text-[#1d1d1f] dark:text-[#f5f5f7] dark:bg-white/10">
{options.map((option, i) => (
<button
key={option}
type="button"
aria-pressed={active === i}
onClick={() => setActive(i)}
className="relative rounded-full px-4 py-2 text-sm"
>
<AnimatePresence>
{active === i && (
<motion.span
layoutId="segmented-pill"
className="absolute inset-0 rounded-full bg-white dark:bg-[#1c1c1e] shadow-[0_1px_2px_rgba(0,0,0,0.03),0_8px_28px_rgba(0,0,0,0.05)]"
transition={spring}
/>
)}
</AnimatePresence>
<span className="relative">{option}</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 Navegación
Dónde usarlo
Imagina la cabecera de una web de reservas que separa su oferta en «Estancias», «Experiencias» y «Servicios». Ahí es donde encajan estas pestañas segmentadas estilo iOS: un cambio neutro entre dos o tres grandes secciones, no un filtro de colores. La píldora blanca se desliza con un muelle suave, como en las apps del iPhone.
Como no lleva color de acento, queda bien en páginas cargadas sin pelearse con tus botones principales. Limítalo a tres opciones y usa palabras que la gente buscaría, no nombres internos ingeniosos.