Avatar
Overviewimport { Avatar, AvatarGroup, CompactAvatarGroup, FlatAvatar } from '@nili/ui';This is the library’s own overview page, rendered live. Switch the language or the theme in the header and it follows.
Sizes
Nine sizes, 80px down to 16px. name is required: an avatar with no name is either an unlabelled image or a decorative blob, and only the call site knows which. Pass an empty string to mark it decorative.
import { Avatar } from "@nili/ui"
export function Example() {
return (
<>
<Avatar size="3xl" name="Ada Lovelace" />
<Avatar size="xl" name="Ada Lovelace" />
<Avatar size="md" name="Ada Lovelace" />
<Avatar size="2xs" name="Ada Lovelace" />
</>
)
}Fallbacks
With no image, initials are derived from name. Override them with initials, replace them entirely with fallback, or use placeholder for the silhouette — an account with no photo and no name worth initialising.
import { Avatar } from "@nili/ui"
export function Example() {
return (
<>
{/* initials from the name */}
<Avatar name="Ada Lovelace" />
{/* explicit initials */}
<Avatar name="محمد رضایی" initials="مر" />
{/* an image, with initials behind it */}
<Avatar name="Grace Hopper" src="/avatars/grace.png" />
{/* the silhouette */}
<Avatar name="" placeholder />
</>
)
}Tones
Figma has no colour axis on Avatar — the tones are an extension, and they exist for groups: a stack of six identical grey circles is unreadable, and tinting them is the cheapest way to tell them apart before the images load.
import { Avatar } from "@nili/ui"
export function Example() {
return (
<>
<Avatar name="Ada Lovelace" tone="soft" />
<Avatar name="Grace Hopper" tone="blue" />
<Avatar name="Radia Perlman" tone="pink" />
</>
)
}Statuses
A marker at the top and one at the bottom. Give it a statusLabel — a coloured dot has no accessible name. Not every size can carry one; the small end drops the marker rather than drawing an illegible speck.
import { Avatar, Icon } from "@nili/ui"
import { RiBuilding2Line } from "@remixicon/react"
export function Example() {
return (
<>
<Avatar name="Ada Lovelace" bottomStatus="online" statusLabel="Online" />
<Avatar name="Ada Lovelace" bottomStatus="busy" statusLabel="Busy" />
<Avatar name="Ada Lovelace" topStatus="verified" statusLabel="Verified" />
<Avatar
name="Apex Financial"
bottomStatus="company"
companyIcon={<Icon icon={RiBuilding2Line} />}
statusLabel="Company account"
/>
</>
)
}Avatar Group
A stack with a “+N” chip. max caps how many are drawn; overflowCount overrides the computed remainder when the list you hold is only a page of a larger set.
import { AvatarGroup } from "@nili/ui"
const team = [
{ id: "a", name: "Ada Lovelace", tone: "blue" },
{ id: "b", name: "Grace Hopper", tone: "purple" },
{ id: "c", name: "Katherine Johnson", tone: "green" },
{ id: "d", name: "Radia Perlman", tone: "pink" },
]
export function Example() {
return (
<>
<AvatarGroup items={team} label="Team members" />
<AvatarGroup items={team} max={3} label="Team members" />
<AvatarGroup items={team} max={2} overflowCount={24} label="Team" />
</>
)
}Compact Avatar Group
A denser stack in a pill — for table rows and list items, where Avatar Group's spacing is too generous. Three sizes, two treatments.
import { CompactAvatarGroup } from "@nili/ui"
export function Example() {
return (
<>
<CompactAvatarGroup items={team} max={3} label="Assignees" />
<CompactAvatarGroup items={team} max={3} appearance="stroke" label="Assignees" />
</>
)
}Flat Avatar
The illustrated avatar, built from interchangeable Figma parts. Indices wrap, so any number is a valid and deterministic choice — handy for deriving a stable avatar from a user id.
import { FlatAvatar } from "@nili/ui"
export function Example() {
return (
<>
<FlatAvatar size="2xl" background={4} hair={2} outfit={1} label="" />
{/* derived from an id — same user, same face, every time */}
<FlatAvatar
size="xl"
background={userId % 8}
hair={userId % 6}
eye={userId % 4}
label=""
/>
</>
)
}Avatar
extends Omit< ComponentPropsWithoutRef<'div'>, 'color' | 'children' >
Variant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| size | 3xl | 2xl | xl | lg | md | sm | xs | 2xs | 3xs | md |
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | |
| tone | soft | yellow | blue | green | pink | purple | red | soft | Background/foreground pair for the fallback surface. |
| name* | string | — | Accessible name. Required, because an avatar with no name is either an unlabelled image or a decorative blob, and only the call site knows which. Pass `''` to mark it decorative when the person's name is already visible next to it. |
| src | string | — | |
| onImageError | () => void | — | |
| initials | string | — | Initials to show when there is no image. Derived from `name` if omitted. |
| fallback | ReactNode | — | Arbitrary fallback content — overrides `initials`. |
| topStatus | verified | pin | favorite | add | remove | notification | — | |
| bottomStatus | online | offline | busy | away | company | — | |
| companyIcon | ReactNode | — | Rendered when `bottomStatus` is `'company'`. |
| statusLabel | string | — | Accessible name for the status marker, e.g. `'Online'`. |
| placeholder | boolean | false | Figma's "Icon" style: a person silhouette on the tone colour, for accounts with no photo and no name worth initialising. |
AvatarGroup
extends Omit< ComponentPropsWithoutRef<'div'>, 'children' >
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | |
| size | 3xl | 2xl | xl | lg | md | sm | xs | 2xs | 3xs | md | |
| items* | AvatarGroupItem[] | — | |
| max | number | — | Render at most this many avatars, then a "+N" chip. |
| overflowCount | number | — | Overrides the computed overflow count. |
| label | string | — | Accessible label for the whole stack, e.g. `'Team members'`. |
AvatarSurface
internalVariant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| tone | soft | yellow | blue | green | pink | purple | red | soft |
CompactAvatarGroup
extends Omit< ComponentPropsWithoutRef<'div'>, 'children' >
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | |
| items* | AvatarGroupItem[] | — | |
| size | sm | xs | 2xs | sm | 40px, 32px or 24px — the three sizes the design defines here. |
| appearance | stroke | default | default | |
| max | number | — | |
| label | string | — |
FlatAvatar
extends Omit< ComponentPropsWithoutRef<'svg'>, 'children' >
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | |
| size | 3xl | 2xl | xl | lg | md | sm | xs | 2xs | 3xs | md | An Avatar size token or a pixel size. |
| background | number | 4 | Zero-based variant index of each Figma part. |
| face | number | 0 | |
| outfit | number | 0 | |
| hair | number | 0 | |
| eye | number | 0 | |
| cheek | number | null | 0 | Optional parts: omit (or `null`) to leave them off. |
| mouth | number | 0 | |
| glasses | number | null | — | |
| hat | number | null | — | |
| label | string | — | Accessible name. Without it the avatar is decorative. |