Skip to main content
The Icon component displays vector icons, image bitmaps, and custom painters. It provides automatic tinting and integrates seamlessly with Lumo UI’s theming system.

Usage

import com.nomanr.lumo.ui.components.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*

// Vector icon
Icon(
    imageVector = Icons.Default.Favorite,
    contentDescription = "Favorite"
)

// Bitmap icon
Icon(
    bitmap = myBitmap,
    contentDescription = "Custom icon"
)

// Custom painter
Icon(
    painter = painterResource("icon.png"),
    contentDescription = "Icon"
)

Vector Icons

The most common way to use icons with Material Icons:
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.outlined.*

// Filled icons
Icon(
    imageVector = Icons.Filled.Home,
    contentDescription = "Home"
)

Icon(
    imageVector = Icons.Filled.Settings,
    contentDescription = "Settings"
)

// Outlined icons
Icon(
    imageVector = Icons.Outlined.Person,
    contentDescription = "Profile"
)

Bitmap Icons

Display icons from bitmap resources:
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.res.imageResource

val bitmap = ImageBitmap.imageResource("my_icon.png")

Icon(
    bitmap = bitmap,
    contentDescription = "Custom icon"
)

Custom Painter Icons

Use any painter implementation:
import androidx.compose.ui.res.painterResource

Icon(
    painter = painterResource("icon.xml"),
    contentDescription = "Vector drawable"
)

Tinting

Theme Color Tinting

Icons automatically use the current content color:
// Uses LocalContentColor by default
Icon(
    imageVector = Icons.Default.Star,
    contentDescription = "Star"
)

// Custom tint
Icon(
    imageVector = Icons.Default.Star,
    contentDescription = "Star",
    tint = AppTheme.colors.primary
)

No Tinting

Display original colors:
import androidx.compose.ui.graphics.Color

Icon(
    imageVector = colorfulIcon,
    contentDescription = "Colorful icon",
    tint = Color.Unspecified // Preserves original colors
)

Conditional Tinting

val isSelected = remember { mutableStateOf(false) }

Icon(
    imageVector = Icons.Default.Favorite,
    contentDescription = "Favorite",
    tint = if (isSelected.value) {
        Color.Red
    } else {
        AppTheme.colors.onSurface
    },
    modifier = Modifier.clickable {
        isSelected.value = !isSelected.value
    }
)

Sizing

Default Size

Icons default to 24.dp if no intrinsic size is available:
// Default 24.dp
Icon(
    imageVector = Icons.Default.Menu,
    contentDescription = "Menu"
)

Custom Sizes

import androidx.compose.foundation.layout.size

// Small icon
Icon(
    imageVector = Icons.Default.Check,
    contentDescription = "Check",
    modifier = Modifier.size(16.dp)
)

// Large icon
Icon(
    imageVector = Icons.Default.Image,
    contentDescription = "Image",
    modifier = Modifier.size(48.dp)
)

Responsive Sizing

// Fill available space
Icon(
    imageVector = Icons.Default.Cloud,
    contentDescription = "Cloud",
    modifier = Modifier.fillMaxSize()
)

// Percentage of parent
Icon(
    imageVector = Icons.Default.Download,
    contentDescription = "Download",
    modifier = Modifier.fillMaxSize(0.5f)
)

Parameters

Icon (ImageVector)

imageVector
ImageVector
required
The vector image to display
contentDescription
String?
required
Description for accessibility. Use null if the icon is purely decorative
modifier
Modifier
default:"Modifier"
Modifier for the icon
tint
Color
default:"LocalContentColor.current"
Tint color to apply to the icon

Icon (ImageBitmap)

bitmap
ImageBitmap
required
The bitmap image to display
contentDescription
String?
required
Description for accessibility
modifier
Modifier
default:"Modifier"
Modifier for the icon
tint
Color
default:"LocalContentColor.current"
Tint color to apply to the icon

Icon (Painter)

painter
Painter
required
The painter to use for drawing the icon
contentDescription
String?
required
Description for accessibility
modifier
Modifier
default:"Modifier"
Modifier for the icon
tint
Color
default:"LocalContentColor.current"
Tint color to apply to the icon

Common Use Cases

