Documentation
Image and Icon Components
Display images from URLs, resources, or bitmaps, plus Material Design icons.
Image Component
From URL
<Image src="https://example.com/photo.jpg" /> From Bitmap
val bitmap = loadBitmap()
<Image bitmap={bitmap} /> Size Control
<Image src={url} w={200} h={200} />
<Image src={url} fillMaxWidth h={300} /> Aspect Ratio
Maintain aspect ratio while fitting container:
<Image src={url} aspectRatio={16.0/9.0} />
<Image src={url} aspectRatio={1.0} /> <!-- Square --> Content Scale
Control how images fit within their bounds:
<Image src={url} fit="crop" /> <!-- Fill, cropping if needed -->
<Image src={url} fit="fit" /> <!-- Fit inside, may have empty space -->
<Image src={url} fit="fillWidth" />
<Image src={url} fit="fillHeight" /> | Fit Value | Effect |
|---|---|
"crop" | Fill bounds, crop overflow |
"fit" | Fit inside bounds, maintain aspect ratio |
"fillWidth" | Fill width, scale height proportionally |
"fillHeight" | Fill height, scale width proportionally |
"fillBounds" | Fill both dimensions (may distort) |
Corner Radius
<Image src={url} cornerRadius={8} />
<Image src={url} cornerRadius={100} /> <!-- Circle --> Circular Images
<Image src={avatar} w={48} h={48} cornerRadius={24} /> Overlay Gradient
Add gradient overlays for better text contrast:
<Image
src={poster}
overlay="v-gradient(transparent 60%, #000)"
h={400}
/> <Box>
<Image src={photo} />
<Box
background="v-gradient(transparent 60%, #000)"
fillMaxSize
/>
<Text color="#FFF" p={16}>Caption</Text>
</Box> Loading State
<Image
src={url}
placeholder={R.drawable.placeholder}
error={R.drawable.error}
/> Clickable Images
Images support onClick like any component:
<Image
src={product.image}
onClick={() => $navigate("/product/{product.id}")}
/> Icon Component
Basic Usage
<Icon name="home" />
<Icon name="favorite" />
<Icon name="settings" /> Size
<Icon name="star" size={16} />
<Icon name="star" size={24} />
<Icon name="star" size={48} /> Color
<Icon name="favorite" color="primary" />
<Icon name="error" color="error" />
<Icon name="check" color="#00FF00" /> Rotation
<Icon name="arrow-forward" rotate={90} /> <!-- Down -->
<Icon name="arrow-forward" rotate={180} /> <!-- Back -->
<Icon name="arrow-forward" rotate={270} /> <!-- Up --> Icon Sets
Access different icon sets with prefixes:
<Icon name="home" /> <!-- Material Default -->
<Icon name="solar:star-bold" /> <!-- Solar Icons -->
<Icon name="lucide:heart" /> <!-- Lucide Icons --> Naming Convention
Icons use kebab-case and automatically map to PascalCase:
arrow-forward→Icons.Default.ArrowForwardsolar:star-bold→Icons.Solar.StarBold
Common Patterns
Avatar
<Image
src={user.avatar}
w={40} h={40}
cornerRadius={20}
/> Hero Image
<Box>
<Image
src={article.cover}
fillMaxWidth
h={250}
fit="crop"
/>
<Box
background="v-gradient(transparent 50%, #000)"
fillMaxSize
/>
<Column
fillMaxSize
verticalArrangement="end"
p={20}
>
<Text fontSize={28} fontWeight="bold" color="#FFF">
{article.title}
</Text>
</Column>
</Box> Product Card
<Card onClick={() => $navigate("/product/{product.id}")}>
<Image
src={product.image}
fillMaxWidth
aspectRatio={1.0}
fit="crop"
/>
<Column p={12} gap={4}>
<Text fontSize={14} maxLines={2}>{product.name}</Text>
<Row gap={4} verticalAlignment="center">
<Icon name="star" size={16} color="primary" />
<Text fontSize={12}>{product.rating}</Text>
</Row>
<Text fontSize={16} fontWeight="bold">${product.price}</Text>
</Column>
</Card> Icon with Label
<Column horizontalAlignment="center" gap={4}>
<Icon name="shopping-cart" size={32} color="primary" />
<Text fontSize={12}>Cart</Text>
</Column> Icon Button
<Button onClick={toggleFavorite}>
<Icon
name={isFavorite ? "favorite" : "favorite-border"}
color={isFavorite ? "error" : "secondary"}
/>
</Button> Rating Stars
val rating = 4.5
<Row gap={4}>
@for (i in 1..5) {
<Icon
name={if (i <= rating) "star" else "star-border"}
color="primary"
size={20}
/>
}
<Text fontSize={14} color="secondary">({reviewCount})</Text>
</Row> Image Gallery Grid
<LazyVerticalGrid columns={3} gap={2}>
@for (photo in photos) {
<Image
src={photo.thumbnail}
aspectRatio={1.0}
fit="crop"
onClick={() => $navigate("/photo/{photo.id}")}
transition:crossfade="photo-{photo.id}"
/>
}
</LazyVerticalGrid> Background Image
<Box fillMaxSize>
<Image
src={backgroundUrl}
fillMaxSize
fit="crop"
/>
<Box
background="v-gradient(transparent, #000000CC)"
fillMaxSize
/>
<Column fillMaxSize p={20} verticalArrangement="center">
<Text fontSize={32} color="#FFF" fontWeight="bold">
Welcome
</Text>
</Column>
</Box> Profile Header
<Column>
<Box h={200}>
<Image src={user.coverPhoto} fillMaxSize fit="crop" />
</Box>
<Row p={16} gap={16}>
<Image
src={user.avatar}
w={80} h={80}
cornerRadius={40}
mt={-40} <!-- Overlap cover photo -->
/>
<Column weight={1}>
<Text fontSize={24} fontWeight="bold">{user.name}</Text>
<Text fontSize={14} color="secondary">{user.bio}</Text>
</Column>
</Row>
</Column> Prop Reference
Image Props
| Prop | Type | Description |
|---|---|---|
src | String | Image URL |
bitmap | Bitmap | Bitmap object |
fit | String | Content scale mode |
aspectRatio | Number | Width/height ratio |
cornerRadius | Number | Corner radius in dp |
overlay | String | Gradient overlay |
placeholder | Resource | Loading placeholder |
error | Resource | Error fallback |
Icon Props
| Prop | Type | Description |
|---|---|---|
name | String | Icon name (kebab-case) |
size | Number | Icon size in dp |
color | String | Icon color |
tint | String | Alias for color |
rotate | Number | Rotation in degrees |
See Also
- Lazy Lists - Display image grids and galleries
- transition:crossfade - Shared element transitions with images
- Button Component - Icon buttons