A React button with a Liquid Glass style, five sizes, icon slots, and link rendering.
Button renders a native button with a Liquid Glass surface, optional leading and trailing icons, and five sizes. Use it for actions; when it should navigate, render it as a link.
The counter below renders the real Button. Clicking updates React state, and the reset button disables itself at zero.
Clicked 0 times
Supports xs / sm / md / lg / xl, defaulting to md. Text and icons scale with the size, so you do not need to pass size to icons separately.
The leading icon sits before the label. The trailing icon sits after the label. Both use the same plain icon container. For icon-only buttons, provide an aria-label; the empty label slot is omitted so the icon stays centered.
The disabled state uses the native disabled attribute, stopping both keyboard and pointer interaction. focusableWhenDisabled keeps the button in the Tab order while disabled; the component exposes it with aria-disabled and blocks activation.
className adjusts the outer click area. The inner base layout already fills the available width:
When the button should navigate instead of trigger an action, set nativeButton={false} and render a link instead of a native <button>:
form links a button to a form elsewhere in the document. When several buttons submit the same form, name and value identify which action the user chose.
No action submitted yet.
Button renders a native <button> by default, so it gets focus, Enter and Space activation, and disabled behavior from the platform. label or children provides the accessible name. Icon-only buttons must use aria-label or aria-labelledby; icon slots are decorative and hidden from assistive technology.
When nativeButton={false} renders a link or another element, keep the visible label meaningful and use the element that matches the action. focusableWhenDisabled keeps a disabled action in the Tab order with aria-disabled while blocking activation.
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | Button text. A truthy label takes precedence over children. |
children | ReactNode | — | Visible content used when label is falsy or omitted. |
leadingIcon | ReactNode | — | Decorative icon before the label. |
trailingIcon | ReactNode | — | Decorative icon after the label. |
size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | Controls height, padding, text, and icon size. |
disabled | boolean | false | Disables the button. |
focusableWhenDisabled | boolean | false | Keeps a disabled button in the Tab order and exposes it with aria-disabled. |
nativeButton | boolean | true | Whether the rendered element is a native <button>. Set it to false when rendering a link or another element. |
type | "button" | "submit" | "reset" | "button" | Native button type. Set "submit" when the button should submit a form. |
form | string | — | ID of the form that owns the button. |
name | string | — | Name submitted with the form. |
value | string | — | Value submitted with the form. |
onClick | MouseEventHandler<HTMLElement> | — | Called when the button is pressed. |
render | ReactElement | ((props, state) => ReactElement) | — | Replaces the rendered element. |
ref | Ref<HTMLElement> | — | Ref forwarded to the rendered element. |
className | string | — | Tailwind classes merged into the outer root. |
style | CSSProperties | — | Inline styles merged into the same element as className. |
ui | { root?: ClassValue; base?: ClassValue; glass?: ClassValue; overlay?: ClassValue; label?: ClassValue; leadingIcon?: ClassValue; trailingIcon?: ClassValue } | — | Tailwind classes for internal slots, keyed by data-slot. |
| Attribute | Description |
|---|---|
data-disabled | Present when the button is disabled. |
data-slot | Marks internal parts (root, base, glass, overlay, leading-icon, label, trailing-icon) for styling. label is omitted for icon-only buttons. |
The component uses the shared glass material. Tune shared --ui-glass-* tokens on a parent, use className for layout, and use ui for internal slots keyed by data-slot. Component-specific values live in src/theme/button.ts. See the theming guide for token layers and presets.