Icon
An icon, size square and drawn in one colour: tint, or else the content colour of where it sits, such as a button's label colour. contentDescription names it for screen readers; pass null when a label beside it already says what it means, and the icon is hidden from them.
import com.pantrixui.components.elements.icon.PantrixIcon
- Three sources. A vector (
imageVector), a bitmap (bitmap) or anypainter: all three are drawn at the same size and in one colour. - Size.
sizeis the icon's width and height; left out, it is the size in the theme'sIconStyle, 24dp on every platform. The icon is drawn at this size whatever the source's own size. - Colour. An icon given no
tinttakes the content colour of where it sits: a button's label colour, a disabled control's faded colour. Where nothing gives a colour it is drawn in the theme'sonSurfacecolour. - The library's icons.
PantrixIconsholds the components' own icons and a few for an app's screens: drawn on a 24-unit grid with a 2-unit stroke, round at its ends and corners. - Right to left. The six icons that point back or forward mirror in a right-to-left layout:
ChevronBack,ChevronForward,FirstPage,LastPage,ArrowBackandArrowForward. The others are drawn the same in every language. - Automation. An icon given a
tagKeycarries the tagIcon_<tagKey>. An icon given no key is not tagged.
Examples
A decorative icon and a named one
The least it takes: a vector and contentDescription. The description has no default, and is written for every icon.
In the first row a label beside the icon says what it is. The icon is decoration: it was given contentDescription = null and is hidden from screen readers, and a reader says only "Saved". The icon in the second row stands alone and carries the meaning itself: its description is "Warning", and a reader reads it out. A description says what the icon means, not what it looks like.
Row(
horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
verticalAlignment = Alignment.CenterVertically
) {
PantrixIcon(imageVector = PantrixIcons.Check, contentDescription = null)
PantrixText(text = "Saved")
}
PantrixIcon(imageVector = PantrixIcons.Warning, contentDescription = "Warning", tagKey = "alert")
Sizes
size is the icon's width and height: 16, 20, 24, 32 and 48 dp. The icon in the middle was given no size: it is the size in the theme's icon style, 24dp on every platform.
An icon is drawn at this size whatever its source's own size. Its stroke is relative to its grid, 2 units in 24: it grows thicker and thinner with the icon.
Row(
horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.lg),
verticalAlignment = Alignment.CenterVertically
) {
PantrixIcon(imageVector = PantrixIcons.Star, contentDescription = null, size = 16.dp, tagKey = "size_16")
PantrixIcon(imageVector = PantrixIcons.Star, contentDescription = null, size = 20.dp, tagKey = "size_20")
PantrixIcon(imageVector = PantrixIcons.Star, contentDescription = null, tagKey = "size_default")
PantrixIcon(imageVector = PantrixIcons.Star, contentDescription = null, size = 32.dp, tagKey = "size_32")
PantrixIcon(imageVector = PantrixIcons.Star, contentDescription = null, size = 48.dp, tagKey = "size_48")
}
Tint and the colour of where it sits
The first row: an icon given no colour is drawn on the page in the theme's onSurface colour; tint gives it a role's colour.
None of the icons in the second row was given a tint. Each took the content colour of where it sits: on a surface filled with primary, the colour that reads on that fill; inside a button, the label's colour; in a disabled button, that button's faded colour.
val colors = PantrixTheme.colors
val spacing = PantrixTheme.spacing
Row(horizontalArrangement = Arrangement.spacedBy(spacing.lg)) {
PantrixIcon(imageVector = PantrixIcons.Info, contentDescription = null)
PantrixIcon(imageVector = PantrixIcons.Info, contentDescription = null, tint = colors.info.color)
PantrixIcon(imageVector = PantrixIcons.Success, contentDescription = null, tint = colors.success.color)
PantrixIcon(imageVector = PantrixIcons.Warning, contentDescription = null, tint = colors.warning.color)
PantrixIcon(imageVector = PantrixIcons.Error, contentDescription = null, tint = colors.danger.color)
}
FlowRow(
horizontalArrangement = Arrangement.spacedBy(spacing.md),
verticalArrangement = Arrangement.spacedBy(spacing.sm),
itemVerticalAlignment = Alignment.CenterVertically
) {
PantrixSurface(color = colors.primary.color) {
PantrixIcon(
imageVector = PantrixIcons.Inbox,
contentDescription = null,
modifier = Modifier.padding(spacing.sm),
tagKey = "on_a_fill"
)
}
PantrixButton(
text = "Refresh",
onClick = {},
leadingIcon = { PantrixIcon(imageVector = PantrixIcons.Refresh, contentDescription = null) },
tagKey = "refresh"
)
PantrixButton(
text = "Refresh",
onClick = {},
enabled = false,
leadingIcon = { PantrixIcon(imageVector = PantrixIcons.Refresh, contentDescription = null) },
tagKey = "refresh_disabled"
)
}
Three sources: vector, bitmap, painter
Three sources, at the same size and in the same colour: a vector, a bitmap and a painter. The bitmap here is drawn in code; in an app it comes from a resource or from an image loader.
The third icon's source is Compose Multiplatform's multicoloured logo. PantrixIcon paints it in one colour and brings it to its own size. The one beside it is the same source drawn with PantrixImage: a picture keeps its own colours.
val bitmap = remember { targetBitmap() }
val logo = painterResource(Res.drawable.compose_multiplatform)
Row(
horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.lg),
verticalAlignment = Alignment.CenterVertically
) {
PantrixIcon(imageVector = PantrixIcons.Star, contentDescription = null, size = 32.dp, tagKey = "vector")
PantrixIcon(bitmap = bitmap, contentDescription = null, size = 32.dp, tagKey = "bitmap")
PantrixIcon(painter = logo, contentDescription = null, size = 32.dp, tagKey = "painter")
PantrixImage(painter = logo, modifier = Modifier.size(32.dp), contentDescription = null)
}
private fun targetBitmap(): ImageBitmap {
val bitmap = ImageBitmap(width = 96, height = 96)
val canvas = Canvas(bitmap)
val ring = Paint().apply {
style = PaintingStyle.Stroke
strokeWidth = 8f
}
canvas.drawCircle(center = Offset(48f, 48f), radius = 36f, paint = ring)
canvas.drawCircle(center = Offset(48f, 48f), radius = 12f, paint = Paint())
return bitmap
}
Icons that mirror in right-to-left layouts
The icons that point back or forward follow the reading direction: they mirror in a right-to-left layout. The search lens and the play triangle do not: they are drawn the same in every language.
Both rows are written with the same six icons in the same order. The second row is in a right-to-left layout: the icons run from right to left and the arrows point the other way, while the search and play icons are drawn as they are.
DirectionalIcons()
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
DirectionalIcons()
}
@Composable
private fun DirectionalIcons() {
Row(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.lg)) {
PantrixIcon(imageVector = PantrixIcons.ArrowBack, contentDescription = "Back")
PantrixIcon(imageVector = PantrixIcons.ChevronBack, contentDescription = "Previous")
PantrixIcon(imageVector = PantrixIcons.ChevronForward, contentDescription = "Next")
PantrixIcon(imageVector = PantrixIcons.ArrowForward, contentDescription = "Forward")
PantrixIcon(imageVector = PantrixIcons.Search, contentDescription = "Search")
PantrixIcon(imageVector = PantrixIcons.Play, contentDescription = "Play")
}
}
All the icons
All the icons in PantrixIcons, with their names. A name is as it is written in code: PantrixIcons.Check. The ones with "mirrors" written under them are flipped in a right-to-left layout; that is read from the icon itself, from its autoMirror field.
As their names are written under them, the icons are decoration and are hidden from screen readers.
FlowRow(
horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.lg)
) {
ALL_ICONS.forEach { icon ->
Column(
modifier = Modifier.width(104.dp),
verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.xs),
horizontalAlignment = Alignment.CenterHorizontally
) {
PantrixIcon(imageVector = icon, contentDescription = null, tagKey = icon.name)
PantrixText(
text = icon.name,
style = PantrixTheme.typography.caption,
textAlign = TextAlign.Center,
maxLines = 1
)
if (icon.autoMirror) {
PantrixText(
text = "mirrors",
style = PantrixTheme.typography.caption,
color = PantrixTheme.colors.textSecondary
)
}
}
}
}
private val ALL_ICONS = listOf(
PantrixIcons.Check,
PantrixIcons.Close,
PantrixIcons.ChevronDown,
PantrixIcons.ChevronForward,
PantrixIcons.ChevronBack,
PantrixIcons.FirstPage,
PantrixIcons.LastPage,
PantrixIcons.ArrowBack,
PantrixIcons.ArrowForward,
PantrixIcons.Calendar,
PantrixIcons.Refresh,
PantrixIcons.ZoomOut,
PantrixIcons.ZoomIn,
PantrixIcons.MoreHorizontal,
PantrixIcons.Minus,
PantrixIcons.Menu,
PantrixIcons.Plus,
PantrixIcons.Info,
PantrixIcons.Success,
PantrixIcons.Warning,
PantrixIcons.Error,
PantrixIcons.Inbox,
PantrixIcons.Star,
PantrixIcons.Folder,
PantrixIcons.Person,
PantrixIcons.Search,
PantrixIcons.Download,
PantrixIcons.Upload,
PantrixIcons.File,
PantrixIcons.Copy,
PantrixIcons.Eye,
PantrixIcons.EyeOff,
PantrixIcons.Pause,
PantrixIcons.Play
)
A default size by style
An icon's size is not a parameter but its style: IconStyle carries the size of an icon that is given none. ProvidePantrixStyles changes it for a part of the tree; PantrixTheme's styles parameter for the whole app. Here the first icon takes its size from the style, the second is given a size: the parameter comes before the style.
val styles = remember { pantrixStyles(IconStyle.override(all = IconStyle(size = 32.dp))) }
ProvidePantrixStyles(styles = styles) {
Row(
horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.lg),
verticalAlignment = Alignment.CenterVertically
) {
PantrixIcon(imageVector = PantrixIcons.Star, contentDescription = null)
PantrixIcon(imageVector = PantrixIcons.Star, contentDescription = null, size = 16.dp)
}
}
API
imageVector
An icon, size square and drawn in one colour: tint, or else the content colour of where it sits, such as a button's label colour. contentDescription names it for screen readers; pass null when a label beside it already says what it means, and the icon is hidden from them.
| Parameter | Type | Default | What it is |
|---|---|---|---|
imageVector | ImageVector | the icon's picture: one of PantrixIcons, or a vector of the app's. | |
contentDescription | String? | ||
modifier | Modifier | Modifier | the icon's modifier. |
size | Dp | PantrixTheme.style(key = IconStyle).size | |
tint | Color | Color.Unspecified | |
tagKey | String? | null | the icon's automation key: the icon is Icon_<tagKey>. Without one it has no tag. |
bitmap
PantrixIcon from a bitmap, drawn at size and in one colour like the vector form.
| Parameter | Type | Default | What it is |
|---|---|---|---|
bitmap | ImageBitmap | the icon's picture, a bitmap: it is tinted whole, so a shape of one colour on a clear ground. | |
contentDescription | String? | what a screen reader calls the icon, or null where a label beside it already says what it means, which hides it from them. | |
modifier | Modifier | Modifier | the icon's modifier. |
size | Dp | PantrixTheme.style(key = IconStyle).size | |
tint | Color | Color.Unspecified | the icon's colour, or else the content colour of where it sits. |
tagKey | String? | null | the icon's automation key: the icon is Icon_<tagKey>. Without one it has no tag. |
painter
PantrixIcon from any painter, drawn at size whatever the painter's own size, and in one colour.
| Parameter | Type | Default | What it is |
|---|---|---|---|
painter | Painter | the icon's picture, from any painter: it is tinted whole. | |
contentDescription | String? | what a screen reader calls the icon, or null where a label beside it already says what it means, which hides it from them. | |
modifier | Modifier | Modifier | the icon's modifier. |
size | Dp | PantrixTheme.style(key = IconStyle).size | |
tint | Color | Color.Unspecified | the icon's colour, or else the content colour of where it sits. |
tagKey | String? | null | the icon's automation key: the icon is Icon_<tagKey>. Without one it has no tag. |
Accessibility
- Screen reader.
contentDescriptionis a decision made for every icon: given words, a screen reader reads them; where a label beside the icon already says what it is, null is given and the icon is hidden from the reader.