InputChip

Functions summary

Unit
@Composable
InputChip(
    selected: Boolean,
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    leadingIcon: (@Composable () -> Unit)?,
    avatar: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    shape: Shape,
    colors: SelectableChipColors,
    elevation: SelectableChipElevation?,
    border: BorderStroke?,
    horizontalArrangement: Arrangement.Horizontal,
    contentPadding: PaddingValues,
    interactionSource: MutableInteractionSource?
)

Material Design input chip

Cmn

Functions

@Composable
fun InputChip(
    selected: Boolean,
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    leadingIcon: (@Composable () -> Unit)? = null,
    avatar: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    shape: Shape = InputChipDefaults.shape,
    colors: SelectableChipColors = InputChipDefaults.inputChipColors(),
    elevation: SelectableChipElevation? = InputChipDefaults.inputChipElevation(),
    border: BorderStroke? = InputChipDefaults.inputChipBorder(enabled, selected),
    horizontalArrangement: Arrangement.Horizontal = InputChipDefaults.horizontalArrangement(),
    contentPadding: PaddingValues = InputChipDefaults.contentPadding(avatar != null, leadingIcon != null, trailingIcon != null),
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design input chip

Chips help people enter information, make selections, filter content, or trigger actions. Chips can show multiple interactive elements together in the same area, such as a list of selectable movie times, or a series of email contacts.

Input chips represent discrete pieces of information entered by a user.

Input chip
image

An Input Chip can have a leading icon or an avatar at its start. In case both are provided, the avatar will take precedence and will be displayed.

Example of an InputChip with a trailing icon:

import androidx.compose.material3.InputChip
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var selected by remember { mutableStateOf(false) }
InputChip(
    selected = selected,
    onClick = { selected = !selected },
    label = { Text("Input Chip") },
)

Example of an InputChip with an avatar and a trailing icon:

import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.Icon
import androidx.compose.material3.InputChip
import androidx.compose.material3.InputChipDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier

var selected by remember { mutableStateOf(false) }
InputChip(
    selected = selected,
    onClick = { selected = !selected },
    label = { Text("Input Chip") },
    avatar = {
        Icon(
            Icons.Filled.Person,
            contentDescription = "Localized description",
            Modifier.size(InputChipDefaults.AvatarSize),
        )
    },
)

Input chips should appear in a set and can be horizontally scrollable:

import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowRight
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material.icons.filled.Tune
import androidx.compose.material3.AssistChip
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.FilterChip
import androidx.compose.material3.FilterChipDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

var expanded by remember { mutableStateOf(false) }
val listSize = 9
val chipData = List(listSize) { index -> "Chip $index" }
Column(horizontalAlignment = Alignment.CenterHorizontally) {
    Row(modifier = Modifier.horizontalScroll(rememberScrollState())) {
        AssistChip(
            onClick = { expanded = !expanded },
            label = { Text("Show All") },
            leadingIcon = {
                Icon(
                    imageVector = Icons.Filled.Tune,
                    contentDescription = "Localized Description",
                    modifier = Modifier.size(FilterChipDefaults.IconSize),
                )
            },
        )
        /*
         * When chip lists exceed the available horizontal screen space, one option is to
         * provide a chip button that opens a menu displaying all chip options. This ensures
         * all options are accessible while maintaining the position of the content below the
         * chip list.
         */
        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
            repeat(listSize) { index ->
                DropdownMenuItem(
                    text = { Text(chipData[index]) },
                    onClick = {},
                    trailingIcon = {
                        Icon(Icons.AutoMirrored.Filled.ArrowRight, contentDescription = null)
                    },
                )
            }
        }
        repeat(listSize) { index ->
            AssistChip(
                modifier = Modifier.padding(horizontal = 4.dp),
                onClick = { /* do something*/ },
                label = { Text(chipData[index]) },
                trailingIcon = { Icon(Icons.Filled.ArrowDropDown, contentDescription = null) },
            )
        }
    }
}

Alternatively, use androidx.compose.foundation.layout.FlowRow to wrap chips to a new line.

