Sidebar

Vertical sidebar navigation with header, scrollable body, footer, labeled sections, and active state — ideal for dashboard layouts with dark mode support.

Preview

Basic sidebar

import { Sidebar, SidebarHeader, SidebarBody, SidebarFooter, SidebarSection, SidebarLabel, SidebarItem } from '@/registry/ui-kit/tailwind-sidebar/react'

function Example() {
  return (
    <Sidebar>
      <SidebarHeader>
        <span className="text-lg font-semibold">Acme</span>
      </SidebarHeader>
      <SidebarBody>
        <SidebarSection>
          <SidebarLabel>General</SidebarLabel>
          <SidebarItem href="#" active>Dashboard</SidebarItem>
          <SidebarItem href="#">Team</SidebarItem>
          <SidebarItem href="#">Projects</SidebarItem>
        </SidebarSection>
      </SidebarBody>
      <SidebarFooter>
        <span className="text-sm text-zinc-500">john@acme.com</span>
      </SidebarFooter>
    </Sidebar>
  )
}

Component API

PropDefaultDescription
SidebarAside container with fixed width, right border, and flex column layout.
SidebarHeaderTop area with bottom border, typically for brand or logo.
SidebarBodyScrollable middle section for navigation items.
SidebarFooterBottom area with top border, typically for user profile.
SidebarSectionGroup wrapper with tight vertical spacing.
SidebarLabelUppercase section label in muted text.
SidebarItemNav link with icon support, hover and active states.
activefalseHighlights the sidebar item as the current page.

Source Code

"use client";

/* ── Sidebar ── */

interface SidebarProps {
  children: React.ReactNode;
  className?: string;
}

function Sidebar({ children, className = "" }: SidebarProps) {
  return (
    <aside
      className={`flex h-full w-64 flex-col border-r border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900 ${className}`}
    >
      {children}
    </aside>
  );
}

/* ── SidebarHeader ── */

interface SidebarHeaderProps {
  children: React.ReactNode;
  className?: string;
}

function SidebarHeader({ children, className = "" }: SidebarHeaderProps) {
  return (
    <div
      className={`px-4 py-4 border-b border-zinc-100 dark:border-zinc-800 ${className}`}
    >
      {children}
    </div>
  );
}

/* ── SidebarBody ── */

interface SidebarBodyProps {
  children: React.ReactNode;
  className?: string;
}

function SidebarBody({ children, className = "" }: SidebarBodyProps) {
  return (
    <div className={`flex-1 overflow-y-auto px-3 py-3 ${className}`}>
      {children}
    </div>
  );
}

/* ── SidebarFooter ── */

interface SidebarFooterProps {
  children: React.ReactNode;
  className?: string;
}

function SidebarFooter({ children, className = "" }: SidebarFooterProps) {
  return (
    <div
      className={`px-4 py-3 border-t border-zinc-100 dark:border-zinc-800 ${className}`}
    >
      {children}
    </div>
  );
}

/* ── SidebarSection ── */

interface SidebarSectionProps {
  children: React.ReactNode;
  className?: string;
}

function SidebarSection({ children, className = "" }: SidebarSectionProps) {
  return <div className={`space-y-0.5 ${className}`}>{children}</div>;
}

/* ── SidebarLabel ── */

interface SidebarLabelProps {
  children: React.ReactNode;
  className?: string;
}

function SidebarLabel({ children, className = "" }: SidebarLabelProps) {
  return (
    <p
      className={`px-3 py-2 text-xs font-medium uppercase tracking-wide text-zinc-400 dark:text-zinc-500 ${className}`}
    >
      {children}
    </p>
  );
}

/* ── SidebarItem ── */

interface SidebarItemProps
  extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
  active?: boolean;
  children: React.ReactNode;
  className?: string;
}

function SidebarItem({
  active = false,
  children,
  className = "",
  ...props
}: SidebarItemProps) {
  return (
    <a
      className={`flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-colors ${
        active
          ? "bg-zinc-100 text-zinc-900 dark:bg-zinc-800 dark:text-zinc-100"
          : "text-zinc-600 hover:bg-zinc-100 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-100"
      } ${className}`}
      aria-current={active ? "page" : undefined}
      {...props}
    >
      {children}
    </a>
  );
}

export {
  Sidebar,
  SidebarHeader,
  SidebarBody,
  SidebarFooter,
  SidebarSection,
  SidebarLabel,
  SidebarItem,
};
export default Sidebar;