Try a free component

Get familiar with Compose Examples by adding a free component in your project

🔎
Step 1
Find a component
{}
Step 2
Copy the code
🎨
Step 3
Customize away
In Avatars

Avatar stack

@Composable
fun AvatarPhoto(imageUrl: String, modifier: Modifier = Modifier) {
    AsyncImage(
        model = imageUrl,
        modifier = modifier.size(40.dp).clip(CircleShape).background(Color.White).border(2.dp, Color.White, CircleShape),
        contentScale = ContentScale.Crop,
        contentDescription = "Avatar",
    )
}

Column(Modifier.padding(24.dp), verticalArrangement = Arrangement.spacedBy(24.dp), horizontalAlignment = Alignment.CenterHorizontally) {
    Row(horizontalArrangement = Arrangement.spacedBy((-12).dp), verticalAlignment = Alignment.CenterVertically) {
        AvatarPhoto(modifier = Modifier.size(32.dp), imageUrl = "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?fit=crop&w=512&q=80")
        AvatarPhoto(modifier = Modifier.zIndex(25f).size(40.dp), imageUrl = "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?fit=crop&w=512&q=80")
        AvatarPhoto(modifier = Modifier.zIndex(50f).size(48.dp), imageUrl = "https://images.unsplash.com/photo-1567532939604-b6b5b0db2604?fit=crop&w=512&q=80")
        AvatarPhoto(modifier = Modifier.zIndex(25f).size(40.dp), imageUrl = "https://images.unsplash.com/photo-1540569014015-19a7be504e3a?fit=crop&w=512&q=80")
        AvatarPhoto(modifier = Modifier.size(32.dp), imageUrl = "https://images.unsplash.com/photo-1506863530036-1efeddceb993?fit=crop&w=512&q=80")
    }

    Row(horizontalArrangement = Arrangement.spacedBy((-12).dp), verticalAlignment = Alignment.CenterVertically) {
        AvatarPhoto(imageUrl = "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?fit=crop&w=512&q=80")
        AvatarPhoto(imageUrl = "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?fit=crop&w=512&q=80")
        AvatarPhoto(imageUrl = "https://images.unsplash.com/photo-1567532939604-b6b5b0db2604?fit=crop&w=512&q=80")
        AvatarPhoto(imageUrl = "https://images.unsplash.com/photo-1540569014015-19a7be504e3a?fit=crop&w=512&q=80")
        AvatarPhoto(imageUrl = "https://images.unsplash.com/photo-1506863530036-1efeddceb993?fit=crop&w=512&q=80")
    }
}
In Lists

Simple List

data class Person(val name: String, val email: String, val photoUrl: String)

val items = listOf(
    Person(name = "Jenny", email = "jenny@email.com", photoUrl = "https://images.unsplash.com/photo-1517841905240-472988babdf9?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=256&q=80"),
    Person(name = "James", email = "james@email.com", photoUrl = "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=256&q=80"),
    Person(name = "Cassidy", email = "cassidy@email.com", photoUrl = "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=256&q=80"),
    Person(name = "Kim", email = "kim@email.com", photoUrl = "https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=256&q=80"),
    Person(name = "Samantha", email = "sam@email.com", photoUrl = "https://images.unsplash.com/photo-1580489944761-15a19d654956?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=256&q=80"),
    Person(name = "John", email = "john@email.com", photoUrl = "https://images.unsplash.com/photo-1580518380430-2f84c0a7fb85?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=256&q=80"),
)

LazyColumn(contentPadding = PaddingValues(vertical = 20.dp)) {
    items(items) { item ->
        Surface(onClick = { /* TODO */ }, shape = MaterialTheme.shapes.large) {
            Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier.fillMaxWidth().padding(16.dp)) {
                AsyncImage(model = item.photoUrl, modifier = Modifier.size(58.dp).clip(CircleShape), contentScale = ContentScale.Crop, contentDescription = null)
                Column {
                    Text(text = item.name, maxLines = 1, overflow = TextOverflow.Ellipsis)
                    Spacer(Modifier.height(4.dp))
                    Text(text = item.email, style = MaterialTheme.typography.bodyMedium, maxLines = 1, overflow = TextOverflow.Ellipsis)
                }
            }
        }
    }
}
In Dialogs

Start aligned when large

/**
 * Add the following dependency to your build.gradle.kts:
 *
 * dependencies {
 *      implementation("com.composables:core:1.11.0")
 * }
 */
 
