Primitives
Toggle
A button with two states that stays pressed until the next click.
import { Toggle } from 'ferry-ui'
import { Archive, Pin } from 'lucide-react'
export default function ToggleHero() {
return (
<>
<Toggle variant="outline" defaultPressed>
<Pin /> Pinned first
</Toggle>
<Toggle variant="outline">
<Archive /> Archived
</Toggle>
</>
)
}Import the component. A toggle has one part.
import { Toggle } from 'ferry-ui'
<Toggle />The variant prop sets the look. A pressed toggle changes its fill.
import { Toggle } from 'ferry-ui'
import { Star } from 'lucide-react'
export default function ToggleVariants() {
return (
<>
<Toggle>
<Star /> Default
</Toggle>
<Toggle defaultPressed>
<Star /> Default, pressed
</Toggle>
<Toggle variant="outline">
<Star /> Outline
</Toggle>
<Toggle variant="outline" defaultPressed>
<Star /> Outline, pressed
</Toggle>
</>
)
}| Variant | Look | Use |
|---|---|---|
default | No border and no fill. | A toggle in a toolbar. |
outline | A border and a fill. | A toggle that stands alone near other controls. |
The size prop sets the height. A toggle has the same height as a Button of the same size.
import { Toggle } from 'ferry-ui'
export default function ToggleSizes() {
return (
<>
<Toggle variant="outline" size="tiny">
Tiny, 26px
</Toggle>
<Toggle variant="outline" size="sm">
Small, 30px
</Toggle>
<Toggle variant="outline" size="md">
Medium, 34px
</Toggle>
</>
)
}| Size | Height |
|---|---|
tiny | 26px |
sm | 30px (default) |
md | 34px |
The sizes default and lg are deprecated names of sm and md. Do not use them.
A toggle with only an icon must have an aria-label. For a tooltip, wrap the toggle in Hint.
import { Hint, Toggle } from 'ferry-ui'
import { Bold, Italic, Underline } from 'lucide-react'
export default function ToggleIconOnly() {
return (
<div role="group" aria-label="Text format" className="flex items-center gap-0.5">
<Hint label="Bold">
<Toggle aria-label="Bold" defaultPressed>
<Bold />
</Toggle>
</Hint>
<Hint label="Italic">
<Toggle aria-label="Italic">
<Italic />
</Toggle>
</Hint>
<Hint label="Underline">
<Toggle aria-label="Underline">
<Underline />
</Toggle>
</Hint>
</div>
)
}Set disabled to refuse clicks. The toggle keeps its state.
import { Toggle } from 'ferry-ui'
import { Pin } from 'lucide-react'
export default function ToggleDisabled() {
return (
<>
<Toggle variant="outline" disabled>
<Pin /> Pinned first
</Toggle>
<Toggle variant="outline" disabled defaultPressed>
<Pin /> Pinned first
</Toggle>
</>
)
}A toggle holds its state by default. Use defaultPressed to press it at the start.
To control the state, pass pressed and onPressedChange. Use this when the state changes other content.
import * as React from 'react'
import { Badge, Toggle } from 'ferry-ui'
import { Archive } from 'lucide-react'
const PROJECTS = [
{ name: 'Customer portal', archived: false },
{ name: 'Marketing site', archived: false },
{ name: 'Old intranet', archived: true },
]
export default function ToggleControlled() {
const [showArchived, setShowArchived] = React.useState(false)
const projects = PROJECTS.filter((project) => showArchived || !project.archived)
return (
<div className="flex w-full max-w-sm flex-col gap-3">
<Toggle variant="outline" className="w-fit" pressed={showArchived} onPressedChange={setShowArchived}>
<Archive /> Archived
</Toggle>
<ul aria-label="Projects" className="divide-y rounded-lg border bg-surface-100 text-[13px] text-foreground">
{projects.map((project) => (
<li key={project.name} className="flex items-center justify-between px-4 py-2.5">
{project.name}
{project.archived && <Badge>Archived</Badge>}
</li>
))}
</ul>
</div>
)
}aria-pressed attribute. A screen reader reads the pressed state.aria-label.Toggle also accepts the props of its Radix UI primitive and each attribute of the <button> element.
| Prop | Type | Default |
|---|---|---|
variant | "default" | "outline" | default |
| ||
size | "default" | "tiny" | "sm" | "md" | "lg" | sm |
Height, on the | ||
pressed | boolean | - |
The controlled state of the toggle. | ||
defaultPressed | boolean | false |
The state of the toggle when initially rendered. Use | ||
onPressedChange | ((pressed: boolean) => void) | - |
The callback that fires when the state of the toggle changes. | ||
asChild | boolean | - |
| See the element or the Radix UI primitive this part renders. | ||
toggleVariants({ variant, size }) returns the classes of a toggle. Use it to give the toggle look to an element that is not a Toggle.
| Option | Type | Role |
|---|---|---|
variant | 'default' or 'outline' | The look. The default is default. |
size | 'tiny', 'sm' or 'md' | The height. The default is sm. |