
Snackbar-style API for elegant toast notifications with stacked toasts, gestures (tap-to-pause, swipe-to-dismiss), category theming, auto-dismiss and smooth spring animations, customizable visuals and easy integration.
🍞 A powerful and elegant toast notification library for Compose Multiplatform with gestures, animations, and theming support.
@Composable
fun App() {
val toastHostState = rememberToastHostState()
val scope = rememberCoroutineScope()
ToastScaffold(
toastHost = { ToastHost(hostState = toastHostState) }
) { paddingValues ->
Button(
onClick = {
scope.launch {
toastHostState.showToast(
message = "Hello, Toast!",
category = ToastCategory.Success
)
}
}
) {
Text("Show Toast")
}
}
}Add the dependency below to your module's build.gradle file:
dependencies {
implementation("io.github.androidpoet:dhyantoast:$version")
}Add the dependency below to your module's build.gradle.kts file:
sourceSets {
commonMain.dependencies {
implementation("io.github.androidpoet:dhyantoast:$version")
}
}Or using the older syntax:
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.github.androidpoet:dhyantoast:$version")
}
}
}DhyānToast follows the same pattern as Material3's Snackbar API, making it familiar and easy to use.
@Composable
fun MyApp() {
// 1. Create toast host state
val toastHostState = rememberToastHostState()
val scope = rememberCoroutineScope()
// 2. Use ToastScaffold instead of regular Scaffold
ToastScaffold(
toastHost = {
ToastHost(
hostState = toastHostState,
alignment = ToastAlignment.Bottom,
autoDismissEnabled = true,
autoDismissDelay = 3000L
)
}
) { paddingValues ->
// Your content here
Button(
onClick = {
scope.launch {
// 3. Show toasts from coroutines
toastHostState.showToast(
message = "Operation completed!",
category = ToastCategory.Success
)
}
}
) {
Text("Show Toast")
}
}
}// Success toast
toastHostState.showToast(
message = "Operation completed successfully!",
title = "Success",
category = ToastCategory.Success
)
// Error toast
toastHostState.showToast(
message = "Something went wrong!",
title = "Error",
category = ToastCategory.Error
)
// Warning toast
toastHostState.showToast(
message = "Please check your input",
title = "Warning",
category = ToastCategory.Warning
)
// General/Info toast
toastHostState.showToast(
message = "Here's some useful information",
category = ToastCategory.General
)
// Custom category
toastHostState.showToast(
message = "Custom notification",
category = ToastCategory.Custom("analytics")
)val toastTheme = ToastTheme(
success = ToastCategoryStyle(
backgroundColor = Color(0xFF4CAF50),
textColor = Color.White,
icon = Icons.Default.Check
),
error = ToastCategoryStyle(
backgroundColor = Color(0xFFF44336),
textColor = Color.White,
icon = Icons.Default.Close
),
warning = ToastCategoryStyle(
backgroundColor = Color(0xFFFF9800),
textColor = Color.White,
icon = Icons.Default.Warning
)
)
ToastHost(
hostState = toastHostState,
theme = toastTheme,
showCloseButton = true,
alignment = ToastAlignment.Top,
visibleCount = 3
)ToastHost(
hostState = toastHostState,
alignment = ToastAlignment.Top, // Top or Bottom
autoDismissEnabled = true, // Auto-dismiss toasts
autoDismissDelay = 3000L, // 3 seconds
visibleCount = 3, // Max visible toasts in stack
categories = listOf( // Filter specific categories
ToastCategory.Success,
ToastCategory.Error
),
maxWidth = 400.dp, // Max width on larger screens
contentPadding = PaddingValues(16.dp), // Padding around toasts
showCloseButton = true, // Show close button
theme = toastTheme // Custom theme
)You can provide your own toast composable for completely custom UI:
ToastHost(
hostState = toastHostState,
toast = { toastData ->
// Your custom toast UI
Surface(
modifier = Modifier.fillMaxWidth().padding(8.dp),
shape = RoundedCornerShape(16.dp),
color = MaterialTheme.colorScheme.primary
) {
Row(modifier = Modifier.padding(16.dp)) {
Text(
text = toastData.message,
color = MaterialTheme.colorScheme.onPrimary
)
}
}
}
)// Clear all toasts
toastHostState.clearAll()
// Dismiss a specific toast
toastData.dismiss()DhyānToast supports intuitive gesture-based interactions:
showCloseButton = true
DhyānToast works on all Compose Multiplatform targets:
| Platform | Status |
|---|---|
| Android | ✅ Supported |
| iOS | ✅ Supported |
| Desktop (JVM) | ✅ Supported |
| Web (JS/WASM) | ✅ Supported |
| macOS | ✅ Supported |
While both use similar APIs, they serve different purposes:
| Feature | DhyānToast | Material3 Snackbar |
|---|---|---|
| Multiple notifications | ✅ Stacked toasts | ❌ One at a time |
| Gesture interactions | ✅ Tap to pause, swipe to dismiss | ❌ Limited |
| Auto-dismiss | ✅ Configurable per toast | |
| Category theming | ✅ Success, Error, Warning, etc. | ❌ Manual styling |
| Stack management | ✅ Visible count control | N/A |
| Alignment | ✅ Top or Bottom | |
| Use case | Non-critical notifications | Actions with undo |
Use DhyānToast when:
Use Snackbar when:
showToast() - Show a new toast notificationclearAll() - Clear all active toastsSnackbarHostState from Material3toastHost parameter while maintaining all Scaffold featurestopBar, bottomBar, snackbarHost, floatingActionButton, etc.ToastCategory.Success - Success notificationsToastCategory.Error - Error messagesToastCategory.Warning - Warning alertsToastCategory.General - General informationToastCategory.Custom(name) - Custom categoriesToastAlignment.Top - Show toasts at top of screenToastAlignment.Bottom - Show toasts at bottom of screen"Dhyān" (ध्यान) means "attention" or "focus" in Sanskrit. This library is designed to grab user attention elegantly with:
visibleCount to limit visible toasts and maintain performancetoastHostState.clearAll()
autoDismissDelay to avoid overwhelming users// Good - Clear and actionable
toastHostState.showToast(
title = "File saved",
message = "Document.pdf saved successfully",
category = ToastCategory.Success
)
// Avoid - Too verbose
toastHostState.showToast(
title = "Success",
message = "The file that you have been working on has been successfully saved to your device storage",
category = ToastCategory.Success
)Contributions are welcome! Please feel free to submit a Pull Request.
Support it by joining stargazers for this repository. ⭐ Also, follow me on GitHub for more cool projects!
Copyright 2025 AndroidPoet (Ranbir Singh)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.🍞 A powerful and elegant toast notification library for Compose Multiplatform with gestures, animations, and theming support.
@Composable
fun App() {
val toastHostState = rememberToastHostState()
val scope = rememberCoroutineScope()
ToastScaffold(
toastHost = { ToastHost(hostState = toastHostState) }
) { paddingValues ->
Button(
onClick = {
scope.launch {
toastHostState.showToast(
message = "Hello, Toast!",
category = ToastCategory.Success
)
}
}
) {
Text("Show Toast")
}
}
}Add the dependency below to your module's build.gradle file:
dependencies {
implementation("io.github.androidpoet:dhyantoast:$version")
}Add the dependency below to your module's build.gradle.kts file:
sourceSets {
commonMain.dependencies {
implementation("io.github.androidpoet:dhyantoast:$version")
}
}Or using the older syntax:
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.github.androidpoet:dhyantoast:$version")
}
}
}DhyānToast follows the same pattern as Material3's Snackbar API, making it familiar and easy to use.
@Composable
fun MyApp() {
// 1. Create toast host state
val toastHostState = rememberToastHostState()
val scope = rememberCoroutineScope()
// 2. Use ToastScaffold instead of regular Scaffold
ToastScaffold(
toastHost = {
ToastHost(
hostState = toastHostState,
alignment = ToastAlignment.Bottom,
autoDismissEnabled = true,
autoDismissDelay = 3000L
)
}
) { paddingValues ->
// Your content here
Button(
onClick = {
scope.launch {
// 3. Show toasts from coroutines
toastHostState.showToast(
message = "Operation completed!",
category = ToastCategory.Success
)
}
}
) {
Text("Show Toast")
}
}
}// Success toast
toastHostState.showToast(
message = "Operation completed successfully!",
title = "Success",
category = ToastCategory.Success
)
// Error toast
toastHostState.showToast(
message = "Something went wrong!",
title = "Error",
category = ToastCategory.Error
)
// Warning toast
toastHostState.showToast(
message = "Please check your input",
title = "Warning",
category = ToastCategory.Warning
)
// General/Info toast
toastHostState.showToast(
message = "Here's some useful information",
category = ToastCategory.General
)
// Custom category
toastHostState.showToast(
message = "Custom notification",
category = ToastCategory.Custom("analytics")
)val toastTheme = ToastTheme(
success = ToastCategoryStyle(
backgroundColor = Color(0xFF4CAF50),
textColor = Color.White,
icon = Icons.Default.Check
),
error = ToastCategoryStyle(
backgroundColor = Color(0xFFF44336),
textColor = Color.White,
icon = Icons.Default.Close
),
warning = ToastCategoryStyle(
backgroundColor = Color(0xFFFF9800),
textColor = Color.White,
icon = Icons.Default.Warning
)
)
ToastHost(
hostState = toastHostState,
theme = toastTheme,
showCloseButton = true,
alignment = ToastAlignment.Top,
visibleCount = 3
)ToastHost(
hostState = toastHostState,
alignment = ToastAlignment.Top, // Top or Bottom
autoDismissEnabled = true, // Auto-dismiss toasts
autoDismissDelay = 3000L, // 3 seconds
visibleCount = 3, // Max visible toasts in stack
categories = listOf( // Filter specific categories
ToastCategory.Success,
ToastCategory.Error
),
maxWidth = 400.dp, // Max width on larger screens
contentPadding = PaddingValues(16.dp), // Padding around toasts
showCloseButton = true, // Show close button
theme = toastTheme // Custom theme
)You can provide your own toast composable for completely custom UI:
ToastHost(
hostState = toastHostState,
toast = { toastData ->
// Your custom toast UI
Surface(
modifier = Modifier.fillMaxWidth().padding(8.dp),
shape = RoundedCornerShape(16.dp),
color = MaterialTheme.colorScheme.primary
) {
Row(modifier = Modifier.padding(16.dp)) {
Text(
text = toastData.message,
color = MaterialTheme.colorScheme.onPrimary
)
}
}
}
)// Clear all toasts
toastHostState.clearAll()
// Dismiss a specific toast
toastData.dismiss()DhyānToast supports intuitive gesture-based interactions:
showCloseButton = true
DhyānToast works on all Compose Multiplatform targets:
| Platform | Status |
|---|---|
| Android | ✅ Supported |
| iOS | ✅ Supported |
| Desktop (JVM) | ✅ Supported |
| Web (JS/WASM) | ✅ Supported |
| macOS | ✅ Supported |
While both use similar APIs, they serve different purposes:
| Feature | DhyānToast | Material3 Snackbar |
|---|---|---|
| Multiple notifications | ✅ Stacked toasts | ❌ One at a time |
| Gesture interactions | ✅ Tap to pause, swipe to dismiss | ❌ Limited |
| Auto-dismiss | ✅ Configurable per toast | |
| Category theming | ✅ Success, Error, Warning, etc. | ❌ Manual styling |
| Stack management | ✅ Visible count control | N/A |
| Alignment | ✅ Top or Bottom | |
| Use case | Non-critical notifications | Actions with undo |
Use DhyānToast when:
Use Snackbar when:
showToast() - Show a new toast notificationclearAll() - Clear all active toastsSnackbarHostState from Material3toastHost parameter while maintaining all Scaffold featurestopBar, bottomBar, snackbarHost, floatingActionButton, etc.ToastCategory.Success - Success notificationsToastCategory.Error - Error messagesToastCategory.Warning - Warning alertsToastCategory.General - General informationToastCategory.Custom(name) - Custom categoriesToastAlignment.Top - Show toasts at top of screenToastAlignment.Bottom - Show toasts at bottom of screen"Dhyān" (ध्यान) means "attention" or "focus" in Sanskrit. This library is designed to grab user attention elegantly with:
visibleCount to limit visible toasts and maintain performancetoastHostState.clearAll()
autoDismissDelay to avoid overwhelming users// Good - Clear and actionable
toastHostState.showToast(
title = "File saved",
message = "Document.pdf saved successfully",
category = ToastCategory.Success
)
// Avoid - Too verbose
toastHostState.showToast(
title = "Success",
message = "The file that you have been working on has been successfully saved to your device storage",
category = ToastCategory.Success
)Contributions are welcome! Please feel free to submit a Pull Request.
Support it by joining stargazers for this repository. ⭐ Also, follow me on GitHub for more cool projects!
Copyright 2025 AndroidPoet (Ranbir Singh)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.