motion-layout-id

ui

src

page.tsx

tsx
"use client"

import { useState } from "react";
import { motion } from "motion/react";

export default function Page() {

    const titles = [ "Tailwind", "React", "Next", "Zustand", "Motion", "Gasp" ];

    const [ selected, setSelected ] = useState(0);

    return (
        <ul className="bg-linear-to-b/hsl lg:bg-linear-to-r/hsl from-rose-500 to-purple-700 flex flex-col lg:flex-row gap-5 p-5">
            {
                titles.map((title, i) => (
                    <li key={ title }>
                        <button className="px-5 py-3 cursor-pointer relative font-orbitron"
                                onClick={ () => setSelected(i) }>
                            <span className="text-xl text-white">{ title }</span>
                            {
                                selected === i && (
                                    <motion.span className="absolute bottom-0 left-0 w-full h-0.5 bg-white"
                                                 layoutId="underline"/>
                                )
                            }
                        </button>
                    </li>
                ))
            }
        </ul>
    )
}

video