Skip to content

LayrzBadge

Kenny Mochizuki Escalona edited this page Aug 28, 2026 · 1 revision

LayrzBadge

A notification indicator overlaid on a corner of any widget.

Metadata Predecessor: None — no ThemedBadge exists in layrz_theme Phase: M6 (pulled forward as an M4/M5 prerequisite) Domain: Feedback Primitive: Hand-rolled (Stack/Positioned, no Material Badge) Status: Merged · Review required.


Overview

LayrzBadge overlays a small indicator on a corner of child without changing child's layout footprint — the badge paints on top via Positioned, so wrapping any widget with a badge never reflows the surrounding layout.

LayrzBadge(
  label: 'Notifications',
  count: 3,
  child: LayrzButton(icon: MdiIcons.bell, style: LayrzButtonStyle.text, onTap: openNotifications),
)

Content follows three forms, in priority order:

  1. count — a number, formatted via formatCount.
  2. icon — an icon glyph, used only when count is null.
  3. Bare dot — when both count and icon are null, the badge renders as a plain presence dot.

LayrzBadgeVisual is the bare, unpositioned form used directly by LayrzBadge; use it standalone when a badge needs to sit inline in a Row rather than overlapping another widget (e.g. LayrzLayoutRailItem places one inline next to a label, not overlapping it).

Overflow: counts above 99 render as 99+

kLayrzBadgeMaxCount is 99. Any count from 0–99 renders as its literal decimal form; anything above 99 renders as exactly 99+ — never a raw large number, and not a configurable cap. Two digits keeps the badge narrow enough to sit over an icon without distorting it. Negative values clamp to 0 — a badge has no concept of negative count.

label is required, deliberately

LayrzBadge.label forces every caller to supply a human-readable description of what the badge signifies (e.g. 'Notifications', 'Unread messages') — not the raw count, which the widget appends itself. This exists because a bare "3" read aloud next to an unlabelled icon is meaningless; label is what turns it into "Notifications, 3 unread."

LayrzBadge merges child's semantics with the badge's own into a single announced node — the child's own semantics (and the badge visual's auto-generated text/icon semantics) are excluded so nothing duplicates into the merged announcement.

LayrzBadgeVisual, by contrast, intentionally does not attach its own Semantics node — a caller placing it directly in a Row (rather than via LayrzBadge) is responsible for merging its own semantics the same way.

API

LayrzBadge

Parameter Type Notes
child Widget Required. The widget the badge overlays. Never affects child's layout size.
label String Required. Human-readable description of what the badge signifies — never the raw count, which is appended automatically. See above.
count int? The number to display. Formatted via LayrzBadgeVisual.formatCount. When both this and icon are null, renders as a bare dot.
icon IconData? Icon glyph. Ignored when count is non-null.
type LayrzBadgeType Defaults to LayrzBadgeType.danger (the conventional color for notification counts).
color Color? Explicit background color, overriding type's resolved token.
alignment LayrzBadgeAlignment Defaults to LayrzBadgeAlignment.topRight. Which corner of child the badge anchors to.
isVisible bool Defaults to true. When false, only child renders — the badge visual and its overlay are not painted at all, but the widget tree stays stable (e.g. for toggling based on an unread count dropping to zero).

LayrzBadgeVisual

The bare, standalone visual — no positioning, no host sizing.

Parameter Type Notes
count int? Same semantics as LayrzBadge.count. Takes precedence over icon if both are set.
icon IconData? Same semantics as LayrzBadge.icon.
type LayrzBadgeType Defaults to LayrzBadgeType.danger.
color Color? Explicit background color override.

LayrzBadgeVisual.formatCount(int count) is a static helper: 0–99 render literally, values above 99 render as 99+, negative values clamp to 0.

LayrzBadgeType (enum)

info · success · warning · danger (default) · context · custom — mirrors LayrzChipType's vocabulary exactly, so semantic-color selection reads the same way across chips and badges. custom honors the constructor's color parameter, falling back to tokens.colors.primary.shade500 if both are unset.

LayrzBadgeAlignment (enum)

topRight (default) · topLeft · bottomRight · bottomLeft — names the four corners rather than exposing a raw Alignment, so a call site reads as intent.

LayrzBadgeStyleSpec

An immutable, paint-only spec (backgroundColor, contentColor) resolved via LayrzBadgeStyleSpec.resolve(type:, color:, tokens:). contentColor is always derived from the resolved background via contrastColor, so number/icon content has adequate contrast regardless of the chosen accent.

Design tokens used

  • Colors: info/success/warning/danger/contextual (background by type), primary (custom-type fallback).
  • Spacing: sp3 (badge diameter), sp1 (horizontal padding for count/icon content).
  • Typography: label (count text, 11px, weight 600).

Related documents

Component Catalog, Milestone 6


Last updated: 2026-08-28 (first documentation of this widget)

Clone this wiki locally