Badge
A count or a dot on a navigation item or an icon button. Figures are set in the mono face, as everywhere numbers are compared.
- Native HTML
- 1.1 KB gzipped · script and styles
@orbex/sonar-components/badge
Examples
Code
import { Badge } from '@orbex/sonar-components/badge'
import { IconButton } from '@orbex/sonar-components/icon-button'
import type { ComponentProps } from 'react'
import notificationsSymbol from '@material-symbols/svg-400/rounded/notifications.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 NotificationsIcon = symbol(notificationsSymbol)
/* A badge sits in the flow or is placed by its container; it does not position itself.
When the element it sits on already says what it counts, the badge is hidden from assistive technology. */
export default function Examples() {
return (
<>
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, font: 'var(--sonar-type-label-lg)' }}>
Payments <Badge count={3} label="3 unpaid invoices" />
</span>
<span style={{ position: 'relative', display: 'inline-flex' }}>
<IconButton label="Notifications, 12 unread" icon={<NotificationsIcon />} />
<Badge count={12} aria-hidden style={{ position: 'absolute', top: -2, right: -4 }} />
</span>
<span style={{ position: 'relative', display: 'inline-flex' }}>
<IconButton label="Notifications, new" icon={<NotificationsIcon />} />
<Badge aria-hidden style={{ position: 'absolute', top: 7, right: 8 }} />
</span>
<Badge count={128} tone="accent" label="128 new documents" />
</>
)
}
Sizes, variants and states
Usage
- Danger for what needs attention, such as unpaid invoices; accent for news.
- A dot says that something is new; a count says how much. Counts above 99 show as 99+.
- The badge does not position itself: its container places it, so it fits any shape it sits on.
Do and don’t
Accessibility
Keyboard
| Key | What it does |
|---|---|
| None | A badge is not interactive; the element it sits on takes focus. |
Roles and attributes
| Element or attribute | What it gives |
|---|---|
label |
A visually hidden phrase read instead of the bare number: “3 unpaid invoices”. |
aria-hidden |
For a badge whose meaning is already in its container’s name, such as an icon button named “Notifications, 12 unread”. |
Notes
- Give it a
labelthat says what it counts; the bare number is then hidden from assistive technology. - When the element it sits on already says it, as an icon button named “Notifications, 12 unread”, hide the badge with
aria-hidden. - White on the danger fill reaches 4.5:1 in both themes.
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 { Badge } from '@orbex/sonar-components/badge'
import '@orbex/sonar-components/badge.css'
API
| Prop | Type | Default |
|---|---|---|
count
The number to show. Without it, the badge is a dot that only signals something new. |
number
|
— |
max
Counts above this show as |
number
|
99 |
label
What the badge means, read by assistive technology instead of the bare number, such as “3 unpaid invoices”. Leave it out only when the element the badge sits on already says it. |
string
|
— |
tone
Danger for things that need attention; accent for news. |
'danger' | 'accent'
|
'danger' |
Also takes every attribute of the native <span>
, except children, and a ref to it.