Skip to content
PorabuildHeroGPUI component library
v0.14.0 · Apache-2.0

Data display

Badge

Display a count or status marker on its children.

Rust
use herogpui::components::badge::{Badge, BadgeAnchor, BadgeLabel};

Badge on docs.rsSource at v0.14.0

Usage

Showing Usage, live: HeroGPUI compiled to WebAssembly. The canvas has no accessibility tree; each example's description and code below carry the same information.

Usage

An element expression with window: &mut Window and cx: &mut App in scope.

Rust
use herogpui::prelude::{Avatar, Badge, BadgeAnchor, BadgeLabel, BadgePlacement, Color, Size};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{AnyElement, px};
use herogpui::gpui;

gpui::div()
    .flex()
    .flex_wrap()
    .items_center()
    .justify_center()
    .gap(px(12.))
    .children(vec![
        BadgeAnchor::new()
            .child(avatar_box(("badge-anchor", 0usize), "Jane Doe"))
            .child(
                Badge::new()
                .color(Color::Danger)
                .size(Size::Sm)
                .text_size(px(14.))
                // `radius(px)` replaces the size step's
                // corner; the step stays the fallback.
                .radius(px(4.))
                .child(BadgeLabel::new().child("5")),
            )
            .into_any_element(),
        BadgeAnchor::new()
            .child(avatar_box(("badge-anchor", 1usize), "Alex Brown"))
            .child(
                Badge::new()
                    .color(Color::Accent)
                    .size(Size::Sm)
                    .child(BadgeLabel::new().child("New")),
            )
            .into_any_element(),
        BadgeAnchor::new()
            .child(avatar_box(("badge-anchor", 2usize), "Chris Davis"))
            .child(
                Badge::new()
                    .color(Color::Success)
                    .size(Size::Sm)
                    .placement(BadgePlacement::BottomRight),
            )
            .into_any_element(),
    ])

Also calls avatar_box (included when you copy).

Sizes

An element expression with window: &mut Window and cx: &mut App in scope.

Rust
use herogpui::prelude::{Avatar, Badge, BadgeAnchor, BadgeLabel, Size};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{AnyElement, px};
use herogpui::gpui;

gpui::div()
    .flex()
    .flex_wrap()
    .items_center()
    .justify_center()
    .gap(px(12.))
    .children(Size::ALL
        .iter()
        .map(|sz| {
            BadgeAnchor::new()
                .child(avatar_box(("badge-anchor", 1usize), "Alex Brown"))
                .child(
                    Badge::new()
                        .size(*sz)
                        .child(BadgeLabel::new().child("5")),
                )
                .into_any_element()
        }))

Also calls avatar_box (included when you copy).

Dot Badge

An element expression with window: &mut Window and cx: &mut App in scope.

Rust
use herogpui::prelude::{Avatar, Badge, BadgeAnchor, BadgeLabel, Color};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{AnyElement, px};
use herogpui::gpui;

gpui::div()
    .flex()
    .flex_wrap()
    .items_center()
    .justify_center()
    .gap(px(12.))
    .children(Color::ALL
        .iter()
        .map(|c| {
            BadgeAnchor::new()
                .child(avatar_box(("badge-anchor", 2usize), "Chris Davis"))
                .child(Badge::new().color(*c))
                .into_any_element()
        }))

Also calls avatar_box (included when you copy).

With Content

An element expression with window: &mut Window and cx: &mut App in scope.

Rust
use herogpui::prelude::{ActiveTheme, Avatar, Badge, BadgeAnchor, BadgeLabel, Color, Size, icons};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{AnyElement, px};
use herogpui::gpui;

