Components / Actions
Buttons
Every call to action in the broadcast. Condensed uppercase type, a real bevel-and-glow for depth, a hover that lifts and a press that seats. Seven intents, five sizes, plus a square IconButton and a segmented ButtonGroup — all built on one cva recipe.
6-8 UI
Variants
Seven intents mapped to the brand. Teal leads, yellow marks live and high-priority actions, and the rest recede so the primary read stays clear.
6-8 UI
Sizes
Five steps from xs to lg, plus a square icon size. Height, padding, type scale, and glyph size move together so density stays balanced.
6-8 UI
States
Hover lifts with a deeper glow; active seats the chip down. Disabled dims and drops interaction, and loading swaps in a spinner while it works.
6-8 UI
Icons
Pass leftIcon or rightIcon on any Button, or reach for a square IconButton when the glyph is the whole story. IconButtons require an aria-label so the control still has a name.
6-8 UI
Button group
A segmented control with exactly one active choice. The active pill is teal and slides between segments on select, so a switch reads as one continuous motion.
6-8 UI
API
Props for each component. Button and IconButton spread native button attributes; ButtonGroup spreads native div attributes.
import { Button } from "@/components/ui/button";
<Button variant="primary" size="md" leftIcon={<Play />}>
Start game
</Button>
<Button variant="outline" loading>Syncing</Button>Button
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "primary" | "secondary" | "outline" | "ghost" | "glass" | "danger" | "link" | "primary" | Visual intent. |
| size | "xs" | "sm" | "md" | "lg" | "icon" | "md" | Height, padding, and type scale. icon is a square footprint. |
| leftIcon | ReactNode | — | Icon rendered before the label. |
| rightIcon | ReactNode | — | Icon rendered after the label. |
| loading | boolean | false | Swaps in a spinner, disables the button, and sets aria-busy. |
| asChild | boolean | false | Render the child element as the button via Radix Slot. |
| ...props | ButtonHTMLAttributes | — | All native button attributes (onClick, type, disabled…). |
IconButton
| Prop | Type | Default | Description |
|---|---|---|---|
| aria-label | string | — | Required — names the control for assistive tech. |
| icon | ReactNode | — | The glyph to render (a lucide icon). |
| variant | same as Button | "primary" | Shares Button's full variant palette. |
| size | "xs" | "sm" | "md" | "lg" | "md" | Square footprint. |
| loading | boolean | false | Swaps the glyph for a spinner and disables the button. |
| asChild | boolean | false | Render the child element as the button via Radix Slot. |
ButtonGroup
| Prop | Type | Default | Description |
|---|---|---|---|
| items | { value; label; icon?; disabled? }[] | — | The segments, left to right. |
| value | string | — | Controlled active value. |
| defaultValue | string | items[0].value | Uncontrolled initial active value. |
| onValueChange | (value: string) => void | — | Fires when a segment is selected. |
| size | "sm" | "md" | "lg" | "md" | Track and segment scale. |
| aria-label | string | — | Required — names the group for assistive tech. |