npx shadcn@latest add https://sdk-components.thesqd.com/r/button.jsonimport { Button } from "@/components/ui/button";
import { ButtonGroup } from "@/components/ui/button-group";import { Button } from "@/components/ui/button";
export function Example() {
return <Button variant="default">Click me</Button>;
}Button
└── children (text, icons with data-icon="inline-start" | "inline-end")
ButtonGroup
└── Button[] (joined visually — first/last get rounded ends)
ToggleButton (Button that flips its own pressed state)
├── pressed / defaultPressed / onPressedChange
└── activeVariant (pressed) · inactiveVariant (default "outline")
SplitButton (primary Button + chevron dropdown)
├── items={[{ label, icon?, onClick, destructive? }]} (actions-menu mode)
└── options={[{ label, description? }]} + onAction (selectable/radio mode)
LongPressButton (press-and-hold to fire; own page/file)
└── onHoldComplete · holdDuration (default 1600ms) · onHoldCancelButton
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "fancy" | "fancy-outline" | "secondary" | "outline" | "ghost" | "destructive" | "destructive-solid" | "link" | "soft" | "tonal" | "coral" | "transparent" | "default" | Visual tone. `default` is brand violet; `fancy` is the glossy gradient pill; `soft` is the tinted treatment. |
color | "brand" | "coral" | "destructive" | "warning" | "success" | "ghost" | "brand" | Tone for `variant="fancy"` (ignored by other variants). `className` still overrides. |
size | "xs" | "sm" | "default" | "xl" | "wide" | "icon" | "icon-xs" | "icon-sm" | "icon-xl" | "default" | `wide` stretches to fill its container. The `icon-*` sizes pair with a single child icon and `aria-label`. |
render | ReactElement | — | Base UI render-prop — pass another element (e.g. `<Link/>`) to swap the underlying tag. |
className | string | — | Override or extend the resolved variant classes. |
ButtonGroup
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | "horizontal" | "vertical" | "horizontal" | Stack adjacent buttons inline or vertically. |
className | string | — | Additional classes applied to the group wrapper. |
ToggleButton
| Prop | Type | Default | Description |
|---|---|---|---|
pressed | boolean | — | Controlled pressed state. Pair with `onPressedChange`. |
defaultPressed | boolean | false | Uncontrolled initial pressed state. |
onPressedChange | (pressed: boolean) => void | — | Fires with the next pressed state on click. |
activeVariant | ButtonVariant | "default" | Variant rendered while pressed (primary by default). |
inactiveVariant | ButtonVariant | "outline" | Variant rendered while not pressed. |
size | ButtonSize | "default" | Same size scale as Button. |
SplitButton
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | Primary button label (actions-menu mode). Ignored when `options` is set. |
onClick | () => void | — | Primary button click handler. |
items | SplitButtonItem[] | — | Action items in the chevron dropdown: `{ label, icon?, onClick?, disabled?, destructive? }`. |
options | SplitButtonOption[] | — | Radio options `{ label, description?, disabled? }`. When set, the primary button's label is the active option (selectable mode). |
defaultValue | number | 0 | Initial selected index in selectable mode. |
value | number | — | Controlled selected index. Pair with `onValueChange`. |
onValueChange | (index: number) => void | — | Fires when the selected index changes (selectable mode). |
onAction | (option, index) => void | — | Fires when the primary button is activated (selectable mode). |
variant | ButtonVariant | — | Variant applied to both the primary and chevron buttons. |
size | ButtonSize | — | Size applied to both buttons. |
chevronLabel | string | "More actions" | Accessible label for the chevron trigger. |