Orbex Sonar-DB Design system , home

Examples

Count, dot and tones
Payments 3 unpaid invoices128 new documents
Code
tsx
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

Forms and tones

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

DoA count on the thing it counts, with its meaning in the label: “12 unread”.
Don’tWords in a badge. A badge holds a number or a dot; a message goes in a notice.
DoCap large counts: 99+ says “a lot” and keeps its size.
Don’tA four-digit badge that outgrows what it sits on.

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 label that 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.

tsx
import { Badge } from '@orbex/sonar-components/badge'
import '@orbex/sonar-components/badge.css'

API

Props of Badge
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 99+.

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.