Badge Overlay
Overlays a numeric badge, dot, or custom label on a wrapped control such as an icon button.
Installation
Badge Overlay is exported from @by/experience-system. Add the package with your package manager:
pnpm add @by/experience-systemIn this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.
Composition
Use BadgeOverlay as the wrapper with BadgeOverlayContent for the indicator:
BadgeOverlay
├── (wrapped control, e.g. Button)
└── BadgeOverlayContentThe first child is the anchor control (usually a Button or icon button). Add one or more BadgeOverlayContent nodes as direct siblings after it. Counts and labels go in children of BadgeOverlayContent; use dot for a compact indicator without text.
Usage
import { BadgeOverlay, BadgeOverlayContent, Button } from '@by/experience-system';
import { Bell } from '@by/icons/ui';Badge Overlay parts (BadgeOverlay, BadgeOverlayContent) are client components ('use client'). Use them inside a Client Component or a dynamic import when using the Next.js App Router.
<BadgeOverlay>
<Button variant="outline" size="icon-sm" aria-label="Notifications">
<Bell />
</Button>
<BadgeOverlayContent>4</BadgeOverlayContent>
</BadgeOverlay>When to use
- When you need to draw attention to new activity, updates, or notifications (for example unread messages).
- To display contextual information like item count, user status, or feature labels (“Beta,” “New”).
- When you want glanceable indicators without extra interaction or layout space.
When not to use
- When the information is critical and needs detailed explanation—use modals or alerts instead.
- If the badge content is too long or complex to read at small sizes.
- When the UI already has many indicators and a badge would add clutter.
Examples
Colors
Use color on BadgeOverlayContent for semantic emphasis. Available colors: accent, neutral, success, error, warning, and info.
Maximum value
Handle max display logic in children (for example {count > 99 ? '99+' : count}).
Show zero
Use hidden on BadgeOverlayContent when you want to suppress the badge (for example hidden={count === 0}).
Position
Use position: top-end, top-start, bottom-end, or bottom-start.
Dot
Set dot for a compact indicator without text. Omit children.
API Reference
Subsection titles name the exports from @by/experience-system. These parts are plain React components (not Radix primitives).
BadgeOverlay
Root wrapper: relative inline-flex, shrink-0. children must include the anchor control plus one or more BadgeOverlayContent direct children.
| Prop | Type | Default |
|---|---|---|
className | string | — |
children | React.ReactNode | — (required) |
Also accepts standard span attributes.
| Data attribute | Values |
|---|---|
data-slot | badge-overlay-root |
BadgeOverlayContent
Absolutely positioned badge. Must be a direct child of BadgeOverlay.
| Prop | Type | Default |
|---|---|---|
color | accent | neutral | success | error | warning | info | error |
position | top-end | top-start | bottom-end | bottom-start | top-end |
overlap | rect | circular | rect |
dot | boolean | false |
hidden | boolean | false |
className | string | — |
children | React.ReactNode | — (ignored when dot is true) |
Also accepts standard span attributes except color is reserved for the semantic variant (use className for CSS color if needed).
| Data attribute | Values |
|---|---|
data-slot | badge-overlay-content |
When dot is true, aria-hidden is set on the badge span; pair with an accessible name on the wrapped control.
Accessibility
- Dot badges set
aria-hiddenon the badge span; pair them with anaria-label(or visible text) on the wrapped control so the notification is announced meaningfully. - For numeric counts, ensure the trigger or a nearby live region conveys the same information when assistive technology should read the value aloud.
Source in the repo: packages/experience-system/src/components/BadgeOverlay/BadgeOverlay.tsx and variants.ts. Agent-oriented usage notes: packages/experience-system/src/components/BadgeOverlay/BadgeOverlay.instructions.md.