Line Nav
ncdai/line-navUnverifiedComponent
Vertical navigation with a line marker that expands on hover and active state.
Install it
npx shadcn@latest add https://raw.githubusercontent.com/exekartik/exeKartik/main/line-nav.jsonSource
1/**2 * This component is inspired by Devouring Details and Skiper UI.3 */45"use client"67import { memo, useEffect, useRef } from "react"8import { motion } from "motion/react"910import { cn } from "@/lib/utils"1112const lineVariants = {13 normal: { width: 24 },14 active: { width: 40 },15 hover: { width: 40 },16}1718export type LineNavItem = {19 title: string20 href: string21}2223export type LineNavProps = {24 className?: string25 /** @fumadocsHref #linenavitem */26 items: LineNavItem[]27 /** Href of the active item. */28 activeHref?: string29 /** Scroll the active item into view on mount. */30 scrollActiveIntoView?: boolean31 /** Called when an item is clicked. */32 onItemClick?: (33 item: LineNavItem,34 event: React.MouseEvent<HTMLAnchorElement>35 ) => void36}3738export function LineNav({39 className,40 items,41 activeHref,42 scrollActiveIntoView = true,43 onItemClick,44}: LineNavProps) {45 const activeItemRef = useRef<HTMLAnchorElement | null>(null)4647 useEffect(() => {48 if (scrollActiveIntoView) {49 activeItemRef.current?.scrollIntoView({ block: "center" })50 }51 }, [scrollActiveIntoView])5253 return (54 <nav55 className={cn("flex flex-col gap-2 py-5.25", className)}56 style={57 {58 "--line-nav-width": `${lineVariants.normal.width}px`,59 } as React.CSSProperties60 }61 >62 {items.map((item, index) => {63 const isActive = item.href === activeHref6465 return (66 <LineNavItem67 key={item.href}68 ref={isActive ? activeItemRef : undefined}69 title={item.title}70 href={item.href}71 active={isActive}72 isLast={index === items.length - 1}73 onClick={74 onItemClick ? (event) => onItemClick(item, event) : undefined75 }76 />77 )78 })}79 </nav>80 )81}8283const LineNavItem = memo(function LineNavItem({84 ref,85 title,86 href,87 active = false,88 isLast = false,89 onClick,90}: {91 ref?: React.Ref<HTMLAnchorElement>92 title: string93 href: string94 active?: boolean95 isLast?: boolean96 onClick?: React.MouseEventHandler<HTMLAnchorElement>97}) {98 return (99 <>100 {/*101 Rendered as a plain anchor to stay framework-agnostic. For client-side102 navigation in Next.js, swap `motion.a` for `motion.create(Link)`103 (import Link from "next/link").104 */}105 <motion.a106 ref={ref}107 aria-current={active ? "page" : undefined}108// … truncated
What it pulls in
npm packages
Files it writes
More from ncdai
All 17 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Apple Hello Effectapple-hello-effect | ncdai | Components | Unverified | 1 dep | |
| Apple Hello Effect - Hindiapple-hello-effect-hindi | ncdai | Components | Unverified | 1 dep | |
| Apple Hello Effect - Spanishapple-hello-effect-spanish | ncdai | Components | Unverified | 1 dep | |
| Apple Hello Effect - Vietnameseapple-hello-effect-vietnamese | ncdai | Components | Unverified | 1 dep | |
| Brand Assets Menubrand-assets-menu | ncdai | Components | Unverified | 1 dep | |
| chevrons-up-down-iconchevrons-up-down-icon | ncdai | Components | Unverified | 1 dep | |
| Code Block Commandcode-block-command | ncdai | Components | Unverified | 4 deps · 3 files | |
| Consent Managerconsent-manager | ncdai | Components | Unverified | 1 dep · 2 files |