val state = rememberDialogState(visible = true)

LaunchedEffect(state.visible) {
    if (state.visible.not()) {
        delay(1000)
        state.visible = true
    }
}
BoxWithConstraints {
    val isCompact = maxWidth <= 600.dp

    Dialog(state) {
        Scrim(enter = fadeIn(), exit = fadeOut(), scrimColor = Color.Black.copy(0.3f))
        DialogPanel(
            modifier = Modifier.systemBarsPadding()
                .padding(16.dp)
                .shadow(8.dp, ComposeTheme.shapes.roundL)
                .background(Color.White, ComposeTheme.shapes.round)
                .padding(24.dp),
            enter = scaleIn(initialScale = 0.8f) + fadeIn(tween(durationMillis = 250)),
            exit = scaleOut(targetScale = 0.6f) + fadeOut(tween(durationMillis = 150))
        ) {
            Column(
                modifier = Modifier.let {
                    if (isCompact) it.fillMaxWidth() else it.widthIn(min = 280.dp, max = 520.dp)
                },
                horizontalAlignment = if (isCompact) Alignment.CenterHorizontally else Alignment.Start
            ) {
                BasicText(
                    text = "Are you sure?",
                    style = ComposeTheme.textStyles.base.copy(
                        fontWeight = FontWeight.Medium,
                        color = ComposeTheme.colors.gray900,
                        textAlign = if (isCompact) TextAlign.Center else TextAlign.Start
                    )
                )
                Spacer(Modifier.height(16.dp))
                BasicText(
                    text = "This action cannot be undone. Choose wisely.",
                    style = ComposeTheme.textStyles.base.copy(
                        fontWeight = FontWeight.Normal,
                        color = ComposeTheme.colors.gray600,
                        textAlign = if (isCompact) TextAlign.Center else TextAlign.Start
                    )
                )
                Spacer(Modifier.height(24.dp))
                Row(
                    horizontalArrangement = Arrangement.spacedBy(8.dp, alignment = Alignment.End),
                    modifier = Modifier.fillMaxWidth()
                ) {
                    Box(Modifier.clip(ComposeTheme.shapes.roundL)
                        .clickable(role = Role.Button) { state.visible = false }
                        .border(1.dp, Color(0xFFBDBDBD), ComposeTheme.shapes.roundL)
                        .padding(horizontal = 14.dp, vertical = 10.dp)
                        .let { if (isCompact) it.weight(1f) else it },
                        contentAlignment = Alignment.Center
                    ) {
                        BasicText(
                            text = "Cancel", style = ComposeTheme.textStyles.base.copy(
                                color = Color(0xFF424242), fontWeight = FontWeight.Medium
                            )
                        )
                    }
                    Box(
                        Modifier.clip(ComposeTheme.shapes.roundL)
                            .clickable(role = Role.Button) { state.visible = false }.background(Color(0xFF212121))
                            .padding(horizontal = 14.dp, vertical = 10.dp)
                            .let { if (isCompact) it.weight(1f) else it },
                        contentAlignment = Alignment.Center
                    ) {
                        BasicText(
                            text = "Continue", style = ComposeTheme.textStyles.base.copy(
                                color = Color.White, fontWeight = FontWeight.Medium
                            )
                        )
                    }
                }
            }
        }
    }
}
In Cards

VisualCardWithAction

Box(Modifier.clip(ComposeTheme.shapes.roundXL).width(400.dp)) {
    AsyncImage(model = "https://images.unsplash.com/photo-1521676129211-b7a9e7592e65?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=512&q=80", contentDescription = "Autumn Collection photo", contentScale = ContentScale.Crop, modifier = Modifier.aspectRatio(1f).fillMaxWidth().background(ComposeTheme.colors.gray50))
    Box(Modifier.align(Alignment.TopCenter).fillMaxWidth().height(64.dp).background(Brush.verticalGradient(listOf(Color.Black.copy(alpha = 0.33f), Color.Transparent))))
    Box(Modifier.align(Alignment.BottomCenter).fillMaxWidth().height(64.dp).background(Brush.verticalGradient(listOf(Color.Transparent, Color.Black.copy(alpha = 0.33f)))))
    BasicText("Autumn Collection", style = ComposeTheme.textStyles.xl3.copy(color = Color.White), modifier = Modifier.padding(16.dp).align(Alignment.BottomStart))

    Box(Modifier.align(Alignment.TopEnd).padding(16.dp).clip(ComposeTheme.shapes.roundFull).clickable(role = Role.Button) { /* TODO */ }.background(Color.White).padding(16.dp), contentAlignment = Alignment.Center) {
        Image(Icons.Outlined.Favorite, contentDescription = "Favorite", colorFilter = ColorFilter.tint(ComposeTheme.colors.gray900))
    }
}
In Settings

