Skip to content
buttery

v1.0.0

Source on GitHub

Version 1.0.0

SidePanel

A panel beside the page, such as help, that narrows the page instead of covering it.

import { SidePanel } from "@butteryui/react";

Demo

When to use it

Use it for

  • Help, notes or an assistant that someone keeps open while they work on the page beside it
  • Details that shouldn't cover the page they're about, in an AppShell's panel slot

Not for

  • Something to finish before going back to the page: use Dialog or FormDialog
  • A record's details that belong to the page itself: use AppPage's aside or DetailPage
  • A short note beside a control: use Popover or InfoButton

Examples

Help panel

A help panel the top bar opens, docked beside the page from 1280px of shell and a sheet under that.

Orders

Today

Twelve orders to roast and pack.

Order notes

An order's notes, whether they're open kept in state: closed, a button brings them back, and their menu clears them.

Roast log

A roast log docked where it's placed, open from the start, its body scrolling above a pinned footer.

Variants and states

Its parts

Outside a shell it docks where it's placed: its title, a menu, expand and close, a body that scrolls and a pinned footer.

As a sheet

In a shell under 1280px wide, Help opens it as a sheet at the window's end over a dim scrim, and the page keeps its width.

Orders

Help opens over this page as a sheet.

Props

SidePanel

PropTypeDefaultDescription
title

required

stringIts title, an h2 in title-sm, which names it, such as "Help".
openbooleanWhether it's open. Pair with onOpenChange to control it.
defaultOpenbooleanfalseWhether it starts open when uncontrolled. Defaults to false.
onOpenChange((open: boolean) => void)Called when it opens or closes, from its close button, Escape or its sheet's scrim.
menuReactNodeIts overflow menu's items, Menu.Items and Menu.Links, an item that deletes or resets something with tone="danger". Leave it out for no menu.
menuLabelstring"More actions"Names the overflow menu's button. Defaults to "More actions".
expandedbooleanWhether a docked panel is widened to 560px. Pair with onExpandedChange to control it.
defaultExpandedbooleanfalseWhether a docked panel starts widened when uncontrolled. Defaults to false.
onExpandedChange((expanded: boolean) => void)Called when its expand button widens or narrows it.
expandLabelstring"Expand"Names the expand button, a toggle that's pressed while the panel is widened. Defaults to "Expand".
footerReactNodeWhat stays pinned under the body while it scrolls, such as a field to ask a question in.
closeLabelstring"Close"Names the close button. Defaults to "Close".
childrenReactNodeWhat the panel holds. It scrolls on its own.

It also takes Omit<MotionElementProps<"aside">, "title" | "children">.

Accessibility

Docked, it's a complementary landmark named by its title: opening it moves focus to its first field to type in, else to the panel itself, and Escape or its close button closes it and hands focus back to what opened it. As a sheet it's a modal dialog named by its title that keeps focus inside. The expand button is a toggle (aria-pressed); a menu item that deletes or resets something is drawn in danger and says so in its words.

KeysWhat they do
EscapeCloses the panel and hands focus back to what opened it
Enter or SpacePresses the focused header button: expand, which a docked panel has, or close
Enter, Space or DownOpens the More actions menu from its button, where Up and Down move, Enter runs an item and Escape closes just the menu
TabStays inside the panel while it's a sheet

Motion

It appears with a `Presence` preset and leaves faster than it came, in about 60% of the time.

With reduced motion: Docked, its content fades in over 100ms instead of 120; as a sheet it fades in and out over 100ms without rising, its scrim fading with it.

Layout

Docked, it's 360px wide (560 expanded) and its parent's height, with a 1px edge on its start side and a --bt-h-header (56px) header whose title truncates and shows in full on hover; its body scrolls on its own above the pinned footer. As a sheet it sits 8px in from the window's end, up to 360px wide; either way its header buttons are 28px.

See it in the roastery demo.