Avatar & AvatarGroup
Avatar shows a person, or a thing, in a small frame. It draws their picture when there is one, their initials when there is not, and a generic silhouette when there is not even a name. An optional presence dot sits on the bottom-right corner. AvatarGroup lays avatars out as an overlapping “facepile” and collapses everyone past Max into a single +N chip.
Screenshots
Section titled “Screenshots”MAUI (iOS)
| Content, sizes, colours | Presence & groups |
|---|---|
Blazor
| Content, sizes, colours | Presence & groups |
|---|---|
Features
Section titled “Features”- Picture, then initials, then silhouette. The initials are drawn under the picture, so they show while it loads and stay if it fails. A broken URL never leaves a hole or a broken-image glyph.
- Initials come from
Name: the first letter of the first and last words, soGrace Brewster HopperisGH,Jean-Luc PicardisJPandada.lovelace@example.comisAL. SetInitialsto override them. ColorFromNamegives each name its own stable hue. The hash is the same on both hosts, so a person gets the same colour in a MAUI app and its Blazor twin.- Circle, rounded-square and square shapes, at any size.
- Presence dot:
Online,Away,BusyorOffline, coloured from the theme’s success, warning, error and outline tokens. AvatarGroupoverlaps its avatars with a separator ring and collapses everyone pastMaxinto a+Nchip.TotalCountlets+Ncount everyone when only a sample is loaded.- Fully themed: with no colours set, both controls follow the active Shiny theme, dark mode included.
- On MAUI, pictures load through ShinyImage, so they are cached, queued and de-duplicated like every other image in the app.
Quick Start
Section titled “Quick Start”<shiny:Avatar xmlns:shiny="http://shiny.net/maui/controls" Name="{Binding DisplayName}" Uri="{Binding PhotoUrl}" Size="48" Status="Online" Command="{Binding OpenProfileCommand}" />
<shiny:AvatarGroup Max="4" Size="32"> <shiny:Avatar Name="Grace Hopper" Uri="https://example.com/grace.jpg" /> <shiny:Avatar Name="Ada Lovelace" ColorFromName="True" /> <shiny:Avatar Name="Alan Turing" ColorFromName="True" /> <shiny:Avatar Name="Linus Torvalds" /> <shiny:Avatar Name="Margaret Hamilton" /></shiny:AvatarGroup>Bind a group with ItemsSource. The ItemTemplate’s root must be an Avatar. A list of strings needs no template: each string becomes an avatar with that name. An ObservableCollection is tracked.
<shiny:AvatarGroup ItemsSource="{Binding Members}" TotalCount="{Binding MemberCount}" Max="5" OverflowCommand="{Binding ShowAllMembersCommand}"> <shiny:AvatarGroup.ItemTemplate> <DataTemplate x:DataType="local:Member"> <shiny:Avatar Name="{Binding Name}" Uri="{Binding PhotoUrl}" ColorFromName="True" /> </DataTemplate> </shiny:AvatarGroup.ItemTemplate></shiny:AvatarGroup>OverflowCommand receives the hidden count (an int).
Blazor
Section titled “Blazor”<Avatar Name="@user.DisplayName" Uri="@user.PhotoUrl" Size="48" Status="AvatarStatus.Online" OnClick="OpenProfile" />
<AvatarGroup Max="5" TotalCount="@memberCount" Size="32" OnOverflowClick="ShowAll"> @foreach (var m in members) { <Avatar @key="m.Id" Name="@m.Name" Uri="@m.PhotoUrl" ColorFromName="true" /> }</AvatarGroup>
@code { void ShowAll(int hiddenCount) => Nav.NavigateTo("/members");}Handling OnClick (or the group’s OnOverflowClick) renders the avatar as a <button>. Otherwise it is a role="img" span.
Avatar Properties
Section titled “Avatar Properties”| Property | Type (MAUI / Blazor) | Default | Description |
|---|---|---|---|
Name |
string |
null |
Drives the initials, the accessible label and ColorFromName |
Initials |
string |
null |
Overrides the derived initials |
Uri |
string |
null |
Picture URL. On MAUI it can also be a resource://, file or data: URI |
Source |
ImageSource |
null |
MAUI only. Any ImageSource, used when Uri is empty |
Size |
double |
40 / -1 (40px) |
Width and height |
Shape |
AvatarShape / AvatarShape? |
Circle / null (circle) |
Circle, Rounded or Square |
Status |
AvatarStatus |
None |
Presence dot: None, Online, Away, Busy, Offline |
StatusColor |
Color / string |
theme | Overrides the dot colour |
FillColor |
Color / string |
theme primary container | Background behind the initials or silhouette |
TextColor |
Color / string |
theme on-primary-container | Colour of the initials and silhouette |
ColorFromName |
bool |
false |
A stable hue per name, with white initials, when FillColor is unset |
RingColor |
Color / string |
theme surface | Ring colour |
RingThickness |
double |
0 / -1 (none) |
Ring thickness |
FontSize |
double |
-1 (auto) |
Size of the initials. Auto is 40% of Size, or 32% for three or more characters |
Command / CommandParameter |
ICommand / object |
null |
MAUI. Runs on tap. Setting it makes the avatar tappable |
Clicked |
event | MAUI. Raised on tap. Subscribing makes the avatar tappable | |
OnClick |
EventCallback<MouseEventArgs> |
Blazor. Raised on click | |
DisplayInitials |
string (read-only) |
The initials actually shown | |
IsShowingImage |
bool (read-only) |
MAUI. True once the picture has loaded and covers the initials |
An avatar with no Command and no Clicked handler takes no taps, so it never gets in the way of a list’s own row selection.
AvatarGroup Properties
Section titled “AvatarGroup Properties”| Property | Type (MAUI / Blazor) | Default | Description |
|---|---|---|---|
Avatars / ChildContent |
IList<Avatar> / RenderFragment |
The avatars, declared inline | |
ItemsSource / ItemTemplate |
IEnumerable / DataTemplate |
null |
MAUI only. Bind instead of declaring |
Max |
int |
0 (all) |
Most avatars drawn before the rest collapse into the chip. The chip itself is not counted |
TotalCount |
int |
0 |
The real head count when the avatars are only a sample. +N counts against this |
Size |
double |
-1 |
When positive, the size of every avatar in the group |
Shape |
AvatarShape? |
null |
When set, the shape of every avatar in the group |
Overlap |
double |
-1 (25% of size) |
How far each avatar tucks under the one before it. 0 lays them side by side |
RingColor |
Color / string |
theme surface | Separator ring. Set it to whatever colour the group sits on |
RingThickness |
double |
2 |
Separator ring thickness |
OverflowFormat |
string |
"+{0}" |
Chip text. {0} is the hidden count |
OverflowCommand / OverflowClicked |
ICommand / event |
MAUI. Chip tapped. The command parameter is the hidden count | |
OnOverflowClick |
EventCallback<int> |
Blazor. Chip clicked, with the hidden count | |
OverflowCount |
int (read-only) |
How many people the chip stands for |
Later avatars sit on top of earlier ones. The +N chip takes the size and shape of the first avatar, so it always matches the row.
Platform Notes
Section titled “Platform Notes”- MAUI: the group writes
Size,Shape,RingThickness,RingColorandMarginonto the avatars it holds, so set them on the group, not on the children. - Blazor: size, shape, fill and ring are CSS custom properties:
--shiny-avatar-size,--shiny-avatar-radius,--shiny-avatar-fill,--shiny-avatar-ink,--shiny-avatar-ring-width,--shiny-avatar-ring-color,--shiny-avatar-overlapand--shiny-avatar-font-size. The group sets them once on its root, and a parameter on a single avatar still wins. - Blazor: avatars must be direct children of the group. An avatar wrapped in another element, such as a tooltip or a link, is counted but can’t be hidden past
Max, because hiding is done by position. - Blazor: the picture is a plain
<img loading="lazy">, so the browser handles caching. - Accessibility: each avatar announces its name and status (“Grace Hopper, Online”). The group announces “4 people and 12 more”.