SettingsScreen

@Composable
fun CategoryItem(title: String, icon: ImageVector, onClick: () -> Unit) {
    Surface(
        onClick = onClick,
        shape = MaterialTheme.shapes.medium,
    ) {
        Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 16.dp), horizontalArrangement = Arrangement.spacedBy(30.dp)) {
            Icon(icon, contentDescription = null, modifier = Modifier.size(28.dp), tint = MaterialTheme.colorScheme.onSurface)
            Text(title, style = MaterialTheme.typography.bodyLarge)
        }
    }
}

@Composable
fun AppVersion(versionText: String, copyrights: String, onClick: () -> Unit) {
    Surface(onClick = onClick) {
        Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 12.dp), horizontalArrangement = Arrangement.spacedBy(30.dp)) {
            Box(
                modifier = Modifier.size(30.dp),
            )

            Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
                Text(versionText, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurface.copy(0.44f))
                Text(copyrights, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurface.copy(0.44f))
            }
        }
    }
}

val listState = rememberLazyListState()
val hasScrolled by remember {
    derivedStateOf {
        listState.firstVisibleItemScrollOffset > 0
    }
}
val appBarElevation by animateDpAsState(targetValue = if (hasScrolled) 4.dp else 0.dp)
Scaffold(
    containerColor = MaterialTheme.colorScheme.surface,
    contentColor = MaterialTheme.colorScheme.onSurface,
    topBar = {
        CenterAlignedTopAppBar(
            colors = TopAppBarDefaults.topAppBarColors(
                containerColor = if (isSystemInDarkTheme()) {
                    MaterialTheme.colorScheme.surfaceVariant.copy(alpha = if (hasScrolled) 1f else 0f)
                } else {
                    MaterialTheme.colorScheme.surface
                },
            ),
            modifier = Modifier.shadow(appBarElevation),
            title = { Text(text = "Settings") },
            navigationIcon = {
                IconButton(onClick = { /*TODO*/ }) {
                    Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = "Go back")
                }
            },
            actions = { },
        )
    },
) { padding ->
    Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.TopCenter) {
        LazyColumn(contentPadding = padding, modifier = Modifier.widthIn(max = 600.dp), state = listState) {
            item { CategoryItem(title = "Account", icon = Icons.Outlined.AccountCircle, onClick = { /*TODO*/ }) }
            item { CategoryItem(title = "Payment methods", icon = Icons.Outlined.CreditCard, onClick = { /*TODO*/ }) }
            item { CategoryItem(title = "Privacy", icon = Icons.Outlined.Lock, onClick = { /*TODO*/ }) }
            item { CategoryItem(title = "Notifications", icon = Icons.Outlined.Notifications, onClick = { /*TODO*/ }) }
            item { CategoryItem(title = "Look & Feel", icon = Icons.Outlined.Style, onClick = { /*TODO*/ }) }
            item { HorizontalDivider(modifier = Modifier.padding(vertical = 12.dp)) }
            item { CategoryItem(title = "FAQ", icon = Icons.Outlined.QuestionMark, onClick = { /*TODO*/ }) }
            item { CategoryItem(title = "Send Feedback", icon = Icons.Outlined.Email, onClick = { /*TODO*/ }) }
            item { CategoryItem(title = "See what's new", icon = Icons.Outlined.AutoAwesome, onClick = { /*TODO*/ }) }
            item { HorizontalDivider(modifier = Modifier.padding(vertical = 12.dp)) }
            item { CategoryItem(title = "Legal", icon = Icons.Outlined.Description, onClick = { /*TODO*/ }) }
            item { CategoryItem(title = "Licenses", icon = Icons.Outlined.Handshake, onClick = { /*TODO*/ }) }
            item { HorizontalDivider(modifier = Modifier.padding(vertical = 12.dp)) }
            item { AppVersion(versionText = "Version 1.0.0", copyrights = "© 2024 Your Company", onClick = { /* TODO Add easter egg after 8 times is clicked */ }) }
        }
    }
}
In MusicPlayback

