Skip to content
Component installs need the registry setup
VegaStack Design

Space Avatar

A space's tile — icon or initial on its hue, a lock when private or personal — and SpaceOption, the space row for pickers.

Status
stable
Since
0.23.112
Accessibility pattern
decorative by default; aria-label makes it an image

Last updated

Install

Add Space Avatar from the VegaStack registry. The CLI verifies the item's integrity hash before writing it.

pnpm dlx shadcn@latest add @vegastack/space-avatar

The same command installs the registry items it composes: @vegastack/avatar, @vegastack/badge.

Usage

import { SpaceAvatar, SpaceOption } from "@/components/ui/space-avatar";

<SpaceOption
  name="Sales"
  secondary="Private · 8 members"
  avatar={
    <SpaceAvatar space={{ name: "Sales", hue: "green", access: "private" }} />
  }
/>;

A space is drawn one way everywhere — the sidebar, a space picker, a Move to… menu, a share dialog's general access row: a rounded-square tile (a person is a circle) with the space's icon, else its first initial, on its hue (one of the ten tag hues). A private space wears a small lock at its corner; a personal space — one person's own Private area — is the lock itself on the muted tile.

Scope

  • Owns: the tile, its hue, the initial or icon, the private lock and the personal tile; the SpaceOption row.
  • Does not own: the space's data, routing, or the picker around a row — compose SpaceOption in a SearchableSelect, a DropdownMenuItem or a list.
  • Compose with: PersonAvatar (people and teams), SearchableSelect, DropdownMenu.

Anatomy

SpaceAvatar — data-slot="space-avatar" | "space-avatar-lock"
SpaceOption — data-slot="space-option" | "space-option-badge"

Examples

Sizes

xs (20px, a sidebar row), sm (24px, the default), default (32px) and lg (40px). The lock and the icon scale with the tile.

SpaceOption

The space twin of PersonOption: the tile, then the name over a smaller muted line, and an optional badge such as "Joined".

  • PrivateOnly you
  • GeneralJoinedEveryone · 42 members
  • SalesPrivate · 8 members

API Reference

SpaceAvatar

PropTypeDefaultDescription
space*Space—The space.
size"default" | "lg" | "sm" | "xs""sm"Tile size: 20, 24, 32 or 40px.

Data attributes and CSS variables on SpaceAvatar

AttributeValues
data-accessmirrors a prop or state value
data-sizemirrors a prop or state value
data-slot"space-avatar" | "space-avatar-lock"

Space

PropTypeDefaultDescription
access*"open" | "personal" | "private"—Who can open it. open — anyone in the workspace; private — members only (a lock at the corner); personal — one person's own Private area (the lock is the tile).
name*string—The space's name; its first letter is the tile when there is no icon.
hueAvatarHue—The space's colour — one of the ten tag hues; none is the muted tile.
iconReact.ReactNode—An icon drawn on the tile in place of the initial — usually a lucide icon.

SpaceOption

PropTypeDefaultDescription
name*React.ReactNode—The space's name.
avatarReact.ReactNode—A leading SpaceAvatar.
badgeReact.ReactNode—A status beside the name, such as "Joined" — a string is a small muted outline badge.
secondaryReact.ReactNode—The smaller, muted second line — such as "Private · 8 members".

Data attributes and CSS variables on SpaceOption

AttributeValues
data-slot"space-option" | "space-option-badge"

Accessibility

  • The tile is decorative (aria-hidden) because the space's name sits beside it. Pass aria-label — "Sales, private" — to make a standalone tile an image of its own.
  • Private is never colour alone: it is the lock glyph. Say "Private" in the row's text as well (secondary or badge) where it matters.
  • Nothing here takes focus; there are no keys to learn.
KeyAction
—Not focusable; the host row is the control
ContractStates tested
Behaviourinitial, icon, hue, private, personal
Accessibilitydecorative, labelled-image, browser-accessibility-test
Visualdefault, hue, private, personal

Do / Don't

Do
Draw every space with SpaceAvatar and list spaces with SpaceOption, so a space reads the same in the sidebar, pickers and dialogs.
Don't
Reuse PersonAvatar or a bare icon for a space — the rounded square and the lock are how a space reads as a space.
Do
Use access='personal' only for a person's own Private area.
Don't
Mark a shared members-only space personal; it is private, with the corner lock.

On this page