Badges communicate a notification count or unread status on top of another element. Badge renders position: absolute, so it is an overlay primitive —
it always needs a positioned (relative) ancestor to anchor
against, it never lays out inline on its own.
Badge implements the Material Design 3 Badge pattern: a small dot (size="sm") for a general notification,
or a numbered pill (size="lg") for a specific count.
You'll most often use it indirectly: NavbarItem and RailItem both
accept a badge prop (a number, or -1 for the dot variant) and render a Badge internally, already
positioned over their icon. Reach for Badge directly only
when overlaying a count on something those components don't cover — e.g. a custom icon
button — in which case wrap the anchor in a relative container
yourself, as shown below.
import { Badge } from '@noxlovette/material'; See it live, with Controls, in Storybook rather than a hand-rolled preview here.
Playground
Control over size and number, overlaid on an icon.
Wrap the anchor element in a relative container so the badge's
absolute positioning resolves against it:
<script lang="ts">
import { Badge, Icon } from '@noxlovette/material';
</script>
<div class="relative inline-flex size-10 items-center justify-center">
<Icon name="mail" />
<Badge size="lg" number={5} />
</div> Or, more commonly, let a navigation item do this for you:
<NavbarItem label="Inbox" href="/inbox" iconProps={{ name: 'mail' }} badge={5} />
<NavbarItem label="Chat" href="/chat" iconProps={{ name: 'chat' }} badge={-1} /> | Prop | Type | Default | Description |
|---|---|---|---|
size | 'sm' | 'lg' | 'lg' | "sm" renders a small dot indicator with no number; "lg" renders a pill sized to fit a number. |
number | number | — | The count to display. Ignored when size is "sm". Values over 99 render as "99+". |
Not independently announced
Badge renders a plain <div> with no ARIA role or live-region behaviour. If the count is important to announce, expose it via the anchor element's own accessible name or an aria-live region.
Color contrast
Uses the error/on-error color pair by default, which meets AA contrast against the badge background regardless of theme.
Positioning context
Because it is position: absolute, always verify its relative ancestor has no overflow: hidden clipping it at small viewport sizes.