Skip to content

Repository files navigation

shadcn/ui Resizable Sidebar

A drop-in enhancement for the shadcn/ui Sidebar.

It keeps the original Sidebar API, composition model, variants, and styling surface, then adds the product behavior most dashboards need: drag resize, rail click collapse, auto collapse, persisted width, and smooth pointer-driven drag.

Demo: shadcn-resize-sidebar.vercel.app

Features

  • Drag the rail to resize the sidebar.
  • Click the same rail to collapse or expand.
  • Use Cmd/Ctrl + B to toggle.
  • Auto-collapse when the rail is dragged past the threshold.
  • Persist width and collapse state across reloads.
  • Restore state on the server with sidebar:state and sidebar:width cookies.
  • Keep the normal shadcn/ui Sidebar composition and customization model.
  • Use Pointer Events and pointer capture for mouse, pen, and touch input.
  • Write live width to --sidebar-width during drag, then commit React state and cookies on release.
  • Keep the mobile Sidebar as an accessible Sheet with title and description.

Stack

  • Next.js 16.2.9
  • React 19.2.7
  • Tailwind CSS 4.3.1
  • shadcn/ui new-york style
  • Radix UI single package 1.6.0
  • Bun
  • TypeScript

Getting Started

git clone https://github.com/lumpinif/shadcn-resizable-sidebar.git
cd shadcn-resizable-sidebar
bun install
bun dev

Open http://localhost:3000.

Steal the Code

This is not a separate component system. Treat it as an enhanced shadcn/ui Sidebar fork.

The core files are:

  • components/ui/sidebar.tsx
  • hooks/use-sidebar-resize.ts
  • components/providers/index.tsx

Use components/providers/index.tsx if you want the demo's server-side cookie restore behavior. Copy app/globals.css if you also want the same shadcn/ui neutral theme tokens.

Basic Usage

import {
  Sidebar,
  SidebarContent,
  SidebarProvider,
  SidebarRail,
} from "@/components/ui/sidebar"

export function AppSidebar() {
  return (
    <SidebarProvider defaultWidth="16rem">
      <Sidebar collapsible="icon">
        <SidebarContent>{/* Your existing sidebar content */}</SidebarContent>
        <SidebarRail />
      </Sidebar>
    </SidebarProvider>
  )
}

SidebarRail is the only new interaction surface users need to discover:

  • Drag it to resize.
  • Click it to collapse or expand.
  • Release after dragging to persist the new width.

Server-Side Restore

The demo reads cookies in a server provider and passes the values into SidebarProvider.

import { cookies } from "next/headers"
import { SidebarProvider } from "@/components/ui/sidebar"

const SIDEBAR_COOKIE_KEY = "sidebar"

export async function Providers({ children }: { children: React.ReactNode }) {
  const cookieStore = await cookies()

  const sidebarState = cookieStore.get(`${SIDEBAR_COOKIE_KEY}:state`)?.value
  const sidebarWidth = cookieStore.get(`${SIDEBAR_COOKIE_KEY}:width`)?.value

  return (
    <SidebarProvider
      cookieKey={SIDEBAR_COOKIE_KEY}
      defaultOpen={sidebarState ? sidebarState === "true" : true}
      defaultWidth={sidebarWidth}
    >
      {children}
    </SidebarProvider>
  )
}

By default, the provider writes:

  • sidebar:state
  • sidebar:width

Use a different cookieKey when a page needs multiple independent sidebars.

Resizing API

SidebarProvider adds:

Prop Purpose
defaultWidth Initial sidebar width. The demo default is 16rem.
cookieKey Prefix for persisted state and width cookies.

SidebarRail adds:

Prop Purpose
enableDrag Enables or disables drag resize. Defaults to true.
direction Set to "right" for a left sidebar, or "left" for a right sidebar.

The demo sidebar clamps width between 14rem and 22rem.

<Sidebar side="left">
  <SidebarRail direction="right" />
</Sidebar>

<Sidebar side="right">
  <SidebarRail direction="left" />
</Sidebar>

useSidebarResize is available if you want to wire the resize behavior to a different panel, but most apps should use SidebarProvider and SidebarRail directly.

Philosophy

Use the shadcn/ui Sidebar as the base. Keep its structure, slots, variants, tokens, and customization habits. Add resize as a thin product layer instead of replacing the component with a different sidebar system.

That means existing Sidebar customizations still work: menu groups, actions, variants, inset layout, floating layout, icon collapse, keyboard toggle, mobile Sheet behavior, and semantic Tailwind tokens.

License

MIT

Star History

Star History Chart

Releases

Packages

Used by

Contributors

Languages