Displays a user’s profile image, falling back to initials (derived from name) or a generic person icon when no image is provided or the image fails to load. Inherits panel surface props (background, border, radius, shadow, …) so it can blend into any context.
Pass src to render the image. When src is missing or fails to load, the avatar derives initials from name — or renders a user icon when neither is provided.
---
import Avatar from "../Avatar.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "md", direction: "row", align: "center" })}>
<Avatar
name="Ada Lovelace"
src="https://i.pravatar.cc/96?u=ada"
alt="Ada Lovelace"
/>
<Avatar name="Alan Turing" />
<Avatar />
</div>Four sizes (xs, sm, md, lg) matching the button scale — so an avatar and a button of the same size align perfectly.
---
import Avatar from "../Avatar.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div
class={stack({
gap: "md",
direction: "row",
align: "center",
flexWrap: "wrap",
})}
>
<Avatar size="xs" name="Ada Lovelace" />
<Avatar size="sm" name="Ada Lovelace" />
<Avatar size="md" name="Ada Lovelace" />
<Avatar size="lg" name="Ada Lovelace" />
</div>Circle (default) or square with a rounded corner.
---
import Avatar from "../Avatar.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "md", direction: "row", align: "center" })}>
<Avatar
shape="circle"
name="Ada Lovelace"
src="https://i.pravatar.cc/96?u=ada"
/>
<Avatar
shape="square"
name="Ada Lovelace"
src="https://i.pravatar.cc/96?u=ada"
/>
</div>Without a src, the avatar falls back to up-to-two uppercase initials derived from name. When name is also missing, a generic icon is rendered.
---
import Avatar from "../Avatar.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "md", direction: "row", align: "center" })}>
<Avatar name="Ada Lovelace" />
<Avatar name="A" />
<Avatar />
</div>Wrap avatars in a <Group> to get a classic face pile — subsequent avatars overlap, each ringed by the surrounding background so neighbours stay visually distinct. Works for both circle and square shapes and every size.
---
import Avatar from "../Avatar.astro";
import { default as AvatarStack } from "@pindoba/astro-group";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "lg", direction: "column" })}>
<AvatarStack variant="stack">
<Avatar name="Ada Lovelace" src="https://i.pravatar.cc/96?u=ada" />
<Avatar name="Alan Turing" src="https://i.pravatar.cc/96?u=alan" />
<Avatar name="Grace Hopper" src="https://i.pravatar.cc/96?u=grace" />
<Avatar name="Ken Thompson" src="https://i.pravatar.cc/96?u=ken" />
<Avatar name="+3" />
</AvatarStack>
<AvatarStack variant="stack">
<Avatar
size="lg"
name="Ada Lovelace"
src="https://i.pravatar.cc/96?u=ada"
/>
<Avatar
size="lg"
name="Alan Turing"
src="https://i.pravatar.cc/96?u=alan"
/>
<Avatar
size="lg"
name="Grace Hopper"
src="https://i.pravatar.cc/96?u=grace"
/>
<Avatar size="lg" name="+12" />
</AvatarStack>
<AvatarStack variant="stack">
<Avatar
shape="square"
name="Ada Lovelace"
src="https://i.pravatar.cc/96?u=ada"
/>
<Avatar
shape="square"
name="Alan Turing"
src="https://i.pravatar.cc/96?u=alan"
/>
<Avatar
shape="square"
name="Grace Hopper"
src="https://i.pravatar.cc/96?u=grace"
/>
<Avatar shape="square" name="+5" />
</AvatarStack>
</div>Avatar no longer ships a built-in status prop. To overlay a presence dot — or any other indicator — wrap the avatar in <Attachment> with placement="bottom-end", anchor="corner", and shape="circle", and pass your indicator through the content slot. This works for any element, not just avatars, and lets you use a colored dot, a <Badge>, an icon, or anything else.
---
import Avatar from "../Avatar.astro";
import Attachment from "@pindoba/astro-attachment";
import { stack } from "@pindoba/styled-system/patterns";
import { css } from "@pindoba/styled-system/css";
type Feedback = "success" | "warning" | "danger" | "neutral" | "primary";
type Size = "xs" | "sm" | "md" | "lg";
const sizes = ["xs", "sm", "md", "lg"] as const;
const dotBase = css({
display: "inline-block",
borderRadius: "full",
background: "colorPalette",
outline: "2px solid",
outlineColor: "colorPalette.border.bold",
});
const sizeClass: Record<Size, string> = {
xs: css({ width: "0.5rem", height: "0.5rem" }),
sm: css({ width: "0.625rem", height: "0.625rem" }),
md: css({ width: "0.75rem", height: "0.75rem" }),
lg: css({ width: "0.875rem", height: "0.875rem" }),
};
const feedbackClass: Record<Feedback, string> = {
primary: css({ colorPalette: "primary" }),
success: css({ colorPalette: "success" }),
warning: css({ colorPalette: "warning" }),
danger: css({ colorPalette: "danger" }),
neutral: css({ colorPalette: "neutral" }),
};
const dotClass = (size: Size, feedback: Feedback) =>
`${dotBase} ${sizeClass[size]} ${feedbackClass[feedback]}`;
const people: Array<{ name: string; feedback: Feedback; src?: string }> = [
{ name: "Ada Lovelace", feedback: "success" },
{ name: "Alan Turing", feedback: "warning" },
{ name: "Grace Hopper", feedback: "danger" },
{ name: "Ken Thompson", feedback: "neutral" },
{
name: "Dennis Ritchie",
feedback: "primary",
src: "https://i.pravatar.cc/96?u=dennis",
},
];
---
<div class={stack({ gap: "lg", direction: "column" })}>
{
sizes.map((size) => (
<div
class={stack({
gap: "md",
direction: "row",
align: "center",
flexWrap: "wrap",
})}
>
{people.map((person) => (
<Attachment placement="bottom-end" anchor="corner" shape="circle">
<Avatar size={size} name={person.name} src={person.src} />
<span slot="content" class={dotClass(size, person.feedback)} />
</Attachment>
))}
</div>
))
}
{
sizes.map((size) => (
<div
class={stack({
gap: "md",
direction: "row",
align: "center",
flexWrap: "wrap",
})}
>
{people.map((person) => (
<Attachment
placement="bottom-end"
anchor="corner"
shape="rect"
hugCorners
>
<Avatar
shape="square"
size={size}
name={person.name}
src={person.src}
/>
<span slot="content" class={dotClass(size, person.feedback)} />
</Attachment>
))}
</div>
))
}
</div>| prop | type | default | req | description |
|---|---|---|---|---|
| src | string | — | Image URL. Omit to render the fallback. | |
| alt | string | — | Accessible alt text for the image. Defaults to `name`. | |
| name | string | — | User name; initials are derived from the first and last word. | |
| size | "xs""sm""md""lg" | "md" | — | |
| emphasis | "primary""secondary""muted""ghost" | "secondary" | — | |
| shape | "circle""square" | "circle" | — | |
| background | PanelBackground | "surface.soft" | Inherited from Panel. | |
| border | PanelBorder | "none" | — | |
| radius | PanelRadius | shape === "circle" ? "full" : "md" | — | |
| passThrough | { root?, image?, fallback? } | — | Slot-level style and prop overrides. |