Button
A native button in four weights. Fully round at rest and squarer while pressed, as in Material 3 Expressive; small and steady in size, because the dashboard is dense.
- Native HTML
- 1.8 KB gzipped · script and styles
@orbex/sonar-components/button
Examples
Code
import { Button } from '@orbex/sonar-components/button'
export default function Variants() {
return (
<>
<Button>Place order</Button>
<Button variant="tonal">Reorder</Button>
<Button variant="outlined">Export</Button>
<Button variant="text">View all</Button>
</>
)
}
Code
import { Button } from '@orbex/sonar-components/button'
import type { ComponentProps } from 'react'
import addSymbol from '@material-symbols/svg-400/rounded/add.svg?raw'
import downloadSymbol from '@material-symbols/svg-400/rounded/download.svg?raw'
import expandSymbol from '@material-symbols/svg-400/rounded/keyboard_arrow_down.svg?raw'
/* Material Symbols Rounded, weight 400, as icon components (Foundations › Icons) */
const symbol = (svg: string) => {
const path = svg.match(/ d="([^"]+)"/)?.[1]
return (props: ComponentProps<'svg'>) => (
<svg viewBox="0 -960 960 960" fill="currentColor" aria-hidden="true" focusable="false" {...props}>
<path d={path} />
</svg>
)
}
const AddIcon = symbol(addSymbol)
const DownloadIcon = symbol(downloadSymbol)
const ExpandIcon = symbol(expandSymbol)
export default function Sizes() {
return (
<>
<Button icon={<AddIcon />}>New order</Button>
<Button variant="outlined" iconEnd={<ExpandIcon />}>
All accounts
</Button>
<Button size="small" variant="tonal" icon={<DownloadIcon />}>
Invoice
</Button>
<Button size="small" variant="outlined">
Details
</Button>
</>
)
}
Code
import { Button } from '@orbex/sonar-components/button'
export default function Disabled() {
return (
<>
<Button disabled>Place order</Button>
<Button variant="tonal" disabled>
Reorder
</Button>
<Button variant="outlined" disabled>
Export
</Button>
<Button variant="text" disabled>
View all
</Button>
</>
)
}
Sizes, variants and states
Usage
- One filled button per view, for the action the view exists for: Place order, Save layout.
- Tonal for frequent secondary actions; outlined for the rest; text for actions inside a card or a list, such as View all.
- Medium in forms, panels and dialogs; small in cards and toolbars. Labels are verbs, in sentence case.
- For navigation, use a link with the same look:
<a class="sonar-button" data-variant="text" data-size="medium">. A button that only navigates confuses screen readers and breaks opening in a new tab. - Prefer leaving an action enabled and explaining what is missing when it is used. A disabled button cannot say why.
Do and don’t
Accessibility
Keyboard
| Key | What it does |
|---|---|
| Tab | Moves focus to the control, and on. |
| Enter or Space | Activates it. |
Roles and attributes
| Element or attribute | What it gives |
|---|---|
<button type="button"> |
A native button: role, name and states come from the browser. It never submits a form unless asked to. |
disabled |
Removes it from the tab order and tells assistive technology it is unavailable. |
| Icons | aria-hidden: the label alone names the action. |
Notes
- A native
<button>withtype="button"by default, so it never submits a form by accident. - Icons are hidden from assistive technology; the label names the action.
- The focus ring is drawn outside the button in
color.focus, at 3:1 or more on every surface. - On touch screens the hit area grows to 48 px around the button without changing how it looks.
Use it
Each component is its own entry point with its own stylesheet, so an app loads only what it uses. The tokens and the cascade layers are set once for the app: see Installation.
import { Button } from '@orbex/sonar-components/button'
import '@orbex/sonar-components/button.css'
API
| Prop | Type | Default |
|---|---|---|
variant
Visual weight. Filled for the one main action of a view, tonal for secondary actions, outlined and text for the rest. |
'filled' | 'tonal' | 'outlined' | 'text'
|
'filled' |
size
Medium in forms, panels and dialogs; small in cards and toolbars. |
'small' | 'medium'
|
'medium' |
icon
Icon before the label. It is decorative: the label names the action. |
ReactNode
|
— |
iconEnd
Icon after the label, such as a chevron on a button that opens a menu. |
ReactNode
|
— |
Also takes every attribute of the native <button>
, and a ref to it.