Primitives
Button
A control that starts an action.
import { Button } from 'ferry-ui'
export default function ButtonHero() {
return (
<>
<Button variant="primary">Save changes</Button>
<Button>Cancel</Button>
</>
)
}variant="primary" for the main action. The other actions keep the default variant.destructive button opens a Confirm Dialog. It does not delete on a click.Import the component. A button has one part.
import { Button } from 'ferry-ui'
<Button />The variant prop sets the look. Each look has one role.
import { Button } from 'ferry-ui'
export default function ButtonVariants() {
return (
<>
<Button>Default</Button>
<Button variant="primary">Primary</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="destructive-solid">Destructive solid</Button>
<Button variant="warning">Warning</Button>
<Button variant="link">Link</Button>
<Button variant="dashed">Dashed</Button>
</>
)
}| Variant | Role |
|---|---|
default | A secondary action. |
primary | The main action of the view. |
outline | A secondary action on a tinted surface. |
ghost | An action in a dense row or a toolbar. |
destructive | The button that starts a destructive action. |
destructive-solid | The confirm button of a destructive dialog. |
warning | An action that needs attention. |
link | An action that looks like a text link. |
dashed | A filter button in a toolbar. |
The size prop sets the height. Use the same height as the fields near the button.
import { Button } from 'ferry-ui'
export default function ButtonSizes() {
return (
<>
<Button size="tiny">Tiny, 26px</Button>
<Button size="sm">Small, 30px</Button>
<Button size="md">Medium, 34px</Button>
<Button size="lg">Large, 38px</Button>
</>
)
}Give a lucide icon to icon or to iconRight. The button sets the size of the icon.
A button with only an icon uses an icon size. It must have an aria-label.
import { Button } from 'ferry-ui'
import { ArrowRight, Plus, Trash2 } from 'lucide-react'
export default function ButtonIcons() {
return (
<>
<Button icon={<Plus />}>New project</Button>
<Button iconRight={<ArrowRight />}>Continue</Button>
<Button variant="ghost" size="icon" icon={<Trash2 />} aria-label="Delete the project" />
</>
)
}Set loading while the action is in progress. The button shows a spinner and refuses clicks.
import * as React from 'react'
import { Button } from 'ferry-ui'
export default function ButtonLoading() {
const [saving, setSaving] = React.useState(false)
function save() {
setSaving(true)
window.setTimeout(() => setSaving(false), 1500)
}
return (
<Button variant="primary" loading={saving} onClick={save}>
{saving ? 'Saving…' : 'Save changes'}
</Button>
)
}With asChild, the button gives its look to its child element. Use it for a link that must look like a button.
import { Button } from 'ferry-ui'
import { ExternalLink } from 'lucide-react'
export default function ButtonAsChild() {
return (
<Button asChild iconRight={<ExternalLink />}>
<a href="https://github.com/Carter2307/ferry-ui" target="_blank" rel="noreferrer">
Open the repository
</a>
</Button>
)
}Button also accepts each attribute of the <button> element.
| Prop | Type | Default |
|---|---|---|
variant | "link" | "default" | "primary" | "outline" | "ghost" | "destructive" | "destructive-solid" | "danger" | "danger-solid" | "warning" | "dashed" | default |
Look.
| ||
size | "tiny" | "sm" | "md" | "lg" | "icon-tiny" | "icon" | "icon-md" | "icon-lg" | sm |
Height. | ||
shape | "default" | "pill" | default |
Corners: | ||
asChild | boolean | false |
Style the single child element (usually an | ||
loading | boolean | false |
Shows a spinner in place of | ||
icon | ReactNode | - |
Leading icon (rendered before children). Pass a bare lucide icon: it is sized for you. | ||
iconRight | ReactNode | - |
Trailing icon (rendered after children). Pass a bare lucide icon: it is sized for you. | ||