MusicPlayerControls

var isPlaying by remember { mutableStateOf(false) }

val repeatModes = listOf("off", "once", "all")
var repeatMode by remember { mutableStateOf(repeatModes[0]) }
var shuffle by remember { mutableStateOf(false) }

Row(
    verticalAlignment = Alignment.CenterVertically,
    horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
    IconButton(
        onClick = {/*TODO Enable shuffle mode*/
            shuffle = shuffle.not()
        },
    ) {
        val icon = when (shuffle) {
            true -> Lucide.Shuffle
            false -> Lucide.Shuffle
        }
        Icon(
            imageVector = icon,
            contentDescription = "Forward 5 seconds",
            modifier = Modifier.size(24.dp),
            tint = MaterialTheme.colorScheme.primary
        )
    }

    IconButton(onClick = {/*TODO Skip to previous media item*/ }) {
        Icon(
            imageVector = Lucide.SkipBack,
            contentDescription = "Play Previous",
            modifier = Modifier.size(36.dp),
            tint = MaterialTheme.colorScheme.primary
        )
    }
    FilledIconButton(onClick = {/*TODO toggle playback*/
        isPlaying = !isPlaying
    }, modifier = Modifier.size(64.dp), shape = CircleShape) {
        if (isPlaying) {
            Icon(imageVector = Lucide.Pause, contentDescription = "Pause", modifier = Modifier.size(48.dp))
        } else {
            Icon(imageVector = Lucide.Play, contentDescription = "Play", modifier = Modifier.size(48.dp))
        }
    }
    IconButton(onClick = {/*TODO Skip to previous media item*/ }) {
        Icon(
            imageVector = Lucide.SkipForward,
            contentDescription = "Play Next",
            modifier = Modifier.size(36.dp),
            tint = MaterialTheme.colorScheme.primary
        )
    }
    IconButton(
        onClick = {
            repeatMode = repeatModes[(repeatModes.indexOf(repeatMode) + 1) % repeatModes.size]
        },
    ) {
        val icon = when (repeatMode) {
            "once" -> Lucide.Repeat1
            "all" -> Lucide.Repeat2
            else -> Lucide.Repeat
        }
        Icon(
            imageVector = icon,
            contentDescription = "Forward 5 seconds",
            modifier = Modifier.size(24.dp),
            tint = MaterialTheme.colorScheme.primary
        )
    }
}
In Dropdowns

Simple dropdown

/**
 * Add the following dependency to your build.gradle.kts:
 *
 * dependencies {
 *      implementation("com.composables:core:1.11.0")
 * }
 */
 
Box(Modifier.height(300.dp).fillMaxWidth()) {
    Menu(modifier = Modifier.align(Alignment.TopCenter).width(240.dp), state = rememberMenuState(expanded = true)) {
        MenuButton(
            Modifier.clip(RoundedCornerShape(6.dp)).background(Color.White)
                .border(1.dp, Color(0xFFBDBDBD), RoundedCornerShape(6.dp))
        ) {
            Row(
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier.padding(horizontal = 14.dp, vertical = 10.dp)
            ) {
                BasicText("Options", style = TextStyle(fontWeight = FontWeight(500)))
                Spacer(Modifier.width(4.dp))
                Image(Icons.Rounded.KeyboardArrowDown, null)
            }
        }

        MenuContent(
            modifier = Modifier.padding(top = 4.dp).width(320.dp).clip(RoundedCornerShape(6.dp))
                .border(1.dp, Color(0xFFE0E0E0), RoundedCornerShape(6.dp)).background(Color.White).padding(4.dp),
            exit = fadeOut()
        ) {
            MenuItem(modifier = Modifier.clip(RoundedCornerShape(6.dp)), onClick = { /* TODO handle click */ }) {
                BasicText("Option 1", Modifier.fillMaxWidth().padding(vertical = 10.dp, horizontal = 10.dp))
            }
            MenuItem(modifier = Modifier.clip(RoundedCornerShape(6.dp)), onClick = { /* TODO handle click */ }) {
                BasicText("Option 2", Modifier.fillMaxWidth().padding(vertical = 10.dp, horizontal = 10.dp))
            }
            MenuItem(modifier = Modifier.clip(RoundedCornerShape(6.dp)), onClick = { /* TODO handle click */ }) {
                BasicText("Option 3", Modifier.fillMaxWidth().padding(vertical = 10.dp, horizontal = 10.dp))
            }
        }
    }
}
In BottomSheets

