Button

Preview

import { Button } from "@/registry/components/button/react/button";
export function ButtonDemo() {
return <Button>Click me maybe</Button>;
}

Installation

You can add the button component in two ways:

  1. During project initialization:
pnpm dlx make-sugarcube@latest init
npx make-sugarcube@latest init
yarn make-sugarcube@latest init
bunx --bun make-sugarcube@latest init

Then select the button component when prompted.

  1. After initialization:
pnpm dlx make-sugarcube@latest components button --framework react
npx make-sugarcube@latest components button --framework react
yarn make-sugarcube@latest components button --framework react
bunx --bun make-sugarcube@latest components button --framework react

What’s included

When you add the button component, you get:

  • button.tsx - The React component implementation
  • button.css - The base styles for the button
  • button.tokens.json - The CSS variables that map to your design tokens
  • @radix-ui/react-slot - The Slot component from Radix UI
  • @clsx - The clsx utility for conditional classes
import { Slot } from "@radix-ui/react-slot";
import cn from "clsx";
import type * as React from "react";
function Button({
className,
asChild = false,
...props
}: React.ComponentProps<"button"> & { asChild?: boolean }) {
const Comp = asChild ? Slot : "button";
return <Comp data-slot="button" className={cn("button", className)} {...props} />;
}
export { Button };
.button {
display: inline-flex;
align-items: center;
justify-content: center;
text-decoration: none;
cursor: pointer;
white-space: nowrap;
background-color: var(--button-bg);
color: var(--button-fg);
height: var(--button-height);
border-color: var(--button-border-color);
border-width: var(--button-border-width);
border-style: var(--button-border-style);
padding-inline: var(--button-padding-inline);
padding-block: var(--button-padding-block);
font-weight: var(--button-font-weight);
border-radius: var(--button-radius);
box-shadow: var(--button-shadow);
letter-spacing: var(--button-tracking);
line-height: var(--button-line-height);
gap: var(--button-gap);
font-size: var(--button-font-size);
font-family: var(--button-font);
}
.button:hover {
background-color: var(--button-bg-hover);
}
.button:active {
background-color: var(--button-bg-active);
}
{
"button": {
"bg": {
"$value": "{color.transparent}"
},
"bg-hover": {
"$value": "{color.bg-offset-1}"
},
"bg-active": {
"$value": "{color.bg-offset-2}"
},
"fg": {
"$value": "{color.text.primary}"
},
"font": {
"$value": "{font.body}"
},
"font-weight": {
"$value": "{weight.button}"
},
"font-size": {
"$value": "{text.sm}"
},
"height": {
"$type": "dimension",
"$value": {
"value": 36,
"unit": "px"
}
},
"radius": {
"$value": "{radius.button}"
},
"gap": {
"$value": "{space.2xs}"
},
"padding-inline": {
"$value": "{space.sm}"
},
"padding-block": {
"$value": "{space.2xs}"
},
"tracking": {
"$value": "{tracking.button}"
},
"border": {
"width": {
"$value": "{stroke.width.thin}"
},
"style": {
"$value": "{stroke.style.solid}"
},
"color": {
"$value": "{stroke.color.primary}"
}
},
"shadow": {
"$value": "{shadow.button}"
}
}
}

Examples

:::note The following examples show how to use data attributes for variants. This is just one possible approach. See the principles section for more information on how to approach component variants. :::

Secondary

import { Button } from "@/registry/components/button/react/button";
export default function ButtonSecondary() {
return <Button data-variant="secondary">Secondary</Button>;
}
/* .button[data-variant="secondary"] {
--button-bg: var(--surface-secondary);
--button-text: var(--text-primary);
--button-bg-hover: var(--surface-secondary-hover);
--button-bg-active: var(--surface-secondary-active);
} */

Danger

import { Button } from "@/registry/components/button/react/button";
export default function ButtonDanger() {
return <Button data-variant="danger">Danger</Button>;
}
.button[data-variant="danger"] {
--button-bg: var(--bg-danger);
--button-fg: var(--color-white);
--button-bg-hover: var(--bg-danger-hover);
--button-bg-active: var(--bg-danger-active);
}