Button
ReadyTriggers an action.
Installation
$ npx @oratiq-js/ui add buttonCopies the component and everything it depends on into your project, then lists the npm packages to install. The code is yours after this.
Usage
import { Button, buttonVariants } from "@/components/ui/button";Variants
Six variants. Exactly one primary action per view — if two things look primary, neither is.
default
The single main action
secondary
Supporting action
outline
Low emphasis, still bounded
ghost
Toolbar and dense UI
destructive
Irreversible action
link
Navigates, not acts
Sizes
Five text sizes and five matching icon-only sizes.
States
Every variant carries the same state contract. Hover and focus are shown live — tab through the row.
default
disabled
loading
loading + text
Loading is not disabled
aria-busy, so a screen-reader user isn't silently dropped out of the tab order mid-submit. Pointer events are blocked instead.With icons
Logical slots — icons swap sides under RTL automatically.
Shape and width
Guidance
Label buttons with the action they perform. The label should make sense read on its own, out of context.
Don't use vague labels. 'OK' and 'Submit' force the user to re-read the surrounding copy to know what happens.
Accessibility
- Icon-only buttons require an aria-label — there is no visible text to announce.
- Focus ring is a 2px ring offset from the background, meeting the 3:1 non-text contrast minimum in both themes.
- Disabled uses the disabled attribute, so the button leaves the tab order; loading uses aria-busy and stays in it.
- asChild renders your element (e.g. next/link) with button styling, keeping the correct semantics for navigation.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "secondary" | "outline" | "ghost" | "destructive" | "link" | "default" | Visual emphasis. |
size | "xs" | "sm" | "default" | "lg" | "xl" | "icon-xs" | "icon-sm" | "icon" | "icon-lg" | "icon-xl" | "default" | Control height and padding. |
shape | "rounded" | "pill" | "square" | "rounded" | Corner treatment. |
loading | boolean | false | Shows a spinner and blocks pointer events. |
loadingText | string | — | Replaces the label while loading. |
fullWidth | boolean | false | Stretches to the container width. |
asChild | boolean | false | Renders the child element instead of a button. |
View source on GitHub → components/ui/button.tsx