With vertical actions

val state = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val scope = rememberCoroutineScope()

LaunchedEffect(Unit) {
    state.show()
}

if (state.isVisible) {
    ModalBottomSheet(onDismissRequest = {
        scope.launch {
            state.hide()
            delay(1500)
            state.show()
        }
    }) {
        val items = listOf(
            Icons.Rounded.Share to "Share",
            Icons.Rounded.Link to "Get Link",
            Icons.Rounded.Edit to "Edit name",
            Icons.Rounded.Delete to "Delete items",
        )
        Column(Modifier.navigationBarsPadding()) {
            items.forEach { item ->
                Row(
                    horizontalArrangement = Arrangement.spacedBy(32.dp),
                    modifier = Modifier.clickable { /* TODO */ }.clip(MaterialTheme.shapes.medium).fillMaxWidth()
                        .padding(horizontal = 32.dp, vertical = 18.dp),
                ) {
                    Icon(item.first, null)
                    Text(item.second)
                }
            }
        }
    }
}
In Accordions

Accordion

LazyColumn {
    item {
        var expanded by remember { mutableStateOf(false) }
        val degrees by animateFloatAsState(if (expanded) -90f else 90f)
        Column {
            Row(modifier = Modifier.clip(ComposeTheme.shapes.roundL).clickable { expanded = expanded.not() }
                .fillMaxWidth().padding(16.dp), horizontalArrangement = Arrangement.SpaceBetween) {
                BasicText("How do I create a new account?", style = ComposeTheme.textStyles.base)
                Image(
                    Lucide.ChevronRight,
                    contentDescription = null,
                    modifier = Modifier.rotate(degrees),
                    colorFilter = ColorFilter.tint(ComposeTheme.colors.gray800)
                )
            }
            AnimatedVisibility(
                visible = expanded,
                enter = expandVertically(
                    spring(
                        stiffness = Spring.StiffnessMediumLow,
                        visibilityThreshold = IntSize.VisibilityThreshold
                    )
                ),
                exit = shrinkVertically()
            ) {
                Box(Modifier.fillMaxWidth().padding(16.dp)) {
                    BasicText(
                        "To create a new account, please follow these steps:\n\n" + "1. Open the app.\n" + "2. Tap on the 'Sign Up' button.\n" + "3. Fill in your details, including your name, email address, and password.\n" + "4. Click 'Create Account'.\n" + "5. You will receive a confirmation email to verify your account. Follow the instructions in the email to complete the registration process.",
                        style = ComposeTheme.textStyles.sm
                    )
                }
            }
            Box(Modifier.fillMaxWidth().height(1.dp).background(ComposeTheme.colors.gray100))
        }
    }
    item {
        var expanded by remember { mutableStateOf(false) }
        val degrees by animateFloatAsState(if (expanded) -90f else 90f)
        Column {
            Row(modifier = Modifier.clip(ComposeTheme.shapes.roundL).clickable { expanded = expanded.not() }
                .fillMaxWidth().padding(16.dp), horizontalArrangement = Arrangement.SpaceBetween) {
                BasicText("How can I reset my password?", style = ComposeTheme.textStyles.base)
                Image(
                    Lucide.ChevronRight,
                    contentDescription = null,
                    modifier = Modifier.rotate(degrees).size(24.dp)
                )
            }
            AnimatedVisibility(
                visible = expanded,
                enter = expandVertically(
                    spring(
                        stiffness = Spring.StiffnessMediumLow,
                        visibilityThreshold = IntSize.VisibilityThreshold
                    )
                ),
                exit = shrinkVertically()
            ) {
                Box(Modifier.fillMaxWidth().padding(16.dp)) {
                    BasicText(
                        "If you need to reset your password, here's what you should do:\n" + "1. On the app's login screen, tap on the 'Forgot Password?' link.\n" + "2. Enter your registered email address.\n" + "3. You will receive an email with a password reset link.\n" + "4. Click on the link and follow the instructions to reset your password.\n" + "5. Once your password is reset, you can log in with your new password.",
                        style = ComposeTheme.textStyles.sm
                    )
                }
            }
            Box(Modifier.fillMaxWidth().height(1.dp).background(ComposeTheme.colors.gray100))
        }
    }
    item {
        var expanded by remember { mutableStateOf(false) }
        val degrees by animateFloatAsState(if (expanded) -90f else 90f)
        Column {
            Row(modifier = Modifier.clip(ComposeTheme.shapes.roundL).clickable { expanded = expanded.not() }
                .fillMaxWidth().padding(16.dp), horizontalArrangement = Arrangement.SpaceBetween) {
                BasicText("How do I update my profile information?", style = ComposeTheme.textStyles.base)
                Image(
                    Lucide.ChevronRight,
                    contentDescription = null,
                    modifier = Modifier.rotate(degrees).size(24.dp)
                )
            }
            AnimatedVisibility(
                visible = expanded,
                enter = expandVertically(
                    spring(
                        stiffness = Spring.StiffnessMediumLow,
                        visibilityThreshold = IntSize.VisibilityThreshold
                    )
                ),
                exit = shrinkVertically()
            ) {
                Box(Modifier.fillMaxWidth().padding(16.dp)) {
                    BasicText(
                        "To update your profile information, please follow these steps:\n" + "1. Log in to your account.\n" + "2. Go to the 'Profile' section of the app.\n" + "3. Click on the 'Edit Profile' button.\n" + "4. Update the information you want to change, such as your name, profile picture, or contact details.\n" + "5. Click 'Save' to save your changes.\n" + "Your profile information will be updated accordingly.",
                        style = ComposeTheme.textStyles.sm
                    )
                }
            }
        }
    }
}
In Forms