gpui::div()
    .flex()
    .flex_wrap()
    .items_center()
    .justify_center()
    .gap(px(12.))
    .children(vec![
        BadgeAnchor::new()
            .child(avatar_box(("badge-anchor", 3usize), "Jane Doe"))
            .child(
                Badge::new()
                    .color(Color::Danger)
                    .size(Size::Sm)
                    .child(BadgeLabel::new().child("5")),
            )
            .into_any_element(),
        BadgeAnchor::new()
            .child(avatar_box(("badge-anchor", 4usize), "Alex Brown"))
            .child(
                Badge::new()
                    .color(Color::Accent)
                    .child(BadgeLabel::new().child("NEW")),
            )
            .into_any_element(),
        BadgeAnchor::new()
            .child(avatar_box(("badge-anchor", 5usize), "Chris Davis"))
            .child(
                Badge::new().color(Color::Success).child(
                    gpui::svg()
                        .size(px(10.))
                        .path(icons::CHECK)
                        .text_color(cx.colors().success.foreground),
                ),
            )
            .into_any_element(),
    ])

Also calls avatar_box (included when you copy).

Variants

An element expression with window: &mut Window and cx: &mut App in scope.

Rust
use herogpui::prelude::{Avatar, Badge, BadgeAnchor, BadgeLabel, BadgeVariant, Color};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{AnyElement, px};
use herogpui::gpui;

gpui::div()
    .flex()
    .flex_wrap()
    .items_center()
    .justify_center()
    .gap(px(12.))
    .children(BadgeVariant::ALL
        .iter()
        .map(|v| {
            BadgeAnchor::new()
                .child(avatar_box(("badge-anchor", 6usize), "Jane Doe"))
                .child(
                    Badge::new()
                        .color(Color::Accent)
                        .variant(*v)
                        .child(BadgeLabel::new().child("5")),
                )
                .into_any_element()
        }))

Also calls avatar_box (included when you copy).

Colors

An element expression with window: &mut Window and cx: &mut App in scope.

Rust
use herogpui::prelude::{Avatar, Badge, BadgeAnchor, BadgeLabel, Color};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{AnyElement, px};
use herogpui::gpui;

gpui::div()
    .flex()
    .flex_wrap()
    .items_center()
    .justify_center()
    .gap(px(12.))
    .children(Color::ALL
        .iter()
        .map(|c| {
            BadgeAnchor::new()
                .child(avatar_box(("badge-anchor", 7usize), "Alex Brown"))
                .child(
                    Badge::new()
                        .color(*c)
                        .child(BadgeLabel::new().child("5")),
                )
                .into_any_element()
        }))

Also calls avatar_box (included when you copy).

Placements

An element expression with window: &mut Window and cx: &mut App in scope.

Rust
use herogpui::prelude::{Avatar, Badge, BadgeAnchor, BadgeLabel, BadgePlacement, Color};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{AnyElement, px};
use herogpui::gpui;

gpui::div()
    .flex()
    .flex_wrap()
    .items_center()
    .justify_center()
    .gap(px(12.))
    .children(vec![
        // No children is v3's dot badge.
        BadgeAnchor::new()
            .child(avatar_box(("badge-anchor", 8usize), "Chris Davis"))
            .child(Badge::new().color(Color::Success))
            .into_any_element(),
        BadgeAnchor::new()
            .child(avatar_box(("badge-anchor", 9usize), "Jane Doe"))
            .child(
                Badge::new()
                    .placement(BadgePlacement::BottomRight)
                    .child(BadgeLabel::new().child("9")),
            )
            .into_any_element(),
        BadgeAnchor::new()
            .child(avatar_box(("badge-anchor", 10usize), "Alex Brown"))
            .child(
                Badge::new()
                    .placement(BadgePlacement::TopLeft)
                    .child(BadgeLabel::new().child("New")),
            )
            .into_any_element(),
        // A long label grows the badge past its min box,
        // and the corner overhang follows the grown box —
        // a quarter of it, per the pinned translate.
        BadgeAnchor::new()
            .child(avatar_box(("badge-anchor", 11usize), "Chris Davis"))
            .child(
                Badge::new()
                    .placement(BadgePlacement::BottomLeft)
                    .child(BadgeLabel::new().child("999+")),
            )
            .into_any_element(),
    ])

