Design system

Avatar & Avatar Stack

User image/initials with size variants.

Avatar Examples

Copy-ready examples for Avatar and AvatarStack (they can be used together or separately).

Avatar (content types)

Avatar supports text initials, image, and icon rendering.

Live preview

Profile placeholder

Text / Image / Icon

import Avatar from "@/packages/ui/src/_components/avatar/Avatar";

export default function Example() {
  return (
    <div style={{ display: "flex", gap: 14, flexWrap: "wrap" }}>
      <Avatar typeOfContent="text" text="John Doe" />
      <Avatar typeOfContent="img" url="/images/user.jpg" alt="User profile photo" />
      <Avatar typeOfContent="icon" iconName="Home" />
    </div>
  );
}

Avatar (sizes)

Use size to change the avatar dimensions (sm / md / lg).

Live preview

Small / Medium / Large

import Avatar from "@/packages/ui/src/_components/avatar/Avatar";

export default function Example() {
  return (
    <div style={{ display: "flex", gap: 14, alignItems: "center" }}>
      <Avatar typeOfContent="text" text="John Doe" size="small" />
      <Avatar typeOfContent="text" text="John Doe" size="medium" />
      <Avatar typeOfContent="text" text="John Doe" size="large" />
    </div>
  );
}

Avatar (surface styles)

Use style to switch the surface appearance.

Live preview

Outlined / Filled / Tonal / Elevated

import Avatar from "@/packages/ui/src/_components/avatar/Avatar";

export default function Example() {
  return (
    <div style={{ display: "flex", gap: 14, flexWrap: "wrap" }}>
      <Avatar typeOfContent="text" text="Jane Doe" style="outlined" />
      <Avatar typeOfContent="text" text="Jane Doe" style="filled" />
      <Avatar typeOfContent="text" text="Jane Doe" style="tonal" />
      <Avatar typeOfContent="text" text="Jane Doe" style="elevated" />
    </div>
  );
}

Avatar (with sub label)

Use subText to render a small label under the avatar.

Live preview

OnlineAdmin
Profile placeholder
Away

Sub label (subText)

import Avatar from "@/packages/ui/src/_components/avatar/Avatar";

export default function Example() {
  return (
    <div style={{ display: "flex", gap: 18, flexWrap: "wrap", alignItems: "center" }}>
      <Avatar typeOfContent="text" text="Jane Doe" subText="Online" />
      <Avatar typeOfContent="icon" iconName="Work" subText="Admin" />
      <Avatar typeOfContent="img" url="/images/user.jpg" alt="User profile photo" subText="Away" />
    </div>
  );
}

Avatar (states & variants)

Interactive/disabled/square + semantic variants for icon avatars.

Live preview

States and variants

import Avatar from "@/packages/ui/src/_components/avatar/Avatar";

export default function Example() {
  return (
    <div style={{ display: "flex", gap: 14, flexWrap: "wrap" }}>
      <Avatar typeOfContent="text" text="Interactive" isInteractive />
      <Avatar typeOfContent="text" text="Disabled" disabled />
      <Avatar typeOfContent="text" text="Square" isSquared />

      <Avatar typeOfContent="icon" iconName="Warning" variant="warning" />
      <Avatar typeOfContent="icon" iconName="Error" variant="danger" />
    </div>
  );
}

Avatar (controlled example)

Example using local state to swap the content type.

Live preview

Selected

Switch content type

import { useState } from "react";
import Avatar from "@/_components/avatar/Avatar";

export default function Example() {
  const [mode, setMode] = useState<"text" | "img" | "icon">("text");

  return (
    <div style={{ display: "grid", gap: 12 }}>
      <div style={{ display: "flex", gap: 10 }}>
        <button type="button" onClick={() => setMode("text")}>Text</button>
        <button type="button" onClick={() => setMode("img")}>Image</button>
        <button type="button" onClick={() => setMode("icon")}>Icon</button>
      </div>

      {mode === "text" ? <Avatar typeOfContent="text" text="Alex Kim" subText="Selected" /> : null}
      {mode === "img" ? <Avatar typeOfContent="img" url="/images/user.jpg" alt="User profile photo" subText="Selected" /> : null}
      {mode === "icon" ? <Avatar typeOfContent="icon" iconName="Person" subText="Selected" /> : null}
    </div>
  );
}

AvatarStack (basic overflow)

Render a stack and limit how many avatars are shown. Remaining avatars are summarized in a trailing element.

Live preview

1+

Horizontal stack + overflow

import Avatar from "@/packages/ui/src/_components/avatar/Avatar";
import AvatarStack from "@/packages/ui/src/_components/avatarStack/AvatarStack";

export default function Example() {
  return (
    <AvatarStack limitElementsToShow={3} size="small" directionStack="horizontal">
      {[
        <Avatar key="a" typeOfContent="text" text="John Doe" />,
        <Avatar key="b" typeOfContent="text" text="Jane Doe" />,
        <Avatar key="c" typeOfContent="text" text="Chris Doe" />,
        <Avatar key="d" typeOfContent="text" text="Sam Doe" />,
      ]}
    </AvatarStack>
  );
}

AvatarStack (vertical + density)

Use directionStack and density to control flow and spacing.

Live preview

0+
0+

Vertical stack (dense vs spaced)

import Avatar from "@/packages/ui/src/_components/avatar/Avatar";
import AvatarStack from "@/packages/ui/src/_components/avatarStack/AvatarStack";