FormLayoutFilled

val focusManager = LocalFocusManager.current
LazyColumn(modifier = Modifier.widthIn(max = 480.dp), verticalArrangement = Arrangement.spacedBy(12.dp), contentPadding = PaddingValues(vertical = 24.dp)) {
    item {
        Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(12.dp)) {
            Surface(onClick = { /* TODO */ }, color = MaterialTheme.colorScheme.surfaceVariant, shape = CircleShape) {
                Box(modifier = Modifier.size(96.dp), contentAlignment = Alignment.Center) {
                    Icon(imageVector = Icons.Outlined.CameraAlt, contentDescription = null, tint = MaterialTheme.colorScheme.onSurfaceVariant)
                }
            }
            Text("Add photo")
        }
    }
    item {
        var imageUrl = remember { mutableStateOf<String?>(null) }
        Box(Modifier.fillMaxWidth()) {
            AsyncImage(model = imageUrl, contentDescription = null)
        }
    }
    item {
        var text by remember { mutableStateOf("") }
        TextField(modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp), label = { Text("First name") }, value = text, onValueChange = { text = it }, singleLine = true, trailingIcon = {
            AnimatedVisibility(visible = text.isNotBlank(), enter = fadeIn(), exit = fadeOut()) {
                IconButton(onClick = { text = "" }) {
                    Icon(Icons.Outlined.Cancel, "Clear")
                }
            }
        }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text, imeAction = ImeAction.Next, capitalization = KeyboardCapitalization.Words), keyboardActions = KeyboardActions {
            focusManager.moveFocus(FocusDirection.Next)
        })

    }
    item {
        var text by remember { mutableStateOf("") }
        TextField(modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp), label = { Text("Last name") }, value = text, onValueChange = { text = it }, singleLine = true, trailingIcon = {
            AnimatedVisibility(visible = text.isNotBlank(), enter = fadeIn(), exit = fadeOut()) {
                IconButton(onClick = { text = "" }) {
                    Icon(Icons.Outlined.Cancel, "Clear")
                }
            }
        }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text, imeAction = ImeAction.Next, capitalization = KeyboardCapitalization.Words), keyboardActions = KeyboardActions {
            focusManager.moveFocus(FocusDirection.Next)
        })
    }
    item { Spacer(Modifier.height(4.dp)) }
    item {
        var text by remember { mutableStateOf("") }
        TextField(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
            label = { Text("Phone number") },
            value = text,
            onValueChange = { text = it },
            trailingIcon = {
                AnimatedVisibility(visible = text.isNotBlank(), enter = fadeIn(), exit = fadeOut()) {
                    IconButton(onClick = { text = "" }) {
                        Icon(Icons.Outlined.Cancel, "Clear")
                    }
                }
            },
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone, imeAction = ImeAction.Next),
            keyboardActions = KeyboardActions {
                focusManager.moveFocus(FocusDirection.Next)
            },
            singleLine = true,
        )
    }
    item { Spacer(Modifier.height(4.dp)) }
    item {
        var text by remember { mutableStateOf("") }
        TextField(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
            label = { Text("Email") },
            value = text,
            onValueChange = { text = it },
            trailingIcon = {
                AnimatedVisibility(visible = text.isNotBlank(), enter = fadeIn(), exit = fadeOut()) {
                    IconButton(onClick = { text = "" }) {
                        Icon(Icons.Outlined.Cancel, "Clear")
                    }
                }
            },
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email, imeAction = ImeAction.Done),
            keyboardActions = KeyboardActions {
                focusManager.clearFocus()
            },
            singleLine = true,
        )
    }
    item { Spacer(Modifier.height(4.dp)) }
    item {
        var text by remember { mutableStateOf("") }
        TextField(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
            value = text,
            onValueChange = {
                text = it
            },
            label = { Text("Country") },
            trailingIcon = {
                AnimatedVisibility(visible = text.isNotBlank(), enter = fadeIn(), exit = fadeOut()) {
                    IconButton(onClick = { text = "" }) {
                        Icon(Icons.Outlined.Cancel, "Clear")
                    }
                }
            },
        )
    }
    item {
        var text by remember { mutableStateOf("") }
        TextField(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
            label = { Text("Street address") },
            value = text,
            onValueChange = { text = it },
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text, imeAction = ImeAction.Next),
            keyboardActions = KeyboardActions {
                focusManager.moveFocus(FocusDirection.Next)
            },
            singleLine = true,
            trailingIcon = {
                AnimatedVisibility(visible = text.isNotBlank(), enter = fadeIn(), exit = fadeOut()) {
                    IconButton(onClick = { text = "" }) {
                        Icon(Icons.Outlined.Cancel, "Clear")
                    }
                }
            },
        )
    }
    item {
        var text by remember { mutableStateOf("") }
        TextField(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
            label = { Text("City") },
            value = text,
            onValueChange = { text = it },
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text, imeAction = ImeAction.Next),
            keyboardActions = KeyboardActions {
                focusManager.moveFocus(FocusDirection.Next)
            },
            singleLine = true,
            trailingIcon = {
                AnimatedVisibility(visible = text.isNotBlank(), enter = fadeIn(), exit = fadeOut()) {
                    IconButton(onClick = { text = "" }) {
                        Icon(Icons.Outlined.Cancel, "Clear")
                    }
                }
            },
        )
    }
    item {
        var text by remember { mutableStateOf("") }
        TextField(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
            label = { Text("Zip/postal code") },
            value = text,
            onValueChange = { text = it },
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text, imeAction = ImeAction.Done),
            keyboardActions = KeyboardActions {
                focusManager.clearFocus()
            },
            singleLine = true,
            trailingIcon = {
                AnimatedVisibility(visible = text.isNotBlank(), enter = fadeIn(), exit = fadeOut()) {
                    IconButton(onClick = { text = "" }) {
                        Icon(Icons.Outlined.Cancel, "Clear")
                    }
                }
            },
        )
    }
    item {
        Text(text = "Groups", style = MaterialTheme.typography.titleMedium, modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 24.dp, bottom = 8.dp))
    }
    item {
        var selected by remember { mutableStateOf<Int?>(null) }
        val options = listOf("Family", "Friends", "Work", "Other")
        Column {
            options.forEachIndexed { i, option ->
                Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(24.dp), modifier = Modifier.clickable { selected = i }.fillMaxWidth().padding(16.dp)) {
                    RadioButton(selected = selected == i, onClick = null)
                    Text(text = option)
                }

            }
        }
    }
    item {
        Text(text = "Notification Options", style = MaterialTheme.typography.titleMedium, modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 24.dp, bottom = 8.dp))
    }
    item {
        var selected by remember { mutableStateOf(false) }
        Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(24.dp), modifier = Modifier.clickable { selected = selected.not() }.fillMaxWidth().padding(16.dp)) {
            Checkbox(checked = selected, onCheckedChange = null)
            Text(text = "Override 'Do not Disturb'")
        }
    }
    item {
        var selected by remember { mutableStateOf(false) }
        Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(24.dp), modifier = Modifier.clickable { selected = selected.not() }.fillMaxWidth().padding(16.dp)) {
            Checkbox(checked = selected, onCheckedChange = null)
            Text(text = "Block calls from this contact")
        }
    }
}
In ResponsiveLayouts