Also calls avatar_box (included when you copy).

Helpers used by these examples

Plain functions over the public API, defined once here and copied with each example that calls them.

avatar_box
/// A neutral block used as the child of badge demos.
/// The anchor every v3 Badge example uses: an `Avatar` with initials behind
/// the badge. Upstream loads three CDN portraits and falls back to
/// `JD`/`AB`/`CD`; the gallery makes no network calls, so the fallback shows.
fn avatar_box(id: impl Into<gpui::ElementId>, name: &'static str) -> AnyElement {
    Avatar::new(id).name(name).into_any_element()
}

Anatomy

Rust types

BadgeBadgeAnchorBadgeLabel

Badge is assembled from these builders. The API reference lists each one.

Customization

Shared appearance belongs on ThemeBuilder::components and .recipe("name"). Typed builders change how Badge looks at one call site. Every builder also carries sx for placement, width and flex: it takes GPUI's own styling methods and refines them over the component's root after the theme, so an instance override wins. Behaviour builders live in the API reference below.

Styling

Badge styling
MethodValuesDescription
color(Color)Color::Default | Color::Accent | Color::Success | Color::Warning | Color::DangerColor role of the badge; fills and label colors resolve through the badge.css cascade.
variant(BadgeVariant)BadgeVariant::Primary | BadgeVariant::Secondary | BadgeVariant::SoftVisual style variant: solid role fill, default fill with a colored label, or the soft mix.
size(Size)Size::Sm | Size::Md | Size::LgSets the min square, radius step, and type size of the badge.
placement(BadgePlacement)BadgePlacement::TopRight | BadgePlacement::TopLeft | BadgePlacement::BottomRight | BadgePlacement::BottomLeftCorner of the anchor the badge points at.
Rust
// The one slot for caller-owned low-level styling: GPUI's
// styling methods, refined over the root element last.
.sx(|el| {
    el.bg(gpui::rgba(0xffa500ff))             // background
        .text_color(gpui::rgba(0x000000ff))   // text
        .w(gpui::px(13.))                     // size
        .h(gpui::px(12.))
})

API reference

Against HeroUI v3.2.6: 6 entries ported, 4 partial, 3 not ported. Partial rows are marked in the tables; entries not ported are listed under each table with the reason.

Builders

Badge builders
BuilderValuesDefaultDescription
ParentElement::extendPartialAnyElement—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::Default | Color::Accent | Color::Success | Color::Warning | Color::DangerColor::DefaultColor role of the badge; fills and label colors resolve through the badge.css cascade.
variant(BadgeVariant)BadgeVariant::Primary | BadgeVariant::Secondary | BadgeVariant::SoftBadgeVariant::PrimaryVisual style variant: solid role fill, default fill with a colored label, or the soft mix.
size(Size)Size::Sm | Size::Md | Size::LgSize::MdSets the min square, radius step, and type size of the badge.
placement(BadgePlacement)BadgePlacement::TopRight | BadgePlacement::TopLeft | BadgePlacement::BottomRight | BadgePlacement::BottomLeftBadgePlacement::TopRightCorner of the anchor the badge points at.
Not ported3 HeroUI entries not ported
Badge builders not ported
HeroUI v3Why it is not ported
Badge.classNameFor the root element.
Badge.Anchor.classNameFor the anchor wrapper.
Badge.Label.classNameFor the label slot.

Parts

Badge parts
PartDescription
BadgeRoot 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. The corner translate resolves from the badge's laid-out box at prepaint (`PlacedBadge`), so a label grown past the min box overhangs a quarter of its grown box; v3's `inline-flex` blockifies to `flex` under the placement classes' absolute positioning, which is what renders.
BadgeAnchorPartialPositioning wrapper on the `.badge-anchor` BEM class: `relative inline-flex shrink-0`, carrying the anchored element plus the badge. Gpui-pre 0.3.3 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.
BadgeLabelLabel 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.