Components

DhButton

Role-colour button (primary / secondary / tertiary / error / ghost) with boolean outlined / elevated surface modifiers, sizes, icon slots, and loading.

Variants

`variant` picks the role colour. Surface defaults to filled — except `secondary`, which outlines by default (the conditional default for the most common Cancel/Skip button).

<DhButton>Secondary</DhButton>                  <!-- bare default -->
<DhButton variant="primary">Primary</DhButton>
<DhButton variant="tertiary">Tertiary</DhButton>
<DhButton variant="error">Error</DhButton>
<DhButton variant="ghost">Ghost</DhButton>

Surface modifiers

`outlined` and `elevated` are boolean modifiers; `elevated` wins if both are set. Default is filled. `outlined` defaults to `true` for `secondary` and `false` for everything else; pass it explicitly to override.

<DhButton variant="primary">Filled (default)</DhButton>
<DhButton variant="primary" outlined>Outlined</DhButton>
<DhButton variant="primary" elevated>Elevated</DhButton>

<!-- Secondary's outlined default is true; pass outlined={false} to fill it. -->
<DhButton>Secondary outlined</DhButton>
<DhButton outlined={false}>Secondary filled</DhButton>

Sizes

`sm` is the default at `2.75rem` tall with `1rem` padding and `0.5rem` corners.

<DhButton variant="primary" size="sm">Small (default)</DhButton>
<DhButton variant="primary" size="md">Medium</DhButton>
<DhButton variant="primary" size="lg">Large</DhButton>

Shape

`square` (default) gives Davidhorn's standard `0.5rem` corner radius. `round` resolves to `--radius-full` for a full pill.

<DhButton variant="primary">Square (default)</DhButton>
<DhButton variant="primary" shape="round">Round (pill)</DhButton>

With icons

<DhButton variant="primary"  startIcon="plus"    text="Create" />
<DhButton                    endIcon="arrow-right" text="Next" />
<DhButton variant="ghost"    startIcon="copy" endIcon="chevron-down" text="Copy" />
<DhButton variant="error"    startIcon="trash-2" text="Delete" />

States

Loading replaces the leading icon with a spinner; the label dims to `0.6` opacity, `aria-busy` is set, and clicks are blocked.

<DhButton variant="primary" text="Default" />
<DhButton variant="primary" text="Disabled" disabled />
<DhButton variant="primary" text="Loading"  loading={isLoading} onclick={simulateLoad} />

As submit in a form

`type='submit'` fires the surrounding form; `type='reset'` clears it. Type defaults to `'button'`.

Clicked 0 times
<form onsubmit={(e) => e.preventDefault()}>
  <DhButton type="submit" variant="primary" text="Submit" />
  <DhButton type="reset" text="Reset" />
</form>

Migrating from Ark

How Ark's button props map to the Justin API. Most are 1:1; the cases below are the ones worth noting.

  • variant="primary"variant="primary"
  • variant="secondary"<DhButton> (default)
  • variant="tertiary"variant="ghost" (new tertiary is filled orange — not a drop-in)
  • variant="neutral"outlined=false
  • variant="danger"variant="error"
  • <a>-styled buttons → <DhLinkButton>

Not covered yet (in flight):

  • shape="circle"DhIconButton (PRD-3240)
  • selected={…}DhToggleButton (PRD-3241)