Radius Morph Nav
Nav items whose corners morph as the pointer arrives.
dark onlyNav items whose corners morph as the pointer arrives.
dark onlyexperiments/radius-morph-nav/index.tsx
const ITEMS = ['Work', 'Lab', 'Notes', 'About']
const RADII: Record<string, { rest: string; hover: string }> = {
Pill: { rest: '0.375rem', hover: '9999px' },
Squish: { rest: '0.75rem', hover: '1.75rem 0.25rem 1.75rem 0.25rem' },
Blob: { rest: '0.75rem', hover: '60% 40% 55% 45% / 50% 55% 45% 50%' },
}
export default function RadiusMorphNav({ variant = 'Pill' }: { variant?: string }) {
const radius = RADII[variant] ?? RADII.Pill
return (
<nav className="[--rmn-fill:#f4f4f6] [--rmn-hover-ink:#111114] [--rmn-ink:#c9c9d2]">
<ul className="flex flex-wrap items-center justify-center gap-2">
{ITEMS.map((item) => (
<li key={item}>
{/* Buttons, not anchors: these lead nowhere, and an href="#" would
lie about that to a screen reader. */}
<button
type="button"
style={{
['--rmn-rest' as string]: radius?.rest,
['--rmn-hover' as string]: radius?.hover,
}}
className={[
'block rounded-[var(--rmn-rest)] px-4 py-2 text-sm font-medium text-[var(--rmn-ink)]',
'border border-[#33333c] transition-all duration-300 ease-[cubic-bezier(0.2,0,0,1)]',
'hover:rounded-[var(--rmn-hover)] hover:border-[var(--rmn-fill)]',
'hover:bg-[var(--rmn-fill)] hover:text-[var(--rmn-hover-ink)]',
'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--rmn-fill)]',
].join(' ')}
>
{item}
</button>
</li>
))}
</ul>
</nav>
)
}