Button Icons

Button(
    onClick = { /* Handle click */ },
    variant = ButtonVariant.Primary
) {
    Icon(
        imageVector = Icons.Default.Add,
        contentDescription = null,
        modifier = Modifier.size(18.dp)
    )
    Spacer(Modifier.width(8.dp))
    Text("Add Item")
}

Icon Button

IconButton(
    onClick = { /* Handle click */ },
    variant = IconButtonVariant.Primary
) {
    Icon(
        imageVector = Icons.Default.Delete,
        contentDescription = "Delete"
    )
}
NavigationBarItem(
    icon = {
        Icon(
            imageVector = if (selected) {
                Icons.Filled.Home
            } else {
                Icons.Outlined.Home
            },
            contentDescription = "Home"
        )
    },
    label = { Text("Home") },
    selected = selected,
    onClick = { /* Navigate */ }
)

Leading/Trailing Icons in Text Fields

TextField(
    value = searchQuery,
    onValueChange = { searchQuery = it },
    leadingIcon = {
        Icon(
            imageVector = Icons.Default.Search,
            contentDescription = "Search"
        )
    },
    trailingIcon = {
        if (searchQuery.isNotEmpty()) {
            IconButton(onClick = { searchQuery = "" }) {
                Icon(
                    imageVector = Icons.Default.Clear,
                    contentDescription = "Clear"
                )
            }
        }
    }
)

Status Icons

Row(
    verticalAlignment = Alignment.CenterVertically,
    horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
    Icon(
        imageVector = when (status) {
            Status.Success -> Icons.Default.CheckCircle
            Status.Warning -> Icons.Default.Warning
            Status.Error -> Icons.Default.Error
            Status.Info -> Icons.Default.Info
        },
        contentDescription = null,
        tint = when (status) {
            Status.Success -> Color.Green
            Status.Warning -> Color.Yellow
            Status.Error -> Color.Red
            Status.Info -> Color.Blue
        }
    )
    Text(statusMessage)
}

Styling

With Background

Box(
    modifier = Modifier
        .size(48.dp)
        .background(
            color = AppTheme.colors.primary,
            shape = CircleShape
        ),
    contentAlignment = Alignment.Center
) {
    Icon(
        imageVector = Icons.Default.Person,
        contentDescription = "Profile",
        tint = AppTheme.colors.onPrimary,
        modifier = Modifier.size(24.dp)
    )
}

With Border

Box(
    modifier = Modifier
        .size(48.dp)
        .border(
            width = 2.dp,
            color = AppTheme.colors.primary,
            shape = CircleShape
        ),
    contentAlignment = Alignment.Center
) {
    Icon(
        imageVector = Icons.Default.Add,
        contentDescription = "Add",
        tint = AppTheme.colors.primary
    )
}

Defaults

  • Default Size: 24.dp (when painter has no intrinsic size)
  • Default Tint: LocalContentColor.current
  • Content Scale: Fit (scales to fill while maintaining aspect ratio)

Accessibility

With Content Description

Always provide descriptions for interactive icons:
IconButton(onClick = { /* Delete */ }) {
    Icon(
        imageVector = Icons.Default.Delete,
        contentDescription = "Delete item" // Screen readers announce this
    )
}

Decorative Icons

Use null for purely decorative icons:
Row {
    Icon(
        imageVector = Icons.Default.Star,
        contentDescription = null // Decorative only
    )
    Text("Featured Item")
}

Best Practices

  1. Content Descriptions: Provide clear descriptions for interactive icons
  2. Decorative Icons: Use null for contentDescription when icon is decorative
  3. Consistent Sizing: Use standard sizes (16dp, 24dp, 48dp) for consistency
  4. Color Contrast: Ensure icons have sufficient contrast with backgrounds
  5. Touch Targets: For interactive icons, ensure minimum 48dp touch target
  6. Loading: Show placeholder or shimmer while loading bitmap icons
  7. Theme Integration: Use theme colors for consistent appearance

Source Reference

See the full implementation in Icon.kt:27-39 (ImageVector), Icon.kt:42-55 (ImageBitmap), and Icon.kt:58-81 (Painter).

Build docs developers (and LLMs) love