Redpanda UIRedpanda UI

Dot Group

A positioning container that pins indicator dots to the corners of content elements, with optional overflow handling and standalone stacking mode.

Made by eblairmckee

Installation

Loading component...

Usage

import { DotGroup } from "@/components/redpanda-ui/dot-group"
import { StatusDot } from "@/components/redpanda-ui/status-dot"
import { Badge } from "@/components/redpanda-ui/badge"

{/* Position dots on content */}
<DotGroup content={<Badge variant="neutral-inverted">kafka</Badge>} size="sm">
  <StatusDot variant="error" />
  <StatusDot variant="warning" />
</DotGroup>

{/* Standalone stacking (no content) */}
<DotGroup size="sm">
  <StatusDot variant="error" />
  <StatusDot variant="warning" />
</DotGroup>

When to use

Use DotGroup when:

  • Positioning indicator dots on a badge, avatar, or other content element
  • Displaying multiple status or count indicators that need compact stacking
  • You need to truncate many indicators to a visible subset (maxVisible prop)

Don't use DotGroup when:

  • You only have a single indicator without content to attach it to (use StatusDot or CountDot directly)
  • You need a label alongside the indicator (use StatusBadge)
  • On a StatusBadge — it already composes StatusDot internally

Modes

Content positioning mode

When content is provided, DotGroup wraps the content in a relative container and positions the dots at the specified corner. This is the primary use case.

<DotGroup content={<Badge variant="neutral-inverted">Service</Badge>} size="sm">
  <StatusDot variant="error" />
</DotGroup>

Standalone mode

Without content, DotGroup renders dots in a horizontal stack with overlapping negative margins. This is useful for inline indicator groups.

<DotGroup size="sm">
  <StatusDot variant="error" />
  <StatusDot variant="warning" />
</DotGroup>

Pattern: Same-type grouping

DotGroup is designed for same-type indicators only. Never mix StatusDot and CountDot in the same group. This ensures consistent sizing and visual weight.

// StatusDot group
<DotGroup content={<Badge variant="neutral-inverted">kafka</Badge>} size="sm">
  <StatusDot variant="error" />
  <StatusDot variant="warning" />
</DotGroup>

// CountDot group
<DotGroup content={<Badge variant="neutral-inverted">broker-0</Badge>} size="sm">
  <CountDot count={5} variant="warning" />
  <CountDot count={2} variant="error" />
</DotGroup>

Pattern: Overflow

When maxVisible is set and children exceed it, DotGroup renders the first N dots followed by a + icon signaling that more indicators exist. The icon sizes and contrasts automatically with the dots.

<DotGroup content={<Badge variant="neutral-inverted">events</Badge>} maxVisible={3} size="sm">
  <StatusDot variant="error" />
  <StatusDot variant="warning" />
  <StatusDot variant="info" />
  <StatusDot variant="success" />
  <StatusDot variant="disabled" />
</DotGroup>
{/* Shows the first 3 dots + overflow indicator */}

Anatomy

Content positioning mode
┌──────────────────────────────────┐
│                        [●][●]   │  ← absolute positioned at corner
│  Badge Label                    │
│                                 │
└──────────────────────────────────┘

Standalone mode
[●][●][●]  ← overlapping inline indicators with ring separation

API Reference

DotGroup

PropTypeDefaultDescription
contentReactNode?Element to position dots relative to
position"top-right" | "top-left" | "bottom-right" | "bottom-left" | "top" | "bottom" | "left" | "right""top-right"Position for dots when using content mode (corners or edge-centers)
size"xxs" | "xs" | "sm" | "md" | "lg""md"Controls dot overlap spacing
maxVisiblenumber?Maximum dots to show; overflow renders a + icon
testIdstring?Test ID for visual regression testing
classNamestring?Additional CSS classes

Credits

  • Follows the overlapping stack pattern from AvatarGroup but simplified for indicator use cases.
  • Designed to compose with StatusDot and CountDot.

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested b…#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • minorv0.3.0Add theme-provider component to the registry with documentation and tests. Includes playground type improvements (export RegistryItem, remove as-const boilerplate) and docs site dark mode border color fix.#109
See full history →
Built by malinskibeniamin. The source code is available on GitHub.

On this page