DhIconButton
Icon-only button rendered as a tight circle (1:1 hit area) by default; shape="square" gives a rounded square. A DhButton with a single icon and no label — reuses its role/surface model (variant primary / secondary / error / ghost, conditional outlined default, state layer, disabled, loading) and scales down slightly on press. ariaLabel is required. DhIconLinkButton is the anchor-rendered counterpart.
An icon-only button that renders as a tight perfect circle — the shape DhButton's pill shape="round" can't give. Reuses DhButton's role/surface model, so variant, outlined, the state layer, disabled, and loading all behave
the same.
Variants
`variant` picks the role colour. Surface defaults to filled — except `secondary`, which outlines by default, mirroring DhButton.
<DhIconButton icon="pencil" ariaLabel="Edit" /> <!-- secondary, outlined by default -->
<DhIconButton icon="plus" ariaLabel="Add" variant="primary" />
<DhIconButton icon="trash-2" ariaLabel="Delete" variant="error" />
<DhIconButton icon="ellipsis" ariaLabel="More" variant="ghost" />Filled, outlined, ghost
`outlined` toggles the ringed surface. Ghost is transparent and ignores it.
<DhIconButton icon="plus" ariaLabel="Add" variant="primary" /> <!-- filled -->
<DhIconButton icon="plus" ariaLabel="Add" variant="primary" outlined /> <!-- ringed -->
<!-- Secondary's outlined default is true; pass outlined={false} to fill it. -->
<DhIconButton icon="pencil" ariaLabel="Edit" />
<DhIconButton icon="pencil" ariaLabel="Edit" outlined={false} />Sizes
The hit area scales while the circle stays 1:1: 2.5 / 3 / 3.5 rem.
<DhIconButton icon="search" ariaLabel="Search" variant="primary" size="sm" />
<DhIconButton icon="search" ariaLabel="Search" variant="primary" size="md" />
<DhIconButton icon="search" ariaLabel="Search" variant="primary" size="lg" />Disabled and loading
Disabled inherits DhButton's neutral fade. Loading swaps the glyph for a centred spinner and sets aria-busy. Click the third button.
<DhIconButton icon="check" ariaLabel="Confirm" variant="primary" />
<DhIconButton icon="check" ariaLabel="Confirm" variant="primary" disabled />
<DhIconButton icon="check" ariaLabel="Saving" variant="primary" loading={isLoading} onclick={simulateLoad} />Press feedback
On :active the button scales down slightly (to 0.97) — a subtle press response; the circle's radius stays constant. Honours prefers-reduced-motion. Press and hold to feel it.
<!-- On press the button scales down slightly (to 0.97); the circle's
radius stays constant. Honours prefers-reduced-motion.
Press and hold to feel it. -->
<DhIconButton icon="heart" ariaLabel="Like" variant="primary" size="lg" />DhIconLinkButton
The anchor-rendered counterpart. Same visuals; navigates instead of firing a handler, so it joins browser history and right-click works.
<DhIconLinkButton href="/settings" icon="settings" ariaLabel="Settings" variant="primary" />
<DhIconLinkButton href="https://figma.com" external icon="external-link" ariaLabel="Open in Figma" />