Agents (llms.txt)

Nav

Sidebar navigation with grouped items, icons, and trailing slots

import {
  Home01,
  Inbox01,
  Settings01,
  Users01,
} from '@untitledui-pro/icons/solid';

import { Badge } from '@/components/badge';
import { Nav } from '@/components/nav';

export default function NavPreview() {
  return (
    <div className="w-64 rounded-xl border border-border bg-background">
      <Nav>
        <Nav.Group label="Workspace">
          <Nav.Item href="#" active>
            <Nav.Icon>
              <Home01 />
            </Nav.Icon>
            <Nav.Label>Home</Nav.Label>
          </Nav.Item>
          <Nav.Item href="#">
            <Nav.Icon>
              <Inbox01 />
            </Nav.Icon>
            <Nav.Label>Inbox</Nav.Label>
            <Nav.Trailing>
              <Badge size="xs" variant="neutral">
                12
              </Badge>
            </Nav.Trailing>
          </Nav.Item>
          <Nav.Item href="#">
            <Nav.Icon>
              <Users01 />
            </Nav.Icon>
            <Nav.Label>Team</Nav.Label>
          </Nav.Item>
        </Nav.Group>
        <Nav.Group label="Settings">
          <Nav.Item href="#">
            <Nav.Icon>
              <Settings01 />
            </Nav.Icon>
            <Nav.Label>Preferences</Nav.Label>
          </Nav.Item>
        </Nav.Group>
      </Nav>
    </div>
  );
}

Dependencies

Source Code

import type { VariantProps } from 'cva';

import { Slot } from '@/components/slot';
import { cn, cva } from '@/lib/utils/classnames';

const Nav = ({
  ref,
  className,
  ...rest
}: React.ComponentPropsWithRef<'nav'>) => (
  <nav
    ref={ref}
    className={cn('flex flex-col gap-6 p-3', className)}
    {...rest}
  />
);

interface NavGroupProps extends React.ComponentPropsWithRef<'div'> {
  label?: React.ReactNode;
}

const NavGroup = ({
  ref,
  className,
  label,
  children,
  ...rest
}: NavGroupProps) => (
  <div ref={ref} className={cn('flex flex-col gap-1', className)} {...rest}>
    {label && (
      <div className="px-2 pt-1 pb-1 font-medium text-foreground-secondary text-xs uppercase tracking-wider">
        {label}
      </div>
    )}
    {children}
  </div>
);

const navItemStyle = cva({
  base: [
    'group relative flex items-center gap-2.5 rounded-lg px-2.5 py-1.5 font-medium text-foreground-secondary text-sm',
    'transition duration-(--duration-hover) ease-(--ease)',
    'hover:bg-foreground/5 hover:text-foreground',
    'focus-visible:ring-(length:--ring-width) ring-ring focus-visible:outline-none',
    'data-[active]:bg-foreground/8 data-[active]:text-foreground',
    '[&>[data-nav-icon]]:size-4 [&>[data-nav-icon]]:shrink-0',
  ],
  variants: {
    size: {
      sm: 'h-7 text-sm',
      md: 'h-8 text-sm',
      lg: 'h-9 text-base',
    },
  },
  defaultVariants: {
    size: 'md',
  },
});

interface NavItemProps
  extends React.ComponentPropsWithRef<'a'>,
    VariantProps<typeof navItemStyle> {
  asChild?: boolean;
  active?: boolean;
}

const NavItem = ({
  ref,
  className,
  size,
  asChild,
  active,
  ...rest
}: NavItemProps) => {
  const Comp = asChild ? Slot : 'a';
  return (
    <Comp
      ref={ref}
      data-active={active ? '' : undefined}
      className={cn(navItemStyle({ size }), className)}
      {...rest}
    />
  );
};

const NavIcon = ({
  ref,
  className,
  ...rest
}: React.ComponentPropsWithRef<'span'>) => (
  <span
    ref={ref}
    data-nav-icon
    aria-hidden
    className={cn('inline-flex items-center justify-center', className)}
    {...rest}
  />
);

const NavLabel = ({
  ref,
  className,
  ...rest
}: React.ComponentPropsWithRef<'span'>) => (
  <span
    ref={ref}
    className={cn('min-w-0 flex-1 truncate', className)}
    {...rest}
  />
);

const NavTrailing = ({
  ref,
  className,
  ...rest
}: React.ComponentPropsWithRef<'span'>) => (
  <span
    ref={ref}
    className={cn(
      'ml-auto inline-flex shrink-0 items-center gap-1 text-foreground-secondary',
      className
    )}
    {...rest}
  />
);

const CompoundNav = Object.assign(Nav, {
  Group: NavGroup,
  Item: NavItem,
  Icon: NavIcon,
  Label: NavLabel,
  Trailing: NavTrailing,
});

export type { NavGroupProps, NavItemProps };
export { CompoundNav as Nav, navItemStyle };

Server component. No 'use client' — navigation markup compound; forwards props, no hooks or own handlers.

Nav is the navigation list used inside an AppShell.Sidebar. It composes groups of Nav.Item rows with optional icons, labels, and trailing content (badges, kbd hints, counters).

Anatomy


          <Nav>
  <Nav.Group label="Workspace">
    <Nav.Item href="/" active>
      <Nav.Icon>{icon}</Nav.Icon>
      <Nav.Label>Inbox</Nav.Label>
      <Nav.Trailing>{badge}</Nav.Trailing>
    </Nav.Item>
  </Nav.Group>
</Nav>
        

API Reference

Extends the nav element.

Extends the div element.

Prop Default Type
label - ReactNode

Extends the a element.

Prop Default Type
active - boolean
size "md" "sm""md""lg"
asChild - boolean

Extends the span element.

Extends the span element.

Extends the span element.

Examples

Default

import {
  Home01,
  Inbox01,
  Settings01,
  Users01,
} from '@untitledui-pro/icons/solid';

import { Badge } from '@/components/badge';
import { Nav } from '@/components/nav';

export default function NavPreview() {
  return (
    <div className="w-64 rounded-xl border border-border bg-background">
      <Nav>
        <Nav.Group label="Workspace">
          <Nav.Item href="#" active>
            <Nav.Icon>
              <Home01 />
            </Nav.Icon>
            <Nav.Label>Home</Nav.Label>
          </Nav.Item>
          <Nav.Item href="#">
            <Nav.Icon>
              <Inbox01 />
            </Nav.Icon>
            <Nav.Label>Inbox</Nav.Label>
            <Nav.Trailing>
              <Badge size="xs" variant="neutral">
                12
              </Badge>
            </Nav.Trailing>
          </Nav.Item>
          <Nav.Item href="#">
            <Nav.Icon>
              <Users01 />
            </Nav.Icon>
            <Nav.Label>Team</Nav.Label>
          </Nav.Item>
        </Nav.Group>
        <Nav.Group label="Settings">
          <Nav.Item href="#">
            <Nav.Icon>
              <Settings01 />
            </Nav.Icon>
            <Nav.Label>Preferences</Nav.Label>
          </Nav.Item>
        </Nav.Group>
      </Nav>
    </div>
  );
}

Previous

Modal

Next

Number Input