Snackbar provides brief feedback about an operation through a message at the bottom of the screen. Snackbars can contain an action button and are temporary by default.
Usage
import com.nomanr.lumo.ui.components.snackbar.Snackbar
import com.nomanr.lumo.ui.components.snackbar.SnackbarHost
val snackbarHostState = remember { SnackbarHostState() }
// Show snackbar
scope.launch {
snackbarHostState.showSnackbar(
message = "Item deleted",
actionLabel = "Undo"
)
}
// Display snackbar
SnackbarHost(hostState = snackbarHostState)
Variants
Simple Snackbar
Basic message without action:
Snackbar(
modifier = Modifier,
content = {
Text("Changes saved successfully")
}
)
Snackbar with Action
Include an action button:
Snackbar(
modifier = Modifier,
action = {
Text(
text = "UNDO",
modifier = Modifier.clickable { /* Handle action */ }
)
},
content = {
Text("Item deleted")
}
)
Snackbar with Dismiss Action
Add a dismiss button:
Snackbar(
modifier = Modifier,
action = {
Text("UNDO", modifier = Modifier.clickable { })
},
dismissAction = {
IconButton(onClick = { /* Dismiss */ }) {
Icon(Icons.Default.Close, "Dismiss")
}
},
content = {
Text("Message sent")
}
)
Using SnackbarData
With Material’s SnackbarHostState:
val snackbarHostState = remember { SnackbarHostState() }
SnackbarHost(snackbarHostState) { data ->
Snackbar(
snackbarData = data,
containerColor = AppTheme.colors.primary,
contentColor = AppTheme.colors.onPrimary
)
}
// Trigger snackbar
scope.launch {
val result = snackbarHostState.showSnackbar(
message = "Operation completed",
actionLabel = "View",
withDismissAction = true
)
when (result) {
SnackbarResult.ActionPerformed -> { /* Handle action */ }
SnackbarResult.Dismissed -> { /* Handle dismiss */ }
}
}
Parameters
Snackbar (with SnackbarData)
Data object containing the snackbar message and actions
modifier
Modifier
default:"Modifier"
Modifier for the snackbar container
shape
Shape
default:"RoundedCornerShape(12.dp)"
The shape of the snackbar
containerColor
Color
default:"AppTheme.colors.primary"
Background color of the snackbar
contentColor
Color
default:"AppTheme.colors.onPrimary"
Color for the message text
actionColor
Color
default:"AppTheme.colors.onPrimary"
Background color for the action button
actionContentColor
Color
default:"AppTheme.colors.primary"
Text color for the action button
dismissActionContentColor
Color
default:"AppTheme.colors.onPrimary"
Color for the dismiss action
Snackbar (Custom)
modifier
Modifier
default:"Modifier"
Modifier for the snackbar container
action
@Composable (() -> Unit)?
default:"null"
Optional action button content
dismissAction
@Composable (() -> Unit)?
default:"null"
Optional dismiss button content
shape
Shape
default:"RoundedCornerShape(12.dp)"
The shape of the snackbar
containerColor
Color
default:"AppTheme.colors.primary"
Background color of the snackbar
contentColor
Color
default:"AppTheme.colors.onPrimary"
Color for the message text
actionContentColor
Color
default:"AppTheme.colors.primary"
Text color for the action button
dismissActionContentColor
Color
default:"AppTheme.colors.onPrimary"
Color for the dismiss action
content
@Composable () -> Unit
required
The message content to display
Styling
Custom Colors
Snackbar(
containerColor = Color(0xFF323232),
contentColor = Color.White,
content = { Text("Dark themed snackbar") }
)
Custom Shape
Snackbar(
shape = RoundedCornerShape(8.dp),
content = { Text("Custom rounded corners") }
)
Layout Specifications
The snackbar has the following layout specifications:
- Container Max Width: 600.dp
- Single Line Height: 56.dp
- Two Lines Height: 68.dp
- Horizontal Spacing: 16.dp
- Horizontal Spacing (Button Side): 8.dp
- Vertical Padding: 6.dp
- Elevation: 8.dp
- Default Shape: RoundedCornerShape(12.dp)
Best Practices
- Brief Messages: Keep messages short and actionable
- Single Action: Include at most one action button
- Action Labels: Use short, action-oriented labels like “UNDO”, “VIEW”, “RETRY”
- Duration: Let snackbars auto-dismiss after a few seconds
- Positioning: Display at the bottom of the screen, above navigation bars
- Frequency: Don’t show multiple snackbars simultaneously
- Accessibility: Ensure action buttons are easily tappable (min 44dp height)
Integration with SnackbarHost
For proper snackbar management in your app:
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
snackbarHost = {
SnackbarHost(hostState = snackbarHostState) { data ->
Snackbar(
snackbarData = data,
modifier = Modifier.padding(16.dp)
)
}
}
) {
// Your content
Button(
onClick = {
scope.launch {
snackbarHostState.showSnackbar("Action completed")
}
}
) {
Text("Show Snackbar")
}
}
Source Reference
See the full implementation in Snackbar.kt:44-97 and Snackbar.kt:100-131.