A collection of "copy, paste, use" snippets and useful elements for those who intend to or are already developing an app in Compose Multiplatform or simply an Android app and already use * Jetpack Compose* and Material3.
A line chart with smooth curves, gradient fill, glow effects, and trend indicator badge.
ProgressionChart |
DoubleTouch |
ProgressionChartGlow(
data = listOf(
ChartDataPoint(100f, "Nov 1"),
ChartDataPoint(90f, "Nov 15"),
ChartDataPoint(100f, "Dec 1"),
ChartDataPoint(103f, "Dec 15"),
ChartDataPoint(105f, "Today"),
),
title = "Bench Press 1RM",
value = "105 kg",
trend = "+5%",
trendDirection = TrendDirection.UP,
style = ProgressionChartStyle(
lineColor = ProgressionGlowColors.LineGreen
)
)// See FullAnalyticsPreview()
ProgressionChartGlow(
data = analyticsData,
style = ProgressionChartStyle(lineColor = ProgressionGlowColors.LinePurple, chartHeight = 220.dp, glowAlpha = 0.5f, lineWidth = 4.dp),
initialSelectionRange = 0.45f..0.82f,
animate = false,
onRangeSelection = { currentRange = it },
)Key Parameters:
| Parameter | Description |
|---|---|
data |
List of ChartDataPoint(value, label) |
title |
Chart title (e.g., exercise name) |
value |
Main value display |
trend |
Trend percentage (e.g., "+5%") |
trendDirection |
TrendDirection.UP, DOWN, or NEUTRAL |
style |
Customize line color, glow, grid, gradients |
Features:
- Smooth cubic BΓ©zier curves
- Gradient fill under the line
- Glow effect on the line
- Last point highlighted with glow ring
- Trend badge with icon
A photo grid with multi-selection support, long-press handling, and selection constraints. Perfect for image galleries with selection limits.
Multiselection |
Double Carousel |
val photos = List(40) { ImageModel(image = "https://picsum.photos/id/${it}/600/600") }
val viewModel = remember { PhotoGridViewModel() }
LaunchedEffect(Unit) {
viewModel.setEvent(
PhotoGridEvents.OnStart(
lockedImage = null,
imageModelList = photos,
selectedImage = emptyList(),
selectionConstraints = SelectionConstraints(min = 1, max = 50),
)
)
}
PhotoGridMultiSelect(
imageModelList = photos,
selectedList = viewModel.uiState.value.selectedImage,
onImageLongClick = { imageModel, index ->
// Handle long press (e.g., show zoom modal)
},
onSelectionChange = { imageModel ->
viewModel.setEvent(PhotoGridEvents.OnPhotoTap(imageModel))
},
lockedImage = null, // Optional locked image that can't be deselected
)Key Parameters:
| Parameter | Description |
|---|---|
imageModelList |
List of ImageModel(image: String) to display |
selectedList |
List of currently selected images |
onImageLongClick |
Callback for long press (image, index) |
onSelectionChange |
Callback when selection changes |
lockedImage |
Optional image that stays selected |
selectionConstraints |
SelectionConstraints(min, max) for validation |
Features:
- Multi-select with visual feedback (checkmarks)
- Selection limit enforcement with bottom sheet warning
- Long-press gesture support
- Locked image support (always selected)
- Select all / Deselect all functionality
- Adaptive grid layout
- Selection counter in footer
A dual-synchronized carousel component with a top full-size image pager and bottom thumbnail strip. Features smooth synchronization, multi-selection, and aspect-ratio-aware borders.
var carouselState by remember {
mutableStateOf(
DoubleCarouselState(
images = List(10) { "https://picsum.photos/id/${it * 10}/800/600" },
currentIndex = 0,
selectedIndices = emptySet()
)
)
}
DoubleCarousel(
state = carouselState,
onStateChange = { carouselState = it },
config = DoubleCarouselConfig(
bottomThumbnailSize = 80.dp,
selectedBorderColor = Color.Cyan,
selectedBorderWidth = 3.dp,
spacing = 8.dp,
)
)Key Parameters:
| Parameter | Description |
|---|---|
state |
DoubleCarouselState(images, currentIndex, selectedIndices) |
onStateChange |
Callback when state changes (navigation or selection) |
config |
Customize thumbnail size, colors, spacing |
DoubleCarouselState Methods:
state.toggleSelection(index) // Toggle image selection
state.updateCurrentIndex(index) // Navigate to image
state.isSelected(index) // Check if image is selectedFeatures:
- Bidirectional Sync: Swipe top pager
βοΈ scroll bottom thumbnails - Multi-Selection: Tap top image to select/deselect with border indicator
- Aspect Ratio Aware: Borders follow actual image shape (not container)
- Snap Behavior: Bottom carousel snaps to center with smooth animations
- Fast Scroll Handling: Debounced synchronization prevents desync
- Customizable Styling: Thumbnail size, colors, borders, spacing
Configuration Options:
| Config Property | Description | Default |
|---|---|---|
maxVisibleInBottom |
Max thumbnails visible in bottom carousel | 5 |
bottomThumbnailSize |
Square thumbnail size | 80.dp |
selectedBorderColor |
Border color for selected images | Cyan |
selectedBorderWidth |
Border width for selected images | 3.dp |
spacing |
Space between bottom thumbnails | 8.dp |
A customizable card with deformable corners and a circular cutout for icons.
DeformableCornerItem(
modifier = Modifier.size(200.dp),
circleRadius = 24.dp,
cardColor = Color(0xFFE0E0E0),
circleColor = Color(0xFFFF5252),
topLeft = 32.dp,
bottomLeft = 32.dp,
bottomRight = 32.dp,
contentCircle = {
Icon(
imageVector = Icons.Default.LocalFireDepartment,
contentDescription = null,
tint = Color.White,
modifier = Modifier.align(Alignment.Center)
)
},
contentRectangle = {
Text("Your content here", modifier = Modifier.align(Alignment.Center))
}
)Key Parameters:
| Parameter | Description |
|---|---|
circleRadius |
Radius of the corner circle |
cardColor |
Background color of the card |
topLeft, bottomLeft, bottomRight |
Corner radius for each corner |
contentCircle |
Composable content inside the circle |
contentRectangle |
Composable content inside the card |
A circular countdown timer with animated progress arc, glow effect, and heartbeat animation.
TimerWatch(
timerState = TimerState(
timeRemaining = 45,
totalTime = 60,
isRest = false
),
isOvertime = false,
showHeartbeat = true,
style = CircularTimerDefaults.style()
)Key Parameters:
| Parameter | Description |
|---|---|
timerState |
Contains timeRemaining, totalTime, isRest |
isOvertime |
Shows red overtime state when true |
showHeartbeat |
Enables pulsing animation under 5 seconds |
style |
Customize colors, sizes, typography |
States:
- Work β Green progress
- Rest β Amber progress
- Overtime β Red progress with negative time display
- Heartbeat β Pulsing animation when < 5 seconds
A weekly bar chart with striped inactive bars and solid active bar.
val weekData = listOf(
BarData(label = "Mon", progress = 0.7f),
BarData(label = "Tue", progress = 0.4f),
BarData(label = "Wed", progress = 0.6f),
BarData(label = "Thu", progress = 0f),
BarData(label = "Fri", progress = 0.5f),
BarData(label = "Sat", progress = 1.0f),
BarData(label = "Sun", progress = 0.65f),
)
BasicBarChart(
chartData = weekData,
selectedIndex = 2,
activeBarColor = Color(0xFFF48C46),
onBarClick = { index -> /* handle click */ }
)Key Parameters:
| Parameter | Description |
|---|---|
chartData |
List of BarData(label, progress) |
selectedIndex |
Index of highlighted bar (-1 for none) |
activeBarColor |
Color of the selected bar |
onBarClick |
Callback when a bar is clicked |
A segmented progress tracker with animated fill, glow effects, and completion checkmark.
TrackerContainer(
fillPercentage = 0.5f, // 0.0 to 1.0
isCompleted = false,
isActive = true,
isGlobalComplete = false,
waveDelayMillis = 0,
rangeStart = 0,
rangeEnd = 100,
style = GlowingTrackerDefaults.style()
)Key Parameters:
| Parameter | Description |
|---|---|
fillPercentage |
Progress from 0.0 to 1.0 |
isCompleted |
Shows checkmark when true |
isActive |
Highlights the segment |
isGlobalComplete |
Triggers wave animation |
style |
Customize colors, block size, animations |
MuscleGroupDonutVariant(
segments = listOf(
DonutSegment("Chest", 5000f, 0.32f, DonutVariantColors.Purple, "5k kg"),
DonutSegment("Legs", 4500f, 0.28f, DonutVariantColors.Orange, "4.5k kg"),
DonutSegment("Back", 4000f, 0.25f, DonutVariantColors.Teal, "4k kg"),
DonutSegment("Shoulders", 1500f, 0.10f, DonutVariantColors.Yellow, "1.5k kg"),
DonutSegment("Arms", 800f, 0.05f, DonutVariantColors.Blue, "0.8k kg"),
),
centerContent = {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(
"15.8k",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
color = Color.White,
)
Text(
"Total kg",
fontSize = 12.sp,
color = Color.Gray,
)
}
},
)Key Parameters:
| Parameter | Description |
|---|---|
segments |
listOf DonutSegment(label, value, percentage, color, subtitle) |
centerContent |
Composable content in the center |
A calendar-based heatmap showing workout consistency with streak tracking and intensity visualization.
ConsistencyHeatmapCardGlow(
year = 2026,
month = 1,
data = HeatmapData(
dayIntensities = mapOf(
LocalDate(2026, 1, 5) to 1f,
LocalDate(2026, 1, 7) to 0.7f,
LocalDate(2026, 1, 9) to 1f,
),
currentStreak = 2,
recordStreak = 12,
),
today = LocalDate(2026, 1, 16),
style = HeatmapStyle(
accentColor = HeatmapGlowColors.AccentBlue
),
onMonthChange = { newYear, newMonth -> /* handle navigation */ }
)Key Parameters:
| Parameter | Description |
|---|---|
year |
Year to display (e.g., 2026) |
month |
Month to display (1-12) |
data |
HeatmapData with dayIntensities, currentStreak, recordStreak |
today |
Current date for highlighting |
style |
Customize colors, glow, cell styling |
onMonthChange |
Callback for month navigation |
Intensity Levels:
- 0.0 β Rest day (dark cell)
- 0.3-0.5 β Light workout
- 0.6-0.8 β Moderate workout
- 1.0 β Intense workout (with glow effect)
A radar/spider chart with multiple overlapping data series, glow effects, and interactive point selection.
RadarChart(
axisLabels = listOf(
RadarAxisLabel("Chest"),
RadarAxisLabel("Back"),
RadarAxisLabel("Legs", isHighlighted = true),
RadarAxisLabel("Shoulders"),
RadarAxisLabel("Arms"),
),
series = listOf(
RadarSeries(
name = "Current",
values = listOf(0.85f, 0.70f, 0.60f, 0.65f, 0.80f),
color = RadarColors.DataPrimary,
),
RadarSeries(
name = "Previous",
values = listOf(0.65f, 0.55f, 0.75f, 0.45f, 0.60f),
color = RadarColors.DataWarning,
fillAlpha = 0.15f,
),
),
title = "Progress Comparison",
onPointClick = { point ->
// Handle point tap
println("${point?.seriesName}: ${point?.label} = ${point?.value}")
}
)Key Parameters:
| Parameter | Description |
|---|---|
axisLabels |
List of RadarAxisLabel(label, isHighlighted) |
series |
List of RadarSeries(name, values, color, fillAlpha) |
title |
Optional chart title |
style |
Customize colors, sizes, glow, grid levels |
onPointClick |
Callback when a point is tapped |
Features:
- Multiple overlapping series for comparison
- Interactive point selection with tooltip
- Series highlighting on tap (others dim)
- Glow effects on polygon and points
- Gradient fill with customizable alpha
- Backwards compatible single-series API
A horizontal scrollable weight picker with snap-to-tick behavior and haptic feedback.
var weight by remember { mutableFloatStateOf(70f) }
WeightScalePicker(
value = weight,
onValueChange = { weight = it },
minValue = 40f,
maxValue = 150f,
step = 0.1f,
onHapticFeedback = { /* vibrate */ },
style = WeightScaleStyle(
accentColor = WeightScaleColors.AccentPurple
)
)Key Parameters:
| Parameter | Description |
|---|---|
value |
Current weight value (e.g., 70.5f) |
onValueChange |
Callback when value changes |
minValue |
Minimum selectable weight |
maxValue |
Maximum selectable weight |
step |
Increment between ticks (0.1 = 100g) |
onHapticFeedback |
Callback for haptic feedback on tick crossing |
style |
Customize colors, tick sizes, indicator |
Features:
- Smooth horizontal drag scrolling
- Snap to nearest tick on release
- Major ticks every 1 kg with labels
- Minor ticks every 0.1 kg
- Center indicator line with dot
- Haptic feedback callback
- Light and dark theme support
An infinite scrolling container with smooth animations and edge fade effects. Perfect for creating auto-scrolling content in any direction.
Top β Bottom |
Bottom β Top |
Left β Right |
Right β Left |
MarqueeContent(
direction = MarqueeDirection.RIGHT_TO_LEFT,
speed = 220f,
fadeEdgeColor = Color(0xFF0D0F14),
fadeEdgeWidth = 40.dp,
delayBetweenLoops = 200,
content = {
// Your scrolling content here
ConsistencyHeatmapCardGlow(
year = 2026,
month = 1,
data = HeatmapData(
dayIntensities = workoutDays,
currentStreak = 2,
recordStreak = 12,
),
today = LocalDate(2026, 1, 16),
)
}
)Key Parameters:
| Parameter | Description |
|---|---|
direction |
Scroll direction: LEFT_TO_RIGHT, RIGHT_TO_LEFT, BOTTOM_TO_TOP, TOP_TO_BOTTOM |
speed |
Scroll speed in pixels per second (default: 220f) |
fadeEdgeColor |
Color for edge gradient fade effect |
fadeEdgeWidth |
Width of fade gradient on edges (default: 40.dp) |
delayBetweenLoops |
Pause duration between animation loops in ms |
content |
Composable content to scroll infinitely |
Features:
- Four directional scrolling modes (horizontal & vertical)
- Smooth infinite loop animation with LinearEasing
- Automatic fade gradients on both edges
- Configurable speed and inter-loop delay
- Works with any composable content
- Auto-sized content measurement
- Seamless looping with no visible jumps
Usage Examples: Horizontal News Ticker:
MarqueeContent(
direction = MarqueeDirection.RIGHT_TO_LEFT,
speed = 150f,
fadeEdgeColor = MaterialTheme.colorScheme.surface,
content = {
Row(
horizontalArrangement = Arrangement.spacedBy(24.dp),
verticalAlignment = Alignment.CenterVertically
) {
repeat(5) {
Text(
"Breaking News: Important update #$it",
style = MaterialTheme.typography.titleMedium
)
}
}
}
)Vertical Infinite Feed:
MarqueeContent(
direction = MarqueeDirection.BOTTOM_TO_TOP,
speed = 100f,
modifier = Modifier.height(300.dp),
fadeEdgeWidth = 60.dp,
content = {
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
repeat(10) { index ->
Card(modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp)) {
Text(
"Item #$index",
modifier = Modifier.padding(24.dp)
)
}
}
}
}
)Common Use Cases:
News tickers and live announcements Infinite product carousels Vertical social feeds Auto-scrolling testimonials Continuous chart/data displays Award/achievement showcases
π‘ Tip: For better performance with heavy content, consider optimizing your composables and using appropriate modifiers. The component automatically measures content size for seamless looping.
Reorderable lists and grids with drag and drop functionality. Supports vertical, horizontal, and 2D grid layouts.
DraggableList - 1D reordering (vertical or horizontal):
var items by remember { mutableStateOf(listOf("A", "B", "C", "D")) }
DraggableList(
items = items,
onReorder = { newList -> items = newList },
key = { it }, // IMPORTANT: stable key for correct reordering
orientation = DragOrientation.VERTICAL,
style = DraggableListStyle(
itemSpacing = 12.dp,
draggedItemScale = 1.02f,
draggedItemElevation = 8.dp,
),
) { item, index, isDragging, dragModifier ->
Card(
modifier = Modifier
.fillMaxWidth()
.then(dragModifier), // Apply dragModifier to enable dragging
) {
Text(item)
}
}DraggableGrid - 2D reordering in a grid:
var items by remember { mutableStateOf((1..9).toList()) }
DraggableGrid(
items = items,
onReorder = { newList -> items = newList },
columns = 3,
key = { it }, // IMPORTANT: stable key for correct reordering
style = DraggableGridStyle(
itemSpacing = 12.dp,
draggedItemScale = 1.08f,
draggedItemElevation = 16.dp,
),
) { item, index, isDragging, dragModifier ->
Card(
modifier = Modifier
.aspectRatio(1f)
.then(dragModifier),
) {
Text("$item", modifier = Modifier.align(Alignment.Center))
}
}Key Parameters:
| Parameter | Description |
|---|---|
items |
List of items to display |
onReorder |
Callback with new list order after drag ends |
key |
CRITICAL: Function to extract stable unique key from item |
orientation |
VERTICAL or HORIZONTAL (DraggableList only) |
columns |
Number of grid columns (DraggableGrid only) |
style |
Customize spacing, scale, elevation, colors |
itemContent |
Composable for each item (receives dragModifier) |
Features:
- Long-press to initiate drag
- Animated item shifting during drag
- Floating copy effect with scale and elevation
- Placeholder slots showing drop positions
- Works with LazyColumn/LazyRow/LazyVerticalGrid
- Stable key support for correct recomposition
β οΈ Important: Always provide akeyfunction that returns a stable, unique identifier for each item. UsinghashCode()or mutable properties will cause incorrect behavior after reordering.
A collection of particle effects for creating stunning premium-style animations. Inspired by Telegram Premium gift screens.
Gold Classic |
Fire Burst |
Pink Dream |
Rainbow Explosion |
PremiumStarCard - Complete card with particle effects:
PremiumStarCard(
modifier = Modifier.fillMaxWidth().height(300.dp),
title = "Gift Premium",
subtitle = "Give someone access to exclusive features",
style = PremiumStarCardStyle(
accentColor = ParticleColors.Gold,
),
burstStyle = ParticleBurstStyle(
particleCount = 100,
shapes = listOf(ParticleShape.Star4Point, ParticleShape.Star6Point),
colors = ParticleColors.GoldPalette,
emissionPattern = EmissionPattern.DIAGONAL_X,
cycleDurationMs = 3000,
spreadAngle = 0.6f,
flutterEnabled = true, // Particles oscillate sideways
maxFlutterAmount = 25f,
),
flickerStyle = FlickerStarsStyle(
particleCount = 30,
colors = ParticleColors.GoldPalette,
),
effectCenterOffset = Offset(0f, -60f), // Move effects behind profile
profileContent = {
Image(
painter = painterResource(Res.drawable.profile),
contentDescription = "Profile",
modifier = Modifier.fillMaxSize().clip(CircleShape),
contentScale = ContentScale.Crop,
)
},
)ParticleBurst - Standalone particle burst effect:
ParticleBurst(
style = ParticleBurstStyle(
particleCount = 80,
shapes = listOf(ParticleShape.Star4Point, ParticleShape.Circle),
colors = ParticleColors.FirePalette,
emissionPattern = EmissionPattern.RADIAL, // 360Β° radial pattern
cycleDurationMs = 2000, // Faster = more intense
flutterEnabled = true,
),
centerOffset = Offset(0f, -50f), // Custom center point
)Key Parameters:
| Parameter | Description |
|---|---|
particleCount |
Number of particles (30-200 recommended) |
shapes |
List of ParticleShape: Star4Point, Star6Point, Circle, Icon(ImageVector), Drawable(DrawableResource) |
colors |
Color palette: GoldPalette, FirePalette, PinkPalette, RainbowPalette |
emissionPattern |
DIAGONAL_X, RADIAL, UPWARD, UPWARD_SPREAD, DOWNWARD, HORIZONTAL |
cycleDurationMs |
Animation duration (lower = faster) |
spreadAngle |
Cone width in radians (0.4-1.2) |
flutterEnabled |
Enables sideways oscillation |
maxFlutterAmount |
Oscillation amplitude in pixels |
effectCenterOffset |
Offset(x, y) to move effect origin |
Available Effects:
- ParticleBurst β Stars/shapes shooting from center
- EmberEffect β Fire-like sparks rising upward
- FlickerStarsEffect β Stars with random intermittent visibility
- StarfieldBackground β Static twinkling star background
- PremiumParticleEffect β Combined effect (all above)
- PremiumStarCard β Complete card with profile, title, and effects
A nutrition tracking card with a semicircular segmented gauge, gradient progression, and stats footer.
```kotlin NutritionCard( title = "Nutrition Overview", score = 70, // 0 to 100 scoreLabel = "Progress", stats = listOf( NutritionStat("Carbs", "149", "g"), NutritionStat("Calories", "1850", "kcal"), NutritionStat("Protein", "82", "g") ), accentGradient = listOf(Color(0xFF4DB6AC), Color(0xFFD4E157)), backgroundColor = Color(0xFF121212), contentColor = Color.White, actionIcon = Icons.Default.MoreVert // Optional action icon ) ```Key Parameters:
| Parameter | Description |
|---|---|
title |
Card title (e.g., "Nutrition Overview") |
score |
Progress value from 0 to 100 |
scoreLabel |
Label above the percentage (e.g., "Progress", "Daily Goal") |
stats |
List of NutritionStat(label, value, unit) for footer |
accentGradient |
Color gradient for filled segments |
backgroundColor |
Card background color |
actionIcon |
Optional icon in top-right corner |
Standalone Gauge Component:
NutritionGauge(
progress = 0.7f, // 0.0 to 1.0
gradient = listOf(Color(0xFF4DB6AC), Color(0xFFD4E157)),
modifier = Modifier.size(280.dp),
segments = 22, // Number of arc segments
innerRadiusDp = 80.dp,
outerRadiusDp = 110.dp,
cornerRadius = 8f, // Roundness of segment corners
showGlow = true,
glowAlpha = 0.1f
)Features:
- Semi-circular segmented arc (180Β°)
- Smooth gradient across filled segments
- Rounded segment corners with glow effect
- Inactive segments shown in dark gray
- Large centered percentage display
- Footer with up to 3 stats
- Fully customizable colors and dimensions
sharedUI/src/commonMain/kotlin/com/arcadone/awesomeui/components/
WIP
- Copy the component file(s) you need into your project
- Adjust the package declaration
- Import required dependencies (Material3, Compose Foundation)
- Use the components as shown in the snippets above
This project is open source. See LICENSE for details.