Hamburger Sheet
NewCustomize
End
Width240px
Size40px
Row height40px
Stagger0.030s
Duration0.45s
Radius16px
Installation
npx shadcn@latest add https://uibrik.com/r/hamburger-sheet.jsonInstall the packages
npm install motionAdd the cn helper
Imports
cnfrom@/lib/utils, whichshadcn initcreates. Add it by hand without shadcn.Copy the source into your project
components/uibrik/hamburger-sheet/hamburger-sheet.tsx"use client"; import { animate, motion, useMotionValue, useReducedMotion, useTransform, type MotionValue } from "motion/react"; import { useEffect, useId, useRef, useState, type KeyboardEvent, type ReactNode } from "react"; import { cn } from "@/lib/utils"; const PAD = 6; const ROW_GAP = 2; const LINE_THICKNESS = 2; const clamp01 = (v: number) => Math.min(Math.max(v, 0), 1); export type HamburgerSheetItem = { label: string; icon?: ReactNode; /** Shown faintly at the end of the row, e.g. a shortcut or count. */ hint?: string; href?: string; onSelect?: () => void; }; export type HamburgerSheetProps = { items: HamburgerSheetItem[]; /** Optional heading beside the close button. */
Adds the files to
components/uibrik/hamburger-sheet and installs motion. With the @uibrik namespace set up: npx shadcn@latest add @uibrik/hamburger-sheet.Usage
import { HamburgerSheet } from "@/components/uibrik/hamburger-sheet/hamburger-sheet";const items = [ { label: "Home", icon: <IconHomeFilled size={16} /> }, { label: "Inbox", icon: <IconMailFilled size={16} />, hint: "12" }, // …3 more];<HamburgerSheet items={items} align="end" width={240} size={40} rowHeight={40} stagger={0.03} duration={0.45} radius={16} title="" closeOnSelect defaultOpen={false} label="Menu" // open={false} // onOpenChange={(open) => {}}/>Props
HamburgerSheet- align
- Type "start" | "end"
- "end"
- Which way the sheet opens from the button: start opens rightward, end leftward.
- width
- Type number
- 240
- Width of the open sheet. Never wider than the screen allows.
- size
- Type number
- 40
- Size of the closed button, and the height of the sheet's header.
- rowHeight
- Type number
- 40
- Height of each row.
- stagger
- Type number
- 0.03
- Delay between one row settling in and the next.
- duration
- Type number
- 0.45
- Length of the morph. It runs on a spring, so reversing mid-way never jumps.
- radius
- Type number
- 16
- Corner radius of the open sheet.
- title
- Type string
- ""
- Optional heading beside the close button.
- closeOnSelect
- Type boolean
- true
- Close after an item is picked.
- itemsrequired
- Type { label: string; icon?: ReactNode; hint?: string; href?: string; onSelect?: () => void }[]
- –
- Rows of the menu.
- open / onOpenChange
- Type boolean / (open) => void
- –
- Controlled open state.
- defaultOpen
- Type boolean
- false
- Open on mount when uncontrolled.
- label
- Type string
- "Menu"
- Accessible name for the button.
- className
- Type string
- –
- Classes for the wrapper.