Blocks
CircleUp Onboarding
An AR social app onboarding slide with floating feature pills, progress dots and dual sign-up CTAs.
CircleUp
✦✦✦✦
Intuitive
Full integration
😊
Easy to use
Just select the AR button when interacting with posts, choose your desired effect or object, and watch as it magically appears on your screen
Installation
caveui components are copy-paste Jetpack Compose built entirely on Material 3 — there's no caveui dependency to add. Make sure Material 3 is on your classpath (it ships with the Compose BOM), then copy the Usage snippet below into your project.
kotlin
// build.gradle.kts (module)
dependencies {
implementation(platform("androidx.compose:compose-bom:2025.06.00"))
implementation("androidx.compose.material3:material3")
}Usage
kotlin
@Composable
fun CircleUpOnboardingScreen(
page: Int = 2,
totalPages: Int = 4,
onSignUp: () -> Unit,
onLogIn: () -> Unit,
) {
val indigo = Color(0xFF2D3282)
val bg = Color(0xFF8B8FD4)
Column(
modifier = Modifier
.fillMaxSize()
.background(bg)
.padding(horizontal = 20.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(Modifier.height(28.dp))
Text(
"CircleUp",
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold,
color = Color.White,
)
Spacer(Modifier.height(16.dp))
// Illustration card
Box(
modifier = Modifier
.fillMaxWidth()
.height(220.dp)
.clip(RoundedCornerShape(20.dp))
.background(Color(0xFF6B6FC4)),
) {
// Stars
repeat(4) { i ->
Text(
"✦",
color = Color.White.copy(alpha = 0.5f),
fontSize = if (i % 2 == 0) 10.sp else 7.sp,
modifier = Modifier.padding(
start = (16 + i * 40).dp,
top = (12 + i * 14).dp,
),
)
}
// Person silhouette
Box(
modifier = Modifier
.align(Alignment.BottomCenter)
.width(96.dp)
.height(140.dp)
.clip(
RoundedCornerShape(topStart = 48.dp, topEnd = 48.dp)
)
.background(Color.White.copy(alpha = 0.18f)),
)
// VR headset bar
Box(
modifier = Modifier
.align(Alignment.Center)
.width(72.dp)
.height(20.dp)
.offset(y = 8.dp)
.clip(RoundedCornerShape(6.dp))
.background(Color(0xFF1a1a2e).copy(alpha = 0.7f)),
)
// "Intuitive" pill
Surface(
color = Color.White,
shape = RoundedCornerShape(12.dp),
modifier = Modifier
.align(Alignment.TopStart)
.padding(start = 12.dp, top = 36.dp),
) {
Text(
"Intuitive",
modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp),
style = MaterialTheme.typography.labelLarge,
fontWeight = FontWeight.Bold,
color = Color(0xFF1a1a2e),
)
}
// "Full integration" pill
Surface(
color = Color.White,
shape = RoundedCornerShape(12.dp),
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(end = 10.dp, bottom = 36.dp),
) {
Text(
"Full integration",
modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp),
style = MaterialTheme.typography.labelLarge,
fontWeight = FontWeight.Bold,
color = Color(0xFF1a1a2e),
)
}
// Emoji badge
Surface(
shape = CircleShape,
color = Color.White,
modifier = Modifier
.align(Alignment.TopEnd)
.padding(end = 20.dp, top = 56.dp)
.size(40.dp),
) {
Box(contentAlignment = Alignment.Center) {
Text("😊", fontSize = 20.sp)
}
}
// AR icon badge
Surface(
shape = CircleShape,
color = Color.White,
border = BorderStroke(2.dp, Color(0xFFE8612C)),
modifier = Modifier
.align(Alignment.BottomStart)
.padding(start = 14.dp, bottom = 48.dp)
.size(40.dp),
) {
Box(contentAlignment = Alignment.Center) {
Icon(
Icons.Outlined.ViewInAr,
contentDescription = "AR",
tint = Color(0xFFE8612C),
modifier = Modifier.size(20.dp),
)
}
}
}
Spacer(Modifier.height(20.dp))
// Progress dots
Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
repeat(totalPages) { i ->
Box(
Modifier
.height(8.dp)
.width(if (i == page) 24.dp else 8.dp)
.clip(CircleShape)
.background(
if (i == page) Color.White
else Color.White.copy(alpha = 0.4f),
),
)
}
}
Spacer(Modifier.height(16.dp))
Text(
"Easy to use",
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.ExtraBold,
color = Color.White,
)
Text(
"Just select the AR button when interacting with posts, choose your desired effect or object, and watch as it magically appears on your screen",
modifier = Modifier.padding(top = 8.dp),
style = MaterialTheme.typography.bodyMedium,
color = Color.White.copy(alpha = 0.8f),
textAlign = TextAlign.Center,
)
Spacer(Modifier.height(24.dp))
Button(
onClick = onSignUp,
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(14.dp),
colors = ButtonDefaults.buttonColors(containerColor = indigo),
) {
Text(
"Sign Up",
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Bold,
)
}
TextButton(onClick = onLogIn, modifier = Modifier.padding(top = 4.dp)) {
Text(
"Log in",
color = Color.White,
style = MaterialTheme.typography.bodyMedium,
)
}
}
}