Glass Nav
washiveil/glass-navFreeComponent
Floating glass pill navigation — sliding hover pill, scroll-adaptive contrast, masked blur scroll edge, working mobile sheet.
Install it
npx shadcn@latest add https://washiveil.alexchih.com/r/glass-nav.jsonSource
1'use client';23import { useEffect, useId, useRef, useState } from 'react';4import { cn } from '@/lib/utils';56interface GlassNavProps {7 brand: React.ReactNode;8 links: { label: string; href: string }[];9 activeHref?: string;10 cta?: { label: string; href: string };11 children?: React.ReactNode;12 className?: string;13}1415export function GlassNav({ brand, links, activeHref, cta, children, className }: GlassNavProps) {16 const headerRef = useRef<HTMLElement>(null);17 const pillRef = useRef<HTMLSpanElement>(null);18 const [open, setOpen] = useState(false);19 const panelId = useId();2021 useEffect(() => {22 const hdr = headerRef.current;23 if (!hdr) return;24 const sync = () => hdr.toggleAttribute('data-scrolled', window.scrollY > 24);25 window.addEventListener('scroll', sync, { passive: true });26 sync();27 return () => window.removeEventListener('scroll', sync);28 }, []);2930 const handleItemEnter = (e: React.MouseEvent<HTMLAnchorElement>) => {31 const el = e.currentTarget;32 const pill = pillRef.current;33 if (!pill) return;34 pill.style.width = `${el.offsetWidth}px`;35 pill.style.height = `${el.offsetHeight}px`;36 pill.style.transform = `translate(${el.offsetLeft}px, ${el.offsetTop}px)`;37 pill.style.opacity = '1';38 };3940 const handleNavLeave = () => {41 if (pillRef.current) pillRef.current.style.opacity = '0';42 };4344 const activeClass = 'bg-ruri font-medium text-white dark:bg-ruri-soft dark:text-deep';45 const inactiveClass = 'text-muted-foreground hover:text-foreground';4647 return (48 <header49 ref={headerRef}50 className={cn('group sticky top-4 z-30 mt-4', className)}51 style={{ viewTransitionName: 'site-nav' }}52 >53 {/* Scroll-edge masked backdrop-blur band */}54 <div55 className="pointer-events-none absolute inset-x-0 -top-4 -z-10 h-[calc(100%+2.5rem)] backdrop-blur-md [mask-image:linear-gradient(to_bottom,black_45%,transparent)]"56 aria-hidden="true"57 />5859 {/* Glass pill */}60 <div className="veil-grain grid grid-cols-[1fr_auto] items-center rounded-full lg:grid-cols-[1fr_auto_1fr] border border-glass-edge bg-glass-strong px-5 py-3 shadow-[inset_0_1px_0_rgba(255,255,255,0.70),inset_0_-1px_0_rgba(28,25,20,0.05),0_8px_32px_rgba(28,25,20,0.08)] backdrop-blur-2xl backdrop-saturate-150 transition-colors duration-300 group-data-[scrolled]:bg-glass-stronger sm:px-6 dark:shadow-[inset_0_1px_0_rgba(255,255,255,0.10),inset_0_-1px_0_rgba(0,0,0,0.35),0_8px_32px_rgba(0,0,0,0.35)]">61// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from washiveil
All 58 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Ambient Fieldambient-field | washiveil | Components | Free | no deps | |
| Chipchip | washiveil | Components | Free | 1 dep | |
| Code Badgecode-badge | washiveil | Components | Free | no deps | |
| Glass Accordionglass-accordion | washiveil | Components | Free | 2 deps | |
| Glass Alertglass-alert | washiveil | Components | Free | 1 dep | |
| Glass Alert Dialogglass-alert-dialog | washiveil | Components | Free | 1 dep | |
| Glass Aspect Ratioglass-aspect-ratio | washiveil | Components | Free | 1 dep | |
| Glass Avatarglass-avatar | washiveil | Components | Free | 1 dep |
