Button
A native <button> with full interactive state tracking. Use asChild to render as any element while keeping all behaviour and data attributes.
Features
Full interactive state tracking via data attributes.
asChild polymorphism to render as any element.
Auto-focus support with data-autofocus.
Defaults to type=“button” to prevent accidental form submission.
Example
Anatomy
import { Button } from '@wire-ui/react'
<Button>Styled Button</Button>Styling
Button tracks all interactive states — hover, focus, active, disabled — via data attributes. Style each state using CSS attribute selectors with Tailwind, CSS Modules, or plain CSS.
<Button className="
bg-white text-black
[data-hover]:bg-black [data-hover]:text-white
[data-active]:scale-95
[data-focus-visible]:ring-2 [data-focus-visible]:ring-black
[data-disabled]:opacity-50 [data-disabled]:cursor-not-allowed
">
Click me
</Button>Using data attributes
Button exposes interactive state as data attributes on the rendered element. Attributes are present (empty string) when active and absent when inactive.
/* Plain CSS */
button[data-hover] { background: #000; color: #fff; }
button[data-active] { transform: scale(0.95); }
button[data-focus-visible] { outline: 2px solid #6366f1; }
button[data-disabled] { opacity: 0.5; cursor: not-allowed; }Props
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Merge all props onto the immediate child element |
disabled | boolean | false | Disables the button; adds data-disabled |
autoFocus | boolean | false | Auto-focuses on mount; adds data-autofocus |
type | 'button' | 'submit' | 'reset' | 'button' | Native button type (ignored when asChild) |
...rest | ButtonHTMLAttributes | — | All standard HTML button attributes |
Data attributes
| Attribute | When present |
|---|---|
data-hover | Mouse is over the button |
data-focus-visible | Button has keyboard focus |
data-active | Button is being pressed |
data-disabled | disabled prop is true |
data-autofocus | autoFocus prop is true |
asChild
asChild merges all props (including data-* attributes and event handlers) onto the child element. The child must be a single React element.
// Renders as <a> with all Button data attributes and handlers
<Button asChild>
<a href="/profile">View profile</a>
</Button>
// Works with custom components too
<Button asChild>
<Link to="/dashboard">Dashboard</Link>
</Button>Accessibility
- Renders as
<button>by default — correct semantics and keyboard behaviour out of the box. type="button"prevents accidental form submission.data-focus-visibleuseselement.matches(':focus-visible')— only keyboard navigation triggers it, not mouse clicks.
Keyboard Interactions
| Key | Description |
|---|---|
| Space | Activates the button. |
| Enter | Activates the button. |
| Tab | Moves focus to the button. |
Last updated on