Sidebar 2
Simple navigation with your team below it and the signed-in person at the bottom.
View code
"use client";
import { Calendar, ChartColumn, FileText, House, MessageSquare, Settings, ShoppingCart, Users } from "lucide-react";
import { useState } from "react";
import {
Sidebar2,
Sidebar2Brand,
Sidebar2Item,
Sidebar2Person,
Sidebar2Section,
Sidebar2User,
} from "@/components/kit/sidebar-2";
const photo = (id: string) => `https://images.unsplash.com/photo-${id}?w=64&h=64&fit=crop&crop=faces`;
const pages = [
{ name: "Dashboard", icon: <House /> },
{ name: "Analytics", icon: <ChartColumn /> },
{ name: "Team", icon: <Users /> },
{ name: "Messages", icon: <MessageSquare /> },
{ name: "Documents", icon: <FileText /> },
{ name: "Calendar", icon: <Calendar /> },
{ name: "Settings", icon: <Settings /> },
];
const team = [
{ name: "Sarah Kim", role: "Design", id: "1494790108377-be9c29b29330", online: true },
{ name: "John Doe", role: "Engineering", id: "1507003211169-0a1dd7228f2d", online: true },
{ name: "Mike Taylor", role: "Engineering", id: "1500648767791-00dcc994a43e", online: false },
{ name: "Lisa Park", role: "Product", id: "1438761681033-6461ffad8d80", online: true },
{ name: "Ravi Singh", role: "Data", id: "1534528741775-53994a69daeb", online: false },
];
export function Sidebar2Demo() {
const [page, setPage] = useState("Dashboard");
return (
<div className="flex h-180 w-full justify-center bg-background">
<Sidebar2 aria-label="Main" className="border-s">
<Sidebar2Brand logo={<ShoppingCart aria-hidden="true" />} title="Acme Store" />
{pages.map(({ name, icon }) => (
<Sidebar2Item key={name} icon={icon} active={page === name} onClick={() => setPage(name)}>
{name}
</Sidebar2Item>
))}
<Sidebar2Section label="Your team">
{team.map(({ name, role, id, online }) => (
<Sidebar2Person key={name} name={name} role={role} avatar={photo(id)} online={online} />
))}
</Sidebar2Section>
<Sidebar2User name="Jordan Diaz" email="jordan@example.com" avatar={photo("1472099645785-5658abf4ff4e")} />
</Sidebar2>
</div>
);
}
A simpler sidebar for smaller apps. It has no collapse or nesting, and it adds people to the navigation.
Installation
bunx --bun shadcn@latest add HarshitMahajan/UI/sidebar-2Copies the code to components/kit/sidebar-2.tsx installs its packages, and adds the tokens it needs to your globals.css. Your existing shadcn components aren't touched.
Usage
import {
Sidebar2,
Sidebar2Brand,
Sidebar2Item,
Sidebar2Person,
Sidebar2Section,
Sidebar2User,
} from "@/components/kit/sidebar-2"<Sidebar2 aria-label="Main">
<Sidebar2Brand logo={<ShoppingCart aria-hidden="true" />} title="Acme Store" />
<Sidebar2Item icon={<House />} active>Dashboard</Sidebar2Item>
<Sidebar2Section label="Your team">
<Sidebar2Person name="Sarah Kim" role="Design" online />
</Sidebar2Section>
<Sidebar2User name="Jordan Diaz" email="jordan@example.com" />
</Sidebar2>Composition
Sidebar2
├── Sidebar2Brand
├── Sidebar2Item
├── Sidebar2Section
│ └── Sidebar2Person
└── Sidebar2UserFeatures
- Pictures with a green online dot
- The person's first letter when there's no picture
- The signed-in person stays pinned to the bottom
- Items render as buttons or as links through the render prop
Navigation only
Leave out the team section for plain navigation.
View code
import { ChartColumn, House, Settings, ShoppingCart } from "lucide-react";
import { Sidebar2, Sidebar2Brand, Sidebar2Item, Sidebar2User } from "@/components/kit/sidebar-2";
export function Sidebar2Navigation() {
return (
<div className="flex h-96 w-full justify-center bg-background">
<Sidebar2 aria-label="Main" className="border-s">
<Sidebar2Brand logo={<ShoppingCart aria-hidden="true" />} title="Acme Store" />
<Sidebar2Item icon={<House />} active>
Dashboard
</Sidebar2Item>
<Sidebar2Item icon={<ChartColumn />}>Analytics</Sidebar2Item>
<Sidebar2Item icon={<Settings />}>Settings</Sidebar2Item>
<Sidebar2User name="Jordan Diaz" email="jordan@example.com" />
</Sidebar2>
</div>
);
}
Without pictures
Leave out avatar to show the person's first letter instead.
View code
import { Sidebar2, Sidebar2Person, Sidebar2Section } from "@/components/kit/sidebar-2";
export function Sidebar2Initials() {
return (
<div className="flex h-64 w-full justify-center bg-background">
<Sidebar2 aria-label="Team" className="border-s">
<Sidebar2Section label="Your team" className="mt-1">
<Sidebar2Person name="Sarah Kim" role="Design" online />
<Sidebar2Person name="John Doe" role="Engineering" online />
<Sidebar2Person name="Lisa Park" />
</Sidebar2Section>
</Sidebar2>
</div>
);
}
Accessibility
Online state
The green dot includes hidden text saying Online, so the state isn't conveyed by color alone.
API Reference
Sidebar2
The frame. Renders an aside element.
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | Additional classes for the frame. |
Sidebar2Brand
Your logo and name.
| Prop | Type | Default | Description |
|---|---|---|---|
| logo | ReactNode | - | An icon or a letter. |
| title | string | - | The name. |
Sidebar2Item
One row.
| Prop | Type | Default | Description |
|---|---|---|---|
| icon | ReactNode | - | The row's icon. |
| active | boolean | false | Marks the current page. |
| render | ReactElement | function | - | Render the row as another element, such as a link or your router's Link. |
Sidebar2Section
A labeled set of rows.
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | - | The section's name. |
Sidebar2Person
A teammate.
| Prop | Type | Default | Description |
|---|---|---|---|
| name | string | - | Their name. |
| role | string | - | Shown on the right. |
| avatar | string | - | The picture's URL. |
| online | boolean | false | Shows the green dot. |
Sidebar2User
The signed-in person, pinned to the bottom.
| Prop | Type | Default | Description |
|---|---|---|---|
| name | string | - | Their name. |
| string | - | A line under the name. | |
| avatar | string | - | The picture's URL. |