Record Button
Record and its stop button as one control. Metallic red, lit from the click, with a glow that breathes like a camera's tally light while the session runs. One width through every state.
Installation
$ pnpm dlx shadcn@latest add @videorc/record-buttonIt brings Button with it.
Usage
import { RecordButton } from "@/components/record-button";<RecordButton onClick={toggleRecording} state={session} />state is where the session stands, and comes in from your app: idle, starting after the click, running once it records or streams, and stopping while it finishes. The button picks its glyph, lights up and says each state's words. Pass your own words for any state in labels ("End livestream" while on air, "Force stop" after a stop that drags on).
<RecordButton labels={{ running: "End livestream" }} state={session} />Every state's words are laid out in the same spot and only the current one shows, so the button is as wide as its longest words and never changes width as the session moves on.
Use it for Record and the button that stops the session, and nothing else: lit red only ever means record or live. Delete stays a destructive Button, and Go Live… stays the chrome primary beside it.
Examples
States
Starting and stopping answer from the click: the button is lit, takes no click, keeps its focus and doesn't dim. Only a running session's glow breathes. Blocked is a disabled button, flat and dimmed; say why with Disabled reason.
In the transport
The Studio's transport puts Record, with its Space key, beside Go Live…. While a session runs, one stop button takes the row. While Go Live… runs its checks, Record is off.
Theming
| Token or attribute | Meaning |
|---|---|
chrome-led | The material, on Button's record variant |
--chrome-led-off-stops, --chrome-led-stops | The metal's bands, idle and lit |
--chrome-led-hi, --chrome-led-lo | The light along its top edge and the shade along its foot |
--chrome-led-glow | The glow around it while the session runs |
data-lit | Lights it: set from starting on |
data-state | idle, starting, running or stopping |
It's polished the way the default button's chrome is: a bright band, a dark horizon just below the middle and the light coming back at the foot. Every stop keeps the white label at 4.5:1 or more in both themes, so the shine is in the bands, never a brighter face. The glow is a layer of its own that breathes on opacity alone, so a session that runs for hours never repaints the button. Under reduced motion, it holds steady. Increase Contrast adds an edge around it.
Keyboard
| Key | Action |
|---|---|
Enter, Space | Starts or stops the session |
A shortcut for Record belongs to the page, not to the button. Show it inside with Shortcut Keys.
Accessibility
It's a one-shot action whose words change ("Record", then "Stop recording"), so it takes no aria-pressed. While starting or stopping, it's aria-disabled and stays focusable, so keyboard focus isn't lost under the user's hands. Announce the session's state in a status region, such as a Status Badge with role="status", not on the button.
API reference
Every Button prop except variant and children, plus:
Prop
Type
RECORD_BUTTON_LABELS holds each state's default words.
Error Boundary
The one render-crash boundary. Its fallback draws what it caught and gets a reset that renders the children again, so a crash stays in its page and the window keeps a way back.
Kebab Menu
The ⋯ menu for an item's low-frequency actions. One item list grouped by hairlines, the destructive item last in red, keys on the right, and a trigger that can wait for its row's hover.