Button

Components

Button

The default action control. Five hierarchy levels, two compact sizes, and no appearance escape hatch.

Variants

Variant is visual weight, not colour choice. Use one primary per screen; everything else is secondary or ghost, and danger is reserved for an action that destroys something.

tsx
import { Button } from "@karnstack/dowel";

<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="muted">Muted</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="danger">Danger</Button>

Sizes

Two, and only two. md is the 28px control height every other dowel control shares; sm is 24px for dense rows and toolbars.

tsx
<Button size="sm">Small</Button>
<Button>Medium</Button>

States

A disabled button keeps its variant and drops to half opacity. Hover derives from the accent, so a retheme carries into it automatically.

tsx
<Button variant="primary" disabled>Disabled</Button>
<Button disabled>Disabled</Button>

Pass an element to render to change the tag. An anchor is not a native button, so it needs nativeButton={false} — Base UI then applies button semantics instead of native-button attributes.

tsx
<Button
  variant="primary"
  nativeButton={false}
  render={<a href="https://github.com/karnstack/dowel" />}
>
  Open the repo
</Button>

Props

PropTypeDefault
variant"primary" | "secondary" | "muted" | "ghost" | "danger""secondary"
size"sm" | "md""md"
renderReactElement
nativeButtonbooleantrue

className and style are absent from ButtonProps and neutralised at runtime. If you need a different button, dowel is the wrong library — that is the point.