Feedback & Status
How your app talks back — toasts, banners, loading skeletons, and the four full-screen
state views. Import from dev.shipkaro.kit.core.designsystem.components (and …state for
the state views).
/docs/components/feedback-light.png/docs/components/feedback-dark.pngKitSnackbar — severity toasts
A snackbar system that reads like the intent. Get a controller, host it once, call
.success() / .error() / .info() / .warning() from anywhere.
val snackbar = rememberKitSnackbarController()
Scaffold(
snackbarHost = { KitSnackbarHost(snackbar.hostState) },
) { /* … */ }
// later, from a button or VM callback:
snackbar.success("Saved!")
snackbar.error("Couldn't reach the server")
Features
- Four styles —
info/success/warning/error— each with its semantic color + icon errordefaults to a longer duration; others short- Optional action label + callback (fires only on tap)
- A new snackbar dismisses the previous one (no queue pile-up)
- Plain
Stringmessages still use the Material default — unrelated callers keep working
KitBanner
An inline, dismissible message block — 4 styles.
KitBanner(
title = "Offline",
text = "Changes will sync when you reconnect.",
style = KitBannerStyle.WARNING, // INFO · SUCCESS · WARNING · ERROR
onDismiss = { showBanner = false }, // omit for non-dismissible
)
State views
Four full-screen (or inline) views for the empty / error / success / loading moments.
Import from …designsystem.state.
when (state) {
Loading -> KitLoadingState(label = "Loading…")
Empty -> KitEmptyState(
title = "No habits yet",
message = "Add your first habit to start a streak.",
actionText = "Add habit",
onAction = ::addHabit,
)
is Error -> KitErrorState(message = state.message, onAction = ::retry)
Success -> KitSuccessState(title = "All done!")
}
Features — each takes an optional message + action button; fullScreen = false renders
an inline variant for use inside a list or card. KitInlineLoading is the compact spinner.
Loading placeholders — Shimmer & Skeleton
// Shimmer modifier on any box
Box(Modifier.size(120.dp, 16.dp).kitShimmer())
// Prebuilt skeletons
KitSkeleton(width = 200.dp, height = 20.dp)
KitSkeletonListItem() // avatar + two lines
KitLinearProgress · KitPullToRefresh
KitLinearProgress(progress = uploaded / total) // determinate
KitIndeterminateLinearProgress() // unknown duration
KitPullToRefresh(isRefreshing = refreshing, onRefresh = ::reload) {
LazyColumn { /* … */ }
}
KitBadge · KitRatingBar
// Count overlay on any composable
KitBadge(count = unread, maxCount = 99) { Icon(KitTheme.icons.bell, null) }
// Tappable 5-star rating (tap the same star to clear)
KitRatingBar(rating = stars, onRatingChange = { stars = it })
Next: Navigation & Media — bottom nav, FAB, avatar, web view.