SupportingPane

var navigationIndex by remember { mutableStateOf(0) }
val scope = rememberCoroutineScope()
val widthSizeClass = calculateWindowSizeClass().widthSizeClass

val navigationItems = listOf(
    mapOf("icon" to Icons.AutoMirrored.Outlined.Message, "label" to "Messages"),
    mapOf("icon" to Icons.Outlined.Photo, "label" to "Photos"),
    mapOf("icon" to Icons.Outlined.VideoCall, "label" to "Videos"),
    mapOf("icon" to Icons.Outlined.Games, "label" to "Games"),
)

@Composable
fun ContentPanel(modifier: Modifier = Modifier) { // TODO replace the contents of this composable with your own content
    Box(modifier.padding(16.dp).border(1.dp, MaterialTheme.colorScheme.outline, RoundedCornerShape(18.dp)).clip(RoundedCornerShape(18.dp)).background(MaterialColors.Gray[100]))
}

@Composable
fun SupportPane(modifier: Modifier = Modifier) { // TODO replace the contents of this composable with your own content
    Box(modifier.padding(16.dp).border(1.dp, MaterialTheme.colorScheme.outline, RoundedCornerShape(18.dp)).clip(RoundedCornerShape(18.dp)).background(MaterialColors.Gray[100]))
}

