Skip to main content
WireKit
Copy for LLM

Indicator

Pins a small thing — an unread count, a status dot, a "NEW" ribbon — to the corner of any target: a bell icon, an avatar, a card, a button.

It exists so you stop hand-rolling absolute positioning with negative corner offsets on every one of them. That pattern is exactly the raw-div scaffolding a component library is supposed to replace — and it silently breaks in RTL.

Basic Usage

An unread count on a bell
3

Corners

position is logical: end is the right corner in LTR and the left corner in RTL, so the badge follows the reading direction on its own.

Every corner
1 2 3 4

Offset

By default the badge is centered on the corner. offset nudges it further out.

Nudged further out
9 9

Naming the badge

The badge must say what it means. A bare "3" next to a bell tells a screen-reader user nothing.

{{-- 1. A count: name it, and hide the raw number from assistive tech --}}
<x-wirekit::indicator>
    <x-wirekit::button icon-only aria-label="Notifications">
        <x-wirekit::icon name="bell" size="md" />
    </x-wirekit::button>
    <x-slot:badge>
        <x-wirekit::badge intent="danger" size="sm">
            <span aria-hidden="true">{{ $unread }}</span>
            <span class="sr-only">{{ $unread }} unread notifications</span>
        </x-wirekit::badge>
    </x-slot:badge>
</x-wirekit::indicator>
{{-- 2. A purely decorative presence dot: hide it, and say it elsewhere --}}
<x-wirekit::indicator position="bottom-end">
    <x-wirekit::avatar :alt="$user->name" />
    <x-slot:badge>
        <span aria-hidden="true" style="width:.625rem;height:.625rem;border-radius:9999px;background:var(--color-wk-success);display:block"></span>
    </x-slot:badge>
</x-wirekit::indicator>
<span class="sr-only">{{ $user->name }} is online</span>

Props

Prop Type Default Description
position string 'top-end' top-end, top-start, bottom-end, bottom-start — logical, so end follows the reading direction
offset string|null null Nudge the badge further out (any CSS length); default centers it on the corner
scope string|null null Scoped personalization name

Slots

Slot Description
default The target being decorated
badge The thing anchored to the corner

Accessibility

  • The badge carries its own meaning. Indicator only positions it. A count needs a real name (3 unread notifications), and a decorative dot needs aria-hidden plus the state stated elsewhere — see the examples above.
  • The badge is pointer-events: none, so it never swallows a click meant for the target underneath. Anything genuinely interactive inside it (a link, a button) gets pointer events back automatically.
  • The badge is out of flow, so decorating a target never resizes it — no layout shift, no touch target shrinking.
  • RTL is automatic: placement uses logical insets, so end moves to the left corner under dir="rtl" with no extra rules.

Keyboard Interaction

This component is presentational and does not respond to keyboard input. The target and any control inside the badge keep their own keyboard behavior.

Pitfalls

  • Do not leave a bare number as the whole badge. "3" is not an accessible name — say "3 unread notifications".
  • Do not put your main action in the badge. It is a decoration on the target, not a second control competing for the same corner.
  • Do not hand-roll the absolute-corner-offset pattern. That is what this replaces — and it does not mirror in RTL.

Design Tokens

Element Token
Corner nudge --indicator-wk-offset (default 0px)

The badge's own colors and shape come from whatever you place in the slot — usually Badge.

Further Reading