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
- 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-avatarThe 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
SpaceOptionrow. - Does not own: the space's data, routing, or the picker around a row — compose
SpaceOptionin aSearchableSelect, aDropdownMenuItemor a list. - Compose with:
PersonAvatar(people and teams),SearchableSelect,DropdownMenu.
Anatomy
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
- GeneralEveryone · 42 members
- SalesPrivate · 8 members
API Reference
SpaceAvatar
| Prop | Type | Default | Description |
|---|---|---|---|
space* | Space | — | The space. |
size | "default" | "lg" | "sm" | "xs" | "sm" | Tile size: 20, 24, 32 or 40px. |
Data attributes and CSS variables on SpaceAvatar
| Attribute | Values |
|---|---|
data-access | mirrors a prop or state value |
data-size | mirrors a prop or state value |
data-slot | "space-avatar" | "space-avatar-lock" |
Space
| Prop | Type | Default | Description |
|---|---|---|---|
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. |
hue | AvatarHue | — | The space's colour — one of the ten tag hues; none is the muted tile. |
icon | React.ReactNode | — | An icon drawn on the tile in place of the initial — usually a lucide icon. |
SpaceOption
| Prop | Type | Default | Description |
|---|---|---|---|
name* | React.ReactNode | — | The space's name. |
avatar | React.ReactNode | — | A leading SpaceAvatar. |
badge | React.ReactNode | — | A status beside the name, such as "Joined" — a string is a small muted outline badge. |
secondary | React.ReactNode | — | The smaller, muted second line — such as "Private · 8 members". |
Data attributes and CSS variables on SpaceOption
| Attribute | Values |
|---|---|
data-slot | "space-option" | "space-option-badge" |
Accessibility
- The tile is decorative (
aria-hidden) because the space's name sits beside it. Passaria-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
(
secondaryorbadge) where it matters. - Nothing here takes focus; there are no keys to learn.
| Key | Action |
|---|---|
| — | Not focusable; the host row is the control |
| Contract | States tested |
|---|---|
| Behaviour | initial, icon, hue, private, personal |
| Accessibility | decorative, labelled-image, browser-accessibility-test |
| Visual | default, hue, private, personal |