
Animated, themeable onboarding flows with page models supporting titles, images and custom content; built-in navigation controls, animated indicators, and global header/footer slots for brand alignment.
KMP Onboarding is a Kotlin Multiplatform library that helps you build rich, animated onboarding flows with Jetpack Compose Multiplatform. It provides ready-made UI primitives for paging, navigation controls, and page indicators so you can focus on your product story instead of wiring boilerplate.
PageViewModel.Add the dependency to the commonMain source set of your Compose Multiplatform project:
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.github.yskuem:kmp-onboarding:1.0.3")
}
}
}
}Below is a simple onboarding flow that demonstrates how to configure pages, customize controls, and react to user actions.
@Composable
fun OnboardingScreen(onFinished: () -> Unit) {
// Define pages with title/body and optional image/decoration.
val pages = listOf(
PageViewModel(
title = "Welcome",
body = "Turn your notes into bite-size quizzes and master grammar faster.",
image = {
Icon(
imageVector = Icons.Outlined.School,
contentDescription = null,
modifier = Modifier.size(160.dp)
)
},
decoration = PageDecoration(
gradient = Brush.verticalGradient(
colors = listOf(
Color(0xFFFFF5F0),
Color(0xFFFFE2D6)
)
)
)
),
PageViewModel(
title = "Auto-generated Quizzes",
body = "Create quizzes from photos of your textbooks and notes.",
image = {
Icon(
imageVector = Icons.Outlined.Quiz,
contentDescription = null,
modifier = Modifier.size(160.dp)
)
},
decoration = PageDecoration(pageColor = Color(0xFFEDEBFA)) // subtle lilac tint
),
PageViewModel(
title = "Daily Progress",
body = "Track streaks and stay motivated with lightweight reminders.",
image = {
Icon(
imageVector = Icons.Outlined.AutoAwesome,
contentDescription = null,
modifier = Modifier.size(160.dp)
)
},
decoration = PageDecoration(pageColor = Color(0xFFE4F5F1))
)
)
// If you want programmatic control, provide your own state:
// val state = rememberIntroState { pages.size }
IntroductionScreen(
pages = pages,
// state = state, // uncomment if you use rememberIntroState above
showSkipButton = true,
showNextButton = true,
showBackButton = true,
showDoneButton = true,
// Button slots
skip = { Text("Skip") },
next = { Text("Next") },
back = { Text("Back") },
done = { Text("Get Started") },
// Callbacks
onSkip = { /* Jump to the end or mark onboarding as seen */ },
onDone = { onFinished() },
// Indicator container styling
dotsContainerStyle = DotsContainerStyle(
containerColor = Color.Transparent,
containerColor = Color.Transparent,
contentPadding = PaddingValues(20.dp)
),
// Button styling
nextButtonStyle = IntroButtonStyle(
containerColor = Color(0xFF6666FF),
contentColor = Color.White,
shape = RoundedCornerShape(8.dp)
),
doneButtonStyle = IntroButtonStyle(
containerColor = Color(0xFF6666FF),
contentColor = Color.White,
shape = RoundedCornerShape(8.dp)
)
// You can also provide globalHeader / globalFooter for a persistent logo/CTA.
)
}rawPages if you need full control over each page's composable content.IntroState via rememberIntroState to control paging programmatically.DotsDecorator to adjust indicator size, shape, colors, and spacing.IntroButtonStyle to change button colors, shapes, and padding.globalHeader and globalFooter slots to inject persistent content like logos or call-to-action buttons.A working sample is included under composeApp. You can run it on Android or iOS to see the onboarding experience in action.
Please refer to the repository for licensing information and usage terms.
KMP Onboarding is a Kotlin Multiplatform library that helps you build rich, animated onboarding flows with Jetpack Compose Multiplatform. It provides ready-made UI primitives for paging, navigation controls, and page indicators so you can focus on your product story instead of wiring boilerplate.
PageViewModel.Add the dependency to the commonMain source set of your Compose Multiplatform project:
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.github.yskuem:kmp-onboarding:1.0.3")
}
}
}
}Below is a simple onboarding flow that demonstrates how to configure pages, customize controls, and react to user actions.
@Composable
fun OnboardingScreen(onFinished: () -> Unit) {
// Define pages with title/body and optional image/decoration.
val pages = listOf(
PageViewModel(
title = "Welcome",
body = "Turn your notes into bite-size quizzes and master grammar faster.",
image = {
Icon(
imageVector = Icons.Outlined.School,
contentDescription = null,
modifier = Modifier.size(160.dp)
)
},
decoration = PageDecoration(
gradient = Brush.verticalGradient(
colors = listOf(
Color(0xFFFFF5F0),
Color(0xFFFFE2D6)
)
)
)
),
PageViewModel(
title = "Auto-generated Quizzes",
body = "Create quizzes from photos of your textbooks and notes.",
image = {
Icon(
imageVector = Icons.Outlined.Quiz,
contentDescription = null,
modifier = Modifier.size(160.dp)
)
},
decoration = PageDecoration(pageColor = Color(0xFFEDEBFA)) // subtle lilac tint
),
PageViewModel(
title = "Daily Progress",
body = "Track streaks and stay motivated with lightweight reminders.",
image = {
Icon(
imageVector = Icons.Outlined.AutoAwesome,
contentDescription = null,
modifier = Modifier.size(160.dp)
)
},
decoration = PageDecoration(pageColor = Color(0xFFE4F5F1))
)
)
// If you want programmatic control, provide your own state:
// val state = rememberIntroState { pages.size }
IntroductionScreen(
pages = pages,
// state = state, // uncomment if you use rememberIntroState above
showSkipButton = true,
showNextButton = true,
showBackButton = true,
showDoneButton = true,
// Button slots
skip = { Text("Skip") },
next = { Text("Next") },
back = { Text("Back") },
done = { Text("Get Started") },
// Callbacks
onSkip = { /* Jump to the end or mark onboarding as seen */ },
onDone = { onFinished() },
// Indicator container styling
dotsContainerStyle = DotsContainerStyle(
containerColor = Color.Transparent,
containerColor = Color.Transparent,
contentPadding = PaddingValues(20.dp)
),
// Button styling
nextButtonStyle = IntroButtonStyle(
containerColor = Color(0xFF6666FF),
contentColor = Color.White,
shape = RoundedCornerShape(8.dp)
),
doneButtonStyle = IntroButtonStyle(
containerColor = Color(0xFF6666FF),
contentColor = Color.White,
shape = RoundedCornerShape(8.dp)
)
// You can also provide globalHeader / globalFooter for a persistent logo/CTA.
)
}rawPages if you need full control over each page's composable content.IntroState via rememberIntroState to control paging programmatically.DotsDecorator to adjust indicator size, shape, colors, and spacing.IntroButtonStyle to change button colors, shapes, and padding.globalHeader and globalFooter slots to inject persistent content like logos or call-to-action buttons.A working sample is included under composeApp. You can run it on Android or iOS to see the onboarding experience in action.
Please refer to the repository for licensing information and usage terms.