export default function Example() {
  return (
    <div style={{ display: "grid", gap: 18 }}>
      <AvatarStack limitElementsToShow={4} size="medium" directionStack="vertical" density="dense">
        {[
          <Avatar key="a" typeOfContent="text" text="John Doe" />,
          <Avatar key="b" typeOfContent="text" text="Jane Doe" />,
          <Avatar key="c" typeOfContent="text" text="Chris Doe" />,
          <Avatar key="d" typeOfContent="text" text="Sam Doe" />,
        ]}
      </AvatarStack>

      <AvatarStack limitElementsToShow={4} size="medium" directionStack="vertical" density="spaced">
        {[
          <Avatar key="a" typeOfContent="text" text="John Doe" />,
          <Avatar key="b" typeOfContent="text" text="Jane Doe" />,
          <Avatar key="c" typeOfContent="text" text="Chris Doe" />,
          <Avatar key="d" typeOfContent="text" text="Sam Doe" />,
        ]}
      </AvatarStack>
    </div>
  );
}

AvatarStack (mixed content)

You can mix Avatar types in a single stack. isInteractive applies a stack-level modifier class.

Live preview

Profile placeholder
0+

Mixed avatars + interactive

import Avatar from "@/packages/ui/src/_components/avatar/Avatar";
import AvatarStack from "@/packages/ui/src/_components/avatarStack/AvatarStack";

export default function Example() {
  return (
    <AvatarStack limitElementsToShow={5} size="large" directionStack="horizontal" isInteractive>
      {[
        <Avatar key="a" typeOfContent="img" url="/images/user.jpg" alt="User profile photo" />,
        <Avatar key="b" typeOfContent="text" text="Jane Doe" />,
        <Avatar key="c" typeOfContent="icon" iconName="Star" variant="secondary" />,
        <Avatar key="d" typeOfContent="text" text="Chris Doe" />,
        <Avatar key="e" typeOfContent="icon" iconName="Verified" variant="success" />,
      ]}
    </AvatarStack>
  );
}

AvatarStack (disabled)

disabled adds a stack-level modifier. You can also pass disabled to each Avatar.

Live preview

1+

Disabled stack

import Avatar from "@/packages/ui/src/_components/avatar/Avatar";
import AvatarStack from "@/packages/ui/src/_components/avatarStack/AvatarStack";

export default function Example() {
  return (
    <AvatarStack limitElementsToShow={3} size="small" directionStack="horizontal" disabled>
      {[
        <Avatar key="a" typeOfContent="text" text="John Doe" disabled />,
        <Avatar key="b" typeOfContent="text" text="Jane Doe" disabled />,
        <Avatar key="c" typeOfContent="text" text="Chris Doe" disabled />,
        <Avatar key="d" typeOfContent="text" text="Sam Doe" disabled />,
      ]}
    </AvatarStack>
  );
}

On this page

Avatar Props

Avatar component that can render text initials, an image, or an icon. Optionally renders a small label below via subText.

Text initials behavior: one word => first 2 letters; 2+ words => first letter of the first two words (uppercase).

If you render an image avatar, always provide a meaningful alt for accessibility.

subText wraps the avatar into a small stack wrapper to place the label under the avatar.

Avatar props
PropTypeRequiredDefaultDescription
typeOfContent"img" | "text" | "icon"Non/aSelects what the avatar renders. Recommended: always pass this prop; otherwise the avatar renders no inner content. (Values: img, text, icon)
size"small" | "medium" | "large"No"small"Size variant (maps to --sm / --md / --lg classes). (Values: small, medium, large)
style"outlined" | "filled" | "tonal" | "elevated"No"outlined"Surface style variant. (Values: outlined, filled, tonal, elevated)
variant"primary" | "secondary" | "tertiary" | "success" | "warning" | "danger" | "info"No"primary"Semantic / color variant (also forwarded to the icon when typeOfContent='icon'). (Values: primary, secondary, tertiary, success, warning, danger, info)
isInteractivebooleanNofalseAdds an interactive modifier class (CSS-driven).
disabledbooleanNofalseAdds a disabled modifier class (CSS-driven).
isSquaredbooleanNofalseRenders a squared avatar (CSS-driven).
textstringNo"John Doe"Only used when typeOfContent='text'. Initials are generated from this string (fallback is 'John Doe').
urlstringNon/aOnly used when typeOfContent='img'. Image URL.
altstringNon/aOnly used when typeOfContent='img'. Image alt text.
iconNamestringNo"Home"Only used when typeOfContent='icon'. Icon name.
subTextstringNon/aOptional small label rendered under the avatar.

Avatar stack Props

Container component used to stack multiple <Avatar /> elements (horizontal or vertical) with optional sizing, density, and interactive/disabled states.

Overflow: after rendering the first limitElementsToShow children, a trailing element can be rendered.

Current behavior note: the implementation may render the “more” element whenever children.length > 1, even if there is no overflow. Style/condition it accordingly in your usage if needed.

Even when the stack is disabled, you can also pass disabled to each Avatar to enforce disabled styling per item.

Avatar stack props
PropTypeRequiredDefaultDescription
limitElementsToShownumberYesn/aMax number of avatar children to render in the stack. Only items with index < limitElementsToShow are rendered.
childrenReactElement<IAvatarProps, typeof Avatar>[]Yesn/aArray of <Avatar /> elements to display.
directionStack"horizontal" | "vertical"No"horizontal"Stack direction / flow. (Values: horizontal, vertical)
size"small" | "medium" | "large"No"small"Stack size modifier (affects avatar sizing via CSS). (Values: small, medium, large)
density"dense" | "spaced"Non/aOptional spacing density modifier. (Values: dense, spaced)
isInteractivebooleanNofalseAdds an interactive modifier class (CSS-driven).
disabledbooleanNofalseAdds a disabled modifier class (CSS-driven).