import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Tune
import androidx.compose.material3.AssistChip
import androidx.compose.material3.FilterChip
import androidx.compose.material3.FilterChipDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEachIndexed

var selected by remember { mutableStateOf(false) }
val colorNames =
    listOf(
        "Blue",
        "Yellow",
        "Red",
        "Orange",
        "Black",
        "Green",
        "White",
        "Magenta",
        "Gray",
        "Transparent",
    )
Column {
    FlowRow(
        modifier =
            Modifier.fillMaxWidth(1f)
                .wrapContentHeight(align = Alignment.Top)
                .then(
                    if (selected) {
                        Modifier.verticalScroll(rememberScrollState())
                    } else {
                        Modifier.horizontalScroll(rememberScrollState())
                    }
                ),
        horizontalArrangement = Arrangement.Start,
        maxLines = if (!selected) 1 else Int.MAX_VALUE,
    ) {
        /*
         * When chip lists exceed the available horizontal screen space, one option is to
         * provide a leading chip that expands the list into a vertical scrolling list. This
         * ensures all options are accessible while maintaining the position of the content
         * below the chip list.
         */
        FilterChip(
            selected = selected,
            modifier =
                Modifier.padding(horizontal = 4.dp)
                    .align(alignment = Alignment.CenterVertically),
            onClick = { selected = !selected },
            label = { Text("Show All") },
            leadingIcon = {
                Icon(
                    imageVector = Icons.Filled.Tune,
                    contentDescription = "Localized Description",
                    modifier = Modifier.size(FilterChipDefaults.IconSize),
                )
            },
        )
        Box(
            Modifier.height(FilterChipDefaults.Height)
                .align(alignment = Alignment.CenterVertically)
        ) {
            VerticalDivider()
        }
        colorNames.fastForEachIndexed { index, element ->
            AssistChip(
                modifier =
                    Modifier.padding(horizontal = 4.dp)
                        .align(alignment = Alignment.CenterVertically),
                onClick = { /* do something*/ },
                label = { Text("$element $index") },
            )
        }
    }
}
Parameters
selected: Boolean

whether this chip is selected or not

onClick: () -> Unit

called when this chip is clicked

label: @Composable () -> Unit

text label for this chip

modifier: Modifier = Modifier

the Modifier to be applied to this chip

enabled: Boolean = true

controls the enabled state of this chip. When false, this component will not respond to user input, and it will appear visually disabled and disabled to accessibility services.

leadingIcon: (@Composable () -> Unit)? = null

optional icon at the start of the chip, preceding the label text

avatar: (@Composable () -> Unit)? = null

optional avatar at the start of the chip, preceding the label text

trailingIcon: (@Composable () -> Unit)? = null

optional icon at the end of the chip

shape: Shape = InputChipDefaults.shape

defines the shape of this chip's container, border (when border is not null), and shadow (when using elevation)

colors: SelectableChipColors = InputChipDefaults.inputChipColors()

ChipColors that will be used to resolve the colors used for this chip in different states. See InputChipDefaults.inputChipColors.

elevation: SelectableChipElevation? = InputChipDefaults.inputChipElevation()

ChipElevation used to resolve the elevation for this chip in different states. This controls the size of the shadow below the chip. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. See InputChipDefaults.inputChipElevation.

border: BorderStroke? = InputChipDefaults.inputChipBorder(enabled, selected)

the border to draw around the container of this chip. Pass null for no border. See InputChipDefaults.inputChipBorder.

horizontalArrangement: Arrangement.Horizontal = InputChipDefaults.horizontalArrangement()

the horizontal arrangement of the chip's children. If there aren't any icons, then the horizontal padding between the label and the border will be the sum of contentPadding and the spacing in this horizontalArrangement.

contentPadding: PaddingValues = InputChipDefaults.contentPadding(avatar != null, leadingIcon != null, trailingIcon != null)

the padding around the content of this chip, including the leadingIcon, avatar, label, and trailingIcon.

interactionSource: MutableInteractionSource? = null

an optional hoisted MutableInteractionSource for observing and emitting Interactions for this chip. You can use this to change the chip's appearance or preview the chip in different states. Note that if null is provided, interactions will still happen internally.