Unstyled, accessible React 19 primitives. Style everything with your own CSS using data-* attributes that reflect interactive state.
import { Button } from '@wire-ui/react'
export default function App() {
return (
<Button
className="
px-4 py-2 rounded-lg bg-indigo-600 text-white font-medium
[data-hover]:bg-indigo-700
[data-active]:scale-95
[data-focus-visible]:ring-2 [data-focus-visible]:ring-indigo-500
[data-disabled]:opacity-40 [data-disabled]:cursor-not-allowed
"
>
Save changes
</Button>
)
}Developer experience
Develop with an open, thought-out API that stays out of your way.
import { Modal } from '@wire-ui/react'
<Modal>
{/* Trigger โ any element */}
<Modal.Trigger asChild>
<button className="btn">Open</button>
</Modal.Trigger>
{/* Backdrop */}
<Modal.Backdrop className="
fixed inset-0 bg-black/50
[data-open]:opacity-100
[data-closed]:opacity-0
" />
{/* Panel */}
<Modal.Panel className="
fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2
bg-white rounded-xl shadow-xl p-6 w-full max-w-md
[data-open]:scale-100
[data-closed]:scale-95
">
<Modal.Title>Are you sure?</Modal.Title>
<Modal.Description>This cannot be undone.</Modal.Description>
<Modal.Close asChild>
<button className="btn-danger">Confirm</button>
</Modal.Close>
</Modal.Panel>
</Modal>Join our fast-growing community