Button
Button component is used to trigger actions.
Want to skip the docs? Try our MCP Server
#
Documentation
#
#
Usage
#
"use client";
import type { ComponentPropsWithRef } from "react";
import { Button } from "@optiaxiom/react";
export function App({
appearance = "default",
size = "md",
}: Pick<ComponentPropsWithRef<typeof Button>, "appearance" | "size">) {
return (
<Button appearance={appearance} size={size}>
Button
</Button>
);
}#
Appearance
#
Use the appearance prop to select between the different button appearances.
import { Button, Group } from "@optiaxiom/react";
export function App() {
return (
<Group flexDirection={["column", "row"]} gap="16">
<Button appearance="primary">Delete</Button>
<Button appearance="danger">Delete</Button>
<Button appearance="danger-outline">Delete</Button>
<Button appearance="default">Delete</Button>
<Button appearance="subtle">Delete</Button>
</Group>
);
}#
Different sizes
#
Use the size prop to modify the size of the button.
import { Button, Group } from "@optiaxiom/react";
export function App() {
return (
<Group flexDirection="column" gap="16">
<Group gap="16">
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
</Group>
<Group gap="16">
<Button appearance="primary" size="sm">
Small
</Button>
<Button appearance="primary" size="md">
Medium
</Button>
<Button appearance="primary" size="lg">
Large
</Button>
</Group>
</Group>
);
}#
Disabled state
#
Set the disabled prop to true to disable buttons and prevent any interactions.
Include visible text that explains why it’s disabled: a disabled button leaves the tab order, so keyboard and screen reader users can’t reach a tooltip on it.
Select an article to publish, duplicate or archive it.
import { Button, Group, Text } from "@optiaxiom/react";
export function App() {
return (
<Group alignItems="start" flexDirection="column" gap="8">
<Group gap="16">
<Button appearance="primary" disabled>
Publish
</Button>
<Button disabled>Duplicate</Button>
<Button appearance="subtle" disabled>
Archive
</Button>
</Group>
<Text color="fg.secondary" fontSize="sm">
Select an article to publish, duplicate or archive it.
</Text>
</Group>
);
}#
Icons
#
Use the icon prop to add icons to a button.
#
Left and right icons
#
Icons are placed to the left by default but can be placed to the right using the iconPosition prop.
"use client";
import type { ComponentPropsWithRef } from "react";
import { IconTrashCan } from "@optiaxiom/icons";
import { Button } from "@optiaxiom/react";
export function App({
appearance = "default",
iconPosition = "start",
}: Pick<ComponentPropsWithRef<typeof Button>, "appearance" | "iconPosition">) {
return (
<Button
appearance={appearance}
icon={<IconTrashCan />}
iconPosition={iconPosition}
>
Delete
</Button>
);
}#
Icon only button
#
Use the icon prop and omit the children to display an icon only button.
For accessibility please make sure to always include an aria-label prop for screen readers and optionally use tooltips to visually denote the button’s intent.
import { IconPen, IconTrashCan } from "@optiaxiom/icons";
import { Button, Group, Tooltip } from "@optiaxiom/react";
export function App() {
return (
<Group gap="16">
<Button appearance="subtle" aria-label="Edit item" icon={<IconPen />} />
<Tooltip content="Remove item">
<Button
appearance="subtle"
aria-label="Remove item"
icon={<IconTrashCan />}
/>
</Tooltip>
</Group>
);
}#
Grouping buttons
#
Use the <ButtonGroup /> component to group related buttons together.
import { Button, ButtonGroup } from "@optiaxiom/react";
export function App() {
return (
<ButtonGroup>
<Button>First</Button>
<Button>Second</Button>
<Button>Third</Button>
</ButtonGroup>
);
}#
Links
#
#
Button as links
#
Set asChild to true and wrap children in an <a> element to render buttons as links.
import { Button } from "@optiaxiom/react";
export function App() {
return (
<Button asChild>
<a href="./props">Sample Link</a>
</Button>
);
}#
Disabled button links
#
Make sure to prevent interactions manually using event.preventDefault() since <a> elements do not support the disabled prop.
Alternatively you can use our Link component which supports the disabled prop.
The report is ready once the import finishes.
import { Button, Group, Link, Text } from "@optiaxiom/react";
export function App() {
return (
<Group gap="8">
<Button asChild disabled>
<Link href="./props">View report</Link>
</Button>
<Text color="fg.secondary" fontSize="sm">
The report is ready once the import finishes.
</Text>
</Group>
);
}#
Loading state
#
Set the loading prop to true to show a loading spinner and mark the button aria-busy.
Don’t also set disabled: a disabled button loses keyboard focus mid-action. The button stays clickable while loading, so ignore repeat clicks in your onClick handler if the action shouldn’t run twice.
"use client";
import { Button, Group, Switch, Tooltip } from "@optiaxiom/react";
import { useState } from "react";
export function App() {
const [loading, setLoading] = useState(true);
return (
<Group flexDirection="column" gap="16">
<Group gap="16">
<Tooltip content="Loading button demo">
<Button appearance="primary" loading={loading}>
Primary
</Button>
</Tooltip>
<Tooltip content="Loading button demo">
<Button loading={loading}>Default</Button>
</Tooltip>
<Tooltip content="Loading button demo">
<Button appearance="subtle" loading={loading}>
Subtle
</Button>
</Tooltip>
</Group>
<Switch
checked={loading}
onCheckedChange={() => setLoading((loading) => !loading)}
>
Loading
</Switch>
</Group>
);
}#
File upload
#
We can create a simple file upload button by rendering the button as a label and including a visually hidden file input.
import { IconUpload } from "@optiaxiom/icons";
import { Button } from "@optiaxiom/react";
import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
export function App() {
return (
<Button asChild icon={<IconUpload />}>
<label>
Upload file
<VisuallyHidden>
<input type="file" />
</VisuallyHidden>
</label>
</Button>
);
}#
Related
#
DropdownMenu
Display a dropdown menu.
SegmentedControl
Toggle buttons for switching between different values or views.
ToggleButton
ToggleButton component represents a button that can be toggled on or off.
#
Props
#
#
Button
#
import { Button } from "@optiaxiom/react";
// or
import { Button } from "@optiaxiom/react/button";Supports all Box props in addition to its own. Renders a <button> element.
Prop |
|---|
addonAfterDisplay content inside the button after
|
addonBeforeDisplay content inside the button before
|
appearanceControl the appearance by selecting between the different button types.
|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
children
|
className
|
disabledWhether the button is disabled.
|
iconDisplay an icon before or after the button content or omit
|
iconPositionControl whether to show the icon before or after the button content.
Default: |
loadingShow a loading spinner and mark the button
|
sizeControl the size of the button.
|
squareWhether button should have square shape (an icon-only button with no label).
|
typeThe default behavior of the button.
|
#
ButtonGroup
#
import { ButtonGroup } from "@optiaxiom/react";
// or
import { ButtonGroup } from "@optiaxiom/react/button";Supports all Box props in addition to its own. Renders a <div> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
children
|
className
|
gap |
orientationThe orientation/layout of the buttons inside the group.
Default: |
#
Accessibility
#
#
Labels
#
- Give an icon only button an
aria-label, since it has no visible text. Button logs a console error when the label is missing. - A disabled button leaves the tab order, so keyboard and screen reader users can’t reach a tooltip on it. Explain why it’s disabled in visible text nearby.
#
Loading
#
loading marks the button aria-busy and keeps it focusable and clickable. Ignore repeat clicks in your handler when the action shouldn’t run twice.
#
Changelog
#
#
0.1.0
#
- Added component