Experience System
Components

Badge Overlay

Overlays a numeric badge, dot, or custom label on a wrapped control such as an icon button.

4

Installation

Badge Overlay is exported from @by/experience-system. Add the package with your package manager:

pnpm add @by/experience-system

In 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)
└── BadgeOverlayContent

The 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.

+99+99+99+99+99+99

Maximum value

Handle max display logic in children (for example {count > 99 ? '99+' : count}).

9999+999+

Show zero

Use hidden on BadgeOverlayContent when you want to suppress the badge (for example hidden={count === 0}).

0

Position

Use position: top-end, top-start, bottom-end, or bottom-start.

1234

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.

PropTypeDefault
classNamestring
childrenReact.ReactNode— (required)

Also accepts standard span attributes.

Data attributeValues
data-slotbadge-overlay-root

BadgeOverlayContent

Absolutely positioned badge. Must be a direct child of BadgeOverlay.

PropTypeDefault
coloraccent | neutral | success | error | warning | infoerror
positiontop-end | top-start | bottom-end | bottom-starttop-end
overlaprect | circularrect
dotbooleanfalse
hiddenbooleanfalse
classNamestring
childrenReact.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 attributeValues
data-slotbadge-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-hidden on the badge span; pair them with an aria-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.