Badge
Display a count or status marker on its children.
1use herogpui::components::badge::{Badge, BadgeAnchor, BadgeLabel};Usage
1use herogpui::prelude::{Badge, BadgeAnchor, BadgeLabel, BadgePlacement, Color, Size};
2use gpui::prelude::*;
3
4row(vec![
5 BadgeAnchor::new()
6 .child(avatar_box(("badge-anchor", 0usize), "Jane Doe"))
7 .child(
8 Badge::new()
9 .color(Color::Danger)
10 .size(Size::Sm)
11 .child(BadgeLabel::new().child("5")),
12 )
13 .into_any_element(),
14 BadgeAnchor::new()
15 .child(avatar_box(("badge-anchor", 1usize), "Alex Brown"))
16 .child(
17 Badge::new()
18 .color(Color::Accent)
19 .size(Size::Sm)
20 .child(BadgeLabel::new().child("New")),
21 )
22 .into_any_element(),
23 BadgeAnchor::new()
24 .child(avatar_box(("badge-anchor", 2usize), "Chris Davis"))
25 .child(
26 Badge::new()
27 .color(Color::Success)
28 .size(Size::Sm)
29 .placement(BadgePlacement::BottomRight),
30 )
31 .into_any_element(),
32])Live HeroGPUI compiled to WebAssembly. Select any example without loading another WASM instance.
Anatomy
Rust types
BadgeBadgeAnchorBadgeLabel
Badge is assembled from these builders. The API reference lists each one.
Customization
Appearance builders and theme tokens Badge uses.
Styling
| Style | Description |
|---|---|
flex + items_center + justify_center + gap(px(2.)) + min_w(px(28.)) + min_h(px(28.)) + control_radius + text_size(px(12.)) + line_height(1.34) + FontWeight::MEDIUM + flex_shrink_0 + border_1(colors.background) | 28px min square, 12px medium text at the 1.34 leading, 2px gap, and the unconditional 1px page-background ring. Is a block-level flex (no inline-flex) and GPUI 0.2.2 has no background-clip, so the ring paints over the fill edge instead of clipping the fill to the padding box. |
(px(16.), px(10.), small_radius) / (px(28.), px(12.), control_radius) / (px(32.), px(14.), soft_radius) | 16px/28px/32px min squares at the 12px/24px/16px radii with 10/12/14px text; `--md` only restates the base. The radius is a step per size, not a pill, and the leadings are Tailwind's unitless multipliers resolved against each size's own text. |
relative + flex + flex_shrink_0 | Positioning wrapper; `inline-flex` is not portable, so is a block-level flex that hugs content inside a flex parent and keeps `shrink-0`. |
BadgeLabel => px(px(2.)) | Two-pixel label padding — the only horizontal padding in the badge sheet; the badge itself has none. |
muted_foreground() => role.soft_foreground(colors.foreground); colors.default.foreground for default | The five color classes only relabel the badge; they set no fill. The soft foreground is the muted label color shared by secondary and soft. |
BadgeVariant::Primary => paint() => (role.color, role.foreground) | The base tokens hold until a compound rule fills with the role; resolves the whole pair in `paint()`. |
BadgeVariant::Secondary => paint() => (colors.default.color, muted_foreground()) | Keeps the base `--badge-bg: var(--default)` whatever the color; only the label follows the color class. |
BadgeVariant::Soft => paint() => (role.soft(), role.soft_foreground(colors.foreground)) | The soft compound cells fill with the per-role soft mix, lighter than the role itself, and keep the soft label. |
BadgePlacement::TopRight => top(-size/4) + right(-size/4) | Corner overlay overhanging a quarter of the badge's own box (4px sm, 7px md, 8px lg). GPUI 0.2.2 has no div-level transform and a percentage inset would resolve against the containing block, so insets the corner by -size/4 — a quarter of the min box; a badge grown past its min box overhangs less than v3's translate would, and only dot and min-box-fitting badges are exact. |
BadgePlacement::TopLeft => top(-size/4) + left(-size/4) | Same quarter-box overhang at the top-left corner, with the same min-box approximation as top-right. |
BadgePlacement::BottomRight => bottom(-size/4) + right(-size/4) | Same quarter-box overhang at the bottom-right corner, with the same min-box approximation. |
BadgePlacement::BottomLeft => bottom(-size/4) + left(-size/4) | Same quarter-box overhang at the bottom-left corner, with the same min-box approximation. |
API reference
Builders
| Builder | Type | Default | Description |
|---|---|---|---|
ParentElement:: | AnyElement | — | Badge content (text, number, or icon); omitted children render the dot badge. Auto-wraps plain string and number children in `Badge.Label`; GPUI elements carry no type a parent can intercept, so the wrap is explicit via `BadgeLabel` and bare `Badge` children draw without the label padding. |
color( | Color | Color:: | Color role of the badge; fills and label colors resolve through the badge.css cascade. |
variant( | BadgeVariant | BadgeVariant:: | Visual style variant: solid role fill, default fill with a colored label, or the soft mix. |
size( | Size | Size:: | Sets the min square, radius step, and type size of the badge. |
placement( | BadgePlacement | BadgePlacement:: | Corner of the anchor the badge points at. |
Parts
| Part | Description |
|---|---|
Badge | Root indicator on the `.badge` BEM classes: an absolutely positioned min-box square (`min-h-7 min-w-7` by size) with a radius step per size, medium text, a 2px gap, and the unconditional 1px page-background ring; empty children render the dot. Is a block-level flex (no inline-flex) and approximates v3's corner translate with a fixed inset, so it is Partial. |
BadgeAnchor | Positioning wrapper on the `.badge-anchor` BEM class: `relative inline-flex shrink-0`, carrying the anchored element plus the badge. GPUI 0.2.2 has no inline-flex, so the wrapper hugs its content only inside a flex parent; the ported `flex_shrink_0` keeps it from compressing in an overflowing row. |
BadgeLabel | Label text slot on the `.badge__label` BEM class — `px-0.5`, the only horizontal padding in the badge sheet. Auto-wraps plain string and number children of the root here; makes that wrap explicit with the `BadgeLabel` part. |