if (widthSizeClass in listOf(WindowWidthSizeClass.Compact, WindowWidthSizeClass.Medium)) {
    val drawerState = rememberDrawerState(DrawerValue.Closed)
    ModalNavigationDrawer(
        modifier = Modifier.fillMaxHeight(),
        drawerState = drawerState,
        drawerContent = {
            ModalDrawerSheet {
                Column {
                    Icon(imageVector = Icons.Rounded.Token, contentDescription = null, modifier = Modifier.padding(16.dp).size(48.dp), tint = MaterialTheme.colorScheme.primary)
                    Spacer(Modifier.height(12.dp))
                    navigationItems.forEachIndexed { index, map ->
                        val icon = map.get("icon") as ImageVector
                        val label = map.get("label") as String
                        NavigationDrawerItem(icon = { Icon(icon, contentDescription = null) }, label = { Text(label) }, selected = index == navigationIndex, onClick = {
                            scope.launch { drawerState.close() }
                            navigationIndex = index
                        }, modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding))
                    }
                }
            }
        },
    ) {
        Scaffold(
            topBar = {
                TopAppBar(title = { Text(navigationItems[navigationIndex].get("label") as String) }, navigationIcon = {
                    IconButton(onClick = { scope.launch { drawerState.open() } }) {
                        Icon(Icons.Rounded.Menu, "Show menu")
                    }
                })
            },
        ) { contentPadding ->
            Column(Modifier.padding(contentPadding).fillMaxSize()) {
                ContentPanel(Modifier.weight(1f).fillMaxWidth())
                HorizontalDivider()
                SupportPane(Modifier.weight(1f).fillMaxWidth())
            }
        }
    }
} else {
    Scaffold {
        PermanentNavigationDrawer(drawerContent = {
            PermanentDrawerSheet(Modifier.width(200.dp)) {
                Column(Modifier.padding(vertical = 24.dp)) {
                    ExtendedFloatingActionButton(
                        onClick = { /*TODO*/ },
                        modifier = Modifier.padding(horizontal = 12.dp),
                    ) {
                        Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.Start)) {
                            Icon(Icons.Outlined.Edit, null)
                            Text("Compose")
                        }
                    }
                    Spacer(Modifier.height(24.dp))
                    LazyColumn(verticalArrangement = Arrangement.spacedBy(4.dp)) {
                        itemsIndexed(navigationItems) { index, map ->
                            val item = navigationItems.get(index)
                            val icon = item.get("icon") as ImageVector
                            val label = item.get("label") as String
                            NavigationDrawerItem(modifier = Modifier.padding(horizontal = 16.dp), selected = index == navigationIndex, icon = { Icon(icon, null) }, label = { Text(label) }, onClick = { navigationIndex = index })
                        }
                    }
                }
            }

        }, content = {
            Row {
                ContentPanel(Modifier.weight(1f).fillMaxHeight())
                VerticalDivider()
                SupportPane(Modifier.width(360.dp).fillMaxHeight())
            }
        })
    }
}
Sit tight. We are loading your preview
🐛 Bugs & Suggestions