Skip to content
  1. Keyline UI
  2. Nav
Keyline UIComponents
  • Get started
    • Installation
    • Theming
    • Modes
    • Configuration
    • Composition
  • Actions
    • Button
    • Button group
    • Split button
    • Toggle
    • Toggle group
    • Toolbar
    • Menu
    • Menubar
    • Context menu
  • Inputs
    • Field and form
    • Checkbox
    • Checkbox group
    • Radio group
    • Switch
    • Slider
    • Segmented
    • Select
    • Native select
    • Combobox
    • Multiselect
    • Number field
    • OTP field
    • Time field
    • Date picker and calendar
    • Date range
  • Data
    • Table
    • Chart
    • Stat and meter
    • Status and badge
    • Progress
    • Skeleton
    • Empty
    • Avatar
    • Kbd
    • Marker
  • Navigation
    • Tabs
    • Breadcrumb
    • Pagination
    • Nav
    • Navigation menu
    • Command menu
  • Overlays
    • Dialog
    • Alert dialog
    • Drawer
    • Sheet
    • Popover
    • Hover card
    • Tooltip
    • Toast
    • Notice
  • Layout
    • App shell
    • Sidebar
    • Panel
    • Resizable
    • Scroll area
    • Accordion
    • Collapsible
    • Carousel
    • Inspector
    • Item
    • Direction
  • Conversation
    • Message
    • Bubble
    • Message scroller
    • Attachment
    • Questionnaire
  • Blocks
    • Shipments

Nav

An app's sections. The current one sits under a cobalt band that stretches to it, across groups too. Items are links with href or buttons; nested items open a list under their parent. In AppShell's rail only the icons show, and the label appears beside each on hover and focus.

Loading the live example…

"use client"

import { ChartNoAxesColumn, FileText, PartyPopper, Plus, UserRound, Warehouse } from "lucide-react"
import { useState } from "react"
import { Nav, NavIdentity, type NavGroup } from "@/components/keyline/ui/nav"

const GROUPS: NavGroup[] = [
  {
    label: "Sales",
    items: [
      { value: "orders", label: "Orders", count: 11, icon: <FileText size={16} aria-hidden="true" /> },
      { value: "clients", label: "Clients", count: 64, icon: <UserRound size={16} aria-hidden="true" /> },
      {
        value: "reports",
        label: "Reports",
        icon: <ChartNoAxesColumn size={16} aria-hidden="true" />,
        items: [
          { value: "reports-weekly", label: "Weekly sales" },
          { value: "reports-quarter", label: "Quarter to date" },
        ],
      },
    ],
  },
  {
    label: "Office",
    items: [
      { value: "warehouse", label: "Warehouse", icon: <Warehouse size={16} aria-hidden="true" /> },
      { value: "parties", label: "Party planning", count: 2, icon: <PartyPopper size={16} aria-hidden="true" /> },
      { value: "hr", label: "Human resources", disabled: true, icon: <Plus size={16} aria-hidden="true" /> },
    ],
  },
]

const TITLES: Record<string, string> = {
  orders: "11 open orders, 2 held",
  clients: "64 active clients",
  "reports-weekly": "Weekly sales: 1,810 reams",
  "reports-quarter": "Quarter to date: 19,880 reams",
  warehouse: "88 pallets on the floor",
  parties: "Two parties this month. Angela has the budget.",
}

export function OfficeSidebar() {
  const [view, setView] = useState("orders")

  return (
    <div className="grid gap-4 sm:grid-cols-[240px_1fr]">
      <Nav
        label="Scranton branch"
        value={view}
        onValueChange={setView}
        groups={GROUPS}
        header={<NavIdentity mark="DM" title="Scranton" meta="Branch 0418" />}
      />
      <p role="status" className="m-0 self-start text-[14px] text-kl-ink-2">
        {TITLES[view]}
      </p>
    </div>
  )
}

Installation

npx shadcn@latest add @keyline-ui/nav

Run it where your components.json is. The first time, map the @keyline-ui registry: one command, in Installation.

Usage

import { Nav, type NavGroup } from "@/components/keyline/ui/nav"
<Nav
  label="Scranton branch"
  value={view}
  onValueChange={setView}
  groups={[{ label: "Sales", items: [{ value: "orders", label: "Orders", count: 11 }] }]}
/>

Props

PropTypeDefaultDescription
items · groupsNavItem[] · NavGroup[]Default —A flat list, or labelled sections divided by a heavy seam.
valuestringDefault —The current item.
onValueChange(value: string) => voidDefault —For button items. Link items navigate.
labelstringDefault —Names the navigation landmark.
header · footerReactNodeDefault —At the top and bottom of the column. NavIdentity is a mark, title and meta line.
orientation"vertical" | "horizontal" | "responsive"Default "vertical"responsive is a column under 300px of its own width, a row above.
layout"control" | "cell"Default "control"cell sits inside another frame, such as AppShell's sidebar.
NavItem{ value, label, href?, icon?, count?, items?, disabled?, action? }Default —items nests links; action is a cell for the row's own commands, usually a NavAction opening a Menu.

This site's component list and page contents are Keyline Nav.

Sheet 45 of 73PreviousPaginationNextNavigation menu
On this page