UserAvatar
Renders one person as a round avatar, falling back to initials whenever there is no picture.
Install
Section titled “Install”pnpm dlx shadcn@latest add https://sg-widgets.vercel.app/r/react/user-avatar.jsonpnpm dlx shadcn-svelte@latest add https://sg-widgets.vercel.app/r/svelte/user-avatar.jsonReact
Loading the React demo…
Svelte
Loading the Svelte demo…
| prop | type | default | meaning |
|---|---|---|---|
name | string | required | Display name. Drives the initials, the tooltip and the accessible name. |
image | string | null | null | The user's image field. |
size | 'sm' | 'md' | 'lg' | 'md' | Diameters 6, 8 and 10. |
inactive | boolean | false | Dims and desaturates without hiding. |
color | 'auto' | 'none' | 'none' | auto tints the initials with a hue derived from the name, the same one every time, readable in light and dark under any theme. |
apiUser | boolean | false | Draws a bot glyph instead of a picture or initials, and names the script account in the tooltip. |
class / className | string | — | Merged after the widget's own classes. |
Initials are the first letter of the first and last word, so Ada Lovelace gives AL and Anna van der Meer gives AM. A single word gives one letter, and a login is split on its punctuation. They come from the core package, so both frameworks derive them identically.
The avatar never renders blank. An image that fails to load falls back to the initials, and with no name at all it is still a muted circle. The name is always in the accessible tree.
An API user is a script account rather than a person, so it has neither a picture nor initials: the circle holds a bot glyph on the secondary token pair, and the tooltip says what it is.
The root carries data attributes for a dimmed user and for an API user.
Events
Section titled “Events”None.
None.
Keyboard
Section titled “Keyboard”Not focusable.
API behaviour
Section titled “API behaviour”A person’s image field is presigned and short-lived, like every other image on the site (field_types/image).
A disabled person is a real row that still owns work: the status field holds a discarded code rather than the row being removed, which is why the widget dims instead of hiding (entity_types/HumanUser).