Avatar
The picture of a person or a thing: a photograph, the initials of a name, or an icon standing for either.
import com.pantrixui.components.elements.avatar.PantrixAvatar
- Initials, an icon or neither. Where
initialsare given they are drawn; where they are not, theiconis; with neither, the avatar is a plain shape filled with its tone's colour. - Photograph. Pantrix loads no pictures.
imageis a slot: the app puts the picture there with its own loader, from a resource, or as a drawing of its own. The picture is drawn over the initials: the letters show while it loads and when it cannot be loaded. - Six tones.
tonefills the avatar with the colour of one of the theme's roles;colorsgives a colour that no role has. A tone says nothing by itself: a screen reader reads the description, not the colour. - Size.
sizeormodifiergives the avatar its size. The initials and the icon are a share of the avatar: they keep their proportion at every size. The style's size is 40dp on Android and iOS, and 32dp on desktop and the web. - Shape. An avatar is a circle on every platform;
AvatarStyle(shape = ...)changes its corners. - As written. Initials are not put in upper case. The first two letters are kept, without the spaces between them.
- Font scale. The initials keep their share when the system's text size is made larger, too: an avatar does not grow with the text around it.
Examples
At its plainest
The least it takes: a description and initials. Its tone is Neutral, and its size the style's.
An avatar that stands alone takes its name from its description: a screen reader reads it as an image named "Ayşe Yılmaz". The letters "AY" are not read out; they are what the description shortens.
PantrixAvatar(contentDescription = "Ayşe Yılmaz", initials = "AY", tagKey = "ayse")
Beside a name
An avatar that stands beside its name has no description: contentDescription = null. The name is written beside it; a screen reader does not read the same name twice, and the avatar is hidden from it.
Initials are drawn as they are written, and are not put in upper case: the "ik" in the last row stays in lower case.
CONTACTS.forEachIndexed { index, contact -> ContactRow(contact = contact, key = "contact_$index") }
@Composable
private fun ContactRow(
contact: AvatarContact,
key: String
) {
Row(
horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.md),
verticalAlignment = Alignment.CenterVertically
) {
PantrixAvatar(contentDescription = null, initials = contact.initials, tone = contact.tone, tagKey = key)
Column {
PantrixText(text = contact.name, style = PantrixTheme.typography.label)
PantrixText(
text = contact.lastTransfer,
style = PantrixTheme.typography.footnote,
color = PantrixTheme.colors.textSecondary
)
}
}
}
private class AvatarContact(
val name: String,
val initials: String,
val lastTransfer: String,
val tone: AvatarTone = AvatarTone.Neutral
)
private val CONTACTS = listOf(
AvatarContact(name = "Ayşe Yılmaz", initials = "AY", lastTransfer = "Sent yesterday: 250,00 TL"),
AvatarContact(
name = "İbrahim Öztürk",
initials = "İÖ",
lastTransfer = "Received on 3 September: 1.200,00 TL",
tone = AvatarTone.Info
),
// Initials are drawn as they are written: lower case stays lower case.
AvatarContact(name = "ilker kaya", initials = "ik", lastTransfer = "No transactions yet", tone = AvatarTone.Success)
)
Tones
tone fills the avatar with the colour of one of the theme's roles, and writes the letters in the colour that reads on it. The default is Neutral: a grey with no meaning at all.
In every tone the avatar is drawn in the role's solid colour, not in its pale container: a small circle of that colour is lost on a light page. A tone says nothing by itself; what a colour is to mean has to be in the words beside it.
FlowRow(
horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)
) {
AvatarTone.entries.forEachIndexed { index, tone ->
PantrixAvatar(
contentDescription = "Avatar in the ${tone.name} tone",
initials = TONE_INITIALS[index],
tone = tone,
tagKey = "tone_${tone.name}"
)
}
}
private val TONE_INITIALS = listOf("AL", "GH", "KJ", "MR", "ŞÖ", "WY")
Sizes
size is the avatar's width and height: 24dp in a comment, 32dp in a dense row, 40dp in a row, 56dp on a card, 72dp on a profile. The size can be given by modifier too; it then takes the place of size.
The initials are four tenths of the avatar and the icon six tenths: the proportion stays the same whatever the size, and no second style is needed.
Row(
horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
verticalAlignment = Alignment.CenterVertically
) {
listOf(24, 32, 40, 56, 72).forEach { size ->
PantrixAvatar(
contentDescription = null,
initials = "DK",
tone = AvatarTone.Primary,
size = size.dp,
tagKey = "size_$size"
)
}
}
Initials
Initials are drawn as they are written. They are not put in upper case: i becomes İ in Turkish and I in other languages, and an avatar is not the place to get a name wrong. The first avatar was given "ik", and so it stayed.
The first two letters of what is given are kept, without the spaces between them: the avatar given "Ayşe Yılmaz" writes "Ay", and the one given "D K" writes "DK". How a name is shortened is the app's to say, not the avatar's: the app gives the letters to draw.
Row(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)) {
PantrixAvatar(contentDescription = "ilker kaya", initials = "ik", tagKey = "as_written")
PantrixAvatar(contentDescription = "Ayşe Yılmaz", initials = "Ayşe Yılmaz", tagKey = "first_two")
PantrixAvatar(contentDescription = "Deniz Kara", initials = "D K", tagKey = "without_spaces")
PantrixAvatar(contentDescription = "Zeynep", initials = "Z", tagKey = "one_letter")
}
A photograph that comes later
A profile whose photograph comes later. The avatar is given its image slot from the start, but the slot draws nothing until "Load photo" is pressed: until then the initials show. When the photograph comes it covers the letters. An image loader does the same while it loads, or when it fails.
The slot is as large as the avatar and is cut to its shape. The "photograph" here is a gradient with no size of its own; for a picture that is not square, ask for ContentScale.Crop. What the picture says of itself is not read: the avatar's description stands for both.
var loaded by rememberSaveable { mutableStateOf(false) }
Row(
horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.md),
verticalAlignment = Alignment.CenterVertically
) {
PantrixAvatar(
contentDescription = "Deniz Kara's profile photo",
initials = "DK",
tone = AvatarTone.Primary,
size = 72.dp,
tagKey = "profile"
) {
if (loaded) Photo()
}
Column(verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.xs)) {
PantrixText(text = "Deniz Kara", style = PantrixTheme.typography.callout)
PantrixButton(
text = if (loaded) "Remove photo" else "Load photo",
onClick = { loaded = !loaded },
variant = ButtonVariant.Outline,
tagKey = "load_photo"
)
}
}
@Composable
private fun Photo() {
val colors = PantrixTheme.colors
val gradient = remember(colors) {
BrushPainter(Brush.linearGradient(listOf(colors.warning.color, colors.danger.color, colors.primary.color)))
}
PantrixImage(painter = gradient, contentScale = ContentScale.Crop, contentDescription = null)
}
An avatar with an icon, and an empty one
An avatar without initials draws its icon: a person, a group, a company. Like the letters, the icon is drawn in the colour that reads on the tone.
The second is given neither letters nor an icon: it is a plain circle filled with its tone's colour. Its description still says its name.
Row(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)) {
PantrixAvatar(contentDescription = "Shared account", icon = PantrixIcons.Person, tagKey = "shared")
PantrixAvatar(contentDescription = "Unknown person", tagKey = "unknown")
}
An avatar with corners
An avatar is a circle on every platform. style changes the style of this avatar alone: AvatarStyle(shape = ...) takes the corners to a step of the theme's shape scale. Here a folder's avatar and a company's are drawn with corners, by ShapeRole.Medium.
Only the field that is set changes: the size and the letters' share come from the theme's style.
val rounded = AvatarStyle(shape = ShapeRole.Medium)
Row(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)) {
PantrixAvatar(
contentDescription = "Documents",
icon = PantrixIcons.Folder,
tone = AvatarTone.Info,
style = rounded
)
PantrixAvatar(
contentDescription = "Pantrix A.Ş.",
initials = "PX",
tone = AvatarTone.Primary,
style = rounded,
tagKey = "company"
)
}
A transparent logo
A picture that is transparent in places shows what is under it. Such a picture is given alone, without initials or an icon: behind this logo there is only the tone's colour.
PantrixAvatar(contentDescription = "Compose Multiplatform", tone = AvatarTone.Primary, tagKey = "logo") {
PantrixImage(painter = painterResource(Res.drawable.compose_multiplatform), contentDescription = null)
}
A colour of its own
colors gives the avatar a fill of the given colour, not of a tone: a team's own colour, say, or a label's. The first avatar's colour is in none of the theme's roles; both its fill and the colour of its letters are given, because only whoever gives a fill the theme does not know can tell what reads on it.
The second is given a fill alone, and that fill is one of the theme's own colours, success.container. The letters take the colour the theme pairs with that fill, without it being given.
val own = ownColors()
Row(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)) {
PantrixAvatar(
contentDescription = "Design team",
initials = "DT",
colors = AvatarColors(container = own.color, content = own.onColor),
tagKey = "team"
)
PantrixAvatar(
contentDescription = "Support team",
initials = "ST",
colors = AvatarColors(container = PantrixTheme.colors.success.container),
tagKey = "support_team"
)
}
API
contentDescription
The picture of a person or a thing: a photograph, the initials of a name, or an icon standing for either.
| Parameter | Type | Default | What it is |
|---|---|---|---|
contentDescription | String? | what a screen reader says for the avatar, usually the name it stands for, or null to hide the avatar from it. | |
modifier | Modifier | Modifier | the avatar's modifier. A size given here goes over size. |
initials | String? | null | the letters to draw, usually one or two. More than two are cut, and none leaves the icon. |
icon | ImageVector? | null | what is drawn where there are no initials: a person, a group, a company. |
tone | AvatarTone | AvatarTone.Neutral | the colour under the initials or the icon, and theirs. A picture covers it. |
colors | AvatarColors? | null | this avatar's own colours, in place of its tone's: the ones it sets, with the tone's for the rest. |
style | AvatarStyle? | null | this call's own style: over every enclosing one and under the density. Only the fields it sets change, on every platform. |
size | Dp | PantrixTheme.style(AvatarStyle, style).size | the avatar's width and height: the style's unless given. |
tagKey | String? | null | the avatar's automation key: it is Avatar_<tagKey>, and is tagged only when given one. |
image | (@Composable () -> Unit)? | null | a picture that fills the avatar, over the initials or the icon. What it says of itself is not read: the avatar's description stands for both. |
AvatarStyle
PantrixAvatar's geometry: how large it is, what its corners are, and how much of it the initials or the icon take.
| Parameter | Type | Default | What it is |
|---|---|---|---|
size | Dp | Dp.Unspecified | The avatar's width and height. |
shape | ShapeSpec | ShapeSpec.Unspecified | The avatar's corners: the round end of the brand's shape scale, a circle, unless a brand or a theme asks for a step of it or a shape of its own. |
initialsScale | Float | Float.NaN | The height the initials are set in, as a fraction of the avatar's shorter side. |
iconScale | Float | Float.NaN | The icon's width and height, as a fraction of the avatar's shorter side. |
AvatarColors
What PantrixAvatar is painted with, for an avatar that does not take its tone's colours: a colour that is set is used, and one that is left out stays the tone's.
| Parameter | Type | Default | What it is |
|---|---|---|---|
container | Color | Color.Unspecified | The fill under the initials or the icon, which a picture covers. The color of the tone's role. |
content | Color | Color.Unspecified | The initials or the icon: the colour that reads on container. The onColor of the tone's role. |
Accessibility
- Screen reader. With a
contentDescriptionthe avatar is read as an image by that name. Given null, it is hidden: that is right for an avatar with its name written beside it. The initials are never read out.