androidx.compose.material3

Build Jetpack Compose UIs with Material Design 3, the next evolution of Material Design. Material 3 includes updated theming and components and Material You personalization features like dynamic color, and is designed to be cohesive with the new Android 12 visual style and system UI.

Material You image

In this page, you'll find documentation for types, properties, and functions available in the androidx.compose.material3 package.

For more information, check out Material Design 3 in Compose.

Overview

Theming

APIs Description
Material Theming MaterialTheme M3 theme
Color scheme ColorScheme M3 color scheme
lightColorScheme M3 light color scheme
darkColorScheme M3 dark color scheme
Dynamic color dynamicLightColorScheme M3 dynamic light color scheme
dynamicDarkColorScheme M3 dynamic dark color scheme
Typography Typography M3 typography
Shape Shapes M3 shape

Components

APIs Description
Badge Badge M3 badge
BadgedBox M3 badged box
Bottom app bar BottomAppBar M3 bottom app bar
Bottom sheet BottomSheetScaffold M3 bottom sheet
ModalBottomSheet M3 modal bottom sheet
Buttons Button M3 filled button
ElevatedButton M3 elevated button
FilledTonalButton M3 filled tonal button
OutlinedButton M3 outlined button
TextButton M3 text button
Cards Card M3 filled card
ElevatedCard M3 elevated card
OutlinedCard M3 outlined card
Checkbox Checkbox M3 checkbox
TriStateCheckbox M3 indeterminate checkbox
Chips AssistChip M3 assist chip
ElevatedAssistChip M3 elevated assist chip
FilterChip M3 filter chip
ElevatedFilterChip M3 elevated filter chip
InputChip M3 input chip
SuggestionChip M3 suggestion chip
ElevatedSuggestionChip M3 elevated suggestion chip
Date Picker DatePicker M3 date picker
DatePickerDialog M3 date picker embeeded in dialog
DateRangePicker M3 date range picker
Dialogs AlertDialog M3 basic dialog
Dividers HorizontalDivider M3 horizontal divider
VerticalDivider M3 vertical divider
Extended FAB ExtendedFloatingActionButton M3 extended FAB
FAB FloatingActionButton M3 FAB
SmallFloatingActionButton M3 small FAB
LargeFloatingActionButton M3 large FAB
Icon button IconButton M3 standard icon button
IconToggleButton M3 standard icon toggle button
FilledIconButton M3 filled icon button
FilledIconToggleButton M3 filled icon toggle button
FilledTonalIconButton M3 filled tonal icon button
FilledTonalIconToggleButton M3 filled tonal icon toggle button
OutlinedIconButton M3 outlined icon button
OutlinedIconToggleButton M3 outlined icon toggle button
Lists ListItem M3 list item
Menus DropdownMenu M3 menu
DropdownMenuItem M3 menu item
ExposedDropdownMenuBox M3 exposed dropdown menu
Navigation bar NavigationBar M3 navigation bar
NavigationBarItem M3 navigation bar item
Navigation drawer ModalNavigationDrawer M3 modal navigation drawer
ModalDrawerSheet M3 modal drawer sheet
PermanentNavigationDrawer M3 permanent standard navigation drawer
PermanentDrawerSheet M3 permanent standard drawer sheet
DismissibleNavigationDrawer M3 dismissible standard navigation drawer
DismissibleDrawerSheet M3 dismissible standard drawer sheet
NavigationDrawerItem M3 navigation drawer item
Navigation rail NavigationRail M3 navigation rail
NavigationRailItem M3 navigation rail item
Progress indicators LinearProgressIndicator M3 linear progress indicator
CircularProgressIndicator M3 circular progress indicator
Radio button RadioButton M3 radio button
Search Bar SearchBar M3 search bar
DockedSearchBar M3 docked search bar
Segmented Button SegmentedButton M3 segmented button
SingleChoiceSegmentedButtonRow M3 single choice segmented button row
MultiChoiceSegmentedButtonRow M3 multiple choice segmented button row
Sliders Slider M3 slider
RangeSlider M3 range slider
Snackbars Snackbar M3 snackbar
Swipe to Dismiss SwipeToDismiss M3 swipe to dismiss
Switch Switch M3 switch
Tabs Tab M3 tab
LeadingIconTab M3 leading icon tab
PrimaryIndicator M3 primary tab indicator
PrimaryTabRow M3 primary tab row
SecondaryIndicator M3 secondary tab indicator
SecondaryTabRow M3 secondary tab row
TabRow M3 fixed tab row
ScrollableTabRow M3 scrollable tab row
Text fields TextField M3 filled text field
OutlinedTextField M3 outlined text field
Time Picker TimePicker M3 time picker
TimeInput M3 time input
Tool tip PlainTooltipBox M3 plain tool tip
RichTooltipBox M3 rich tool tip
Top app bar TopAppBar M3 small top app bar
CenterAlignedTopAppBar M3 center-aligned top app bar
MediumTopAppBar M3 medium top app bar
LargeTopAppBar M3 large top app bar

Surfaces and layout

APIs Description
Surfaces Surface M3 surface
Scaffold Scaffold M3 layout

Icons and text

APIs Description
Icon Icon M3 icon
Text Text M3 text

Also check out the androidx.compose.material.icons package.

Interfaces

BasicTooltipState

The state that is associated with an instance of a tooltip.

Cmn
BottomAppBarScrollBehavior

A BottomAppBarScrollBehavior defines how a bottom app bar should behave when the content under it is scrolled.

Cmn
BottomAppBarState

A state object that can be hoisted to control and observe the bottom app bar state.

Cmn
CaretScope

Caret scope for TooltipBox to be used to obtain the LayoutCoordinates of the anchor content, and to draw a caret for the tooltip.

Cmn
DatePickerFormatter

A date formatter interface used by DatePicker.

Cmn
DatePickerState

A state object that can be hoisted to observe the date picker state.

Cmn
DateRangePickerState

A state object that can be hoisted to observe the date range picker state.

Cmn
MultiChoiceSegmentedButtonRowScope

Scope for the children of a MultiChoiceSegmentedButtonRow

Cmn
NavigationDrawerItemColors

Represents the colors of the various elements of a drawer item.

Cmn
SelectableDates

An interface that controls the selectable dates and years in the date pickers UI.

Cmn
SingleChoiceSegmentedButtonRowScope

Scope for the children of a SingleChoiceSegmentedButtonRow

Cmn
SnackbarData

Interface to represent the data of one particular Snackbar as a piece of the SnackbarHostState.

Cmn
SnackbarVisuals

Interface to represent the visuals of one particular Snackbar as a piece of the SnackbarData.

Cmn
TabIndicatorScope

Scope for the composable used to render a Tab indicator, this can be used for more complex indicators requiring layout information about the tabs like TabRowDefaults.PrimaryIndicator and TabRowDefaults.SecondaryIndicator

Cmn
TooltipState

The state that is associated with a TooltipBox.

Cmn
TopAppBarScrollBehavior

A TopAppBarScrollBehavior defines how an app bar should behave when the content under it is scrolled.

Cmn

Classes

BottomSheetScaffoldState

State of the BottomSheetScaffold composable.

Cmn
ButtonColors

Represents the container and content colors used in a button in different states.

Cmn
ButtonElevation

Represents the elevation for a button in different states.

Cmn
CalendarLocale

Represents a Locale for the calendar.

Cmn
android
CardColors

Represents the container and content colors used in a card in different states.

Cmn
CardElevation

Represents the elevation for a card in different states.

Cmn
CaretProperties

Properties for the caret of the tooltip if enabled.

Cmn
CheckboxColors

Represents the colors used by the three different sections (checkmark, box, and border) of a Checkbox or TriStateCheckbox in different states.

Cmn
ChipBorder

This class is deprecated. Maintained for binary compatibility.

Cmn
ChipColors

Represents the container and content colors used in a clickable chip in different states.

Cmn
ChipElevation

Represents the elevation used in a selectable chip in different states.

Cmn
ColorScheme

A color scheme holds all the named color parameters for a MaterialTheme.

Cmn
DatePickerColors

Represents the colors used by the date picker.

Cmn
DisplayMode

Represents the different modes that a date picker can be at.

Cmn
DrawerState

State of the ModalNavigationDrawer and DismissibleNavigationDrawer composable.

Cmn
ExposedDropdownMenuBoxScope

Scope for ExposedDropdownMenuBox.

android
FabPosition

The possible positions for a FloatingActionButton attached to a Scaffold.

Cmn
FloatingActionButtonElevation

Represents the tonal and shadow elevation for a floating action button in different states.

Cmn
IconButtonColors

Represents the container and content colors used in an icon button in different states.

Cmn
IconToggleButtonColors

Represents the container and content colors used in a toggleable icon button in different states.

Cmn
ListItemColors

Represents the container and content colors used in a list item in different states.

Cmn
MenuItemColors

Represents the text and icon colors used in a menu item at different states.

Cmn
ModalBottomSheetProperties

Properties used to customize the behavior of a ModalBottomSheet.

android
NavigationBarItemColors

Represents the colors of the various elements of a navigation item.

Cmn
NavigationRailItemColors

Represents the colors of the various elements of a navigation item.

Cmn
RadioButtonColors

Represents the color used by a RadioButton in different states.

Cmn
RangeSliderState

Class that holds information about RangeSlider's active range.

Cmn
RichTooltipColors
Cmn
RippleConfiguration

Configuration for ripple appearance, provided using LocalRippleConfiguration.

Cmn
SearchBarColors

Represents the colors used by a search bar in different states.

android
SegmentedButtonColors

The different colors used in parts of the SegmentedButton in different states

Cmn
SelectableChipColors

Represents the container and content colors used in a selectable chip in different states.

Cmn
SelectableChipElevation

Represents the elevation used in a selectable chip in different states.

Cmn
Shapes

Material surfaces can be displayed in different shapes.

Cmn
SheetState

State of a sheet composable, such as ModalBottomSheet

Cmn
SliderColors

Represents the color used by a Slider in different states.

Cmn
SliderPositions

This class is deprecated. Not necessary with the introduction of Slider state

Cmn
SliderState

Class that holds information about Slider's active range.

Cmn
SnackbarHostState

State of the SnackbarHost, which controls the queue and the current Snackbar being shown inside the SnackbarHost.

Cmn
SwipeToDismissBoxState

State of the SwipeToDismissBox composable.

Cmn
SwitchColors

Represents the colors used by a Switch in different states

Cmn
TabPosition

Data class that contains information about a tab's position on screen, used for calculating where to place the indicator that shows which tab is selected.

Cmn
TextFieldColors

Represents the colors of the input text, container, and content (including label, placeholder, leading and trailing icons) used in a text field in different states.

Cmn
TimePickerColors

Represents the colors used by a TimePicker in different states

Cmn
TimePickerLayoutType

Represents the different configurations for the layout of the Time Picker

Cmn
TimePickerState

A class to handle state changes in a TimePicker

Cmn
TopAppBarColors

Represents the colors used by a top app bar in different states.

Cmn
TopAppBarState

A state object that can be hoisted to control and observe the top app bar state.

Cmn
Typography

The Material Design type scale includes a range of contrasting styles that support the needs of your product and its content.

Cmn

Objects

AlertDialogDefaults

Contains default values used for AlertDialog and BasicAlertDialog.

android
AssistChipDefaults

Contains the baseline values used by AssistChip.

Cmn
BadgeDefaults

Default values used for Badge implementations.

Cmn
BottomAppBarDefaults

Contains default values used for the bottom app bar implementations.

Cmn
BottomSheetDefaults

Contains the default values used by ModalBottomSheet and BottomSheetScaffold.

Cmn
ButtonDefaults

Contains the default values used by all 5 button types.

Cmn
CardDefaults

Contains the default values used by all card types.

Cmn
CheckboxDefaults

Defaults used in Checkbox and TriStateCheckbox.

Cmn
DatePickerDefaults

Contains default values used by the DatePicker.

Cmn
DateRangePickerDefaults

Contains default values used by the DateRangePicker.

Cmn
DividerDefaults

Default values for Divider

Cmn
DrawerDefaults

Object to hold default values for ModalNavigationDrawer

Cmn
ExposedDropdownMenuDefaults

Contains default values used by Exposed Dropdown Menu.

android
FilterChipDefaults

Contains the baseline values used by FilterChip.

Cmn
FloatingActionButtonDefaults

Contains the default values used by FloatingActionButton

Cmn
IconButtonDefaults

Contains the default values used by all icon button types.

Cmn
InputChipDefaults

Contains the baseline values used by an InputChip.

Cmn
ListItemDefaults

Contains the default values used by list items.

Cmn
MaterialTheme

Contains functions to access the current theme values provided at the call site's position in the hierarchy.

Cmn
MenuDefaults

Contains default values used for DropdownMenu and DropdownMenuItem.

Cmn
ModalBottomSheetDefaults

Default values for ModalBottomSheet

android
NavigationBarDefaults

Defaults used in NavigationBar.

Cmn
NavigationBarItemDefaults

Defaults used in NavigationBarItem.

Cmn
NavigationDrawerItemDefaults

Defaults used in NavigationDrawerItem.

Cmn
NavigationRailDefaults

Defaults used in NavigationRail

Cmn
NavigationRailItemDefaults

Defaults used in NavigationRailItem.

Cmn
OutlinedTextFieldDefaults

Contains the default values used by OutlinedTextField.

Cmn
ProgressIndicatorDefaults

Contains the default values used for LinearProgressIndicator and CircularProgressIndicator.

Cmn
RadioButtonDefaults

Defaults used in RadioButton.

Cmn
RippleDefaults

Default values used by ripple.

Cmn
ScaffoldDefaults

Object containing various default values for Scaffold component.

Cmn
SearchBarDefaults

Defaults used in SearchBar and DockedSearchBar.

android
SegmentedButtonDefaults
Cmn
ShapeDefaults

Contains the default values used by Shapes

Cmn
SliderDefaults

Object to hold defaults used by Slider

Cmn
SnackbarDefaults

Contains the default values used for Snackbar.

Cmn
SuggestionChipDefaults

Contains the baseline values used by SuggestionChip.

Cmn
SwipeToDismissBoxDefaults

Contains default values for SwipeToDismissBox and SwipeToDismissBoxState.

Cmn
SwitchDefaults

Contains the default values used by Switch

Cmn
TabRowDefaults

Contains default implementations and values used for TabRow.

Cmn
TextFieldDefaults

Contains the default values used by TextField.

Cmn
TimePickerDefaults

Contains the default values used by TimePicker

Cmn
TooltipDefaults

Tooltip defaults that contain default values for both PlainTooltip and RichTooltip

Cmn
TopAppBarDefaults

Contains default values used for the top app bar implementations.

Cmn

Annotations

Enums

DismissDirection

This enum is deprecated. Dismiss direction is no longer used by SwipeToDismissBoxState.

Cmn
DismissValue

This enum is deprecated. DismissValue is no longer used by SwipeToDismissBoxState.

Cmn
DrawerValue

Possible values of DrawerState.

Cmn
SheetValue

Possible values of SheetState.

Cmn
SnackbarDuration

Possible durations of the Snackbar in SnackbarHost

Cmn
SnackbarResult

Possible results of the SnackbarHostState.showSnackbar call

Cmn
SwipeToDismissBoxValue

The directions in which a SwipeToDismissBox can be dismissed.

Cmn

Type aliases

CalendarLocale

Represents a Locale for the calendar.

android

Top-level functions summary

Unit
@ExperimentalMaterial3Api
@Composable
AlertDialog(
    onDismissRequest: () -> Unit,
    modifier: Modifier,
    properties: DialogProperties,
    content: @Composable () -> Unit
)

This function is deprecated. Use BasicAlertDialog instead

android
Unit
@Composable
AlertDialog(
    onDismissRequest: () -> Unit,
    confirmButton: @Composable () -> Unit,
    modifier: Modifier,
    dismissButton: (@Composable () -> Unit)?,
    icon: (@Composable () -> Unit)?,
    title: (@Composable () -> Unit)?,
    text: (@Composable () -> Unit)?,
    shape: Shape,
    containerColor: Color,
    iconContentColor: Color,
    titleContentColor: Color,
    textContentColor: Color,
    tonalElevation: Dp,
    properties: DialogProperties
)

Material Design basic dialog.

android
Unit
@Composable
AssistChip(
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    shape: Shape,
    colors: ChipColors,
    elevation: ChipElevation?,
    border: BorderStroke?,
    interactionSource: MutableInteractionSource?
)

Material Design assist chip.

Cmn
Unit
@Composable
Badge(
    modifier: Modifier,
    containerColor: Color,
    contentColor: Color,
    content: (@Composable RowScope.() -> Unit)?
)

A badge represents dynamic information such as a number of pending requests in a navigation bar.

Cmn
Unit
@Composable
BadgedBox(
    badge: @Composable BoxScope.() -> Unit,
    modifier: Modifier,
    content: @Composable BoxScope.() -> Unit
)

Material Design badge box.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
BasicAlertDialog(
    onDismissRequest: () -> Unit,
    modifier: Modifier,
    properties: DialogProperties,
    content: @Composable () -> Unit
)

Basic alert dialog dialog.

android
Unit
@Composable
BottomAppBar(
    modifier: Modifier,
    containerColor: Color,
    contentColor: Color,
    tonalElevation: Dp,
    contentPadding: PaddingValues,
    windowInsets: WindowInsets,
    content: @Composable RowScope.() -> Unit
)

Material Design bottom app bar.

Cmn
Unit
@Composable
BottomAppBar(
    actions: @Composable RowScope.() -> Unit,
    modifier: Modifier,
    floatingActionButton: (@Composable () -> Unit)?,
    containerColor: Color,
    contentColor: Color,
    tonalElevation: Dp,
    contentPadding: PaddingValues,
    windowInsets: WindowInsets
)

Material Design bottom app bar.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
BottomAppBar(
    modifier: Modifier,
    containerColor: Color,
    contentColor: Color,
    tonalElevation: Dp,
    contentPadding: PaddingValues,
    windowInsets: WindowInsets,
    scrollBehavior: BottomAppBarScrollBehavior?,
    content: @Composable RowScope.() -> Unit
)

Material Design bottom app bar.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
BottomAppBar(
    actions: @Composable RowScope.() -> Unit,
    modifier: Modifier,
    floatingActionButton: (@Composable () -> Unit)?,
    containerColor: Color,
    contentColor: Color,
    tonalElevation: Dp,
    contentPadding: PaddingValues,
    windowInsets: WindowInsets,
    scrollBehavior: BottomAppBarScrollBehavior?
)

Material Design bottom app bar.

Cmn
BottomAppBarState
@ExperimentalMaterial3Api
BottomAppBarState(
    initialHeightOffsetLimit: Float,
    initialHeightOffset: Float,
    initialContentOffset: Float
)

Creates a BottomAppBarState.

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
BottomSheetScaffold(
    sheetContent: @Composable ColumnScope.() -> Unit,
    modifier: Modifier,
    scaffoldState: BottomSheetScaffoldState,
    sheetPeekHeight: Dp,
    sheetMaxWidth: Dp,
    sheetShape: Shape,
    sheetContainerColor: Color,
    sheetContentColor: Color,
    sheetTonalElevation: Dp,
    sheetShadowElevation: Dp,
    sheetDragHandle: (@Composable () -> Unit)?,
    sheetSwipeEnabled: Boolean,
    topBar: (@Composable () -> Unit)?,
    snackbarHost: @Composable (SnackbarHostState) -> Unit,
    containerColor: Color,
    contentColor: Color,
    content: @Composable (PaddingValues) -> Unit
)

Material Design standard bottom sheet scaffold.

Cmn
Unit
@Composable
Button(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: ButtonColors,
    elevation: ButtonElevation?,
    border: BorderStroke?,
    contentPadding: PaddingValues,
    interactionSource: MutableInteractionSource?,
    content: @Composable RowScope.() -> Unit
)

Material Design button.

Cmn
Unit
@Composable
Card(
    modifier: Modifier,
    shape: Shape,
    colors: CardColors,
    elevation: CardElevation,
    border: BorderStroke?,
    content: @Composable ColumnScope.() -> Unit
)

Material Design filled card.

Cmn
Unit
@Composable
Card(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: CardColors,
    elevation: CardElevation,
    border: BorderStroke?,
    interactionSource: MutableInteractionSource?,
    content: @Composable ColumnScope.() -> Unit
)

Material Design filled card.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
CenterAlignedTopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier,
    navigationIcon: @Composable () -> Unit,
    actions: @Composable RowScope.() -> Unit,
    windowInsets: WindowInsets,
    colors: TopAppBarColors,
    scrollBehavior: TopAppBarScrollBehavior?
)

Material Design center-aligned small top app bar.

Cmn
Unit
@Composable
Checkbox(
    checked: Boolean,
    onCheckedChange: ((Boolean) -> Unit)?,
    modifier: Modifier,
    enabled: Boolean,
    colors: CheckboxColors,
    interactionSource: MutableInteractionSource?
)

Material Design checkbox.

Cmn
Unit
@Composable
CircularProgressIndicator(
    modifier: Modifier,
    color: Color,
    strokeWidth: Dp,
    trackColor: Color,
    strokeCap: StrokeCap
)

Indeterminate Material Design circular progress indicator.

Cmn
Unit
@Composable
CircularProgressIndicator(
    progress: Float,
    modifier: Modifier,
    color: Color,
    strokeWidth: Dp,
    trackColor: Color,
    strokeCap: StrokeCap
)

This function is deprecated. Use the overload that takes `progress` as a lambda

Cmn
Unit
@Composable
CircularProgressIndicator(
    progress: () -> Float,
    modifier: Modifier,
    color: Color,
    strokeWidth: Dp,
    trackColor: Color,
    strokeCap: StrokeCap,
    gapSize: Dp
)

Determinate Material Design circular progress indicator.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
DatePicker(
    state: DatePickerState,
    modifier: Modifier,
    dateFormatter: DatePickerFormatter,
    title: (@Composable () -> Unit)?,
    headline: (@Composable () -> Unit)?,
    showModeToggle: Boolean,
    colors: DatePickerColors
)

Material Design date picker.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
DatePickerDialog(
    onDismissRequest: () -> Unit,
    confirmButton: @Composable () -> Unit,
    modifier: Modifier,
    dismissButton: (@Composable () -> Unit)?,
    shape: Shape,
    tonalElevation: Dp,
    colors: DatePickerColors,
    properties: DialogProperties,
    content: @Composable ColumnScope.() -> Unit
)

Material Design date picker dialog.

android
DatePickerState
@ExperimentalMaterial3Api
DatePickerState(
    locale: CalendarLocale,
    initialSelectedDateMillis: Long?,
    initialDisplayedMonthMillis: Long?,
    yearRange: IntRange,
    initialDisplayMode: DisplayMode,
    selectableDates: SelectableDates
)

Creates a DatePickerState.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
DateRangePicker(
    state: DateRangePickerState,
    modifier: Modifier,
    dateFormatter: DatePickerFormatter,
    title: (@Composable () -> Unit)?,
    headline: (@Composable () -> Unit)?,
    showModeToggle: Boolean,
    colors: DatePickerColors
)

Material Design date range picker.

Cmn
DateRangePickerState
@ExperimentalMaterial3Api
DateRangePickerState(
    locale: CalendarLocale,
    initialSelectedStartDateMillis: Long?,
    initialSelectedEndDateMillis: Long?,
    initialDisplayedMonthMillis: Long?,
    yearRange: IntRange,
    initialDisplayMode: DisplayMode,
    selectableDates: SelectableDates
)

Creates a DateRangePickerState.

Cmn
Unit
@Composable
DismissibleDrawerSheet(
    modifier: Modifier,
    drawerShape: Shape,
    drawerContainerColor: Color,
    drawerContentColor: Color,
    drawerTonalElevation: Dp,
    windowInsets: WindowInsets,
    content: @Composable ColumnScope.() -> Unit
)

Content inside of a dismissible navigation drawer.

Cmn
Unit
@Composable
DismissibleNavigationDrawer(
    drawerContent: @Composable () -> Unit,
    modifier: Modifier,
    drawerState: DrawerState,
    gesturesEnabled: Boolean,
    content: @Composable () -> Unit
)

Material Design navigation drawer.

Cmn
Unit
@Composable
Divider(modifier: Modifier, thickness: Dp, color: Color)

This function is deprecated. Renamed to HorizontalDivider

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
DockedSearchBar(
    query: String,
    onQueryChange: (String) -> Unit,
    onSearch: (String) -> Unit,
    active: Boolean,
    onActiveChange: (Boolean) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    placeholder: (@Composable () -> Unit)?,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    shape: Shape,
    colors: SearchBarColors,
    tonalElevation: Dp,
    shadowElevation: Dp,
    interactionSource: MutableInteractionSource?,
    content: @Composable ColumnScope.() -> Unit
)

Material Design search.

android
Unit
@Composable
DropdownMenu(
    expanded: Boolean,
    onDismissRequest: () -> Unit,
    modifier: Modifier,
    offset: DpOffset,
    scrollState: ScrollState,
    properties: PopupProperties,
    shape: Shape,
    containerColor: Color,
    tonalElevation: Dp,
    shadowElevation: Dp,
    border: BorderStroke?,
    content: @Composable ColumnScope.() -> Unit
)

Material Design dropdown menu.

android
Unit
@Composable
DropdownMenuItem(
    text: @Composable () -> Unit,
    onClick: () -> Unit,
    modifier: Modifier,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    enabled: Boolean,
    colors: MenuItemColors,
    contentPadding: PaddingValues,
    interactionSource: MutableInteractionSource?
)

Material Design dropdown menu item.

android
Unit
@Composable
ElevatedAssistChip(
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    shape: Shape,
    colors: ChipColors,
    elevation: ChipElevation?,
    border: BorderStroke?,
    interactionSource: MutableInteractionSource?
)

Material Design elevated assist chip.

Cmn
Unit
@Composable
ElevatedButton(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: ButtonColors,
    elevation: ButtonElevation?,
    border: BorderStroke?,
    contentPadding: PaddingValues,
    interactionSource: MutableInteractionSource?,
    content: @Composable RowScope.() -> Unit
)

Material Design elevated button.

Cmn
Unit
@Composable
ElevatedCard(
    modifier: Modifier,
    shape: Shape,
    colors: CardColors,
    elevation: CardElevation,
    content: @Composable ColumnScope.() -> Unit
)

Material Design elevated card.

Cmn
Unit
@Composable
ElevatedCard(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: CardColors,
    elevation: CardElevation,
    interactionSource: MutableInteractionSource?,
    content: @Composable ColumnScope.() -> Unit
)

Material Design elevated card.

Cmn
Unit
@Composable
ElevatedFilterChip(
    selected: Boolean,
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    shape: Shape,
    colors: SelectableChipColors,
    elevation: SelectableChipElevation?,
    border: BorderStroke?,
    interactionSource: MutableInteractionSource?
)

Material Design elevated filter chip.

Cmn
Unit
@Composable
ElevatedSuggestionChip(
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    icon: (@Composable () -> Unit)?,
    shape: Shape,
    colors: ChipColors,
    elevation: ChipElevation?,
    border: BorderStroke?,
    interactionSource: MutableInteractionSource?
)

Material Design elevated suggestion chip.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
ExposedDropdownMenuBox(
    expanded: Boolean,
    onExpandedChange: (Boolean) -> Unit,
    modifier: Modifier,
    content: @Composable ExposedDropdownMenuBoxScope.() -> Unit
)

Material Design Exposed Dropdown Menu.

android
Unit
@Composable
ExtendedFloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier,
    shape: Shape,
    containerColor: Color,
    contentColor: Color,
    elevation: FloatingActionButtonElevation,
    interactionSource: MutableInteractionSource?,
    content: @Composable RowScope.() -> Unit
)

Material Design extended floating action button.

Cmn
Unit
@Composable
ExtendedFloatingActionButton(
    text: @Composable () -> Unit,
    icon: @Composable () -> Unit,
    onClick: () -> Unit,
    modifier: Modifier,
    expanded: Boolean,
    shape: Shape,
    containerColor: Color,
    contentColor: Color,
    elevation: FloatingActionButtonElevation,
    interactionSource: MutableInteractionSource?
)

Material Design extended floating action button.

Cmn
Unit
@Composable
FilledIconButton(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: IconButtonColors,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material Design filled icon button.

Cmn
Unit
@Composable
FilledIconToggleButton(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: IconToggleButtonColors,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material Design filled icon toggle button.

Cmn
Unit
@Composable
FilledTonalButton(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: ButtonColors,
    elevation: ButtonElevation?,
    border: BorderStroke?,
    contentPadding: PaddingValues,
    interactionSource: MutableInteractionSource?,
    content: @Composable RowScope.() -> Unit
)

Material Design filled tonal button.

Cmn
Unit
@Composable
FilledTonalIconButton(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: IconButtonColors,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material Design filled tonal icon button.

Cmn
Unit
@Composable
FilledTonalIconToggleButton(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: IconToggleButtonColors,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material Design filled tonal icon toggle button.

Cmn
Unit
@Composable
FilterChip(
    selected: Boolean,
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    shape: Shape,
    colors: SelectableChipColors,
    elevation: SelectableChipElevation?,
    border: BorderStroke?,
    interactionSource: MutableInteractionSource?
)

Material Design filter chip.

Cmn
Unit
@Composable
FloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier,
    shape: Shape,
    containerColor: Color,
    contentColor: Color,
    elevation: FloatingActionButtonElevation,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material Design floating action button.

Cmn
Unit
@Composable
HorizontalDivider(modifier: Modifier, thickness: Dp, color: Color)

Material Design divider.

Cmn
Unit
@Composable
Icon(
    bitmap: ImageBitmap,
    contentDescription: String?,
    modifier: Modifier,
    tint: Color
)

A Material Design icon component that draws bitmap using tint, with a default value of LocalContentColor.

Cmn
Unit
@Composable
Icon(
    imageVector: ImageVector,
    contentDescription: String?,
    modifier: Modifier,
    tint: Color
)

A Material Design icon component that draws imageVector using tint, with a default value of LocalContentColor.

Cmn
Unit
@Composable
Icon(
    painter: Painter,
    contentDescription: String?,
    modifier: Modifier,
    tint: Color
)

A Material Design icon component that draws painter using tint, with a default value of LocalContentColor.

Cmn
Unit
@Composable
IconButton(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    colors: IconButtonColors,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material Design standard icon button.

Cmn
Unit
@Composable
IconToggleButton(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    colors: IconToggleButtonColors,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material Design standard icon toggle button.

Cmn
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?,
    interactionSource: MutableInteractionSource?
)

Material Design input chip.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
Label(
    label: @Composable CaretScope.() -> Unit,
    modifier: Modifier,
    interactionSource: MutableInteractionSource?,
    isPersistent: Boolean,
    content: @Composable () -> Unit
)

Label component that will append a label to content.

Cmn
Unit
@Composable
LargeFloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier,
    shape: Shape,
    containerColor: Color,
    contentColor: Color,
    elevation: FloatingActionButtonElevation,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material Design large floating action button.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
LargeTopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier,
    navigationIcon: @Composable () -> Unit,
    actions: @Composable RowScope.() -> Unit,
    windowInsets: WindowInsets,
    colors: TopAppBarColors,
    scrollBehavior: TopAppBarScrollBehavior?
)

Material Design large top app bar.

Cmn
Unit
@Composable
LeadingIconTab(
    selected: Boolean,
    onClick: () -> Unit,
    text: @Composable () -> Unit,
    icon: @Composable () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    selectedContentColor: Color,
    unselectedContentColor: Color,
    interactionSource: MutableInteractionSource?
)

Material Design tab.

Cmn
Unit
@Composable
LinearProgressIndicator(
    modifier: Modifier,
    color: Color,
    trackColor: Color,
    strokeCap: StrokeCap,
    gapSize: Dp
)

Indeterminate Material Design linear progress indicator.

Cmn
Unit
@Composable
LinearProgressIndicator(
    progress: Float,
    modifier: Modifier,
    color: Color,
    trackColor: Color,
    strokeCap: StrokeCap
)

This function is deprecated. Use the overload that takes `progress` as a lambda

Cmn
Unit
@Composable
LinearProgressIndicator(
    progress: () -> Float,
    modifier: Modifier,
    color: Color,
    trackColor: Color,
    strokeCap: StrokeCap,
    gapSize: Dp,
    drawStopIndicator: (DrawScope.() -> Unit)?
)

Determinate Material Design linear progress indicator.

Cmn
Unit
@Composable
ListItem(
    headlineContent: @Composable () -> Unit,
    modifier: Modifier,
    overlineContent: (@Composable () -> Unit)?,
    supportingContent: (@Composable () -> Unit)?,
    leadingContent: (@Composable () -> Unit)?,
    trailingContent: (@Composable () -> Unit)?,
    colors: ListItemColors,
    tonalElevation: Dp,
    shadowElevation: Dp
)

Material Design list item.

Cmn
Unit
@Composable
MaterialTheme(
    colorScheme: ColorScheme,
    shapes: Shapes,
    typography: Typography,
    content: @Composable () -> Unit
)

Material Theming refers to the customization of your Material Design app to better reflect your product’s brand.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
MediumTopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier,
    navigationIcon: @Composable () -> Unit,
    actions: @Composable RowScope.() -> Unit,
    windowInsets: WindowInsets,
    colors: TopAppBarColors,
    scrollBehavior: TopAppBarScrollBehavior?
)

Material Design medium top app bar.

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
ModalBottomSheet(
    onDismissRequest: () -> Unit,
    modifier: Modifier,
    sheetState: SheetState,
    sheetMaxWidth: Dp,
    shape: Shape,
    containerColor: Color,
    contentColor: Color,
    tonalElevation: Dp,
    scrimColor: Color,
    dragHandle: (@Composable () -> Unit)?,
    windowInsets: WindowInsets,
    properties: ModalBottomSheetProperties,
    content: @Composable ColumnScope.() -> Unit
)

Material Design modal bottom sheet.

android
Unit
@Composable
ModalDrawerSheet(
    modifier: Modifier,
    drawerShape: Shape,
    drawerContainerColor: Color,
    drawerContentColor: Color,
    drawerTonalElevation: Dp,
    windowInsets: WindowInsets,
    content: @Composable ColumnScope.() -> Unit
)

Content inside of a modal navigation drawer.

Cmn
Unit
@Composable
ModalNavigationDrawer(
    drawerContent: @Composable () -> Unit,
    modifier: Modifier,
    drawerState: DrawerState,
    gesturesEnabled: Boolean,
    scrimColor: Color,
    content: @Composable () -> Unit
)

Material Design navigation drawer.

Cmn
Unit

Material Segmented Button.

Cmn
Unit
@Composable
NavigationBar(
    modifier: Modifier,
    containerColor: Color,
    contentColor: Color,
    tonalElevation: Dp,
    windowInsets: WindowInsets,
    content: @Composable RowScope.() -> Unit
)

Material Design bottom navigation bar.

Cmn
Unit
@Composable
NavigationDrawerItem(
    label: @Composable () -> Unit,
    selected: Boolean,
    onClick: () -> Unit,
    modifier: Modifier,
    icon: (@Composable () -> Unit)?,
    badge: (@Composable () -> Unit)?,
    shape: Shape,
    colors: NavigationDrawerItemColors,
    interactionSource: MutableInteractionSource?
)

Material Design navigation drawer item.

Cmn
Unit
@Composable
NavigationRail(
    modifier: Modifier,
    containerColor: Color,
    contentColor: Color,
    header: (@Composable ColumnScope.() -> Unit)?,
    windowInsets: WindowInsets,
    content: @Composable ColumnScope.() -> Unit
)

Material Design bottom navigation rail.

Cmn
Unit
@Composable
NavigationRailItem(
    selected: Boolean,
    onClick: () -> Unit,
    icon: @Composable () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    label: (@Composable () -> Unit)?,
    alwaysShowLabel: Boolean,
    colors: NavigationRailItemColors,
    interactionSource: MutableInteractionSource?
)

Material Design navigation rail item.

Cmn
Unit
@Composable
OutlinedButton(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: ButtonColors,
    elevation: ButtonElevation?,
    border: BorderStroke?,
    contentPadding: PaddingValues,
    interactionSource: MutableInteractionSource?,
    content: @Composable RowScope.() -> Unit
)

Material Design outlined button.

Cmn
Unit
@Composable
OutlinedCard(
    modifier: Modifier,
    shape: Shape,
    colors: CardColors,
    elevation: CardElevation,
    border: BorderStroke,
    content: @Composable ColumnScope.() -> Unit
)

Material Design outlined card.

Cmn
Unit
@Composable
OutlinedCard(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: CardColors,
    elevation: CardElevation,
    border: BorderStroke,
    interactionSource: MutableInteractionSource?,
    content: @Composable ColumnScope.() -> Unit
)

Material Design outlined card.

Cmn
Unit
@Composable
OutlinedIconButton(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: IconButtonColors,
    border: BorderStroke?,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material Design outlined icon button.

Cmn
Unit
@Composable
OutlinedIconToggleButton(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: IconToggleButtonColors,
    border: BorderStroke?,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material Design outlined icon toggle button.

Cmn
Unit
@Composable
OutlinedTextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    readOnly: Boolean,
    textStyle: TextStyle,
    label: (@Composable () -> Unit)?,
    placeholder: (@Composable () -> Unit)?,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    prefix: (@Composable () -> Unit)?,
    suffix: (@Composable () -> Unit)?,
    supportingText: (@Composable () -> Unit)?,
    isError: Boolean,
    visualTransformation: VisualTransformation,
    keyboardOptions: KeyboardOptions,
    keyboardActions: KeyboardActions,
    singleLine: Boolean,
    maxLines: Int,
    minLines: Int,
    interactionSource: MutableInteractionSource?,
    shape: Shape,
    colors: TextFieldColors
)

Material Design outlined text field.

Cmn
Unit
@Composable
OutlinedTextField(
    value: TextFieldValue,
    onValueChange: (TextFieldValue) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    readOnly: Boolean,
    textStyle: TextStyle,
    label: (@Composable () -> Unit)?,
    placeholder: (@Composable () -> Unit)?,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    prefix: (@Composable () -> Unit)?,
    suffix: (@Composable () -> Unit)?,
    supportingText: (@Composable () -> Unit)?,
    isError: Boolean,
    visualTransformation: VisualTransformation,
    keyboardOptions: KeyboardOptions,
    keyboardActions: KeyboardActions,
    singleLine: Boolean,
    maxLines: Int,
    minLines: Int,
    interactionSource: MutableInteractionSource?,
    shape: Shape,
    colors: TextFieldColors
)

Material Design outlined text field.

Cmn
Unit
@Composable
PermanentDrawerSheet(
    modifier: Modifier,
    drawerShape: Shape,
    drawerContainerColor: Color,
    drawerContentColor: Color,
    drawerTonalElevation: Dp,
    windowInsets: WindowInsets,
    content: @Composable ColumnScope.() -> Unit
)

Content inside of a permanent navigation drawer.

Cmn
Unit
@Composable
PermanentNavigationDrawer(
    drawerContent: @Composable () -> Unit,
    modifier: Modifier,
    content: @Composable () -> Unit
)

Material Design navigation permanent drawer.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
PrimaryScrollableTabRow(
    selectedTabIndex: Int,
    modifier: Modifier,
    scrollState: ScrollState,
    containerColor: Color,
    contentColor: Color,
    edgePadding: Dp,
    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit,
    divider: @Composable () -> Unit,
    tabs: @Composable () -> Unit
)

Material Design Scrollable Primary tabs

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
PrimaryTabRow(
    selectedTabIndex: Int,
    modifier: Modifier,
    containerColor: Color,
    contentColor: Color,
    indicator: @Composable TabIndicatorScope.() -> Unit,
    divider: @Composable () -> Unit,
    tabs: @Composable () -> Unit
)

Material Design Fixed Primary tabs

Cmn
Unit

This function is used to set the current value of LocalTextStyle, merging the given style with the current style values for any missing attributes.

Cmn
Unit
@Composable
RadioButton(
    selected: Boolean,
    onClick: (() -> Unit)?,
    modifier: Modifier,
    enabled: Boolean,
    colors: RadioButtonColors,
    interactionSource: MutableInteractionSource?
)

Material Design radio button.

Cmn
Unit
@Composable
RangeSlider(
    value: ClosedFloatingPointRange<Float>,
    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    valueRange: ClosedFloatingPointRange<Float>,
    steps: @IntRange(from = 0) Int,
    onValueChangeFinished: (() -> Unit)?,
    colors: SliderColors
)

Material Design Range slider.

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
RangeSlider(
    state: RangeSliderState,
    modifier: Modifier,
    enabled: Boolean,
    colors: SliderColors,
    startInteractionSource: MutableInteractionSource,
    endInteractionSource: MutableInteractionSource,
    startThumb: @Composable (RangeSliderState) -> Unit,
    endThumb: @Composable (RangeSliderState) -> Unit,
    track: @Composable (RangeSliderState) -> Unit
)

Material Design Range slider.

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
RangeSlider(
    value: ClosedFloatingPointRange<Float>,
    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    valueRange: ClosedFloatingPointRange<Float>,
    onValueChangeFinished: (() -> Unit)?,
    colors: SliderColors,
    startInteractionSource: MutableInteractionSource,
    endInteractionSource: MutableInteractionSource,
    startThumb: @Composable (RangeSliderState) -> Unit,
    endThumb: @Composable (RangeSliderState) -> Unit,
    track: @Composable (RangeSliderState) -> Unit,
    steps: @IntRange(from = 0) Int
)

Material Design Range slider.

Cmn
Unit
@Composable
Scaffold(
    modifier: Modifier,
    topBar: @Composable () -> Unit,
    bottomBar: @Composable () -> Unit,
    snackbarHost: @Composable () -> Unit,
    floatingActionButton: @Composable () -> Unit,
    floatingActionButtonPosition: FabPosition,
    containerColor: Color,
    contentColor: Color,
    contentWindowInsets: WindowInsets,
    content: @Composable (PaddingValues) -> Unit
)

Material Design layout.

Cmn
Unit
@Composable
ScrollableTabRow(
    selectedTabIndex: Int,
    modifier: Modifier,
    containerColor: Color,
    contentColor: Color,
    edgePadding: Dp,
    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit,
    divider: @Composable () -> Unit,
    tabs: @Composable () -> Unit
)

Material Design tabs

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
SearchBar(
    query: String,
    onQueryChange: (String) -> Unit,
    onSearch: (String) -> Unit,
    active: Boolean,
    onActiveChange: (Boolean) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    placeholder: (@Composable () -> Unit)?,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    shape: Shape,
    colors: SearchBarColors,
    tonalElevation: Dp,
    shadowElevation: Dp,
    windowInsets: WindowInsets,
    interactionSource: MutableInteractionSource?,
    content: @Composable ColumnScope.() -> Unit
)

Material Design search.

android
Unit
@ExperimentalMaterial3Api
@Composable
SecondaryScrollableTabRow(
    selectedTabIndex: Int,
    modifier: Modifier,
    scrollState: ScrollState,
    containerColor: Color,
    contentColor: Color,
    edgePadding: Dp,
    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit,
    divider: @Composable () -> Unit,
    tabs: @Composable () -> Unit
)

Material Design Scrollable Secondary tabs

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
SecondaryTabRow(
    selectedTabIndex: Int,
    modifier: Modifier,
    containerColor: Color,
    contentColor: Color,
    indicator: @Composable TabIndicatorScope.() -> Unit,
    divider: @Composable () -> Unit,
    tabs: @Composable () -> Unit
)

Material Design Fixed Secondary tabs

Cmn
Unit

Material Segmented Button.

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
Slider(
    state: SliderState,
    modifier: Modifier,
    enabled: Boolean,
    colors: SliderColors,
    interactionSource: MutableInteractionSource,
    thumb: @Composable (SliderState) -> Unit,
    track: @Composable (SliderState) -> Unit
)

Material Design slider.

Cmn
Unit
@Composable
Slider(
    value: Float,
    onValueChange: (Float) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    valueRange: ClosedFloatingPointRange<Float>,
    steps: @IntRange(from = 0) Int,
    onValueChangeFinished: (() -> Unit)?,
    colors: SliderColors,
    interactionSource: MutableInteractionSource
)

Material Design slider.

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
Slider(
    value: Float,
    onValueChange: (Float) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    onValueChangeFinished: (() -> Unit)?,
    colors: SliderColors,
    interactionSource: MutableInteractionSource,
    steps: @IntRange(from = 0) Int,
    thumb: @Composable (SliderState) -> Unit,
    track: @Composable (SliderState) -> Unit,
    valueRange: ClosedFloatingPointRange<Float>
)

Material Design slider.

Cmn
Unit
@Composable
SmallFloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier,
    shape: Shape,
    containerColor: Color,
    contentColor: Color,
    elevation: FloatingActionButtonElevation,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material Design small floating action button.

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
SmallTopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier,
    navigationIcon: @Composable () -> Unit,
    actions: @Composable RowScope.() -> Unit,
    windowInsets: WindowInsets,
    colors: TopAppBarColors,
    scrollBehavior: TopAppBarScrollBehavior?
)

This function is deprecated. Use TopAppBar instead.

Cmn
Unit
@Composable
Snackbar(
    snackbarData: SnackbarData,
    modifier: Modifier,
    actionOnNewLine: Boolean,
    shape: Shape,
    containerColor: Color,
    contentColor: Color,
    actionColor: Color,
    actionContentColor: Color,
    dismissActionContentColor: Color
)

Material Design snackbar.

Cmn
Unit
@Composable
Snackbar(
    modifier: Modifier,
    action: (@Composable () -> Unit)?,
    dismissAction: (@Composable () -> Unit)?,
    actionOnNewLine: Boolean,
    shape: Shape,
    containerColor: Color,
    contentColor: Color,
    actionContentColor: Color,
    dismissActionContentColor: Color,
    content: @Composable () -> Unit
)

Material Design snackbar.

Cmn
Unit
@Composable
SnackbarHost(
    hostState: SnackbarHostState,
    modifier: Modifier,
    snackbar: @Composable (SnackbarData) -> Unit
)

Host for Snackbars to be used in Scaffold to properly show, hide and dismiss items based on Material specification and the hostState.

Cmn
Unit
@Composable
SuggestionChip(
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    icon: (@Composable () -> Unit)?,
    shape: Shape,
    colors: ChipColors,
    elevation: ChipElevation?,
    border: BorderStroke?,
    interactionSource: MutableInteractionSource?
)

Material Design suggestion chip.

Cmn
Unit
@Composable
@NonRestartableComposable
Surface(
    modifier: Modifier,
    shape: Shape,
    color: Color,
    contentColor: Color,
    tonalElevation: Dp,
    shadowElevation: Dp,
    border: BorderStroke?,
    content: @Composable () -> Unit
)

Material surface is the central metaphor in material design.

Cmn
Unit
@Composable
@NonRestartableComposable
Surface(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    color: Color,
    contentColor: Color,
    tonalElevation: Dp,
    shadowElevation: Dp,
    border: BorderStroke?,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material surface is the central metaphor in material design.

Cmn
Unit
@Composable
@NonRestartableComposable
Surface(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    color: Color,
    contentColor: Color,
    tonalElevation: Dp,
    shadowElevation: Dp,
    border: BorderStroke?,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material surface is the central metaphor in material design.

Cmn
Unit
@Composable
@NonRestartableComposable
Surface(
    selected: Boolean,
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    color: Color,
    contentColor: Color,
    tonalElevation: Dp,
    shadowElevation: Dp,
    border: BorderStroke?,
    interactionSource: MutableInteractionSource?,
    content: @Composable () -> Unit
)

Material surface is the central metaphor in material design.

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
SwipeToDismiss(
    state: SwipeToDismissBoxState,
    background: @Composable RowScope.() -> Unit,
    dismissContent: @Composable RowScope.() -> Unit,
    modifier: Modifier,
    directions: Set<SwipeToDismissBoxValue>
)

This function is deprecated. Use SwipeToDismissBox instead

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
SwipeToDismissBox(
    state: SwipeToDismissBoxState,
    backgroundContent: @Composable RowScope.() -> Unit,
    modifier: Modifier,
    enableDismissFromStartToEnd: Boolean,
    enableDismissFromEndToStart: Boolean,
    content: @Composable RowScope.() -> Unit
)

A composable that can be dismissed by swiping left or right.

Cmn
Unit
@Composable
Switch(
    checked: Boolean,
    onCheckedChange: ((Boolean) -> Unit)?,
    modifier: Modifier,
    thumbContent: (@Composable () -> Unit)?,
    enabled: Boolean,
    colors: SwitchColors,
    interactionSource: MutableInteractionSource?
)

Material Design Switch.

Cmn
Unit
@Composable
Tab(
    selected: Boolean,
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    selectedContentColor: Color,
    unselectedContentColor: Color,
    interactionSource: MutableInteractionSource?,
    content: @Composable ColumnScope.() -> Unit
)

Material Design tab.

Cmn
Unit
@Composable
Tab(
    selected: Boolean,
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    text: (@Composable () -> Unit)?,
    icon: (@Composable () -> Unit)?,
    selectedContentColor: Color,
    unselectedContentColor: Color,
    interactionSource: MutableInteractionSource?
)

Material Design tab.

Cmn
Unit
@Composable
TabRow(
    selectedTabIndex: Int,
    modifier: Modifier,
    containerColor: Color,
    contentColor: Color,
    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit,
    divider: @Composable () -> Unit,
    tabs: @Composable () -> Unit
)

Material Design tabs

Cmn
Unit
@Composable
Text(
    text: String,
    modifier: Modifier,
    color: Color,
    fontSize: TextUnit,
    fontStyle: FontStyle?,
    fontWeight: FontWeight?,
    fontFamily: FontFamily?,
    letterSpacing: TextUnit,
    textDecoration: TextDecoration?,
    textAlign: TextAlign?,
    lineHeight: TextUnit,
    overflow: TextOverflow,
    softWrap: Boolean,
    maxLines: Int,
    minLines: Int,
    onTextLayout: ((TextLayoutResult) -> Unit)?,
    style: TextStyle
)

High level element that displays text and provides semantics / accessibility information.

Cmn
Unit
@Composable
Text(
    text: AnnotatedString,
    modifier: Modifier,
    color: Color,
    fontSize: TextUnit,
    fontStyle: FontStyle?,
    fontWeight: FontWeight?,
    fontFamily: FontFamily?,
    letterSpacing: TextUnit,
    textDecoration: TextDecoration?,
    textAlign: TextAlign?,
    lineHeight: TextUnit,
    overflow: TextOverflow,
    softWrap: Boolean,
    maxLines: Int,
    minLines: Int,
    inlineContent: Map<StringInlineTextContent>,
    onTextLayout: (TextLayoutResult) -> Unit,
    style: TextStyle
)

High level element that displays text and provides semantics / accessibility information.

Cmn
Unit
@Composable
TextButton(
    onClick: () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    shape: Shape,
    colors: ButtonColors,
    elevation: ButtonElevation?,
    border: BorderStroke?,
    contentPadding: PaddingValues,
    interactionSource: MutableInteractionSource?,
    content: @Composable RowScope.() -> Unit
)

Material Design text button.

Cmn
Unit
@Composable
TextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    readOnly: Boolean,
    textStyle: TextStyle,
    label: (@Composable () -> Unit)?,
    placeholder: (@Composable () -> Unit)?,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    prefix: (@Composable () -> Unit)?,
    suffix: (@Composable () -> Unit)?,
    supportingText: (@Composable () -> Unit)?,
    isError: Boolean,
    visualTransformation: VisualTransformation,
    keyboardOptions: KeyboardOptions,
    keyboardActions: KeyboardActions,
    singleLine: Boolean,
    maxLines: Int,
    minLines: Int,
    interactionSource: MutableInteractionSource?,
    shape: Shape,
    colors: TextFieldColors
)

Material Design filled text field.

Cmn
Unit
@Composable
TextField(
    value: TextFieldValue,
    onValueChange: (TextFieldValue) -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    readOnly: Boolean,
    textStyle: TextStyle,
    label: (@Composable () -> Unit)?,
    placeholder: (@Composable () -> Unit)?,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    prefix: (@Composable () -> Unit)?,
    suffix: (@Composable () -> Unit)?,
    supportingText: (@Composable () -> Unit)?,
    isError: Boolean,
    visualTransformation: VisualTransformation,
    keyboardOptions: KeyboardOptions,
    keyboardActions: KeyboardActions,
    singleLine: Boolean,
    maxLines: Int,
    minLines: Int,
    interactionSource: MutableInteractionSource?,
    shape: Shape,
    colors: TextFieldColors
)

Material Design filled text field.

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
TimeInput(
    state: TimePickerState,
    modifier: Modifier,
    colors: TimePickerColors
)

Time pickers help users select and set a specific time.

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
TimePicker(
    state: TimePickerState,
    modifier: Modifier,
    colors: TimePickerColors,
    layoutType: TimePickerLayoutType
)

Material Design time picker.

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
TooltipBox(
    positionProvider: PopupPositionProvider,
    tooltip: @Composable CaretScope.() -> Unit,
    state: TooltipState,
    modifier: Modifier,
    focusable: Boolean,
    enableUserInput: Boolean,
    content: @Composable () -> Unit
)

Material TooltipBox that wraps a composable with a tooltip.

Cmn
TooltipState
@ExperimentalMaterial3Api
TooltipState(
    initialIsVisible: Boolean,
    isPersistent: Boolean,
    mutatorMutex: MutatorMutex
)

Constructor extension function for TooltipState

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
TopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier,
    navigationIcon: @Composable () -> Unit,
    actions: @Composable RowScope.() -> Unit,
    windowInsets: WindowInsets,
    colors: TopAppBarColors,
    scrollBehavior: TopAppBarScrollBehavior?
)

Material Design small top app bar.

Cmn
Unit
@Composable
TriStateCheckbox(
    state: ToggleableState,
    onClick: (() -> Unit)?,
    modifier: Modifier,
    enabled: Boolean,
    colors: CheckboxColors,
    interactionSource: MutableInteractionSource?
)

Material Design checkbox parent.

Cmn
Unit
@Composable
VerticalDivider(modifier: Modifier, thickness: Dp, color: Color)

Material Design divider.

Cmn
Color
@Composable
contentColorFor(backgroundColor: Color)

The Material color system contains pairs of colors that are typically used for the background and content color inside a component.

Cmn
ColorScheme
darkColorScheme(
    primary: Color,
    onPrimary: Color,
    primaryContainer: Color,
    onPrimaryContainer: Color,
    inversePrimary: Color,
    secondary: Color,
    onSecondary: Color,
    secondaryContainer: Color,
    onSecondaryContainer: Color,
    tertiary: Color,
    onTertiary: Color,
    tertiaryContainer: Color,
    onTertiaryContainer: Color,
    background: Color,
    onBackground: Color,
    surface: Color,
    onSurface: Color,
    surfaceVariant: Color,
    onSurfaceVariant: Color,
    surfaceTint: Color,
    inverseSurface: Color,
    inverseOnSurface: Color,
    error: Color,
    onError: Color,
    errorContainer: Color,
    onErrorContainer: Color,
    outline: Color,
    outlineVariant: Color,
    scrim: Color,
    surfaceBright: Color,
    surfaceContainer: Color,
    surfaceContainerHigh: Color,
    surfaceContainerHighest: Color,
    surfaceContainerLow: Color,
    surfaceContainerLowest: Color,
    surfaceDim: Color
)

Returns a dark Material color scheme.

Cmn
ColorScheme
@RequiresApi(value = 31)
dynamicDarkColorScheme(context: Context)

Creates a dark dynamic color scheme.

android
ColorScheme

Creates a light dynamic color scheme.

android
ColorScheme
lightColorScheme(
    primary: Color,
    onPrimary: Color,
    primaryContainer: Color,
    onPrimaryContainer: Color,
    inversePrimary: Color,
    secondary: Color,
    onSecondary: Color,
    secondaryContainer: Color,
    onSecondaryContainer: Color,
    tertiary: Color,
    onTertiary: Color,
    tertiaryContainer: Color,
    onTertiaryContainer: Color,
    background: Color,
    onBackground: Color,
    surface: Color,
    onSurface: Color,
    surfaceVariant: Color,
    onSurfaceVariant: Color,
    surfaceTint: Color,
    inverseSurface: Color,
    inverseOnSurface: Color,
    error: Color,
    onError: Color,
    errorContainer: Color,
    onErrorContainer: Color,
    outline: Color,
    outlineVariant: Color,
    scrim: Color,
    surfaceBright: Color,
    surfaceContainer: Color,
    surfaceContainerHigh: Color,
    surfaceContainerHighest: Color,
    surfaceContainerLow: Color,
    surfaceContainerLowest: Color,
    surfaceDim: Color
)

Returns a light Material color scheme.

Cmn
BottomAppBarState
@ExperimentalMaterial3Api
@Composable
rememberBottomAppBarState(
    initialHeightOffsetLimit: Float,
    initialHeightOffset: Float,
    initialContentOffset: Float
)

Creates a BottomAppBarState that is remembered across compositions.

Cmn
BottomSheetScaffoldState

Create and remember a BottomSheetScaffoldState.

Cmn
DatePickerState
@Composable
@ExperimentalMaterial3Api
rememberDatePickerState(
    initialSelectedDateMillis: Long?,
    initialDisplayedMonthMillis: Long?,
    yearRange: IntRange,
    initialDisplayMode: DisplayMode,
    selectableDates: SelectableDates
)

Creates a DatePickerState for a DatePicker that is remembered across compositions.

Cmn
DateRangePickerState
@Composable
@ExperimentalMaterial3Api
rememberDateRangePickerState(
    initialSelectedStartDateMillis: Long?,
    initialSelectedEndDateMillis: Long?,
    initialDisplayedMonthMillis: Long?,
    yearRange: IntRange,
    initialDisplayMode: DisplayMode,
    selectableDates: SelectableDates
)

Creates a DateRangePickerState for a DateRangePicker that is remembered across compositions.

Cmn
DrawerState
@Composable
rememberDrawerState(
    initialValue: DrawerValue,
    confirmStateChange: (DrawerValue) -> Boolean
)

Create and remember a DrawerState.

Cmn
SheetState
@Composable
@ExperimentalMaterial3Api
rememberModalBottomSheetState(
    skipPartiallyExpanded: Boolean,
    confirmValueChange: (SheetValue) -> Boolean
)

Create and remember a SheetState for ModalBottomSheet.

android
SheetState
@Composable
@ExperimentalMaterial3Api
rememberStandardBottomSheetState(
    initialValue: SheetValue,
    confirmValueChange: (SheetValue) -> Boolean,
    skipHiddenState: Boolean
)

Create and remember a SheetState for BottomSheetScaffold.

Cmn
SwipeToDismissBoxState
@Composable
@ExperimentalMaterial3Api
rememberSwipeToDismissBoxState(
    initialValue: SwipeToDismissBoxValue,
    confirmValueChange: (SwipeToDismissBoxValue) -> Boolean,
    positionalThreshold: (totalDistance: Float) -> Float
)

Create and remember a SwipeToDismissBoxState.

Cmn
TimePickerState
@Composable
@ExperimentalMaterial3Api
rememberTimePickerState(
    initialHour: Int,
    initialMinute: Int,
    is24Hour: Boolean
)

Creates a TimePickerState for a time picker that is remembered across compositions and configuration changes.

Cmn
TooltipState
@Composable
@ExperimentalMaterial3Api
rememberTooltipState(
    initialIsVisible: Boolean,
    isPersistent: Boolean,
    mutatorMutex: MutatorMutex
)

Create and remember the default TooltipState for TooltipBox.

Cmn
TopAppBarState
@ExperimentalMaterial3Api
@Composable
rememberTopAppBarState(
    initialHeightOffsetLimit: Float,
    initialHeightOffset: Float,
    initialContentOffset: Float
)

Creates a TopAppBarState that is remembered across compositions.

Cmn
IndicationNodeFactory
ripple(bounded: Boolean, radius: Dp, color: Color)

Creates a Ripple using the provided values and values inferred from the theme.

Cmn
IndicationNodeFactory
ripple(color: ColorProducer, bounded: Boolean, radius: Dp)

Creates a Ripple using the provided values and values inferred from the theme.

Cmn

Extension functions summary

Unit
@Composable
RowScope.NavigationBarItem(
    selected: Boolean,
    onClick: () -> Unit,
    icon: @Composable () -> Unit,
    modifier: Modifier,
    enabled: Boolean,
    label: (@Composable () -> Unit)?,
    alwaysShowLabel: Boolean,
    colors: NavigationBarItemColors,
    interactionSource: MutableInteractionSource?
)

Material Design navigation bar item.

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
CaretScope.PlainTooltip(
    modifier: Modifier,
    caretProperties: CaretProperties?,
    shape: Shape,
    contentColor: Color,
    containerColor: Color,
    tonalElevation: Dp,
    shadowElevation: Dp,
    content: @Composable () -> Unit
)

Plain tooltip that provides a descriptive message.

Cmn
android
Unit
@Composable
@ExperimentalMaterial3Api
CaretScope.RichTooltip(
    modifier: Modifier,
    title: (@Composable () -> Unit)?,
    action: (@Composable () -> Unit)?,
    caretProperties: CaretProperties?,
    shape: Shape,
    colors: RichTooltipColors,
    tonalElevation: Dp,
    shadowElevation: Dp,
    text: @Composable () -> Unit
)

Rich text tooltip that allows the user to pass in a title, text, and action.

Cmn
android
Unit
@Composable
@ExperimentalMaterial3Api
MultiChoiceSegmentedButtonRowScope.SegmentedButton(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    shape: Shape,
    modifier: Modifier,
    enabled: Boolean,
    colors: SegmentedButtonColors,
    border: BorderStroke,
    interactionSource: MutableInteractionSource?,
    icon: @Composable () -> Unit,
    label: @Composable () -> Unit
)

Material Segmented Button.

Cmn
Unit
@Composable
@ExperimentalMaterial3Api
SingleChoiceSegmentedButtonRowScope.SegmentedButton(
    selected: Boolean,
    onClick: () -> Unit,
    shape: Shape,
    modifier: Modifier,
    enabled: Boolean,
    colors: SegmentedButtonColors,
    border: BorderStroke,
    interactionSource: MutableInteractionSource?,
    icon: @Composable () -> Unit,
    label: @Composable () -> Unit
)

Material Segmented Button.

Cmn
Color
ColorScheme.contentColorFor(backgroundColor: Color)

The Material color system contains pairs of colors that are typically used for the background and content color inside a component.

Cmn
Unit
DrawScope.drawStopIndicator(
    stopSize: Dp,
    color: Color,
    strokeCap: StrokeCap
)

Draws the stop indicator at the end of the track.

Cmn
Modifier

Reserves at least 48.dp in size to disambiguate touch interactions if the element would measure smaller.

Cmn
Color

Computes the surface tonal color at different elevation levels e.g. surface1 through surface5.

Cmn

Top-level properties summary

ProvidableCompositionLocal<Dp>

CompositionLocal containing the current absolute elevation provided by Surface components.

Cmn
ProvidableCompositionLocal<Color>

CompositionLocal containing the preferred content color for a given position in the hierarchy.

Cmn
ProvidableCompositionLocal<Boolean>

CompositionLocal that configures whether Material components that have a visual size that is lower than the minimum touch target size for accessibility (such as Button) will include extra space outside the component to ensure that they are accessible.

Cmn
ProvidableCompositionLocal<Boolean>

This property is deprecated. Use LocalMinimumInteractiveComponentEnforcement instead.

Cmn
ProvidableCompositionLocal<RippleConfiguration>

CompositionLocal used for providing RippleConfiguration down the tree.

Cmn
ProvidableCompositionLocal<TextStyle>

CompositionLocal containing the preferred TextStyle that will be used by Text components by default.

Cmn
ProvidableCompositionLocal<Boolean>

Composition Local used to check if ColorScheme.applyTonalElevation will be applied down the tree.

Cmn
ProvidableCompositionLocal<Boolean>

Temporary CompositionLocal to allow configuring whether the old ripple implementation that uses the deprecated androidx.compose.material.ripple.RippleTheme API should be used in Material components and LocalIndication, instead of the new ripple API.

Cmn
Boolean

Flag indicating if Scaffold should subcompose and measure its children during measurement or during placement.

Cmn

Top-level functions

AlertDialog

@ExperimentalMaterial3Api
@Composable
fun AlertDialog(
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    properties: DialogProperties = DialogProperties(),
    content: @Composable () -> Unit
): Unit

Basic alert dialog dialog.

Dialogs provide important prompts in a user flow. They can require an action, communicate information, or help users accomplish a task.

Basic dialog image

This basic alert dialog expects an arbitrary content that is defined by the caller. Note that your content will need to define its own styling.

By default, the displayed dialog has the minimum height and width that the Material Design spec defines. If required, these constraints can be overwritten by providing a width or height Modifiers.

Basic alert dialog usage with custom content:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.BasicAlertDialog
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val openDialog = remember { mutableStateOf(true) }

if (openDialog.value) {
    BasicAlertDialog(
        onDismissRequest = {
            // Dismiss the dialog when the user clicks outside the dialog or on the back
            // button. If you want to disable that functionality, simply use an empty
            // onDismissRequest.
            openDialog.value = false
        }
    ) {
        Surface(
            modifier = Modifier
                .wrapContentWidth()
                .wrapContentHeight(),
            shape = MaterialTheme.shapes.large,
            tonalElevation = AlertDialogDefaults.TonalElevation
        ) {
            Column(modifier = Modifier.padding(16.dp)) {
                Text(
                    text = "This area typically contains the supportive text " +
                        "which presents the details regarding the Dialog's purpose.",
                )
                Spacer(modifier = Modifier.height(24.dp))
                TextButton(
                    onClick = {
                        openDialog.value = false
                    },
                    modifier = Modifier.align(Alignment.End)
                ) {
                    Text("Confirm")
                }
            }
        }
    }
}
Parameters
onDismissRequest: () -> Unit

called when the user tries to dismiss the Dialog by clicking outside or pressing the back button. This is not called when the dismiss button is clicked.

modifier: Modifier = Modifier

the Modifier to be applied to this dialog's content.

properties: DialogProperties = DialogProperties()

typically platform specific properties to further configure the dialog.

content: @Composable () -> Unit

the content of the dialog

AlertDialog

@Composable
fun AlertDialog(
    onDismissRequest: () -> Unit,
    confirmButton: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    dismissButton: (@Composable () -> Unit)? = null,
    icon: (@Composable () -> Unit)? = null,
    title: (@Composable () -> Unit)? = null,
    text: (@Composable () -> Unit)? = null,
    shape: Shape = AlertDialogDefaults.shape,
    containerColor: Color = AlertDialogDefaults.containerColor,
    iconContentColor: Color = AlertDialogDefaults.iconContentColor,
    titleContentColor: Color = AlertDialogDefaults.titleContentColor,
    textContentColor: Color = AlertDialogDefaults.textContentColor,
    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
    properties: DialogProperties = DialogProperties()
): Unit

Material Design basic dialog.

Dialogs provide important prompts in a user flow. They can require an action, communicate information, or help users accomplish a task.

Basic dialog image

The dialog will position its buttons, typically TextButtons, based on the available space. By default it will try to place them horizontally next to each other and fallback to horizontal placement if not enough space is available.

Simple usage:

import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val openDialog = remember { mutableStateOf(true) }

if (openDialog.value) {
    AlertDialog(
        onDismissRequest = {
            // Dismiss the dialog when the user clicks outside the dialog or on the back
            // button. If you want to disable that functionality, simply use an empty
            // onDismissRequest.
            openDialog.value = false
        },
        title = {
            Text(text = "Title")
        },
        text = {
            Text(text = "Turned on by default")
        },
        confirmButton = {
            TextButton(
                onClick = {
                    openDialog.value = false
                }
            ) {
                Text("Confirm")
            }
        },
        dismissButton = {
            TextButton(
                onClick = {
                    openDialog.value = false
                }
            ) {
                Text("Dismiss")
            }
        }
    )
}

Usage with a "Hero" icon:

import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val openDialog = remember { mutableStateOf(true) }

if (openDialog.value) {
    AlertDialog(
        onDismissRequest = {
            // Dismiss the dialog when the user clicks outside the dialog or on the back
            // button. If you want to disable that functionality, simply use an empty
            // onDismissRequest.
            openDialog.value = false
        },
        icon = { Icon(Icons.Filled.Favorite, contentDescription = null) },
        title = {
            Text(text = "Title")
        },
        text = {
            Text(
                "This area typically contains the supportive text " +
                    "which presents the details regarding the Dialog's purpose."
            )
        },
        confirmButton = {
            TextButton(
                onClick = {
                    openDialog.value = false
                }
            ) {
                Text("Confirm")
            }
        },
        dismissButton = {
            TextButton(
                onClick = {
                    openDialog.value = false
                }
            ) {
                Text("Dismiss")
            }
        }
    )
}
Parameters
onDismissRequest: () -> Unit

called when the user tries to dismiss the Dialog by clicking outside or pressing the back button. This is not called when the dismiss button is clicked.

confirmButton: @Composable () -> Unit

button which is meant to confirm a proposed action, thus resolving what triggered the dialog. The dialog does not set up any events for this button so they need to be set up by the caller.

modifier: Modifier = Modifier

the Modifier to be applied to this dialog

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

button which is meant to dismiss the dialog. The dialog does not set up any events for this button so they need to be set up by the caller.

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

optional icon that will appear above the title or above the text, in case a title was not provided.

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

title which should specify the purpose of the dialog. The title is not mandatory, because there may be sufficient information inside the text.

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

text which presents the details regarding the dialog's purpose.

shape: Shape = AlertDialogDefaults.shape

defines the shape of this dialog's container

containerColor: Color = AlertDialogDefaults.containerColor

the color used for the background of this dialog. Use Color.Transparent to have no color.

iconContentColor: Color = AlertDialogDefaults.iconContentColor

the content color used for the icon.

titleContentColor: Color = AlertDialogDefaults.titleContentColor

the content color used for the title.

textContentColor: Color = AlertDialogDefaults.textContentColor

the content color used for the text.

tonalElevation: Dp = AlertDialogDefaults.TonalElevation

when containerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

properties: DialogProperties = DialogProperties()

typically platform specific properties to further configure the dialog.

See also
BasicAlertDialog

AssistChip

@Composable
fun AssistChip(
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    shape: Shape = AssistChipDefaults.shape,
    colors: ChipColors = AssistChipDefaults.assistChipColors(),
    elevation: ChipElevation? = AssistChipDefaults.assistChipElevation(),
    border: BorderStroke? = AssistChipDefaults.assistChipBorder(enabled),
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design assist 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.

Assist chips represent smart or automated actions that can span multiple apps, such as opening a calendar event from the home screen. Assist chips function as though the user asked an assistant to complete the action. They should appear dynamically and contextually in a UI.

Assist chip image

This assist chip is applied with a flat style. If you want an elevated style, use the ElevatedAssistChip.

Example of a flat AssistChip:

import androidx.compose.foundation.layout.size
import androidx.compose.material3.AssistChip
import androidx.compose.material3.Icon
import androidx.compose.material3.Text

AssistChip(
    onClick = { /* Do something! */ },
    label = { Text("Assist Chip") },
    leadingIcon = {
        Icon(
            Icons.Filled.Settings,
            contentDescription = "Localized description",
            Modifier.size(AssistChipDefaults.IconSize)
        )
    }
)
Parameters
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

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

optional icon at the end of the chip

shape: Shape = AssistChipDefaults.shape

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

colors: ChipColors = AssistChipDefaults.assistChipColors()

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

elevation: ChipElevation? = AssistChipDefaults.assistChipElevation()

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 AssistChipDefaults.assistChipElevation.

border: BorderStroke? = AssistChipDefaults.assistChipBorder(enabled)

the border to draw around the container of this chip. Pass null for no border. See AssistChipDefaults.assistChipBorder.

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.

@Composable
fun Badge(
    modifier: Modifier = Modifier,
    containerColor: Color = BadgeDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    content: (@Composable RowScope.() -> Unit)? = null
): Unit

A badge represents dynamic information such as a number of pending requests in a navigation bar.

Badges can be icon only or contain short text.

Badge image

See BadgedBox for a top level layout that will properly place the badge relative to content such as text or an icon.

Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this badge

containerColor: Color = BadgeDefaults.containerColor

the color used for the background of this badge

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this badge. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

content: (@Composable RowScope.() -> Unit)? = null

optional content to be rendered inside this badge

BadgedBox

@Composable
fun BadgedBox(
    badge: @Composable BoxScope.() -> Unit,
    modifier: Modifier = Modifier,
    content: @Composable BoxScope.() -> Unit
): Unit

Material Design badge box.

A badge represents dynamic information such as a number of pending requests in a navigation bar.

Badges can be icon only or contain short text.

Badge image

A common use case is to display a badge with navigation bar items. For more information, see Navigation Bar

A simple icon with badge example looks like:

import androidx.compose.material3.Badge
import androidx.compose.material3.BadgedBox
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Text
import androidx.compose.ui.semantics.semantics

NavigationBar {
    NavigationBarItem(
        icon = {
            BadgedBox(
                badge = {
                    Badge {
                        val badgeNumber = "8"
                        Text(
                            badgeNumber,
                            modifier = Modifier.semantics {
                                contentDescription = "$badgeNumber new notifications"
                            }
                        )
                    }
                }) {
                Icon(
                    Icons.Filled.Star,
                    contentDescription = "Favorite"
                )
            }
        },
        selected = false,
        onClick = {}
    )
}
Parameters
badge: @Composable BoxScope.() -> Unit

the badge to be displayed - typically a Badge

modifier: Modifier = Modifier

the Modifier to be applied to this BadgedBox

content: @Composable BoxScope.() -> Unit

the anchor to which this badge will be positioned

BasicAlertDialog

@ExperimentalMaterial3Api
@Composable
fun BasicAlertDialog(
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    properties: DialogProperties = DialogProperties(),
    content: @Composable () -> Unit
): Unit

Basic alert dialog dialog.

Dialogs provide important prompts in a user flow. They can require an action, communicate information, or help users accomplish a task.

Basic dialog image

This basic alert dialog expects an arbitrary content that is defined by the caller. Note that your content will need to define its own styling.

By default, the displayed dialog has the minimum height and width that the Material Design spec defines. If required, these constraints can be overwritten by providing a width or height Modifiers.

Basic alert dialog usage with custom content:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.BasicAlertDialog
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val openDialog = remember { mutableStateOf(true) }

if (openDialog.value) {
    BasicAlertDialog(
        onDismissRequest = {
            // Dismiss the dialog when the user clicks outside the dialog or on the back
            // button. If you want to disable that functionality, simply use an empty
            // onDismissRequest.
            openDialog.value = false
        }
    ) {
        Surface(
            modifier = Modifier
                .wrapContentWidth()
                .wrapContentHeight(),
            shape = MaterialTheme.shapes.large,
            tonalElevation = AlertDialogDefaults.TonalElevation
        ) {
            Column(modifier = Modifier.padding(16.dp)) {
                Text(
                    text = "This area typically contains the supportive text " +
                        "which presents the details regarding the Dialog's purpose.",
                )
                Spacer(modifier = Modifier.height(24.dp))
                TextButton(
                    onClick = {
                        openDialog.value = false
                    },
                    modifier = Modifier.align(Alignment.End)
                ) {
                    Text("Confirm")
                }
            }
        }
    }
}
Parameters
onDismissRequest: () -> Unit

called when the user tries to dismiss the Dialog by clicking outside or pressing the back button. This is not called when the dismiss button is clicked.

modifier: Modifier = Modifier

the Modifier to be applied to this dialog's content.

properties: DialogProperties = DialogProperties()

typically platform specific properties to further configure the dialog.

content: @Composable () -> Unit

the content of the dialog

@Composable
fun BottomAppBar(
    modifier: Modifier = Modifier,
    containerColor: Color = BottomAppBarDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    tonalElevation: Dp = BottomAppBarDefaults.ContainerElevation,
    contentPadding: PaddingValues = BottomAppBarDefaults.ContentPadding,
    windowInsets: WindowInsets = BottomAppBarDefaults.windowInsets,
    content: @Composable RowScope.() -> Unit
): Unit

Material Design bottom app bar.

A bottom app bar displays navigation and key actions at the bottom of mobile screens.

Bottom app bar image

If you are interested in displaying a FloatingActionButton, consider using another overload.

Also see NavigationBar.

Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this BottomAppBar

containerColor: Color = BottomAppBarDefaults.containerColor

the color used for the background of this BottomAppBar. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this BottomAppBar. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

tonalElevation: Dp = BottomAppBarDefaults.ContainerElevation

when containerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

contentPadding: PaddingValues = BottomAppBarDefaults.ContentPadding

the padding applied to the content of this BottomAppBar

windowInsets: WindowInsets = BottomAppBarDefaults.windowInsets

a window insets that app bar will respect.

content: @Composable RowScope.() -> Unit

the content of this BottomAppBar. The default layout here is a Row, so content inside will be placed horizontally.

@Composable
fun BottomAppBar(
    actions: @Composable RowScope.() -> Unit,
    modifier: Modifier = Modifier,
    floatingActionButton: (@Composable () -> Unit)? = null,
    containerColor: Color = BottomAppBarDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    tonalElevation: Dp = BottomAppBarDefaults.ContainerElevation,
    contentPadding: PaddingValues = BottomAppBarDefaults.ContentPadding,
    windowInsets: WindowInsets = BottomAppBarDefaults.windowInsets
): Unit

Material Design bottom app bar.

A bottom app bar displays navigation and key actions at the bottom of mobile screens.

Bottom app bar image

import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton

BottomAppBar(
    actions = {
        IconButton(onClick = { /* doSomething() */ }) {
            Icon(Icons.Filled.Menu, contentDescription = "Localized description")
        }
    }
)

It can optionally display a FloatingActionButton embedded at the end of the BottomAppBar.

import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton

BottomAppBar(
    actions = {
        IconButton(onClick = { /* doSomething() */ }) {
            Icon(Icons.Filled.Check, contentDescription = "Localized description")
        }
        IconButton(onClick = { /* doSomething() */ }) {
            Icon(
                Icons.Filled.Edit,
                contentDescription = "Localized description",
            )
        }
    },
    floatingActionButton = {
        FloatingActionButton(
            onClick = { /* do something */ },
            containerColor = BottomAppBarDefaults.bottomAppBarFabColor,
            elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation()
        ) {
            Icon(Icons.Filled.Add, "Localized description")
        }
    }
)

Also see NavigationBar.

Parameters
actions: @Composable RowScope.() -> Unit

the icon content of this BottomAppBar. The default layout here is a Row, so content inside will be placed horizontally.

modifier: Modifier = Modifier

the Modifier to be applied to this BottomAppBar

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

optional floating action button at the end of this BottomAppBar

containerColor: Color = BottomAppBarDefaults.containerColor

the color used for the background of this BottomAppBar. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this BottomAppBar. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

tonalElevation: Dp = BottomAppBarDefaults.ContainerElevation

when containerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

contentPadding: PaddingValues = BottomAppBarDefaults.ContentPadding

the padding applied to the content of this BottomAppBar

windowInsets: WindowInsets = BottomAppBarDefaults.windowInsets

a window insets that app bar will respect.

@ExperimentalMaterial3Api
@Composable
fun BottomAppBar(
    modifier: Modifier = Modifier,
    containerColor: Color = BottomAppBarDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    tonalElevation: Dp = BottomAppBarDefaults.ContainerElevation,
    contentPadding: PaddingValues = BottomAppBarDefaults.ContentPadding,
    windowInsets: WindowInsets = BottomAppBarDefaults.windowInsets,
    scrollBehavior: BottomAppBarScrollBehavior? = null,
    content: @Composable RowScope.() -> Unit
): Unit

Material Design bottom app bar.

A bottom app bar displays navigation and key actions at the bottom of mobile screens.

Bottom app bar image

If you are interested in displaying a FloatingActionButton, consider using another overload.

Also see NavigationBar.

Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this BottomAppBar

containerColor: Color = BottomAppBarDefaults.containerColor

the color used for the background of this BottomAppBar. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this BottomAppBar. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

tonalElevation: Dp = BottomAppBarDefaults.ContainerElevation

when containerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

contentPadding: PaddingValues = BottomAppBarDefaults.ContentPadding

the padding applied to the content of this BottomAppBar

windowInsets: WindowInsets = BottomAppBarDefaults.windowInsets

a window insets that app bar will respect.

scrollBehavior: BottomAppBarScrollBehavior? = null

a BottomAppBarScrollBehavior which holds various offset values that will be applied by this bottom app bar to set up its height. A scroll behavior is designed to work in conjunction with a scrolled content to change the bottom app bar appearance as the content scrolls. See BottomAppBarScrollBehavior.nestedScrollConnection.

content: @Composable RowScope.() -> Unit

the content of this BottomAppBar. The default layout here is a Row, so content inside will be placed horizontally.

@ExperimentalMaterial3Api
@Composable
fun BottomAppBar(
    actions: @Composable RowScope.() -> Unit,
    modifier: Modifier = Modifier,
    floatingActionButton: (@Composable () -> Unit)? = null,
    containerColor: Color = BottomAppBarDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    tonalElevation: Dp = BottomAppBarDefaults.ContainerElevation,
    contentPadding: PaddingValues = BottomAppBarDefaults.ContentPadding,
    windowInsets: WindowInsets = BottomAppBarDefaults.windowInsets,
    scrollBehavior: BottomAppBarScrollBehavior? = null
): Unit

Material Design bottom app bar.

A bottom app bar displays navigation and key actions at the bottom of mobile screens.

Bottom app bar image

import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton

BottomAppBar(
    actions = {
        IconButton(onClick = { /* doSomething() */ }) {
            Icon(Icons.Filled.Menu, contentDescription = "Localized description")
        }
    }
)

It can optionally display a FloatingActionButton embedded at the end of the BottomAppBar.

import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton

BottomAppBar(
    actions = {
        IconButton(onClick = { /* doSomething() */ }) {
            Icon(Icons.Filled.Check, contentDescription = "Localized description")
        }
        IconButton(onClick = { /* doSomething() */ }) {
            Icon(
                Icons.Filled.Edit,
                contentDescription = "Localized description",
            )
        }
    },
    floatingActionButton = {
        FloatingActionButton(
            onClick = { /* do something */ },
            containerColor = BottomAppBarDefaults.bottomAppBarFabColor,
            elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation()
        ) {
            Icon(Icons.Filled.Add, "Localized description")
        }
    }
)

A bottom app bar that uses a scrollBehavior to customize its nested scrolling behavior when working in conjunction with a scrolling content looks like:

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.ui.input.nestedscroll.nestedScroll

val scrollBehavior = BottomAppBarDefaults.exitAlwaysScrollBehavior()
Scaffold(
    modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
    bottomBar = {
        BottomAppBar(
            actions = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(Icons.Filled.Check, contentDescription = "Localized description")
                }
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(Icons.Filled.Edit, contentDescription = "Localized description")
                }
            },
            scrollBehavior = scrollBehavior
        )
    },
    floatingActionButton = {
        FloatingActionButton(
            modifier = Modifier.offset(y = 4.dp),
            onClick = { /* do something */ },
            containerColor = BottomAppBarDefaults.bottomAppBarFabColor,
            elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation()
        ) {
            Icon(Icons.Filled.Add, "Localized description")
        }
    },
    floatingActionButtonPosition = FabPosition.EndOverlay,
    content = { innerPadding ->
        LazyColumn(
            contentPadding = innerPadding,
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            val list = (0..75).map { it.toString() }
            items(count = list.size) {
                Text(
                    text = list[it],
                    style = MaterialTheme.typography.bodyLarge,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp)
                )
            }
        }
    }
)

Also see NavigationBar.

Parameters
actions: @Composable RowScope.() -> Unit

the icon content of this BottomAppBar. The default layout here is a Row, so content inside will be placed horizontally.

modifier: Modifier = Modifier

the Modifier to be applied to this BottomAppBar

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

optional floating action button at the end of this BottomAppBar

containerColor: Color = BottomAppBarDefaults.containerColor

the color used for the background of this BottomAppBar. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this BottomAppBar. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

tonalElevation: Dp = BottomAppBarDefaults.ContainerElevation

when containerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

contentPadding: PaddingValues = BottomAppBarDefaults.ContentPadding

the padding applied to the content of this BottomAppBar

windowInsets: WindowInsets = BottomAppBarDefaults.windowInsets

a window insets that app bar will respect.

scrollBehavior: BottomAppBarScrollBehavior? = null

a BottomAppBarScrollBehavior which holds various offset values that will be applied by this bottom app bar to set up its height. A scroll behavior is designed to work in conjunction with a scrolled content to change the bottom app bar appearance as the content scrolls. See BottomAppBarScrollBehavior.nestedScrollConnection.

BottomAppBarState

@ExperimentalMaterial3Api
fun BottomAppBarState(
    initialHeightOffsetLimit: Float,
    initialHeightOffset: Float,
    initialContentOffset: Float
): BottomAppBarState

Creates a BottomAppBarState.

Parameters
initialHeightOffsetLimit: Float

the initial value for BottomAppBarState.heightOffsetLimit, which represents the pixel limit that a bottom app bar is allowed to collapse when the scrollable content is scrolled

initialHeightOffset: Float

the initial value for BottomAppBarState.heightOffset. The initial offset height offset should be between zero and initialHeightOffsetLimit.

initialContentOffset: Float

the initial value for BottomAppBarState.contentOffset

BottomSheetScaffold

@Composable
@ExperimentalMaterial3Api
fun BottomSheetScaffold(
    sheetContent: @Composable ColumnScope.() -> Unit,
    modifier: Modifier = Modifier,
    scaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(),
    sheetPeekHeight: Dp = BottomSheetDefaults.SheetPeekHeight,
    sheetMaxWidth: Dp = BottomSheetDefaults.SheetMaxWidth,
    sheetShape: Shape = BottomSheetDefaults.ExpandedShape,
    sheetContainerColor: Color = BottomSheetDefaults.ContainerColor,
    sheetContentColor: Color = contentColorFor(sheetContainerColor),
    sheetTonalElevation: Dp = 0.dp,
    sheetShadowElevation: Dp = BottomSheetDefaults.Elevation,
    sheetDragHandle: (@Composable () -> Unit)? = { BottomSheetDefaults.DragHandle() },
    sheetSwipeEnabled: Boolean = true,
    topBar: (@Composable () -> Unit)? = null,
    snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },
    containerColor: Color = MaterialTheme.colorScheme.surface,
    contentColor: Color = contentColorFor(containerColor),
    content: @Composable (PaddingValues) -> Unit
): Unit

Material Design standard bottom sheet scaffold.

Standard bottom sheets co-exist with the screen’s main UI region and allow for simultaneously viewing and interacting with both regions. They are commonly used to keep a feature or secondary content visible on screen when content in main UI region is frequently scrolled or panned.

Bottom sheet image

This component provides API to put together several material components to construct your screen, by ensuring proper layout strategy for them and collecting necessary data so these components will work together correctly.

A simple example of a standard bottom sheet looks like this:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.rememberBottomSheetScaffoldState
import androidx.compose.runtime.rememberCoroutineScope

val scope = rememberCoroutineScope()
val scaffoldState = rememberBottomSheetScaffoldState()

BottomSheetScaffold(
    scaffoldState = scaffoldState,
    sheetPeekHeight = 128.dp,
    sheetContent = {
        Box(
            Modifier
                .fillMaxWidth()
                .height(128.dp),
            contentAlignment = Alignment.Center
        ) {
            Text("Swipe up to expand sheet")
        }
        Column(
            Modifier
                .fillMaxWidth()
                .padding(64.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text("Sheet content")
            Spacer(Modifier.height(20.dp))
            Button(
                onClick = {
                    scope.launch { scaffoldState.bottomSheetState.partialExpand() }
                }
            ) {
                Text("Click to collapse sheet")
            }
        }
    }) { innerPadding ->
    Box(
        modifier = Modifier
            .fillMaxSize()
            .padding(innerPadding),
        contentAlignment = Alignment.Center
    ) {
        Text("Scaffold Content")
    }
}
Parameters
sheetContent: @Composable ColumnScope.() -> Unit

the content of the bottom sheet

modifier: Modifier = Modifier

the Modifier to be applied to this scaffold

scaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState()

the state of the bottom sheet scaffold

sheetPeekHeight: Dp = BottomSheetDefaults.SheetPeekHeight

the height of the bottom sheet when it is collapsed

sheetMaxWidth: Dp = BottomSheetDefaults.SheetMaxWidth

Dp that defines what the maximum width the sheet will take. Pass in Dp.Unspecified for a sheet that spans the entire screen width.

sheetShape: Shape = BottomSheetDefaults.ExpandedShape

the shape of the bottom sheet

sheetContainerColor: Color = BottomSheetDefaults.ContainerColor

the background color of the bottom sheet

sheetContentColor: Color = contentColorFor(sheetContainerColor)

the preferred content color provided by the bottom sheet to its children. Defaults to the matching content color for sheetContainerColor, or if that is not a color from the theme, this will keep the same content color set above the bottom sheet.

sheetTonalElevation: Dp = 0.dp

when sheetContainerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

sheetShadowElevation: Dp = BottomSheetDefaults.Elevation

the shadow elevation of the bottom sheet

sheetDragHandle: (@Composable () -> Unit)? = { BottomSheetDefaults.DragHandle() }

optional visual marker to pull the scaffold's bottom sheet

sheetSwipeEnabled: Boolean = true

whether the sheet swiping is enabled and should react to the user's input

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

top app bar of the screen, typically a SmallTopAppBar

snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) }

component to host Snackbars that are pushed to be shown via SnackbarHostState.showSnackbar, typically a SnackbarHost

containerColor: Color = MaterialTheme.colorScheme.surface

the color used for the background of this scaffold. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this scaffold. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

content: @Composable (PaddingValues) -> Unit

content of the screen. The lambda receives a PaddingValues that should be applied to the content root via Modifier.padding and Modifier.consumeWindowInsets to properly offset top and bottom bars. If using Modifier.verticalScroll, apply this modifier to the child of the scroll, and not on the scroll itself.

@Composable
fun Button(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = ButtonDefaults.shape,
    colors: ButtonColors = ButtonDefaults.buttonColors(),
    elevation: ButtonElevation? = ButtonDefaults.buttonElevation(),
    border: BorderStroke? = null,
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
    interactionSource: MutableInteractionSource? = null,
    content: @Composable RowScope.() -> Unit
): Unit

Material Design button.

Buttons help people initiate actions, from sending an email, to sharing a document, to liking a post.

Filled button image

Filled buttons are high-emphasis buttons. Filled buttons have the most visual impact after the FloatingActionButton, and should be used for important, final actions that complete a flow, like "Save", "Join now", or "Confirm".

import androidx.compose.material3.Button
import androidx.compose.material3.Text

Button(onClick = { /* Do something! */ }) { Text("Button") }
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.Text

Button(
    onClick = { /* Do something! */ },
    contentPadding = ButtonDefaults.ButtonWithIconContentPadding
) {
    Icon(
        Icons.Filled.Favorite,
        contentDescription = "Localized description",
        modifier = Modifier.size(ButtonDefaults.IconSize)
    )
    Spacer(Modifier.size(ButtonDefaults.IconSpacing))
    Text("Like")
}

Choose the best button for an action based on the amount of emphasis it needs. The more important an action is, the higher emphasis its button should be.

The default text style for internal Text components will be set to Typography.labelLarge.

Parameters
onClick: () -> Unit

called when this button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this button

enabled: Boolean = true

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

shape: Shape = ButtonDefaults.shape

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

colors: ButtonColors = ButtonDefaults.buttonColors()

ButtonColors that will be used to resolve the colors for this button in different states. See ButtonDefaults.buttonColors.

elevation: ButtonElevation? = ButtonDefaults.buttonElevation()

ButtonElevation used to resolve the elevation for this button in different states. This controls the size of the shadow below the button. See ButtonElevation.shadowElevation.

border: BorderStroke? = null

the border to draw around the container of this button

contentPadding: PaddingValues = ButtonDefaults.ContentPadding

the spacing values to apply internally between the container and the content

interactionSource: MutableInteractionSource? = null

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

@Composable
fun Card(
    modifier: Modifier = Modifier,
    shape: Shape = CardDefaults.shape,
    colors: CardColors = CardDefaults.cardColors(),
    elevation: CardElevation = CardDefaults.cardElevation(),
    border: BorderStroke? = null,
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design filled card.

Cards contain contain content and actions that relate information about a subject. Filled cards provide subtle separation from the background. This has less emphasis than elevated or outlined cards.

This Card does not handle input events - see the other Card overloads if you want a clickable or selectable Card.

Filled card image

Card sample:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Card
import androidx.compose.material3.Text

Card(Modifier.size(width = 180.dp, height = 100.dp)) {
    Box(Modifier.fillMaxSize()) {
        Text("Card content", Modifier.align(Alignment.Center))
    }
}
Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this card

shape: Shape = CardDefaults.shape

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

colors: CardColors = CardDefaults.cardColors()

CardColors that will be used to resolve the colors used for this card in different states. See CardDefaults.cardColors.

elevation: CardElevation = CardDefaults.cardElevation()

CardElevation used to resolve the elevation for this card in different states. This controls the size of the shadow below the card. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. See also: Surface.

border: BorderStroke? = null

the border to draw around the container of this card

@Composable
fun Card(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = CardDefaults.shape,
    colors: CardColors = CardDefaults.cardColors(),
    elevation: CardElevation = CardDefaults.cardElevation(),
    border: BorderStroke? = null,
    interactionSource: MutableInteractionSource? = null,
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design filled card.

Cards contain contain content and actions that relate information about a subject. Filled cards provide subtle separation from the background. This has less emphasis than elevated or outlined cards.

This Card handles click events, calling its onClick lambda.

Filled card image

Clickable card sample:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Card
import androidx.compose.material3.Text

Card(
    onClick = { /* Do something */ },
    modifier = Modifier.size(width = 180.dp, height = 100.dp)
) {
    Box(Modifier.fillMaxSize()) {
        Text("Clickable", Modifier.align(Alignment.Center))
    }
}
Parameters
onClick: () -> Unit

called when this card is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this card

enabled: Boolean = true

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

shape: Shape = CardDefaults.shape

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

colors: CardColors = CardDefaults.cardColors()

CardColors that will be used to resolve the color(s) used for this card in different states. See CardDefaults.cardColors.

elevation: CardElevation = CardDefaults.cardElevation()

CardElevation used to resolve the elevation for this card in different states. This controls the size of the shadow below the card. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. See also: Surface.

border: BorderStroke? = null

the border to draw around the container of this card

interactionSource: MutableInteractionSource? = null

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

CenterAlignedTopAppBar

@ExperimentalMaterial3Api
@Composable
fun CenterAlignedTopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    navigationIcon: @Composable () -> Unit = {},
    actions: @Composable RowScope.() -> Unit = {},
    windowInsets: WindowInsets = TopAppBarDefaults.windowInsets,
    colors: TopAppBarColors = TopAppBarDefaults.centerAlignedTopAppBarColors(),
    scrollBehavior: TopAppBarScrollBehavior? = null
): Unit

Material Design center-aligned small top app bar.

Top app bars display information and actions at the top of a screen.

This small top app bar has a header title that is horizontally aligned to the center.

Center-aligned top app bar image

This CenterAlignedTopAppBar has slots for a title, navigation icon, and actions.

A center aligned top app bar that uses a scrollBehavior to customize its nested scrolling behavior when working in conjunction with a scrolling content looks like:

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text

Scaffold(
    topBar = {
        CenterAlignedTopAppBar(
            title = {
                Text(
                    "Centered TopAppBar",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
            },
            navigationIcon = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Menu,
                        contentDescription = "Localized description"
                    )
                }
            },
            actions = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Favorite,
                        contentDescription = "Localized description"
                    )
                }
            }
        )
    },
    content = { innerPadding ->
        LazyColumn(
            contentPadding = innerPadding,
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            val list = (0..75).map { it.toString() }
            items(count = list.size) {
                Text(
                    text = list[it],
                    style = MaterialTheme.typography.bodyLarge,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp)
                )
            }
        }
    }
)
Parameters
title: @Composable () -> Unit

the title to be displayed in the top app bar

modifier: Modifier = Modifier

the Modifier to be applied to this top app bar

navigationIcon: @Composable () -> Unit = {}

the navigation icon displayed at the start of the top app bar. This should typically be an IconButton or IconToggleButton.

actions: @Composable RowScope.() -> Unit = {}

the actions displayed at the end of the top app bar. This should typically be IconButtons. The default layout here is a Row, so icons inside will be placed horizontally.

windowInsets: WindowInsets = TopAppBarDefaults.windowInsets

a window insets that app bar will respect.

colors: TopAppBarColors = TopAppBarDefaults.centerAlignedTopAppBarColors()

TopAppBarColors that will be used to resolve the colors used for this top app bar in different states. See TopAppBarDefaults.centerAlignedTopAppBarColors.

scrollBehavior: TopAppBarScrollBehavior? = null

a TopAppBarScrollBehavior which holds various offset values that will be applied by this top app bar to set up its height and colors. A scroll behavior is designed to work in conjunction with a scrolled content to change the top app bar appearance as the content scrolls. See TopAppBarScrollBehavior.nestedScrollConnection.

Checkbox

@Composable
fun Checkbox(
    checked: Boolean,
    onCheckedChange: ((Boolean) -> Unit)?,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    colors: CheckboxColors = CheckboxDefaults.colors(),
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design checkbox.

Checkboxes allow users to select one or more items from a set. Checkboxes can turn an option on or off.

Checkbox image

Simple Checkbox sample:

import androidx.compose.material3.Checkbox
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val checkedState = remember { mutableStateOf(true) }
Checkbox(
    checked = checkedState.value,
    onCheckedChange = { checkedState.value = it }
)

Combined Checkbox with Text sample:

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.selection.toggleable
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val (checkedState, onStateChange) = remember { mutableStateOf(true) }
Row(
    Modifier
        .fillMaxWidth()
        .height(56.dp)
        .toggleable(
            value = checkedState,
            onValueChange = { onStateChange(!checkedState) },
            role = Role.Checkbox
        )
        .padding(horizontal = 16.dp),
    verticalAlignment = Alignment.CenterVertically
) {
    Checkbox(
        checked = checkedState,
        onCheckedChange = null // null recommended for accessibility with screenreaders
    )
    Text(
        text = "Option selection",
        style = MaterialTheme.typography.bodyLarge,
        modifier = Modifier.padding(start = 16.dp)
    )
}
Parameters
checked: Boolean

whether this checkbox is checked or unchecked

onCheckedChange: ((Boolean) -> Unit)?

called when this checkbox is clicked. If null, then this checkbox will not be interactable, unless something else handles its input events and updates its state.

modifier: Modifier = Modifier

the Modifier to be applied to this checkbox

enabled: Boolean = true

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

colors: CheckboxColors = CheckboxDefaults.colors()

CheckboxColors that will be used to resolve the colors used for this checkbox in different states. See CheckboxDefaults.colors.

interactionSource: MutableInteractionSource? = null

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

See also
TriStateCheckbox

if you require support for an indeterminate state.

CircularProgressIndicator

@Composable
fun CircularProgressIndicator(
    modifier: Modifier = Modifier,
    color: Color = ProgressIndicatorDefaults.circularColor,
    strokeWidth: Dp = ProgressIndicatorDefaults.CircularStrokeWidth,
    trackColor: Color = ProgressIndicatorDefaults.circularIndeterminateTrackColor,
    strokeCap: StrokeCap = ProgressIndicatorDefaults.CircularIndeterminateStrokeCap
): Unit

Indeterminate Material Design circular progress indicator.

Progress indicators express an unspecified wait time or display the duration of a process.

Circular progress indicator image

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.CircularProgressIndicator

Column(horizontalAlignment = Alignment.CenterHorizontally) {
    CircularProgressIndicator()
}
Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this progress indicator

color: Color = ProgressIndicatorDefaults.circularColor

color of this progress indicator

strokeWidth: Dp = ProgressIndicatorDefaults.CircularStrokeWidth

stroke width of this progress indicator

trackColor: Color = ProgressIndicatorDefaults.circularIndeterminateTrackColor

color of the track behind the indicator, visible when the progress has not reached the area of the overall indicator yet

strokeCap: StrokeCap = ProgressIndicatorDefaults.CircularIndeterminateStrokeCap

stroke cap to use for the ends of this progress indicator

CircularProgressIndicator

@Composable
fun CircularProgressIndicator(
    progress: Float,
    modifier: Modifier = Modifier,
    color: Color = ProgressIndicatorDefaults.circularColor,
    strokeWidth: Dp = ProgressIndicatorDefaults.CircularStrokeWidth,
    trackColor: Color = ProgressIndicatorDefaults.circularTrackColor,
    strokeCap: StrokeCap = ProgressIndicatorDefaults.CircularDeterminateStrokeCap
): Unit

CircularProgressIndicator

@Composable
fun CircularProgressIndicator(
    progress: () -> Float,
    modifier: Modifier = Modifier,
    color: Color = ProgressIndicatorDefaults.circularColor,
    strokeWidth: Dp = ProgressIndicatorDefaults.CircularStrokeWidth,
    trackColor: Color = ProgressIndicatorDefaults.circularDeterminateTrackColor,
    strokeCap: StrokeCap = ProgressIndicatorDefaults.CircularDeterminateStrokeCap,
    gapSize: Dp = ProgressIndicatorDefaults.CircularIndicatorTrackGapSize
): Unit

Determinate Material Design circular progress indicator.

Progress indicators express an unspecified wait time or display the duration of a process.

Circular progress indicator image

By default there is no animation between progress values. You can use ProgressIndicatorDefaults.ProgressAnimationSpec as the default recommended AnimationSpec when animating progress, such as in the following example:

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.material.Slider
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var progress by remember { mutableStateOf(0.1f) }
val animatedProgress by animateFloatAsState(
    targetValue = progress,
    animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec
)

Column(horizontalAlignment = Alignment.CenterHorizontally) {
    CircularProgressIndicator(progress = { animatedProgress })
    Spacer(Modifier.requiredHeight(30.dp))
    Slider(
        modifier = Modifier
            .padding(start = 24.dp, end = 24.dp)
            .semantics {
                val progressPercent = (progress * 100).toInt()
                if (progressPercent in progressBreakpoints) {
                    stateDescription = "Progress $progressPercent%"
                }
            },
        value = progress,
        valueRange = 0f..1f,
        steps = 100,
        onValueChange = {
            progress = it
        })
}
Parameters
progress: () -> Float

the progress of this progress indicator, where 0.0 represents no progress and 1.0 represents full progress. Values outside of this range are coerced into the range.

modifier: Modifier = Modifier

the Modifier to be applied to this progress indicator

color: Color = ProgressIndicatorDefaults.circularColor

color of this progress indicator

strokeWidth: Dp = ProgressIndicatorDefaults.CircularStrokeWidth

stroke width of this progress indicator

trackColor: Color = ProgressIndicatorDefaults.circularDeterminateTrackColor

color of the track behind the indicator, visible when the progress has not reached the area of the overall indicator yet

strokeCap: StrokeCap = ProgressIndicatorDefaults.CircularDeterminateStrokeCap

stroke cap to use for the ends of this progress indicator

gapSize: Dp = ProgressIndicatorDefaults.CircularIndicatorTrackGapSize

size of the gap between the progress indicator and the track

DatePicker

@ExperimentalMaterial3Api
@Composable
fun DatePicker(
    state: DatePickerState,
    modifier: Modifier = Modifier,
    dateFormatter: DatePickerFormatter = remember { DatePickerDefaults.dateFormatter() },
    title: (@Composable () -> Unit)? = { DatePickerDefaults.DatePickerTitle( displayMode = state.displayMode, modifier = Modifier.padding(DatePickerTitlePadding) ) },
    headline: (@Composable () -> Unit)? = { DatePickerDefaults.DatePickerHeadline( selectedDateMillis = state.selectedDateMillis, displayMode = state.displayMode, dateFormatter = dateFormatter, modifier = Modifier.padding(DatePickerHeadlinePadding) ) },
    showModeToggle: Boolean = true,
    colors: DatePickerColors = DatePickerDefaults.colors()
): Unit

Material Design date picker.

Date pickers let people select a date and preferably should be embedded into Dialogs. See DatePickerDialog.

By default, a date picker lets you pick a date via a calendar UI. However, it also allows switching into a date input mode for a manual entry of dates using the numbers on a keyboard.

Date picker image

A simple DatePicker looks like:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.DatePicker
import androidx.compose.material3.Text
import androidx.compose.material3.rememberDatePickerState

Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
    // Pre-select a date for January 4, 2020
    val datePickerState = rememberDatePickerState(initialSelectedDateMillis = 1578096000000)
    DatePicker(state = datePickerState, modifier = Modifier.padding(16.dp))

    Text(
        "Selected date timestamp: ${datePickerState.selectedDateMillis ?: "no selection"}",
        modifier = Modifier.align(Alignment.CenterHorizontally)
    )
}

A DatePicker with an initial UI of a date input mode looks like:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.DatePicker
import androidx.compose.material3.Text
import androidx.compose.material3.rememberDatePickerState

Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
    val state = rememberDatePickerState(initialDisplayMode = DisplayMode.Input)
    DatePicker(state = state, modifier = Modifier.padding(16.dp))

    Text(
        "Entered date timestamp: ${state.selectedDateMillis ?: "no input"}",
        modifier = Modifier.align(Alignment.CenterHorizontally)
    )
}

A DatePicker with a provided SelectableDates that blocks certain days from being selected looks like:

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.DatePicker
import androidx.compose.material3.Text
import androidx.compose.material3.rememberDatePickerState

val datePickerState = rememberDatePickerState(
    selectableDates = object : SelectableDates {
        // Blocks Sunday and Saturday from being selected.
        override fun isSelectableDate(utcTimeMillis: Long): Boolean {
            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val dayOfWeek = Instant.ofEpochMilli(utcTimeMillis).atZone(ZoneId.of("UTC"))
                    .toLocalDate().dayOfWeek
                dayOfWeek != DayOfWeek.SUNDAY && dayOfWeek != DayOfWeek.SATURDAY
            } else {
                val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
                calendar.timeInMillis = utcTimeMillis
                calendar[Calendar.DAY_OF_WEEK] != Calendar.SUNDAY &&
                    calendar[Calendar.DAY_OF_WEEK] != Calendar.SATURDAY
            }
        }

        // Allow selecting dates from year 2023 forward.
        override fun isSelectableYear(year: Int): Boolean {
            return year > 2022
        }
    }
)

Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
    DatePicker(state = datePickerState)
    Text(
        "Selected date timestamp: ${datePickerState.selectedDateMillis ?: "no selection"}",
        modifier = Modifier.align(Alignment.CenterHorizontally)
    )
}
Parameters
state: DatePickerState

state of the date picker. See rememberDatePickerState.

modifier: Modifier = Modifier

the Modifier to be applied to this date picker

dateFormatter: DatePickerFormatter = remember { DatePickerDefaults.dateFormatter() }

a DatePickerFormatter that provides formatting skeletons for dates display

title: (@Composable () -> Unit)? = { DatePickerDefaults.DatePickerTitle( displayMode = state.displayMode, modifier = Modifier.padding(DatePickerTitlePadding) ) }

the title to be displayed in the date picker

headline: (@Composable () -> Unit)? = { DatePickerDefaults.DatePickerHeadline( selectedDateMillis = state.selectedDateMillis, displayMode = state.displayMode, dateFormatter = dateFormatter, modifier = Modifier.padding(DatePickerHeadlinePadding) ) }

the headline to be displayed in the date picker

showModeToggle: Boolean = true

indicates if this DatePicker should show a mode toggle action that transforms it into a date input

colors: DatePickerColors = DatePickerDefaults.colors()

DatePickerColors that will be used to resolve the colors used for this date picker in different states. See DatePickerDefaults.colors.

DatePickerDialog

@ExperimentalMaterial3Api
@Composable
fun DatePickerDialog(
    onDismissRequest: () -> Unit,
    confirmButton: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    dismissButton: (@Composable () -> Unit)? = null,
    shape: Shape = DatePickerDefaults.shape,
    tonalElevation: Dp = DatePickerDefaults.TonalElevation,
    colors: DatePickerColors = DatePickerDefaults.colors(),
    properties: DialogProperties = DialogProperties(usePlatformDefaultWidth = false),
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design date picker dialog.

A dialog for displaying a DatePicker. Date pickers let people select a date.

A sample for displaying a DatePicker in a dialog:

import androidx.compose.material3.DatePicker
import androidx.compose.material3.DatePickerDialog
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

// Decoupled snackbar host state from scaffold state for demo purposes.
val snackState = remember { SnackbarHostState() }
val snackScope = rememberCoroutineScope()
SnackbarHost(hostState = snackState, Modifier)
val openDialog = remember { mutableStateOf(true) }
// TODO demo how to read the selected date from the state.
if (openDialog.value) {
    val datePickerState = rememberDatePickerState()
    val confirmEnabled = remember {
        derivedStateOf { datePickerState.selectedDateMillis != null }
    }
    DatePickerDialog(
        onDismissRequest = {
            // Dismiss the dialog when the user clicks outside the dialog or on the back
            // button. If you want to disable that functionality, simply use an empty
            // onDismissRequest.
            openDialog.value = false
        },
        confirmButton = {
            TextButton(
                onClick = {
                    openDialog.value = false
                    snackScope.launch {
                        snackState.showSnackbar(
                            "Selected date timestamp: ${datePickerState.selectedDateMillis}"
                        )
                    }
                },
                enabled = confirmEnabled.value
            ) {
                Text("OK")
            }
        },
        dismissButton = {
            TextButton(
                onClick = {
                    openDialog.value = false
                }
            ) {
                Text("Cancel")
            }
        }
    ) {
        DatePicker(state = datePickerState)
    }
}
Parameters
onDismissRequest: () -> Unit

called when the user tries to dismiss the Dialog by clicking outside or pressing the back button. This is not called when the dismiss button is clicked.

confirmButton: @Composable () -> Unit

button which is meant to confirm a proposed action, thus resolving what triggered the dialog. The dialog does not set up any events for this button, nor does it control its enablement, so those need to be set up by the caller.

modifier: Modifier = Modifier

the Modifier to be applied to this dialog's content.

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

button which is meant to dismiss the dialog. The dialog does not set up any events for this button so they need to be set up by the caller.

shape: Shape = DatePickerDefaults.shape

defines the dialog's surface shape as well its shadow

tonalElevation: Dp = DatePickerDefaults.TonalElevation

when DatePickerColors.containerColor is ColorScheme.surface, a higher the elevation will result in a darker color in light theme and lighter color in dark theme

colors: DatePickerColors = DatePickerDefaults.colors()

DatePickerColors that will be used to resolve the colors used for this date picker in different states. See DatePickerDefaults.colors.

properties: DialogProperties = DialogProperties(usePlatformDefaultWidth = false)

typically platform specific properties to further configure the dialog

content: @Composable ColumnScope.() -> Unit

the content of the dialog (i.e. a DatePicker, for example)

DatePickerState

@ExperimentalMaterial3Api
fun DatePickerState(
    locale: CalendarLocale,
    initialSelectedDateMillis: Long? = null,
    initialDisplayedMonthMillis: Long? = initialSelectedDateMillis,
    yearRange: IntRange = DatePickerDefaults.YearRange,
    initialDisplayMode: DisplayMode = DisplayMode.Picker,
    selectableDates: SelectableDates = DatePickerDefaults.AllDates
): DatePickerState

Creates a DatePickerState.

Note that in most cases, you are advised to use the rememberDatePickerState when in a composition.

Parameters
locale: CalendarLocale

a CalendarLocale to be used when formatting dates, determining the input format, and more

initialSelectedDateMillis: Long? = null

timestamp in UTC milliseconds from the epoch that represents an initial selection of a date. Provide a null to indicate no selection. Note that the state's DatePickerState.selectedDateMillis will provide a timestamp that represents the start of the day, which may be different than the provided initialSelectedDateMillis.

initialDisplayedMonthMillis: Long? = initialSelectedDateMillis

timestamp in UTC milliseconds from the epoch that represents an initial selection of a month to be displayed to the user. In case null is provided, the displayed month would be the current one.

yearRange: IntRange = DatePickerDefaults.YearRange

an IntRange that holds the year range that the date picker will be limited to

initialDisplayMode: DisplayMode = DisplayMode.Picker

an initial DisplayMode that this state will hold

selectableDates: SelectableDates = DatePickerDefaults.AllDates

a SelectableDates that is consulted to check if a date is allowed. In case a date is not allowed to be selected, it will appear disabled in the UI.

Throws
kotlin.IllegalArgumentException

if the initial selected date or displayed month represent a year that is out of the year range.

DateRangePicker

@ExperimentalMaterial3Api
@Composable
fun DateRangePicker(
    state: DateRangePickerState,
    modifier: Modifier = Modifier,
    dateFormatter: DatePickerFormatter = remember { DatePickerDefaults.dateFormatter() },
    title: (@Composable () -> Unit)? = { DateRangePickerDefaults.DateRangePickerTitle( displayMode = state.displayMode, modifier = Modifier.padding(DateRangePickerTitlePadding) ) },
    headline: (@Composable () -> Unit)? = { DateRangePickerDefaults.DateRangePickerHeadline( selectedStartDateMillis = state.selectedStartDateMillis, selectedEndDateMillis = state.selectedEndDateMillis, displayMode = state.displayMode, dateFormatter, modifier = Modifier.padding(DateRangePickerHeadlinePadding) ) },
    showModeToggle: Boolean = true,
    colors: DatePickerColors = DatePickerDefaults.colors()
): Unit

Material Design date range picker.

Date range pickers let people select a range of dates and can be embedded into Dialogs.

Date range picker image

A simple DateRangePicker looks like:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Icon
import androidx.compose.material3.DateRangePicker
import androidx.compose.material3.IconButton
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.rememberDateRangePickerState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.zIndex

// Decoupled snackbar host state from scaffold state for demo purposes.
val snackState = remember { SnackbarHostState() }
val snackScope = rememberCoroutineScope()
SnackbarHost(hostState = snackState, Modifier.zIndex(1f))

val state = rememberDateRangePickerState()
Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Top) {
    // Add a row with "Save" and dismiss actions.
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .background(DatePickerDefaults.colors().containerColor)
            .padding(start = 12.dp, end = 12.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        IconButton(onClick = { /* dismiss the UI */ }) {
            Icon(Icons.Filled.Close, contentDescription = "Localized description")
        }
        TextButton(
            onClick = {
                snackScope.launch {
                    val range =
                        state.selectedStartDateMillis!!..state.selectedEndDateMillis!!
                    snackState.showSnackbar("Saved range (timestamps): $range")
                }
            },
            enabled = state.selectedEndDateMillis != null
        ) {
            Text(text = "Save")
        }
    }
    DateRangePicker(state = state, modifier = Modifier.weight(1f))
}
Parameters
state: DateRangePickerState

state of the date range picker. See rememberDateRangePickerState.

modifier: Modifier = Modifier

the Modifier to be applied to this date range picker

dateFormatter: DatePickerFormatter = remember { DatePickerDefaults.dateFormatter() }

a DatePickerFormatter that provides formatting skeletons for dates display

title: (@Composable () -> Unit)? = { DateRangePickerDefaults.DateRangePickerTitle( displayMode = state.displayMode, modifier = Modifier.padding(DateRangePickerTitlePadding) ) }

the title to be displayed in the date range picker

headline: (@Composable () -> Unit)? = { DateRangePickerDefaults.DateRangePickerHeadline( selectedStartDateMillis = state.selectedStartDateMillis, selectedEndDateMillis = state.selectedEndDateMillis, displayMode = state.displayMode, dateFormatter, modifier = Modifier.padding(DateRangePickerHeadlinePadding) ) }

the headline to be displayed in the date range picker

showModeToggle: Boolean = true

indicates if this DateRangePicker should show a mode toggle action that transforms it into a date range input

colors: DatePickerColors = DatePickerDefaults.colors()

DatePickerColors that will be used to resolve the colors used for this date range picker in different states. See DatePickerDefaults.colors.

DateRangePickerState

@ExperimentalMaterial3Api
fun DateRangePickerState(
    locale: CalendarLocale,
    initialSelectedStartDateMillis: Long? = null,
    initialSelectedEndDateMillis: Long? = null,
    initialDisplayedMonthMillis: Long? = initialSelectedStartDateMillis,
    yearRange: IntRange = DatePickerDefaults.YearRange,
    initialDisplayMode: DisplayMode = DisplayMode.Picker,
    selectableDates: SelectableDates = DatePickerDefaults.AllDates
): DateRangePickerState

Creates a DateRangePickerState.

Note that in most cases, you are advised to use the rememberDateRangePickerState when in a composition.

Parameters
locale: CalendarLocale

a CalendarLocale to be used when formatting dates, determining the input format, and more

initialSelectedStartDateMillis: Long? = null

timestamp in UTC milliseconds from the epoch that represents an initial selection of a start date. Provide a null to indicate no selection.

initialSelectedEndDateMillis: Long? = null

timestamp in UTC milliseconds from the epoch that represents an initial selection of an end date. Provide a null to indicate no selection.

initialDisplayedMonthMillis: Long? = initialSelectedStartDateMillis

timestamp in UTC milliseconds from the epoch that represents an initial selection of a month to be displayed to the user. By default, in case an initialSelectedStartDateMillis is provided, the initial displayed month would be the month of the selected date. Otherwise, in case null is provided, the displayed month would be the current one.

yearRange: IntRange = DatePickerDefaults.YearRange

an IntRange that holds the year range that the date picker will be limited to

initialDisplayMode: DisplayMode = DisplayMode.Picker

an initial DisplayMode that this state will hold

selectableDates: SelectableDates = DatePickerDefaults.AllDates

a SelectableDates that is consulted to check if a date is allowed. In case a date is not allowed to be selected, it will appear disabled in the UI

Throws
kotlin.IllegalArgumentException

if the initial timestamps do not fall within the year range this state is created with, or the end date precedes the start date, or when an end date is provided without a start date (e.g. the start date was null, while the end date was not).

DismissibleDrawerSheet

@Composable
fun DismissibleDrawerSheet(
    modifier: Modifier = Modifier,
    drawerShape: Shape = RectangleShape,
    drawerContainerColor: Color = DrawerDefaults.standardContainerColor,
    drawerContentColor: Color = contentColorFor(drawerContainerColor),
    drawerTonalElevation: Dp = DrawerDefaults.DismissibleDrawerElevation,
    windowInsets: WindowInsets = DrawerDefaults.windowInsets,
    content: @Composable ColumnScope.() -> Unit
): Unit

Content inside of a dismissible navigation drawer.

Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this drawer's content

drawerShape: Shape = RectangleShape

defines the shape of this drawer's container

drawerContainerColor: Color = DrawerDefaults.standardContainerColor

the color used for the background of this drawer. Use Color.Transparent to have no color.

drawerContentColor: Color = contentColorFor(drawerContainerColor)

the preferred color for content inside this drawer. Defaults to either the matching content color for drawerContainerColor, or to the current LocalContentColor if drawerContainerColor is not a color from the theme.

drawerTonalElevation: Dp = DrawerDefaults.DismissibleDrawerElevation

when drawerContainerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

windowInsets: WindowInsets = DrawerDefaults.windowInsets

a window insets for the sheet.

content: @Composable ColumnScope.() -> Unit

content inside of a dismissible navigation drawer

DismissibleNavigationDrawer

@Composable
fun DismissibleNavigationDrawer(
    drawerContent: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),
    gesturesEnabled: Boolean = true,
    content: @Composable () -> Unit
): Unit

Material Design navigation drawer.

Navigation drawers provide ergonomic access to destinations in an app. They’re often next to app content and affect the screen’s layout grid.

Navigation drawer image

Dismissible standard drawers can be used for layouts that prioritize content (such as a photo gallery) or for apps where users are unlikely to switch destinations often. They should use a visible navigation menu icon to open and close the drawer.

import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.DismissibleDrawerSheet
import androidx.compose.material3.DismissibleNavigationDrawer
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationDrawerItem
import androidx.compose.material3.Text
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()
// icons to mimic drawer destinations
val items = listOf(Icons.Default.Favorite, Icons.Default.Face, Icons.Default.Email)
val selectedItem = remember { mutableStateOf(items[0]) }
BackHandler(enabled = drawerState.isOpen) {
    scope.launch {
        drawerState.close()
    }
}

DismissibleNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        DismissibleDrawerSheet {
            Spacer(Modifier.height(12.dp))
            items.forEach { item ->
                NavigationDrawerItem(
                    icon = { Icon(item, contentDescription = null) },
                    label = { Text(item.name) },
                    selected = item == selectedItem.value,
                    onClick = {
                        scope.launch { drawerState.close() }
                        selectedItem.value = item
                    },
                    modifier = Modifier.padding(horizontal = 12.dp)
                )
            }
        }
    },
    content = {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(text = if (drawerState.isClosed) ">>> Swipe >>>" else "<<< Swipe <<<")
            Spacer(Modifier.height(20.dp))
            Button(onClick = { scope.launch { drawerState.open() } }) {
                Text("Click to open")
            }
        }
    }
)
Parameters
drawerContent: @Composable () -> Unit

content inside this drawer

modifier: Modifier = Modifier

the Modifier to be applied to this drawer

drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed)

state of the drawer

gesturesEnabled: Boolean = true

whether or not the drawer can be interacted by gestures

content: @Composable () -> Unit

content of the rest of the UI

@Composable
fun Divider(
    modifier: Modifier = Modifier,
    thickness: Dp = DividerDefaults.Thickness,
    color: Color = DividerDefaults.color
): Unit

DockedSearchBar

@ExperimentalMaterial3Api
@Composable
fun DockedSearchBar(
    query: String,
    onQueryChange: (String) -> Unit,
    onSearch: (String) -> Unit,
    active: Boolean,
    onActiveChange: (Boolean) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    placeholder: (@Composable () -> Unit)? = null,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    shape: Shape = SearchBarDefaults.dockedShape,
    colors: SearchBarColors = SearchBarDefaults.colors(),
    tonalElevation: Dp = SearchBarDefaults.TonalElevation,
    shadowElevation: Dp = SearchBarDefaults.ShadowElevation,
    interactionSource: MutableInteractionSource? = null,
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design search.

A search bar represents a floating search field that allows users to enter a keyword or phrase and get relevant information. It can be used as a way to navigate through an app via search queries.

An active search bar expands into a search "view" and can be used to display dynamic suggestions.

Search bar image

A DockedSearchBar displays search results in a bounded table below the input field. It is meant to be an alternative to SearchBar when expanding to full-screen size is undesirable on large screens such as tablets.

An example looks like:

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.DockedSearchBar
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.semantics.semantics

var text by rememberSaveable { mutableStateOf("") }
var active by rememberSaveable { mutableStateOf(false) }

Box(Modifier.fillMaxSize().semantics { isTraversalGroup = true }) {
    DockedSearchBar(
        modifier = Modifier
            .align(Alignment.TopCenter)
            .padding(top = 8.dp)
            .semantics { traversalIndex = -1f },
        query = text,
        onQueryChange = { text = it },
        onSearch = { active = false },
        active = active,
        onActiveChange = { active = it },
        placeholder = { Text("Hinted search text") },
        leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) },
        trailingIcon = { Icon(Icons.Default.MoreVert, contentDescription = null) },
    ) {
        repeat(4) { idx ->
            val resultText = "Suggestion $idx"
            ListItem(
                headlineContent = { Text(resultText) },
                supportingContent = { Text("Additional info") },
                leadingContent = { Icon(Icons.Filled.Star, contentDescription = null) },
                modifier = Modifier
                    .clickable {
                        text = resultText
                        active = false
                    }
                    .fillMaxWidth()
                    .padding(horizontal = 16.dp, vertical = 4.dp)
            )
        }
    }

    LazyColumn(
        contentPadding = PaddingValues(start = 16.dp, top = 72.dp, end = 16.dp, bottom = 16.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        val list = List(100) { "Text $it" }
        items(count = list.size) {
            Text(list[it], Modifier.fillMaxWidth().padding(horizontal = 16.dp))
        }
    }
}
Parameters
query: String

the query text to be shown in the search bar's input field

onQueryChange: (String) -> Unit

the callback to be invoked when the input service updates the query. An updated text comes as a parameter of the callback.

onSearch: (String) -> Unit

the callback to be invoked when the input service triggers the ImeAction.Search action. The current query comes as a parameter of the callback.

active: Boolean

whether this search bar is active

onActiveChange: (Boolean) -> Unit

the callback to be invoked when this search bar's active state is changed

modifier: Modifier = Modifier

the Modifier to be applied to this search bar

enabled: Boolean = true

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

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

the placeholder to be displayed when the search bar's query is empty.

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

the leading icon to be displayed at the beginning of the search bar container

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

the trailing icon to be displayed at the end of the search bar container

shape: Shape = SearchBarDefaults.dockedShape

the shape of this search bar

colors: SearchBarColors = SearchBarDefaults.colors()

SearchBarColors that will be used to resolve the colors used for this search bar in different states. See SearchBarDefaults.colors.

tonalElevation: Dp = SearchBarDefaults.TonalElevation

when SearchBarColors.containerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

shadowElevation: Dp = SearchBarDefaults.ShadowElevation

the elevation for the shadow below the search bar

interactionSource: MutableInteractionSource? = null

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

content: @Composable ColumnScope.() -> Unit

the content of this search bar that will be displayed below the input field

@Composable
fun DropdownMenu(
    expanded: Boolean,
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    offset: DpOffset = DpOffset(0.dp, 0.dp),
    scrollState: ScrollState = rememberScrollState(),
    properties: PopupProperties = PopupProperties(focusable = true),
    shape: Shape = MenuDefaults.shape,
    containerColor: Color = MenuDefaults.containerColor,
    tonalElevation: Dp = MenuDefaults.TonalElevation,
    shadowElevation: Dp = MenuDefaults.ShadowElevation,
    border: BorderStroke? = null,
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design dropdown menu.

Menus display a list of choices on a temporary surface. They appear when users interact with a button, action, or other control.

Dropdown menu image

A DropdownMenu behaves similarly to a Popup, and will use the position of the parent layout to position itself on screen. Commonly a DropdownMenu will be placed in a Box with a sibling that will be used as the 'anchor'. Note that a DropdownMenu by itself will not take up any space in a layout, as the menu is displayed in a separate window, on top of other content.

The content of a DropdownMenu will typically be DropdownMenuItems, as well as custom content. Using DropdownMenuItems will result in a menu that matches the Material specification for menus. Also note that the content is placed inside a scrollable Column, so using a LazyColumn as the root layout inside content is unsupported.

onDismissRequest will be called when the menu should close - for example when there is a tap outside the menu, or when the back key is pressed.

DropdownMenu changes its positioning depending on the available space, always trying to be fully visible. Depending on layout direction, first it will try to align its start to the start of its parent, then its end to the end of its parent, and then to the edge of the window. Vertically, it will try to align its top to the bottom of its parent, then its bottom to top of its parent, and then to the edge of the window.

An offset can be provided to adjust the positioning of the menu for cases when the layout bounds of its parent do not coincide with its visual bounds.

Example usage:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var expanded by remember { mutableStateOf(false) }

Box(
    modifier = Modifier
        .fillMaxSize()
        .wrapContentSize(Alignment.TopStart)
) {
    IconButton(onClick = { expanded = true }) {
        Icon(Icons.Default.MoreVert, contentDescription = "Localized description")
    }
    DropdownMenu(
        expanded = expanded,
        onDismissRequest = { expanded = false }
    ) {
        DropdownMenuItem(
            text = { Text("Edit") },
            onClick = { /* Handle edit! */ },
            leadingIcon = {
                Icon(
                    Icons.Outlined.Edit,
                    contentDescription = null
                )
            })
        DropdownMenuItem(
            text = { Text("Settings") },
            onClick = { /* Handle settings! */ },
            leadingIcon = {
                Icon(
                    Icons.Outlined.Settings,
                    contentDescription = null
                )
            })
        HorizontalDivider()
        DropdownMenuItem(
            text = { Text("Send Feedback") },
            onClick = { /* Handle send feedback! */ },
            leadingIcon = {
                Icon(
                    Icons.Outlined.Email,
                    contentDescription = null
                )
            },
            trailingIcon = { Text("F11", textAlign = TextAlign.Center) })
    }
}

Example usage with a ScrollState to control the menu items scroll position:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var expanded by remember { mutableStateOf(false) }
val scrollState = rememberScrollState()
Box(
    modifier = Modifier
        .fillMaxSize()
        .wrapContentSize(Alignment.TopStart)
) {
    IconButton(onClick = { expanded = true }) {
        Icon(Icons.Default.MoreVert, contentDescription = "Localized description")
    }
    DropdownMenu(
        expanded = expanded,
        onDismissRequest = { expanded = false },
        scrollState = scrollState
    ) {
        repeat(30) {
            DropdownMenuItem(
                text = { Text("Item ${it + 1}") },
                onClick = { /* TODO */ },
                leadingIcon = {
                    Icon(
                        Icons.Outlined.Edit,
                        contentDescription = null
                    )
                })
        }
    }
    LaunchedEffect(expanded) {
        if (expanded) {
            // Scroll to show the bottom menu items.
            scrollState.scrollTo(scrollState.maxValue)
        }
    }
}
Parameters
expanded: Boolean

whether the menu is expanded or not

onDismissRequest: () -> Unit

called when the user requests to dismiss the menu, such as by tapping outside the menu's bounds

modifier: Modifier = Modifier

Modifier to be applied to the menu's content

offset: DpOffset = DpOffset(0.dp, 0.dp)

DpOffset from the original position of the menu. The offset respects the LayoutDirection, so the offset's x position will be added in LTR and subtracted in RTL.

scrollState: ScrollState = rememberScrollState()

a ScrollState to used by the menu's content for items vertical scrolling

properties: PopupProperties = PopupProperties(focusable = true)

PopupProperties for further customization of this popup's behavior

shape: Shape = MenuDefaults.shape

the shape of the menu

containerColor: Color = MenuDefaults.containerColor

the container color of the menu

tonalElevation: Dp = MenuDefaults.TonalElevation

when containerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

shadowElevation: Dp = MenuDefaults.ShadowElevation

the elevation for the shadow below the menu

border: BorderStroke? = null

the border to draw around the container of the menu. Pass null for no border.

content: @Composable ColumnScope.() -> Unit

the content of this dropdown menu, typically a DropdownMenuItem

@Composable
fun DropdownMenuItem(
    text: @Composable () -> Unit,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    enabled: Boolean = true,
    colors: MenuItemColors = MenuDefaults.itemColors(),
    contentPadding: PaddingValues = MenuDefaults.DropdownMenuItemContentPadding,
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design dropdown menu item.

Menus display a list of choices on a temporary surface. They appear when users interact with a button, action, or other control.

Dropdown menu image

Example usage:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var expanded by remember { mutableStateOf(false) }

Box(
    modifier = Modifier
        .fillMaxSize()
        .wrapContentSize(Alignment.TopStart)
) {
    IconButton(onClick = { expanded = true }) {
        Icon(Icons.Default.MoreVert, contentDescription = "Localized description")
    }
    DropdownMenu(
        expanded = expanded,
        onDismissRequest = { expanded = false }
    ) {
        DropdownMenuItem(
            text = { Text("Edit") },
            onClick = { /* Handle edit! */ },
            leadingIcon = {
                Icon(
                    Icons.Outlined.Edit,
                    contentDescription = null
                )
            })
        DropdownMenuItem(
            text = { Text("Settings") },
            onClick = { /* Handle settings! */ },
            leadingIcon = {
                Icon(
                    Icons.Outlined.Settings,
                    contentDescription = null
                )
            })
        HorizontalDivider()
        DropdownMenuItem(
            text = { Text("Send Feedback") },
            onClick = { /* Handle send feedback! */ },
            leadingIcon = {
                Icon(
                    Icons.Outlined.Email,
                    contentDescription = null
                )
            },
            trailingIcon = { Text("F11", textAlign = TextAlign.Center) })
    }
}
Parameters
text: @Composable () -> Unit

text of the menu item

onClick: () -> Unit

called when this menu item is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this menu item

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

optional leading icon to be displayed at the beginning of the item's text

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

optional trailing icon to be displayed at the end of the item's text. This trailing icon slot can also accept Text to indicate a keyboard shortcut.

enabled: Boolean = true

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

colors: MenuItemColors = MenuDefaults.itemColors()

MenuItemColors that will be used to resolve the colors used for this menu item in different states. See MenuDefaults.itemColors.

contentPadding: PaddingValues = MenuDefaults.DropdownMenuItemContentPadding

the padding applied to the content of this menu item

interactionSource: MutableInteractionSource? = null

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

ElevatedAssistChip

@Composable
fun ElevatedAssistChip(
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    shape: Shape = AssistChipDefaults.shape,
    colors: ChipColors = AssistChipDefaults.elevatedAssistChipColors(),
    elevation: ChipElevation? = AssistChipDefaults.elevatedAssistChipElevation(),
    border: BorderStroke? = null,
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design elevated assist 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.

Assist chips represent smart or automated actions that can span multiple apps, such as opening a calendar event from the home screen. Assist chips function as though the user asked an assistant to complete the action. They should appear dynamically and contextually in a UI.

Assist chip image

This assist chip is applied with an elevated style. If you want a flat style, use the AssistChip.

Example of an elevated AssistChip with a trailing icon:

import androidx.compose.foundation.layout.size
import androidx.compose.material3.ElevatedAssistChip
import androidx.compose.material3.Icon
import androidx.compose.material3.Text

ElevatedAssistChip(
    onClick = { /* Do something! */ },
    label = { Text("Assist Chip") },
    leadingIcon = {
        Icon(
            Icons.Filled.Settings,
            contentDescription = "Localized description",
            Modifier.size(AssistChipDefaults.IconSize)
        )
    }
)
Parameters
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

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

optional icon at the end of the chip

shape: Shape = AssistChipDefaults.shape

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

colors: ChipColors = AssistChipDefaults.elevatedAssistChipColors()

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

elevation: ChipElevation? = AssistChipDefaults.elevatedAssistChipElevation()

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 AssistChipDefaults.elevatedAssistChipElevation.

border: BorderStroke? = null

the border to draw around the container of this chip

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.

ElevatedButton

@Composable
fun ElevatedButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = ButtonDefaults.elevatedShape,
    colors: ButtonColors = ButtonDefaults.elevatedButtonColors(),
    elevation: ButtonElevation? = ButtonDefaults.elevatedButtonElevation(),
    border: BorderStroke? = null,
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
    interactionSource: MutableInteractionSource? = null,
    content: @Composable RowScope.() -> Unit
): Unit

Material Design elevated button.

Buttons help people initiate actions, from sending an email, to sharing a document, to liking a post.

Elevated button image

Elevated buttons are high-emphasis buttons that are essentially FilledTonalButtons with a shadow. To prevent shadow creep, only use them when absolutely necessary, such as when the button requires visual separation from patterned container.

import androidx.compose.material3.ElevatedButton
import androidx.compose.material3.Text

ElevatedButton(onClick = { /* Do something! */ }) { Text("Elevated Button") }

Choose the best button for an action based on the amount of emphasis it needs. The more important an action is, the higher emphasis its button should be.

The default text style for internal Text components will be set to Typography.labelLarge.

Parameters
onClick: () -> Unit

called when this button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this button

enabled: Boolean = true

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

shape: Shape = ButtonDefaults.elevatedShape

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

colors: ButtonColors = ButtonDefaults.elevatedButtonColors()

ButtonColors that will be used to resolve the colors for this button in different states. See ButtonDefaults.elevatedButtonColors.

elevation: ButtonElevation? = ButtonDefaults.elevatedButtonElevation()

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

border: BorderStroke? = null

the border to draw around the container of this button

contentPadding: PaddingValues = ButtonDefaults.ContentPadding

the spacing values to apply internally between the container and the content

interactionSource: MutableInteractionSource? = null

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

ElevatedCard

@Composable
fun ElevatedCard(
    modifier: Modifier = Modifier,
    shape: Shape = CardDefaults.elevatedShape,
    colors: CardColors = CardDefaults.elevatedCardColors(),
    elevation: CardElevation = CardDefaults.elevatedCardElevation(),
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design elevated card.

Elevated cards contain content and actions that relate information about a subject. They have a drop shadow, providing more separation from the background than filled cards, but less than outlined cards.

This ElevatedCard does not handle input events - see the other ElevatedCard overloads if you want a clickable or selectable ElevatedCard.

Elevated card image

Elevated card sample:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Text

ElevatedCard(Modifier.size(width = 180.dp, height = 100.dp)) {
    Box(Modifier.fillMaxSize()) {
        Text("Card content", Modifier.align(Alignment.Center))
    }
}
Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this card

shape: Shape = CardDefaults.elevatedShape

defines the shape of this card's container and shadow (when using elevation)

colors: CardColors = CardDefaults.elevatedCardColors()

CardColors that will be used to resolve the color(s) used for this card in different states. See CardDefaults.elevatedCardElevation.

elevation: CardElevation = CardDefaults.elevatedCardElevation()

CardElevation used to resolve the elevation for this card in different states. This controls the size of the shadow below the card. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. See also: Surface.

ElevatedCard

@Composable
fun ElevatedCard(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = CardDefaults.elevatedShape,
    colors: CardColors = CardDefaults.elevatedCardColors(),
    elevation: CardElevation = CardDefaults.elevatedCardElevation(),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design elevated card.

Elevated cards contain content and actions that relate information about a subject. They have a drop shadow, providing more separation from the background than filled cards, but less than outlined cards.

This ElevatedCard handles click events, calling its onClick lambda.

Elevated card image

Clickable elevated card sample:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Text

ElevatedCard(
    onClick = { /* Do something */ },
    modifier = Modifier.size(width = 180.dp, height = 100.dp)
) {
    Box(Modifier.fillMaxSize()) {
        Text("Clickable", Modifier.align(Alignment.Center))
    }
}
Parameters
onClick: () -> Unit

called when this card is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this card

enabled: Boolean = true

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

shape: Shape = CardDefaults.elevatedShape

defines the shape of this card's container and shadow (when using elevation)

colors: CardColors = CardDefaults.elevatedCardColors()

CardColors that will be used to resolve the color(s) used for this card in different states. See CardDefaults.elevatedCardElevation.

elevation: CardElevation = CardDefaults.elevatedCardElevation()

CardElevation used to resolve the elevation for this card in different states. This controls the size of the shadow below the card. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. See also: Surface.

interactionSource: MutableInteractionSource? = null

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

ElevatedFilterChip

@Composable
fun ElevatedFilterChip(
    selected: Boolean,
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    shape: Shape = FilterChipDefaults.shape,
    colors: SelectableChipColors = FilterChipDefaults.elevatedFilterChipColors(),
    elevation: SelectableChipElevation? = FilterChipDefaults.elevatedFilterChipElevation(),
    border: BorderStroke? = null,
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design elevated filter 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.

Filter chips use tags or descriptive words to filter content. They can be a good alternative to toggle buttons or checkboxes.

Filter chip image

This filter chip is applied with an elevated style. If you want a flat style, use the FilterChip.

Tapping on a filter chip toggles its selection state. A selection state leadingIcon can be provided (e.g. a checkmark) to be appended at the starting edge of the chip's label.

Example of an elevated FilterChip with a trailing icon:

import androidx.compose.foundation.layout.size
import androidx.compose.material3.ElevatedFilterChip
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var selected by remember { mutableStateOf(false) }
ElevatedFilterChip(
    selected = selected,
    onClick = { selected = !selected },
    label = { Text("Filter chip") },
    leadingIcon = if (selected) {
        {
            Icon(
                imageVector = Icons.Filled.Done,
                contentDescription = "Localized Description",
                modifier = Modifier.size(FilterChipDefaults.IconSize)
            )
        }
    } else {
        null
    }
)
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. When selected is true, this icon may visually indicate that the chip is selected (for example, via a checkmark icon).

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

optional icon at the end of the chip

shape: Shape = FilterChipDefaults.shape

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

colors: SelectableChipColors = FilterChipDefaults.elevatedFilterChipColors()

SelectableChipColors that will be used to resolve the colors used for this chip in different states. See FilterChipDefaults.elevatedFilterChipColors.

elevation: SelectableChipElevation? = FilterChipDefaults.elevatedFilterChipElevation()

SelectableChipElevation 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 FilterChipDefaults.filterChipElevation.

border: BorderStroke? = null

the border to draw around the container of this chip. Pass null for no border. See FilterChipDefaults.filterChipBorder.

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.

ElevatedSuggestionChip

@Composable
fun ElevatedSuggestionChip(
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    icon: (@Composable () -> Unit)? = null,
    shape: Shape = SuggestionChipDefaults.shape,
    colors: ChipColors = SuggestionChipDefaults.elevatedSuggestionChipColors(),
    elevation: ChipElevation? = SuggestionChipDefaults.elevatedSuggestionChipElevation(),
    border: BorderStroke? = null,
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design elevated suggestion 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.

Suggestion chips help narrow a user's intent by presenting dynamically generated suggestions, such as possible responses or search filters.

Suggestion chip image

This suggestion chip is applied with an elevated style. If you want a flat style, use the SuggestionChip.

Example of an elevated SuggestionChip with a trailing icon:

import androidx.compose.material3.ElevatedSuggestionChip
import androidx.compose.material3.Text

ElevatedSuggestionChip(
    onClick = { /* Do something! */ },
    label = { Text("Suggestion Chip") }
)
Parameters
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.

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

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

shape: Shape = SuggestionChipDefaults.shape

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

colors: ChipColors = SuggestionChipDefaults.elevatedSuggestionChipColors()

ChipColors that will be used to resolve the colors used for this chip in

elevation: ChipElevation? = SuggestionChipDefaults.elevatedSuggestionChipElevation()

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 Surface and SuggestionChipDefaults.elevatedSuggestionChipElevation.

border: BorderStroke? = null

the border to draw around the container of this chip different states. See SuggestionChipDefaults.elevatedSuggestionChipColors.

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.

ExposedDropdownMenuBox

@ExperimentalMaterial3Api
@Composable
fun ExposedDropdownMenuBox(
    expanded: Boolean,
    onExpandedChange: (Boolean) -> Unit,
    modifier: Modifier = Modifier,
    content: @Composable ExposedDropdownMenuBoxScope.() -> Unit
): Unit

Material Design Exposed Dropdown Menu.

Menus display a list of choices on a temporary surface. They appear when users interact with a button, action, or other control.

Exposed dropdown menus, sometimes also called "spinners" or "combo boxes", display the currently selected item in a text field to which the menu is anchored. In some cases, it can accept and display user input (whether or not it’s listed as a menu choice), in which case it may be used to implement autocomplete.

Exposed dropdown menu image

The ExposedDropdownMenuBox is expected to contain a TextField (or OutlinedTextField) and ExposedDropdownMenu as content. The menuAnchor modifier should be passed to the text field.

An example of a read-only Exposed Dropdown Menu:

import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val options = listOf("Option 1", "Option 2", "Option 3", "Option 4", "Option 5")
var expanded by remember { mutableStateOf(false) }
var selectedOptionText by remember { mutableStateOf(options[0]) }
// We want to react on tap/press on TextField to show menu
ExposedDropdownMenuBox(
    expanded = expanded,
    onExpandedChange = { expanded = it },
) {
    TextField(
        // The `menuAnchor` modifier must be passed to the text field for correctness.
        modifier = Modifier.menuAnchor(),
        readOnly = true,
        value = selectedOptionText,
        onValueChange = {},
        label = { Text("Label") },
        trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
        colors = ExposedDropdownMenuDefaults.textFieldColors(),
    )
    ExposedDropdownMenu(
        expanded = expanded,
        onDismissRequest = { expanded = false },
    ) {
        options.forEach { selectionOption ->
            DropdownMenuItem(
                text = { Text(selectionOption) },
                onClick = {
                    selectedOptionText = selectionOption
                    expanded = false
                },
                contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
            )
        }
    }
}

An example of an editable Exposed Dropdown Menu:

import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val options = listOf("Option 1", "Option 2", "Option 3", "Option 4", "Option 5")
var expanded by remember { mutableStateOf(false) }
var selectedOptionText by remember { mutableStateOf("") }
ExposedDropdownMenuBox(
    expanded = expanded,
    onExpandedChange = { expanded = it },
) {
    TextField(
        // The `menuAnchor` modifier must be passed to the text field for correctness.
        modifier = Modifier.menuAnchor(),
        value = selectedOptionText,
        onValueChange = { selectedOptionText = it },
        label = { Text("Label") },
        trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
        colors = ExposedDropdownMenuDefaults.textFieldColors(),
    )
    // filter options based on text field value
    val filteringOptions = options.filter { it.contains(selectedOptionText, ignoreCase = true) }
    if (filteringOptions.isNotEmpty()) {
        ExposedDropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false },
        ) {
            filteringOptions.forEach { selectionOption ->
                DropdownMenuItem(
                    text = { Text(selectionOption) },
                    onClick = {
                        selectedOptionText = selectionOption
                        expanded = false
                    },
                    contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
                )
            }
        }
    }
}
Parameters
expanded: Boolean

whether the menu is expanded or not

onExpandedChange: (Boolean) -> Unit

called when the exposed dropdown menu is clicked and the expansion state changes.

modifier: Modifier = Modifier

the Modifier to be applied to this ExposedDropdownMenuBox

content: @Composable ExposedDropdownMenuBoxScope.() -> Unit

the content of this ExposedDropdownMenuBox, typically a TextField and an ExposedDropdownMenu. The menuAnchor modifier should be passed to the text field for proper menu behavior.

ExtendedFloatingActionButton

@Composable
fun ExtendedFloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    shape: Shape = FloatingActionButtonDefaults.extendedFabShape,
    containerColor: Color = FloatingActionButtonDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable RowScope.() -> Unit
): Unit

Material Design extended floating action button.

Extended FABs help people take primary actions. They're wider than FABs to accommodate a text label and larger target area.

Extended FAB image

The other extended floating action button overload supports a text label and icon.

import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Text

ExtendedFloatingActionButton(onClick = { /* do something */ }) {
    Text(text = "Extended FAB")
}
Parameters
onClick: () -> Unit

called when this FAB is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this FAB

shape: Shape = FloatingActionButtonDefaults.extendedFabShape

defines the shape of this FAB's container and shadow (when using elevation)

containerColor: Color = FloatingActionButtonDefaults.containerColor

the color used for the background of this FAB. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this FAB. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation()

FloatingActionButtonElevation used to resolve the elevation for this FAB in different states. This controls the size of the shadow below the FAB. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. See also: Surface.

interactionSource: MutableInteractionSource? = null

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

content: @Composable RowScope.() -> Unit

the content of this FAB, typically a Text label

ExtendedFloatingActionButton

@Composable
fun ExtendedFloatingActionButton(
    text: @Composable () -> Unit,
    icon: @Composable () -> Unit,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    expanded: Boolean = true,
    shape: Shape = FloatingActionButtonDefaults.extendedFabShape,
    containerColor: Color = FloatingActionButtonDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design extended floating action button.

Extended FABs help people take primary actions. They're wider than FABs to accommodate a text label and larger target area.

Extended FAB image

The other extended floating action button overload is for FABs without an icon.

Default content description for accessibility is extended from the extended fabs icon. For custom behavior, you can provide your own via Modifier.semantics.

import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.Text

ExtendedFloatingActionButton(
    onClick = { /* do something */ },
    icon = { Icon(Icons.Filled.Add, "Localized description") },
    text = { Text(text = "Extended FAB") },
)
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Scaffold
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.remember

val listState = rememberLazyListState()
// The FAB is initially expanded. Once the first visible item is past the first item we
// collapse the FAB. We use a remembered derived state to minimize unnecessary compositions.
val expandedFab by remember {
    derivedStateOf {
        listState.firstVisibleItemIndex == 0
    }
}
Scaffold(
    floatingActionButton = {
        ExtendedFloatingActionButton(
            onClick = { /* do something */ },
            expanded = expandedFab,
            icon = { Icon(Icons.Filled.Add, "Localized Description") },
            text = { Text(text = "Extended FAB") },
        )
    },
    isFloatingActionButtonDocked = false,
    floatingActionButtonPosition = FabPosition.End,
) {
    LazyColumn(state = listState, modifier = Modifier.fillMaxSize()) {
        for (index in 0 until 100) {
            item {
                Text(
                    text = "List item - $index",
                    modifier = Modifier.padding(24.dp)
                )
            }
        }
    }
}
Parameters
text: @Composable () -> Unit

label displayed inside this FAB

icon: @Composable () -> Unit

optional icon for this FAB, typically an Icon

onClick: () -> Unit

called when this FAB is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this FAB

expanded: Boolean = true

controls the expansion state of this FAB. In an expanded state, the FAB will show both the icon and text. In a collapsed state, the FAB will show only the icon.

shape: Shape = FloatingActionButtonDefaults.extendedFabShape

defines the shape of this FAB's container and shadow (when using elevation)

containerColor: Color = FloatingActionButtonDefaults.containerColor

the color used for the background of this FAB. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this FAB. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation()

FloatingActionButtonElevation used to resolve the elevation for this FAB in different states. This controls the size of the shadow below the FAB. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. See also: Surface.

interactionSource: MutableInteractionSource? = null

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

FilledIconButton

@Composable
fun FilledIconButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = IconButtonDefaults.filledShape,
    colors: IconButtonColors = IconButtonDefaults.filledIconButtonColors(),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material Design filled icon button.

Icon buttons help people take supplementary actions with a single tap. They’re used when a compact button is required, such as in a toolbar or image list.

Filled icon button image

content should typically be an Icon (see androidx.compose.material.icons.Icons). If using a custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.

Filled icon button sample:

import androidx.compose.material3.FilledIconButton
import androidx.compose.material3.Icon

FilledIconButton(onClick = { /* doSomething() */ }) {
    Icon(Icons.Outlined.Lock, contentDescription = "Localized description")
}
Parameters
onClick: () -> Unit

called when this icon button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this icon button

enabled: Boolean = true

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

shape: Shape = IconButtonDefaults.filledShape

defines the shape of this icon button's container

colors: IconButtonColors = IconButtonDefaults.filledIconButtonColors()

IconButtonColors that will be used to resolve the colors used for this icon button in different states. See IconButtonDefaults.filledIconButtonColors.

interactionSource: MutableInteractionSource? = null

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

content: @Composable () -> Unit

the content of this icon button, typically an Icon

FilledIconToggleButton

@Composable
fun FilledIconToggleButton(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = IconButtonDefaults.filledShape,
    colors: IconToggleButtonColors = IconButtonDefaults.filledIconToggleButtonColors(),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material Design filled icon toggle button.

Icon buttons help people take supplementary actions with a single tap. They’re used when a compact button is required, such as in a toolbar or image list.

Filled icon toggle button image

content should typically be an Icon (see androidx.compose.material.icons.Icons). If using a custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.

Toggleable filled icon button sample:

import androidx.compose.material3.FilledIconToggleButton
import androidx.compose.material3.Icon
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var checked by remember { mutableStateOf(false) }
FilledIconToggleButton(checked = checked, onCheckedChange = { checked = it }) {
    if (checked) {
        Icon(Icons.Filled.Lock, contentDescription = "Localized description")
    } else {
        Icon(Icons.Outlined.Lock, contentDescription = "Localized description")
    }
}
Parameters
checked: Boolean

whether this icon button is toggled on or off

onCheckedChange: (Boolean) -> Unit

called when this icon button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this icon button

enabled: Boolean = true

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

shape: Shape = IconButtonDefaults.filledShape

defines the shape of this icon button's container

colors: IconToggleButtonColors = IconButtonDefaults.filledIconToggleButtonColors()

IconToggleButtonColors that will be used to resolve the colors used for this icon button in different states. See IconButtonDefaults.filledIconToggleButtonColors.

interactionSource: MutableInteractionSource? = null

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

content: @Composable () -> Unit

the content of this icon button, typically an Icon

FilledTonalButton

@Composable
fun FilledTonalButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = ButtonDefaults.filledTonalShape,
    colors: ButtonColors = ButtonDefaults.filledTonalButtonColors(),
    elevation: ButtonElevation? = ButtonDefaults.filledTonalButtonElevation(),
    border: BorderStroke? = null,
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
    interactionSource: MutableInteractionSource? = null,
    content: @Composable RowScope.() -> Unit
): Unit

Material Design filled tonal button.

Buttons help people initiate actions, from sending an email, to sharing a document, to liking a post.

Filled tonal button image

Filled tonal buttons are medium-emphasis buttons that is an alternative middle ground between default Buttons (filled) and OutlinedButtons. They can be used in contexts where lower-priority button requires slightly more emphasis than an outline would give, such as "Next" in an onboarding flow. Tonal buttons use the secondary color mapping.

import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.Text

FilledTonalButton(onClick = { /* Do something! */ }) { Text("Filled Tonal Button") }

Choose the best button for an action based on the amount of emphasis it needs. The more important an action is, the higher emphasis its button should be.

The default text style for internal Text components will be set to Typography.labelLarge.

Parameters
onClick: () -> Unit

called when this button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this button

enabled: Boolean = true

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

shape: Shape = ButtonDefaults.filledTonalShape

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

colors: ButtonColors = ButtonDefaults.filledTonalButtonColors()

ButtonColors that will be used to resolve the colors for this button in different states. See ButtonDefaults.filledTonalButtonColors.

elevation: ButtonElevation? = ButtonDefaults.filledTonalButtonElevation()

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

border: BorderStroke? = null

the border to draw around the container of this button

contentPadding: PaddingValues = ButtonDefaults.ContentPadding

the spacing values to apply internally between the container and the content

interactionSource: MutableInteractionSource? = null

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

FilledTonalIconButton

@Composable
fun FilledTonalIconButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = IconButtonDefaults.filledShape,
    colors: IconButtonColors = IconButtonDefaults.filledTonalIconButtonColors(),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material Design filled tonal icon button.

Icon buttons help people take supplementary actions with a single tap. They’re used when a compact button is required, such as in a toolbar or image list.

Filled tonal icon button image

A filled tonal icon button is a medium-emphasis icon button that is an alternative middle ground between the default FilledIconButton and OutlinedIconButton. They can be used in contexts where the lower-priority icon button requires slightly more emphasis than an outline would give.

content should typically be an Icon (see androidx.compose.material.icons.Icons). If using a custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.

Filled tonal icon button sample:

import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon

FilledTonalIconButton(onClick = { /* doSomething() */ }) {
    Icon(Icons.Outlined.Lock, contentDescription = "Localized description")
}
Parameters
onClick: () -> Unit

called when this icon button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this icon button

enabled: Boolean = true

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

shape: Shape = IconButtonDefaults.filledShape

defines the shape of this icon button's container

colors: IconButtonColors = IconButtonDefaults.filledTonalIconButtonColors()

IconButtonColors that will be used to resolve the colors used for this icon button in different states. See IconButtonDefaults.filledIconButtonColors.

interactionSource: MutableInteractionSource? = null

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

content: @Composable () -> Unit

the content of this icon button, typically an Icon

FilledTonalIconToggleButton

@Composable
fun FilledTonalIconToggleButton(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = IconButtonDefaults.filledShape,
    colors: IconToggleButtonColors = IconButtonDefaults.filledTonalIconToggleButtonColors(),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material Design filled tonal icon toggle button.

Icon buttons help people take supplementary actions with a single tap. They’re used when a compact button is required, such as in a toolbar or image list.

Filled tonal icon toggle button image

A filled tonal toggle icon button is a medium-emphasis icon button that is an alternative middle ground between the default FilledIconToggleButton and OutlinedIconToggleButton. They can be used in contexts where the lower-priority icon button requires slightly more emphasis than an outline would give.

content should typically be an Icon (see androidx.compose.material.icons.Icons). If using a custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.

Toggleable filled tonal icon button sample:

import androidx.compose.material3.FilledTonalIconToggleButton
import androidx.compose.material3.Icon
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var checked by remember { mutableStateOf(false) }
FilledTonalIconToggleButton(checked = checked, onCheckedChange = { checked = it }) {
    if (checked) {
        Icon(Icons.Filled.Lock, contentDescription = "Localized description")
    } else {
        Icon(Icons.Outlined.Lock, contentDescription = "Localized description")
    }
}
Parameters
checked: Boolean

whether this icon button is toggled on or off

onCheckedChange: (Boolean) -> Unit

called when this icon button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this icon button

enabled: Boolean = true

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

shape: Shape = IconButtonDefaults.filledShape

defines the shape of this icon button's container

colors: IconToggleButtonColors = IconButtonDefaults.filledTonalIconToggleButtonColors()

IconToggleButtonColors that will be used to resolve the colors used for this icon button in different states. See IconButtonDefaults.filledIconToggleButtonColors.

interactionSource: MutableInteractionSource? = null

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

content: @Composable () -> Unit

the content of this icon button, typically an Icon

FilterChip

@Composable
fun FilterChip(
    selected: Boolean,
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    shape: Shape = FilterChipDefaults.shape,
    colors: SelectableChipColors = FilterChipDefaults.filterChipColors(),
    elevation: SelectableChipElevation? = FilterChipDefaults.filterChipElevation(),
    border: BorderStroke? = FilterChipDefaults.filterChipBorder(enabled, selected),
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design filter 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.

Filter chips use tags or descriptive words to filter content. They can be a good alternative to toggle buttons or checkboxes.

Filter chip image

This filter chip is applied with a flat style. If you want an elevated style, use the ElevatedFilterChip.

Tapping on a filter chip toggles its selection state. A selection state leadingIcon can be provided (e.g. a checkmark) to be appended at the starting edge of the chip's label.

Example of a flat FilterChip with a trailing icon:

import androidx.compose.foundation.layout.size
import androidx.compose.material3.FilterChip
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var selected by remember { mutableStateOf(false) }
FilterChip(
    selected = selected,
    onClick = { selected = !selected },
    label = { Text("Filter chip") },
    leadingIcon = if (selected) {
        {
            Icon(
                imageVector = Icons.Filled.Done,
                contentDescription = "Localized Description",
                modifier = Modifier.size(FilterChipDefaults.IconSize)
            )
        }
    } else {
        null
    }
)

Example of a FilterChip with both a leading icon and a selected icon:

import androidx.compose.foundation.layout.size
import androidx.compose.material3.FilterChip
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var selected by remember { mutableStateOf(false) }
FilterChip(
    selected = selected,
    onClick = { selected = !selected },
    label = { Text("Filter chip") },
    leadingIcon = if (selected) {
        {
            Icon(
                imageVector = Icons.Filled.Done,
                contentDescription = "Localized Description",
                modifier = Modifier.size(FilterChipDefaults.IconSize)
            )
        }
    } else {
        {
            Icon(
                imageVector = Icons.Filled.Home,
                contentDescription = "Localized description",
                modifier = Modifier.size(FilterChipDefaults.IconSize)
            )
        }
    }
)
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. When selected is true, this icon may visually indicate that the chip is selected (for example, via a checkmark icon).

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

optional icon at the end of the chip

shape: Shape = FilterChipDefaults.shape

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

colors: SelectableChipColors = FilterChipDefaults.filterChipColors()

SelectableChipColors that will be used to resolve the colors used for this chip in different states. See FilterChipDefaults.filterChipColors.

elevation: SelectableChipElevation? = FilterChipDefaults.filterChipElevation()

SelectableChipElevation 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 FilterChipDefaults.filterChipElevation.

border: BorderStroke? = FilterChipDefaults.filterChipBorder(enabled, selected)

the border to draw around the container of this chip. Pass null for no border. See FilterChipDefaults.filterChipBorder.

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.

FloatingActionButton

@Composable
fun FloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    shape: Shape = FloatingActionButtonDefaults.shape,
    containerColor: Color = FloatingActionButtonDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material Design floating action button.

The FAB represents the most important action on a screen. It puts key actions within reach.

FAB image

FAB typically contains an icon, for a FAB with text and an icon, see ExtendedFloatingActionButton.

import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon

FloatingActionButton(
    onClick = { /* do something */ },
) {
    Icon(Icons.Filled.Add, "Localized description")
}
Parameters
onClick: () -> Unit

called when this FAB is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this FAB

shape: Shape = FloatingActionButtonDefaults.shape

defines the shape of this FAB's container and shadow (when using elevation)

containerColor: Color = FloatingActionButtonDefaults.containerColor

the color used for the background of this FAB. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this FAB. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation()

FloatingActionButtonElevation used to resolve the elevation for this FAB in different states. This controls the size of the shadow below the FAB. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. See also: Surface.

interactionSource: MutableInteractionSource? = null

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

content: @Composable () -> Unit

the content of this FAB, typically an Icon

HorizontalDivider

@Composable
fun HorizontalDivider(
    modifier: Modifier = Modifier,
    thickness: Dp = DividerDefaults.Thickness,
    color: Color = DividerDefaults.color
): Unit

Material Design divider.

A divider is a thin line that groups content in lists and layouts.

Divider image

Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this divider line.

thickness: Dp = DividerDefaults.Thickness

thickness of this divider line. Using Dp.Hairline will produce a single pixel divider regardless of screen density.

color: Color = DividerDefaults.color

color of this divider line.

@Composable
fun Icon(
    bitmap: ImageBitmap,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    tint: Color = LocalContentColor.current
): Unit

A Material Design icon component that draws bitmap using tint, with a default value of LocalContentColor. If bitmap has no intrinsic size, this component will use the recommended default size. Icon is an opinionated component designed to be used with single-color icons so that they can be tinted correctly for the component they are placed in. For multicolored icons and icons that should not be tinted, use Color.Unspecified for tint. For generic images that should not be tinted, and do not follow the recommended icon size, use the generic androidx.compose.foundation.Image instead. For a clickable icon, see IconButton.

To learn more about icons, see Material Design icons

Parameters
bitmap: ImageBitmap

ImageBitmap to draw inside this icon

contentDescription: String?

text used by accessibility services to describe what this icon represents. This should always be provided unless this icon is used for decorative purposes, and does not represent a meaningful action that a user can take. This text should be localized, such as by using androidx.compose.ui.res.stringResource or similar

modifier: Modifier = Modifier

the Modifier to be applied to this icon

tint: Color = LocalContentColor.current

tint to be applied to bitmap. If Color.Unspecified is provided, then no tint is applied.

@Composable
fun Icon(
    imageVector: ImageVector,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    tint: Color = LocalContentColor.current
): Unit

A Material Design icon component that draws imageVector using tint, with a default value of LocalContentColor. If imageVector has no intrinsic size, this component will use the recommended default size. Icon is an opinionated component designed to be used with single-color icons so that they can be tinted correctly for the component they are placed in. For multicolored icons and icons that should not be tinted, use Color.Unspecified for tint. For generic images that should not be tinted, and do not follow the recommended icon size, use the generic androidx.compose.foundation.Image instead. For a clickable icon, see IconButton.

To learn more about icons, see Material Design icons

Parameters
imageVector: ImageVector

ImageVector to draw inside this icon

contentDescription: String?

text used by accessibility services to describe what this icon represents. This should always be provided unless this icon is used for decorative purposes, and does not represent a meaningful action that a user can take. This text should be localized, such as by using androidx.compose.ui.res.stringResource or similar

modifier: Modifier = Modifier

the Modifier to be applied to this icon

tint: Color = LocalContentColor.current

tint to be applied to imageVector. If Color.Unspecified is provided, then no tint is applied.

@Composable
fun Icon(
    painter: Painter,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    tint: Color = LocalContentColor.current
): Unit

A Material Design icon component that draws painter using tint, with a default value of LocalContentColor. If painter has no intrinsic size, this component will use the recommended default size. Icon is an opinionated component designed to be used with single-color icons so that they can be tinted correctly for the component they are placed in. For multicolored icons and icons that should not be tinted, use Color.Unspecified for tint. For generic images that should not be tinted, and do not follow the recommended icon size, use the generic androidx.compose.foundation.Image instead. For a clickable icon, see IconButton.

To learn more about icons, see Material Design icons

Parameters
painter: Painter

Painter to draw inside this icon

contentDescription: String?

text used by accessibility services to describe what this icon represents. This should always be provided unless this icon is used for decorative purposes, and does not represent a meaningful action that a user can take. This text should be localized, such as by using androidx.compose.ui.res.stringResource or similar

modifier: Modifier = Modifier

the Modifier to be applied to this icon

tint: Color = LocalContentColor.current

tint to be applied to painter. If Color.Unspecified is provided, then no tint is applied.

IconButton

@Composable
fun IconButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    colors: IconButtonColors = IconButtonDefaults.iconButtonColors(),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material Design standard icon button.

Icon buttons help people take supplementary actions with a single tap. They’re used when a compact button is required, such as in a toolbar or image list.

Standard icon button image

content should typically be an Icon (see androidx.compose.material.icons.Icons). If using a custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.

import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton

IconButton(onClick = { /* doSomething() */ }) {
    Icon(Icons.Outlined.Lock, contentDescription = "Localized description")
}
Parameters
onClick: () -> Unit

called when this icon button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this icon button

enabled: Boolean = true

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

colors: IconButtonColors = IconButtonDefaults.iconButtonColors()

IconButtonColors that will be used to resolve the colors used for this icon button in different states. See IconButtonDefaults.iconButtonColors.

interactionSource: MutableInteractionSource? = null

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

content: @Composable () -> Unit

the content of this icon button, typically an Icon

IconToggleButton

@Composable
fun IconToggleButton(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    colors: IconToggleButtonColors = IconButtonDefaults.iconToggleButtonColors(),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material Design standard icon toggle button.

Icon buttons help people take supplementary actions with a single tap. They’re used when a compact button is required, such as in a toolbar or image list.

Standard icon toggle button image

content should typically be an Icon (see androidx.compose.material.icons.Icons). If using a custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.

import androidx.compose.material3.Icon
import androidx.compose.material3.IconToggleButton
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var checked by remember { mutableStateOf(false) }
IconToggleButton(checked = checked, onCheckedChange = { checked = it }) {
    if (checked) {
        Icon(Icons.Filled.Lock, contentDescription = "Localized description")
    } else {
        Icon(Icons.Outlined.Lock, contentDescription = "Localized description")
    }
}
Parameters
checked: Boolean

whether this icon button is toggled on or off

onCheckedChange: (Boolean) -> Unit

called when this icon button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this icon button

enabled: Boolean = true

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

colors: IconToggleButtonColors = IconButtonDefaults.iconToggleButtonColors()

IconToggleButtonColors that will be used to resolve the colors used for this icon button in different states. See IconButtonDefaults.iconToggleButtonColors.

interactionSource: MutableInteractionSource? = null

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

content: @Composable () -> Unit

the content of this icon button, typically an Icon

InputChip

@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),
    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.material3.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") },
    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.rememberScrollState
import androidx.compose.material3.AssistChip
import androidx.compose.material3.Text

Column(horizontalAlignment = Alignment.CenterHorizontally) {
    Row(modifier = Modifier.horizontalScroll(rememberScrollState())) {
        repeat(9) { index ->
            AssistChip(
                modifier = Modifier.padding(horizontal = 4.dp),
                onClick = { /* do something*/ },
                label = { Text("Chip $index") }
            )
        }
    }
}

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

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.material3.AssistChip
import androidx.compose.material3.Text
import androidx.compose.ui.util.fastForEachIndexed

val colorNames = listOf(
    "Blue", "Yellow", "Red", "Orange", "Black", "Green",
    "White", "Magenta", "Gray", "Transparent"
)
Column {
    FlowRow(
        Modifier
            .fillMaxWidth(1f)
            .wrapContentHeight(align = Alignment.Top),
        horizontalArrangement = Arrangement.Start,
    ) {
        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.

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.

@ExperimentalMaterial3Api
@Composable
fun Label(
    label: @Composable CaretScope.() -> Unit,
    modifier: Modifier = Modifier,
    interactionSource: MutableInteractionSource? = null,
    isPersistent: Boolean = false,
    content: @Composable () -> Unit
): Unit

Label component that will append a label to content. The positioning logic uses TooltipDefaults.rememberPlainTooltipPositionProvider.

Label appended to thumbs of Slider:

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.Icon
import androidx.compose.material3.Label
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var sliderPosition by remember { mutableStateOf(0f) }
val interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    Slider(
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        value = sliderPosition,
        onValueChange = { sliderPosition = it },
        valueRange = 0f..100f,
        interactionSource = interactionSource,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        },
        thumb = {
            Label(
                label = {
                    PlainTooltip(
                        modifier = Modifier
                            .requiredSize(45.dp, 25.dp)
                            .wrapContentWidth()
                    ) {
                        Text("%.2f".format(sliderPosition))
                    }
                },
                interactionSource = interactionSource
            ) {
                Icon(
                    imageVector = Icons.Filled.Favorite,
                    contentDescription = null,
                    modifier = Modifier.size(ButtonDefaults.IconSize),
                    tint = Color.Red
                )
            }
        }
    )
}

Label appended to thumbs of RangeSlider:

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.Label
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.RangeSlider
import androidx.compose.material3.RangeSliderState
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

val rangeSliderState = remember {
    RangeSliderState(
        0f,
        100f,
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        }
    )
}
val startInteractionSource = remember { MutableInteractionSource() }
val endInteractionSource = remember { MutableInteractionSource() }
val startThumbAndTrackColors = SliderDefaults.colors(
    thumbColor = Color.Blue,
    activeTrackColor = Color.Red
)
val endThumbColors = SliderDefaults.colors(thumbColor = Color.Green)
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    RangeSlider(
        state = rangeSliderState,
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        startInteractionSource = startInteractionSource,
        endInteractionSource = endInteractionSource,
        startThumb = {
            Label(
                label = {
                    PlainTooltip(
                        modifier = Modifier
                            .requiredSize(45.dp, 25.dp)
                            .wrapContentWidth()
                    ) {
                        Text("%.2f".format(rangeSliderState.activeRangeStart))
                    }
                },
                interactionSource = startInteractionSource
            ) {
                SliderDefaults.Thumb(
                    interactionSource = startInteractionSource,
                    colors = startThumbAndTrackColors
                )
            }
        },
        endThumb = {
            Label(
                label = {
                    PlainTooltip(
                        modifier = Modifier
                            .requiredSize(45.dp, 25.dp)
                            .wrapContentWidth()
                    ) {
                        Text("%.2f".format(rangeSliderState.activeRangeEnd))
                    }
                },
                interactionSource = endInteractionSource
            ) {
                SliderDefaults.Thumb(
                    interactionSource = endInteractionSource,
                    colors = endThumbColors
                )
            }
        },
        track = { rangeSliderState ->
            SliderDefaults.Track(
                colors = startThumbAndTrackColors,
                rangeSliderState = rangeSliderState
            )
        }
    )
}
Parameters
label: @Composable CaretScope.() -> Unit

composable that will be appended to content

modifier: Modifier = Modifier

Modifier that will be applied to content

interactionSource: MutableInteractionSource? = null

the MutableInteractionSource representing the stream of Interactions for the content.

isPersistent: Boolean = false

boolean to determine if the label should be persistent. If true, then the label will always show and be anchored to content. if false, then the label will only show when pressing down or hovering over the content.

content: @Composable () -> Unit

the composable that label will anchor to.

LargeFloatingActionButton

@Composable
fun LargeFloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    shape: Shape = FloatingActionButtonDefaults.largeShape,
    containerColor: Color = FloatingActionButtonDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material Design large floating action button.

The FAB represents the most important action on a screen. It puts key actions within reach.

Large FAB image

import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
import androidx.compose.material3.LargeFloatingActionButton

LargeFloatingActionButton(
    onClick = { /* do something */ },
) {
    Icon(
        Icons.Filled.Add,
        contentDescription = "Localized description",
        modifier = Modifier.size(FloatingActionButtonDefaults.LargeIconSize),
    )
}
Parameters
onClick: () -> Unit

called when this FAB is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this FAB

shape: Shape = FloatingActionButtonDefaults.largeShape

defines the shape of this FAB's container and shadow (when using elevation)

containerColor: Color = FloatingActionButtonDefaults.containerColor

the color used for the background of this FAB. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this FAB. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation()

FloatingActionButtonElevation used to resolve the elevation for this FAB in different states. This controls the size of the shadow below the FAB. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. See also: Surface.

interactionSource: MutableInteractionSource? = null

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

content: @Composable () -> Unit

the content of this FAB, typically an Icon

LargeTopAppBar

@ExperimentalMaterial3Api
@Composable
fun LargeTopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    navigationIcon: @Composable () -> Unit = {},
    actions: @Composable RowScope.() -> Unit = {},
    windowInsets: WindowInsets = TopAppBarDefaults.windowInsets,
    colors: TopAppBarColors = TopAppBarDefaults.largeTopAppBarColors(),
    scrollBehavior: TopAppBarScrollBehavior? = null
): Unit

Material Design large top app bar.

Top app bars display information and actions at the top of a screen.

Large top app bar image

This LargeTopAppBar has slots for a title, navigation icon, and actions. In its default expanded state, the title is displayed in a second row under the navigation and actions.

A large top app bar that uses a scrollBehavior to customize its nested scrolling behavior when working in conjunction with scrolling content looks like:

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.ui.input.nestedscroll.nestedScroll

val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
    modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
    topBar = {
        LargeTopAppBar(
            title = {
                Text(
                    "Large TopAppBar",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
            },
            navigationIcon = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Menu,
                        contentDescription = "Localized description"
                    )
                }
            },
            actions = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Favorite,
                        contentDescription = "Localized description"
                    )
                }
            },
            scrollBehavior = scrollBehavior
        )
    },
    content = { innerPadding ->
        LazyColumn(
            contentPadding = innerPadding,
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            val list = (0..75).map { it.toString() }
            items(count = list.size) {
                Text(
                    text = list[it],
                    style = MaterialTheme.typography.bodyLarge,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp)
                )
            }
        }
    }
)
Parameters
title: @Composable () -> Unit

the title to be displayed in the top app bar. This title will be used in the app bar's expanded and collapsed states, although in its collapsed state it will be composed with a smaller sized TextStyle

modifier: Modifier = Modifier

the Modifier to be applied to this top app bar

navigationIcon: @Composable () -> Unit = {}

the navigation icon displayed at the start of the top app bar. This should typically be an IconButton or IconToggleButton.

actions: @Composable RowScope.() -> Unit = {}

the actions displayed at the end of the top app bar. This should typically be IconButtons. The default layout here is a Row, so icons inside will be placed horizontally.

windowInsets: WindowInsets = TopAppBarDefaults.windowInsets

a window insets that app bar will respect.

colors: TopAppBarColors = TopAppBarDefaults.largeTopAppBarColors()

TopAppBarColors that will be used to resolve the colors used for this top app bar in different states. See TopAppBarDefaults.largeTopAppBarColors.

scrollBehavior: TopAppBarScrollBehavior? = null

a TopAppBarScrollBehavior which holds various offset values that will be applied by this top app bar to set up its height and colors. A scroll behavior is designed to work in conjunction with a scrolled content to change the top app bar appearance as the content scrolls. See TopAppBarScrollBehavior.nestedScrollConnection.

LeadingIconTab

@Composable
fun LeadingIconTab(
    selected: Boolean,
    onClick: () -> Unit,
    text: @Composable () -> Unit,
    icon: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    selectedContentColor: Color = LocalContentColor.current,
    unselectedContentColor: Color = selectedContentColor,
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design tab.

Tabs organize content across different screens, data sets, and other interactions.

A LeadingIconTab represents a single page of content using a text label and an icon in front of the label. It represents its selected state by tinting the text label and icon with selectedContentColor.

This should typically be used inside of a TabRow, see the corresponding documentation for example usage.

Parameters
selected: Boolean

whether this tab is selected or not

onClick: () -> Unit

called when this tab is clicked

text: @Composable () -> Unit

the text label displayed in this tab

icon: @Composable () -> Unit

the icon displayed in this tab. Should be 24.dp.

modifier: Modifier = Modifier

the Modifier to be applied to this tab

enabled: Boolean = true

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

selectedContentColor: Color = LocalContentColor.current

the color for the content of this tab when selected, and the color of the ripple.

unselectedContentColor: Color = selectedContentColor

the color for the content of this tab when not selected

interactionSource: MutableInteractionSource? = null

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

See also
Tab

LinearProgressIndicator

@Composable
fun LinearProgressIndicator(
    modifier: Modifier = Modifier,
    color: Color = ProgressIndicatorDefaults.linearColor,
    trackColor: Color = ProgressIndicatorDefaults.linearTrackColor,
    strokeCap: StrokeCap = ProgressIndicatorDefaults.LinearStrokeCap,
    gapSize: Dp = ProgressIndicatorDefaults.LinearIndicatorTrackGapSize
): Unit

Indeterminate Material Design linear progress indicator.

Progress indicators express an unspecified wait time or display the duration of a process.

Linear progress indicator image

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.LinearProgressIndicator

Column(horizontalAlignment = Alignment.CenterHorizontally) {
    LinearProgressIndicator()
}
Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this progress indicator

color: Color = ProgressIndicatorDefaults.linearColor

color of this progress indicator

trackColor: Color = ProgressIndicatorDefaults.linearTrackColor

color of the track behind the indicator, visible when the progress has not reached the area of the overall indicator yet

strokeCap: StrokeCap = ProgressIndicatorDefaults.LinearStrokeCap

stroke cap to use for the ends of this progress indicator

gapSize: Dp = ProgressIndicatorDefaults.LinearIndicatorTrackGapSize

size of the gap between the progress indicator and the track

LinearProgressIndicator

@Composable
fun LinearProgressIndicator(
    progress: Float,
    modifier: Modifier = Modifier,
    color: Color = ProgressIndicatorDefaults.linearColor,
    trackColor: Color = ProgressIndicatorDefaults.linearTrackColor,
    strokeCap: StrokeCap = ProgressIndicatorDefaults.LinearStrokeCap
): Unit

LinearProgressIndicator

@Composable
fun LinearProgressIndicator(
    progress: () -> Float,
    modifier: Modifier = Modifier,
    color: Color = ProgressIndicatorDefaults.linearColor,
    trackColor: Color = ProgressIndicatorDefaults.linearTrackColor,
    strokeCap: StrokeCap = ProgressIndicatorDefaults.LinearStrokeCap,
    gapSize: Dp = ProgressIndicatorDefaults.LinearIndicatorTrackGapSize,
    drawStopIndicator: (DrawScope.() -> Unit)? = { drawStopIndicator( stopSize = ProgressIndicatorDefaults.LinearTrackStopIndicatorSize, color = color, strokeCap = strokeCap ) }
): Unit

Determinate Material Design linear progress indicator.

Progress indicators express an unspecified wait time or display the duration of a process.

Linear progress indicator image

By default there is no animation between progress values. You can use ProgressIndicatorDefaults.ProgressAnimationSpec as the default recommended AnimationSpec when animating progress, such as in the following example:

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.material.Slider
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var progress by remember { mutableStateOf(0.1f) }
val animatedProgress by animateFloatAsState(
    targetValue = progress,
    animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec
)

Column(horizontalAlignment = Alignment.CenterHorizontally) {
    LinearProgressIndicator(
        progress = { animatedProgress },
    )
    Spacer(Modifier.requiredHeight(30.dp))
    Slider(
        modifier = Modifier
            .padding(start = 24.dp, end = 24.dp)
            .semantics {
                val progressPercent = (progress * 100).toInt()
                if (progressPercent in progressBreakpoints) {
                    stateDescription = "Progress $progressPercent%"
                }
            },
        value = progress,
        valueRange = 0f..1f,
        steps = 100,
        onValueChange = {
            progress = it
        })
}
Parameters
progress: () -> Float

the progress of this progress indicator, where 0.0 represents no progress and 1.0 represents full progress. Values outside of this range are coerced into the range.

modifier: Modifier = Modifier

the Modifier to be applied to this progress indicator

color: Color = ProgressIndicatorDefaults.linearColor

color of this progress indicator

trackColor: Color = ProgressIndicatorDefaults.linearTrackColor

color of the track behind the indicator, visible when the progress has not reached the area of the overall indicator yet

strokeCap: StrokeCap = ProgressIndicatorDefaults.LinearStrokeCap

stroke cap to use for the ends of this progress indicator

gapSize: Dp = ProgressIndicatorDefaults.LinearIndicatorTrackGapSize

size of the gap between the progress indicator and the track

drawStopIndicator: (DrawScope.() -> Unit)? = { drawStopIndicator( stopSize = ProgressIndicatorDefaults.LinearTrackStopIndicatorSize, color = color, strokeCap = strokeCap ) }

lambda that will be called to draw the stop indicator

@Composable
fun ListItem(
    headlineContent: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    overlineContent: (@Composable () -> Unit)? = null,
    supportingContent: (@Composable () -> Unit)? = null,
    leadingContent: (@Composable () -> Unit)? = null,
    trailingContent: (@Composable () -> Unit)? = null,
    colors: ListItemColors = ListItemDefaults.colors(),
    tonalElevation: Dp = ListItemDefaults.Elevation,
    shadowElevation: Dp = ListItemDefaults.Elevation
): Unit

Material Design list item.

Lists are continuous, vertical indexes of text or images.

Lists image

This component can be used to achieve the list item templates existing in the spec. One-line list items have a singular line of headline content. Two-line list items additionally have either supporting or overline content. Three-line list items have either both supporting and overline content, or extended (two-line) supporting text. For example:

  • one-line item

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.Text

Column {
    ListItem(
        headlineContent = { Text("One line list item with 24x24 icon") },
        leadingContent = {
            Icon(
                Icons.Filled.Favorite,
                contentDescription = "Localized description",
            )
        }
    )
    HorizontalDivider()
}
  • two-line item

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.Text

Column {
    ListItem(
        headlineContent = { Text("Two line list item with trailing") },
        supportingContent = { Text("Secondary text") },
        trailingContent = { Text("meta") },
        leadingContent = {
            Icon(
                Icons.Filled.Favorite,
                contentDescription = "Localized description",
            )
        }
    )
    HorizontalDivider()
}
  • three-line item with both overline and supporting content

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.Text

Column {
    ListItem(
        headlineContent = { Text("Three line list item") },
        overlineContent = { Text("OVERLINE") },
        supportingContent = { Text("Secondary text") },
        leadingContent = {
            Icon(
                Icons.Filled.Favorite,
                contentDescription = "Localized description",
            )
        },
        trailingContent = { Text("meta") }
    )
    HorizontalDivider()
}
  • three-line item with extended supporting content

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.Text

Column {
    ListItem(
        headlineContent = { Text("Three line list item") },
        supportingContent = {
            Text("Secondary text that is long and perhaps goes onto another line")
        },
        leadingContent = {
            Icon(
                Icons.Filled.Favorite,
                contentDescription = "Localized description",
            )
        },
        trailingContent = { Text("meta") }
    )
    HorizontalDivider()
}
Parameters
headlineContent: @Composable () -> Unit

the headline content of the list item

modifier: Modifier = Modifier

Modifier to be applied to the list item

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

the content displayed above the headline content

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

the supporting content of the list item

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

the leading content of the list item

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

the trailing meta text, icon, switch or checkbox

colors: ListItemColors = ListItemDefaults.colors()

ListItemColors that will be used to resolve the background and content color for this list item in different states. See ListItemDefaults.colors

tonalElevation: Dp = ListItemDefaults.Elevation

the tonal elevation of this list item

shadowElevation: Dp = ListItemDefaults.Elevation

the shadow elevation of this list item

MaterialTheme

@Composable
fun MaterialTheme(
    colorScheme: ColorScheme = MaterialTheme.colorScheme,
    shapes: Shapes = MaterialTheme.shapes,
    typography: Typography = MaterialTheme.typography,
    content: @Composable () -> Unit
): Unit

Material Theming refers to the customization of your Material Design app to better reflect your product’s brand.

Material components such as Button and Checkbox use values provided here when retrieving default values.

All values may be set by providing this component with the colorScheme, typography attributes. Use this to configure the overall theme of elements within this MaterialTheme.

Any values that are not set will inherit the current value from the theme, falling back to the defaults if there is no parent MaterialTheme. This allows using a MaterialTheme at the top of your application, and then separate MaterialTheme(s) for different screens / parts of your UI, overriding only the parts of the theme definition that need to change.

Parameters
colorScheme: ColorScheme = MaterialTheme.colorScheme

A complete definition of the Material Color theme for this hierarchy

shapes: Shapes = MaterialTheme.shapes

A set of corner shapes to be used as this hierarchy's shape system

typography: Typography = MaterialTheme.typography

A set of text styles to be used as this hierarchy's typography system

MediumTopAppBar

@ExperimentalMaterial3Api
@Composable
fun MediumTopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    navigationIcon: @Composable () -> Unit = {},
    actions: @Composable RowScope.() -> Unit = {},
    windowInsets: WindowInsets = TopAppBarDefaults.windowInsets,
    colors: TopAppBarColors = TopAppBarDefaults.mediumTopAppBarColors(),
    scrollBehavior: TopAppBarScrollBehavior? = null
): Unit

Material Design medium top app bar.

Top app bars display information and actions at the top of a screen.

Medium top app bar image

This MediumTopAppBar has slots for a title, navigation icon, and actions. In its default expanded state, the title is displayed in a second row under the navigation and actions.

A medium top app bar that uses a scrollBehavior to customize its nested scrolling behavior when working in conjunction with scrolling content looks like:

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MediumTopAppBar
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.ui.input.nestedscroll.nestedScroll

val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
    modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
    topBar = {
        MediumTopAppBar(
            title = {
                Text(
                    "Medium TopAppBar",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
            },
            navigationIcon = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Menu,
                        contentDescription = "Localized description"
                    )
                }
            },
            actions = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Favorite,
                        contentDescription = "Localized description"
                    )
                }
            },
            scrollBehavior = scrollBehavior
        )
    },
    content = { innerPadding ->
        LazyColumn(
            contentPadding = innerPadding,
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            val list = (0..75).map { it.toString() }
            items(count = list.size) {
                Text(
                    text = list[it],
                    style = MaterialTheme.typography.bodyLarge,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp)
                )
            }
        }
    }
)
Parameters
title: @Composable () -> Unit

the title to be displayed in the top app bar. This title will be used in the app bar's expanded and collapsed states, although in its collapsed state it will be composed with a smaller sized TextStyle

modifier: Modifier = Modifier

the Modifier to be applied to this top app bar

navigationIcon: @Composable () -> Unit = {}

the navigation icon displayed at the start of the top app bar. This should typically be an IconButton or IconToggleButton.

actions: @Composable RowScope.() -> Unit = {}

the actions displayed at the end of the top app bar. This should typically be IconButtons. The default layout here is a Row, so icons inside will be placed horizontally.

windowInsets: WindowInsets = TopAppBarDefaults.windowInsets

a window insets that app bar will respect.

colors: TopAppBarColors = TopAppBarDefaults.mediumTopAppBarColors()

TopAppBarColors that will be used to resolve the colors used for this top app bar in different states. See TopAppBarDefaults.mediumTopAppBarColors.

scrollBehavior: TopAppBarScrollBehavior? = null

a TopAppBarScrollBehavior which holds various offset values that will be applied by this top app bar to set up its height and colors. A scroll behavior is designed to work in conjunction with a scrolled content to change the top app bar appearance as the content scrolls. See TopAppBarScrollBehavior.nestedScrollConnection.

ModalBottomSheet

@Composable
@ExperimentalMaterial3Api
fun ModalBottomSheet(
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    sheetState: SheetState = rememberModalBottomSheetState(),
    sheetMaxWidth: Dp = BottomSheetDefaults.SheetMaxWidth,
    shape: Shape = BottomSheetDefaults.ExpandedShape,
    containerColor: Color = BottomSheetDefaults.ContainerColor,
    contentColor: Color = contentColorFor(containerColor),
    tonalElevation: Dp = 0.dp,
    scrimColor: Color = BottomSheetDefaults.ScrimColor,
    dragHandle: (@Composable () -> Unit)? = { BottomSheetDefaults.DragHandle() },
    windowInsets: WindowInsets = BottomSheetDefaults.windowInsets,
    properties: ModalBottomSheetProperties = ModalBottomSheetDefaults.properties(),
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design modal bottom sheet.

Modal bottom sheets are used as an alternative to inline menus or simple dialogs on mobile, especially when offering a long list of action items, or when items require longer descriptions and icons. Like dialogs, modal bottom sheets appear in front of app content, disabling all other app functionality when they appear, and remaining on screen until confirmed, dismissed, or a required action has been taken.

Bottom sheet image

A simple example of a modal bottom sheet looks like this:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.selection.toggleable
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable

var openBottomSheet by rememberSaveable { mutableStateOf(false) }
var skipPartiallyExpanded by remember { mutableStateOf(false) }
var edgeToEdgeEnabled by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
val bottomSheetState = rememberModalBottomSheetState(
    skipPartiallyExpanded = skipPartiallyExpanded
)

// App content
Column(
    horizontalAlignment = Alignment.Start,
    verticalArrangement = Arrangement.spacedBy(4.dp)
) {
    Row(
        Modifier.toggleable(
            value = skipPartiallyExpanded,
            role = Role.Checkbox,
            onValueChange = { checked -> skipPartiallyExpanded = checked }
        )
    ) {
        Checkbox(checked = skipPartiallyExpanded, onCheckedChange = null)
        Spacer(Modifier.width(16.dp))
        Text("Skip partially expanded State")
    }
    Row(
        Modifier.toggleable(
            value = edgeToEdgeEnabled,
            role = Role.Checkbox,
            onValueChange = { checked -> edgeToEdgeEnabled = checked }
        )
    ) {
        Checkbox(checked = edgeToEdgeEnabled, onCheckedChange = null)
        Spacer(Modifier.width(16.dp))
        Text("Toggle edge to edge enabled")
    }
    Button(
        onClick = { openBottomSheet = !openBottomSheet },
        modifier = Modifier.align(Alignment.CenterHorizontally)
    ) {
        Text(text = "Show Bottom Sheet")
    }
}

// Sheet content
if (openBottomSheet) {
    val windowInsets = if (edgeToEdgeEnabled)
        WindowInsets(0) else BottomSheetDefaults.windowInsets

    ModalBottomSheet(
        onDismissRequest = { openBottomSheet = false },
        sheetState = bottomSheetState,
        windowInsets = windowInsets
    ) {

        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
            Button(
                // Note: If you provide logic outside of onDismissRequest to remove the sheet,
                // you must additionally handle intended state cleanup, if any.
                onClick = {
                    scope.launch { bottomSheetState.hide() }.invokeOnCompletion {
                        if (!bottomSheetState.isVisible) {
                            openBottomSheet = false
                        }
                    }
                }
            ) {
                Text("Hide Bottom Sheet")
            }
        }
        var text by remember { mutableStateOf("") }
        OutlinedTextField(
            value = text,
            onValueChange = { text = it },
            modifier = Modifier.padding(horizontal = 16.dp),
            label = { Text("Text field") }
        )
        LazyColumn {
            items(25) {
                ListItem(
                    headlineContent = { Text("Item $it") },
                    leadingContent = {
                        Icon(
                            Icons.Default.Favorite,
                            contentDescription = "Localized description"
                        )
                    },
                    colors = ListItemDefaults.colors(
                        containerColor = MaterialTheme.colorScheme.surfaceContainerLow
                    ),
                )
            }
        }
    }
}
Parameters
onDismissRequest: () -> Unit

Executes when the user clicks outside of the bottom sheet, after sheet animates to Hidden.

modifier: Modifier = Modifier

Optional Modifier for the bottom sheet.

sheetState: SheetState = rememberModalBottomSheetState()

The state of the bottom sheet.

sheetMaxWidth: Dp = BottomSheetDefaults.SheetMaxWidth

Dp that defines what the maximum width the sheet will take. Pass in Dp.Unspecified for a sheet that spans the entire screen width.

shape: Shape = BottomSheetDefaults.ExpandedShape

The shape of the bottom sheet.

containerColor: Color = BottomSheetDefaults.ContainerColor

The color used for the background of this bottom sheet

contentColor: Color = contentColorFor(containerColor)

The preferred color for content inside this bottom sheet. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

tonalElevation: Dp = 0.dp

when containerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

scrimColor: Color = BottomSheetDefaults.ScrimColor

Color of the scrim that obscures content when the bottom sheet is open.

dragHandle: (@Composable () -> Unit)? = { BottomSheetDefaults.DragHandle() }

Optional visual marker to swipe the bottom sheet.

windowInsets: WindowInsets = BottomSheetDefaults.windowInsets

window insets to be passed to the bottom sheet window via PaddingValues params.

properties: ModalBottomSheetProperties = ModalBottomSheetDefaults.properties()

ModalBottomSheetProperties for further customization of this modal bottom sheet's behavior.

content: @Composable ColumnScope.() -> Unit

The content to be displayed inside the bottom sheet.

ModalDrawerSheet

@Composable
fun ModalDrawerSheet(
    modifier: Modifier = Modifier,
    drawerShape: Shape = DrawerDefaults.shape,
    drawerContainerColor: Color = DrawerDefaults.modalContainerColor,
    drawerContentColor: Color = contentColorFor(drawerContainerColor),
    drawerTonalElevation: Dp = DrawerDefaults.ModalDrawerElevation,
    windowInsets: WindowInsets = DrawerDefaults.windowInsets,
    content: @Composable ColumnScope.() -> Unit
): Unit

Content inside of a modal navigation drawer.

Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this drawer's content

drawerShape: Shape = DrawerDefaults.shape

defines the shape of this drawer's container

drawerContainerColor: Color = DrawerDefaults.modalContainerColor

the color used for the background of this drawer. Use Color.Transparent to have no color.

drawerContentColor: Color = contentColorFor(drawerContainerColor)

the preferred color for content inside this drawer. Defaults to either the matching content color for drawerContainerColor, or to the current LocalContentColor if drawerContainerColor is not a color from the theme.

drawerTonalElevation: Dp = DrawerDefaults.ModalDrawerElevation

when drawerContainerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

windowInsets: WindowInsets = DrawerDefaults.windowInsets

a window insets for the sheet.

content: @Composable ColumnScope.() -> Unit

content inside of a modal navigation drawer

ModalNavigationDrawer

@Composable
fun ModalNavigationDrawer(
    drawerContent: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),
    gesturesEnabled: Boolean = true,
    scrimColor: Color = DrawerDefaults.scrimColor,
    content: @Composable () -> Unit
): Unit

Material Design navigation drawer.

Navigation drawers provide ergonomic access to destinations in an app.

Modal navigation drawers block interaction with the rest of an app’s content with a scrim. They are elevated above most of the app’s UI and don’t affect the screen’s layout grid.

Navigation drawer image

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.NavigationDrawerItem
import androidx.compose.material3.Text
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()
// icons to mimic drawer destinations
val items = listOf(Icons.Default.Favorite, Icons.Default.Face, Icons.Default.Email)
val selectedItem = remember { mutableStateOf(items[0]) }
ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        ModalDrawerSheet {
            Spacer(Modifier.height(12.dp))
            items.forEach { item ->
                NavigationDrawerItem(
                    icon = { Icon(item, contentDescription = null) },
                    label = { Text(item.name) },
                    selected = item == selectedItem.value,
                    onClick = {
                        scope.launch { drawerState.close() }
                        selectedItem.value = item
                    },
                    modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
                )
            }
        }
    },
    content = {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(text = if (drawerState.isClosed) ">>> Swipe >>>" else "<<< Swipe <<<")
            Spacer(Modifier.height(20.dp))
            Button(onClick = { scope.launch { drawerState.open() } }) {
                Text("Click to open")
            }
        }
    }
)
Parameters
drawerContent: @Composable () -> Unit

content inside this drawer

modifier: Modifier = Modifier

the Modifier to be applied to this drawer

drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed)

state of the drawer

gesturesEnabled: Boolean = true

whether or not the drawer can be interacted by gestures

scrimColor: Color = DrawerDefaults.scrimColor

color of the scrim that obscures content when the drawer is open

content: @Composable () -> Unit

content of the rest of the UI

MultiChoiceSegmentedButtonRow

@Composable
@ExperimentalMaterial3Api
fun MultiChoiceSegmentedButtonRow(
    modifier: Modifier = Modifier,
    space: Dp = SegmentedButtonDefaults.BorderWidth,
    content: @Composable MultiChoiceSegmentedButtonRowScope.() -> Unit
): Unit

Material Segmented Button.

A Layout to correctly position, size, and add semantics to SegmentedButtons in a Row. It handles overlapping items so that strokes of the item are correctly on top of each other.

MultiChoiceSegmentedButtonRow is used when the selection allows multiple value, for correct semantics.

import androidx.compose.foundation.layout.size
import androidx.compose.material.Icon
import androidx.compose.material3.MultiChoiceSegmentedButtonRow
import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember

val checkedList = remember { mutableStateListOf<Int>() }
val options = listOf("Favorites", "Trending", "Saved")
val icons = listOf(
    Icons.Filled.StarBorder,
    Icons.AutoMirrored.Filled.TrendingUp,
    Icons.Filled.BookmarkBorder
)
MultiChoiceSegmentedButtonRow {
    options.forEachIndexed { index, label ->
        SegmentedButton(
            shape = SegmentedButtonDefaults.itemShape(index = index, count = options.size),
            icon = {
                SegmentedButtonDefaults.Icon(active = index in checkedList) {
                    Icon(
                        imageVector = icons[index],
                        contentDescription = null,
                        modifier = Modifier.size(SegmentedButtonDefaults.IconSize)
                    )
                }
            },
            onCheckedChange = {
                if (index in checkedList) {
                    checkedList.remove(index)
                } else {
                    checkedList.add(index)
                }
            },
            checked = index in checkedList
        ) {
            Text(label)
        }
    }
}
Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this row

space: Dp = SegmentedButtonDefaults.BorderWidth

the dimension of the overlap between buttons. Should be equal to the stroke width used on the items.

content: @Composable MultiChoiceSegmentedButtonRowScope.() -> Unit

the content of this Segmented Button Row, typically a sequence of SegmentedButtons

@Composable
fun NavigationBar(
    modifier: Modifier = Modifier,
    containerColor: Color = NavigationBarDefaults.containerColor,
    contentColor: Color = MaterialTheme.colorScheme.contentColorFor(containerColor),
    tonalElevation: Dp = NavigationBarDefaults.Elevation,
    windowInsets: WindowInsets = NavigationBarDefaults.windowInsets,
    content: @Composable RowScope.() -> Unit
): Unit

Material Design bottom navigation bar.

Navigation bars offer a persistent and convenient way to switch between primary destinations in an app.

Navigation bar image

NavigationBar should contain three to five NavigationBarItems, each representing a singular destination.

A simple example looks like:

import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember

var selectedItem by remember { mutableIntStateOf(0) }
val items = listOf("Songs", "Artists", "Playlists")

NavigationBar {
    items.forEachIndexed { index, item ->
        NavigationBarItem(
            icon = { Icon(Icons.Filled.Favorite, contentDescription = item) },
            label = { Text(item) },
            selected = selectedItem == index,
            onClick = { selectedItem = index }
        )
    }
}

See NavigationBarItem for configuration specific to each item, and not the overall NavigationBar component.

Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this navigation bar

containerColor: Color = NavigationBarDefaults.containerColor

the color used for the background of this navigation bar. Use Color.Transparent to have no color.

contentColor: Color = MaterialTheme.colorScheme.contentColorFor(containerColor)

the preferred color for content inside this navigation bar. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

tonalElevation: Dp = NavigationBarDefaults.Elevation

when containerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

windowInsets: WindowInsets = NavigationBarDefaults.windowInsets

a window insets of the navigation bar.

content: @Composable RowScope.() -> Unit

the content of this navigation bar, typically 3-5 NavigationBarItems

@Composable
fun NavigationDrawerItem(
    label: @Composable () -> Unit,
    selected: Boolean,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    icon: (@Composable () -> Unit)? = null,
    badge: (@Composable () -> Unit)? = null,
    shape: Shape = NavigationDrawerTokens.ActiveIndicatorShape.value,
    colors: NavigationDrawerItemColors = NavigationDrawerItemDefaults.colors(),
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design navigation drawer item.

A NavigationDrawerItem represents a destination within drawers, either ModalNavigationDrawer, PermanentNavigationDrawer or DismissibleNavigationDrawer.

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.NavigationDrawerItem
import androidx.compose.material3.Text
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()
// icons to mimic drawer destinations
val items = listOf(Icons.Default.Favorite, Icons.Default.Face, Icons.Default.Email)
val selectedItem = remember { mutableStateOf(items[0]) }
ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        ModalDrawerSheet {
            Spacer(Modifier.height(12.dp))
            items.forEach { item ->
                NavigationDrawerItem(
                    icon = { Icon(item, contentDescription = null) },
                    label = { Text(item.name) },
                    selected = item == selectedItem.value,
                    onClick = {
                        scope.launch { drawerState.close() }
                        selectedItem.value = item
                    },
                    modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
                )
            }
        }
    },
    content = {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(text = if (drawerState.isClosed) ">>> Swipe >>>" else "<<< Swipe <<<")
            Spacer(Modifier.height(20.dp))
            Button(onClick = { scope.launch { drawerState.open() } }) {
                Text("Click to open")
            }
        }
    }
)
Parameters
label: @Composable () -> Unit

text label for this item

selected: Boolean

whether this item is selected

onClick: () -> Unit

called when this item is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this item

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

optional icon for this item, typically an Icon

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

optional badge to show on this item from the end side

colors: NavigationDrawerItemColors = NavigationDrawerItemDefaults.colors()

NavigationDrawerItemColors that will be used to resolve the colors used for this item in different states. See NavigationDrawerItemDefaults.colors.

interactionSource: MutableInteractionSource? = null

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

@Composable
fun NavigationRail(
    modifier: Modifier = Modifier,
    containerColor: Color = NavigationRailDefaults.ContainerColor,
    contentColor: Color = contentColorFor(containerColor),
    header: (@Composable ColumnScope.() -> Unit)? = null,
    windowInsets: WindowInsets = NavigationRailDefaults.windowInsets,
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design bottom navigation rail.

Navigation rails provide access to primary destinations in apps when using tablet and desktop screens.

Navigation rail image

The navigation rail should be used to display three to seven app destinations and, optionally, a FloatingActionButton or a logo header. Each destination is typically represented by an icon and an optional text label.

NavigationRail should contain multiple NavigationRailItems, each representing a singular destination.

A simple example looks like:

import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationRail
import androidx.compose.material3.NavigationRailItem
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember

var selectedItem by remember { mutableIntStateOf(0) }
val items = listOf("Home", "Search", "Settings")
val icons = listOf(Icons.Filled.Home, Icons.Filled.Search, Icons.Filled.Settings)
NavigationRail {
    items.forEachIndexed { index, item ->
        NavigationRailItem(
            icon = { Icon(icons[index], contentDescription = item) },
            label = { Text(item) },
            selected = selectedItem == index,
            onClick = { selectedItem = index }
        )
    }
}

See NavigationRailItem for configuration specific to each item, and not the overall NavigationRail component.

Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this navigation rail

containerColor: Color = NavigationRailDefaults.ContainerColor

the color used for the background of this navigation rail. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this navigation rail. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

header: (@Composable ColumnScope.() -> Unit)? = null

optional header that may hold a FloatingActionButton or a logo

windowInsets: WindowInsets = NavigationRailDefaults.windowInsets

a window insets of the navigation rail.

content: @Composable ColumnScope.() -> Unit

the content of this navigation rail, typically 3-7 NavigationRailItems

@Composable
fun NavigationRailItem(
    selected: Boolean,
    onClick: () -> Unit,
    icon: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    label: (@Composable () -> Unit)? = null,
    alwaysShowLabel: Boolean = true,
    colors: NavigationRailItemColors = NavigationRailItemDefaults.colors(),
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design navigation rail item.

A NavigationRailItem represents a destination within a NavigationRail.

Navigation rails provide access to primary destinations in apps when using tablet and desktop screens.

The text label is always shown (if it exists) when selected. Showing text labels if not selected is controlled by alwaysShowLabel.

Parameters
selected: Boolean

whether this item is selected

onClick: () -> Unit

called when this item is clicked

icon: @Composable () -> Unit

icon for this item, typically an Icon

modifier: Modifier = Modifier

the Modifier to be applied to this item

enabled: Boolean = true

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

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

optional text label for this item

alwaysShowLabel: Boolean = true

whether to always show the label for this item. If false, the label will only be shown when this item is selected.

colors: NavigationRailItemColors = NavigationRailItemDefaults.colors()

NavigationRailItemColors that will be used to resolve the colors used for this item in different states. See NavigationRailItemDefaults.colors.

interactionSource: MutableInteractionSource? = null

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

OutlinedButton

@Composable
fun OutlinedButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = ButtonDefaults.outlinedShape,
    colors: ButtonColors = ButtonDefaults.outlinedButtonColors(),
    elevation: ButtonElevation? = null,
    border: BorderStroke? = ButtonDefaults.outlinedButtonBorder,
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
    interactionSource: MutableInteractionSource? = null,
    content: @Composable RowScope.() -> Unit
): Unit

Material Design outlined button.

Buttons help people initiate actions, from sending an email, to sharing a document, to liking a post.

Outlined button image

Outlined buttons are medium-emphasis buttons. They contain actions that are important, but are not the primary action in an app. Outlined buttons pair well with Buttons to indicate an alternative, secondary action.

import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text

OutlinedButton(onClick = { /* Do something! */ }) { Text("Outlined Button") }

Choose the best button for an action based on the amount of emphasis it needs. The more important an action is, the higher emphasis its button should be.

The default text style for internal Text components will be set to Typography.labelLarge.

Parameters
onClick: () -> Unit

called when this button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this button

enabled: Boolean = true

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

shape: Shape = ButtonDefaults.outlinedShape

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

colors: ButtonColors = ButtonDefaults.outlinedButtonColors()

ButtonColors that will be used to resolve the colors for this button in different states. See ButtonDefaults.outlinedButtonColors.

elevation: ButtonElevation? = null

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

border: BorderStroke? = ButtonDefaults.outlinedButtonBorder

the border to draw around the container of this button. Pass null for no border.

contentPadding: PaddingValues = ButtonDefaults.ContentPadding

the spacing values to apply internally between the container and the content

interactionSource: MutableInteractionSource? = null

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

OutlinedCard

@Composable
fun OutlinedCard(
    modifier: Modifier = Modifier,
    shape: Shape = CardDefaults.outlinedShape,
    colors: CardColors = CardDefaults.outlinedCardColors(),
    elevation: CardElevation = CardDefaults.outlinedCardElevation(),
    border: BorderStroke = CardDefaults.outlinedCardBorder(),
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design outlined card.

Outlined cards contain content and actions that relate information about a subject. They have a visual boundary around the container. This can provide greater emphasis than the other types.

This OutlinedCard does not handle input events - see the other OutlinedCard overloads if you want a clickable or selectable OutlinedCard.

Outlined card image

Outlined card sample:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Text

OutlinedCard(Modifier.size(width = 180.dp, height = 100.dp)) {
    Box(Modifier.fillMaxSize()) {
        Text("Card content", Modifier.align(Alignment.Center))
    }
}
Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this card

shape: Shape = CardDefaults.outlinedShape

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

colors: CardColors = CardDefaults.outlinedCardColors()

CardColors that will be used to resolve the color(s) used for this card in different states. See CardDefaults.outlinedCardColors.

elevation: CardElevation = CardDefaults.outlinedCardElevation()

CardElevation used to resolve the elevation for this card in different states. This controls the size of the shadow below the card. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. See also: Surface.

border: BorderStroke = CardDefaults.outlinedCardBorder()

the border to draw around the container of this card

OutlinedCard

@Composable
fun OutlinedCard(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = CardDefaults.outlinedShape,
    colors: CardColors = CardDefaults.outlinedCardColors(),
    elevation: CardElevation = CardDefaults.outlinedCardElevation(),
    border: BorderStroke = CardDefaults.outlinedCardBorder(enabled),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design outlined card.

Outlined cards contain content and actions that relate information about a subject. They have a visual boundary around the container. This can provide greater emphasis than the other types.

This OutlinedCard handles click events, calling its onClick lambda.

Outlined card image

Clickable outlined card sample:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Text

OutlinedCard(
    onClick = { /* Do something */ },
    modifier = Modifier.size(width = 180.dp, height = 100.dp)
) {
    Box(Modifier.fillMaxSize()) {
        Text("Clickable", Modifier.align(Alignment.Center))
    }
}
Parameters
onClick: () -> Unit

called when this card is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this card

enabled: Boolean = true

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

shape: Shape = CardDefaults.outlinedShape

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

colors: CardColors = CardDefaults.outlinedCardColors()

CardColors that will be used to resolve the color(s) used for this card in different states. See CardDefaults.outlinedCardColors.

elevation: CardElevation = CardDefaults.outlinedCardElevation()

CardElevation used to resolve the elevation for this card in different states. This controls the size of the shadow below the card. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. See also: Surface.

border: BorderStroke = CardDefaults.outlinedCardBorder(enabled)

the border to draw around the container of this card

interactionSource: MutableInteractionSource? = null

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

OutlinedIconButton

@Composable
fun OutlinedIconButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = IconButtonDefaults.outlinedShape,
    colors: IconButtonColors = IconButtonDefaults.outlinedIconButtonColors(),
    border: BorderStroke? = IconButtonDefaults.outlinedIconButtonBorder(enabled),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material Design outlined icon button.

Icon buttons help people take supplementary actions with a single tap. They’re used when a compact button is required, such as in a toolbar or image list.

Outlined icon button image

Icon buttons help people take supplementary actions with a single tap. They’re used when a compact button is required, such as in a toolbar or image list.

Use this "contained" icon button when the component requires more visual separation from the background.

content should typically be an Icon (see androidx.compose.material.icons.Icons). If using a custom icon, note that the typical size for the internal icon is 24 x 24 dp. The outlined icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.

import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedIconButton

OutlinedIconButton(onClick = { /* doSomething() */ }) {
    Icon(Icons.Outlined.Lock, contentDescription = "Localized description")
}
Parameters
onClick: () -> Unit

called when this icon button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this icon button

enabled: Boolean = true

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

shape: Shape = IconButtonDefaults.outlinedShape

defines the shape of this icon button's container and border (when border is not null)

colors: IconButtonColors = IconButtonDefaults.outlinedIconButtonColors()

IconButtonColors that will be used to resolve the colors used for this icon button in different states. See IconButtonDefaults.outlinedIconButtonColors.

border: BorderStroke? = IconButtonDefaults.outlinedIconButtonBorder(enabled)

the border to draw around the container of this icon button. Pass null for no border. See IconButtonDefaults.outlinedIconButtonBorder.

interactionSource: MutableInteractionSource? = null

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

content: @Composable () -> Unit

the content of this icon button, typically an Icon

OutlinedIconToggleButton

@Composable
fun OutlinedIconToggleButton(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = IconButtonDefaults.outlinedShape,
    colors: IconToggleButtonColors = IconButtonDefaults.outlinedIconToggleButtonColors(),
    border: BorderStroke? = IconButtonDefaults.outlinedIconToggleButtonBorder(enabled, checked),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material Design outlined icon toggle button.

Icon buttons help people take supplementary actions with a single tap. They’re used when a compact button is required, such as in a toolbar or image list.

Outlined icon toggle button image

content should typically be an Icon (see androidx.compose.material.icons.Icons). If using a custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.

import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedIconToggleButton
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var checked by remember { mutableStateOf(false) }
OutlinedIconToggleButton(checked = checked, onCheckedChange = { checked = it }) {
    if (checked) {
        Icon(Icons.Filled.Lock, contentDescription = "Localized description")
    } else {
        Icon(Icons.Outlined.Lock, contentDescription = "Localized description")
    }
}
Parameters
checked: Boolean

whether this icon button is toggled on or off

onCheckedChange: (Boolean) -> Unit

called when this icon button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this icon button

enabled: Boolean = true

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

shape: Shape = IconButtonDefaults.outlinedShape

defines the shape of this icon button's container and border (when border is not null)

colors: IconToggleButtonColors = IconButtonDefaults.outlinedIconToggleButtonColors()

IconToggleButtonColors that will be used to resolve the colors used for this icon button in different states. See IconButtonDefaults.outlinedIconToggleButtonColors.

border: BorderStroke? = IconButtonDefaults.outlinedIconToggleButtonBorder(enabled, checked)

the border to draw around the container of this icon button. Pass null for no border. See IconButtonDefaults.outlinedIconToggleButtonBorder.

interactionSource: MutableInteractionSource? = null

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

content: @Composable () -> Unit

the content of this icon button, typically an Icon

OutlinedTextField

@Composable
fun OutlinedTextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    label: (@Composable () -> Unit)? = null,
    placeholder: (@Composable () -> Unit)? = null,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    prefix: (@Composable () -> Unit)? = null,
    suffix: (@Composable () -> Unit)? = null,
    supportingText: (@Composable () -> Unit)? = null,
    isError: Boolean = false,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    singleLine: Boolean = false,
    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
    minLines: Int = 1,
    interactionSource: MutableInteractionSource? = null,
    shape: Shape = OutlinedTextFieldDefaults.shape,
    colors: TextFieldColors = OutlinedTextFieldDefaults.colors()
): Unit

Material Design outlined text field.

Text fields allow users to enter text into a UI. They typically appear in forms and dialogs. Outlined text fields have less visual emphasis than filled text fields. When they appear in places like forms, where many text fields are placed together, their reduced emphasis helps simplify the layout.

Outlined text field image

See example usage:

import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable

var text by rememberSaveable { mutableStateOf("") }

OutlinedTextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Label") }
)

If apart from input text change you also want to observe the cursor location, selection range, or IME composition use the OutlinedTextField overload with the TextFieldValue parameter instead.

Parameters
value: String

the input text to be shown in the text field

onValueChange: (String) -> Unit

the callback that is triggered when the input service updates the text. An updated text comes as a parameter of the callback

modifier: Modifier = Modifier

the Modifier to be applied to this text field

enabled: Boolean = true

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

readOnly: Boolean = false

controls the editable state of the text field. When true, the text field cannot be modified. However, a user can focus it and copy text from it. Read-only text fields are usually used to display pre-filled forms that a user cannot edit.

textStyle: TextStyle = LocalTextStyle.current

the style to be applied to the input text. Defaults to LocalTextStyle.

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

the optional label to be displayed inside the text field container. The default text style for internal Text is Typography.bodySmall when the text field is in focus and Typography.bodyLarge when the text field is not in focus

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

the optional placeholder to be displayed when the text field is in focus and the input text is empty. The default text style for internal Text is Typography.bodyLarge

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

the optional leading icon to be displayed at the beginning of the text field container

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

the optional trailing icon to be displayed at the end of the text field container

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

the optional prefix to be displayed before the input text in the text field

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

the optional suffix to be displayed after the input text in the text field

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

the optional supporting text to be displayed below the text field

isError: Boolean = false

indicates if the text field's current value is in error. If set to true, the label, bottom indicator and trailing icon by default will be displayed in error color

visualTransformation: VisualTransformation = VisualTransformation.None

transforms the visual representation of the input value For example, you can use PasswordVisualTransformation to create a password text field. By default, no visual transformation is applied.

keyboardOptions: KeyboardOptions = KeyboardOptions.Default

software keyboard options that contains configuration such as KeyboardType and ImeAction

keyboardActions: KeyboardActions = KeyboardActions.Default

when the input service emits an IME action, the corresponding callback is called. Note that this IME action may be different from what you specified in KeyboardOptions.imeAction

singleLine: Boolean = false

when true, this text field becomes a single horizontally scrolling text field instead of wrapping onto multiple lines. The keyboard will be informed to not show the return key as the ImeAction. Note that maxLines parameter will be ignored as the maxLines attribute will be automatically set to 1.

maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE

the maximum height in terms of maximum number of visible lines. It is required that 1 <= minLines<= maxLines. This parameter is ignored when singleLine is true.

minLines: Int = 1

the minimum height in terms of minimum number of visible lines. It is required that 1 <= minLines<= maxLines. This parameter is ignored when singleLine is true.

interactionSource: MutableInteractionSource? = null

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

shape: Shape = OutlinedTextFieldDefaults.shape

defines the shape of this text field's border

colors: TextFieldColors = OutlinedTextFieldDefaults.colors()

TextFieldColors that will be used to resolve the colors used for this text field in different states. See OutlinedTextFieldDefaults.colors.

OutlinedTextField

@Composable
fun OutlinedTextField(
    value: TextFieldValue,
    onValueChange: (TextFieldValue) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    label: (@Composable () -> Unit)? = null,
    placeholder: (@Composable () -> Unit)? = null,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    prefix: (@Composable () -> Unit)? = null,
    suffix: (@Composable () -> Unit)? = null,
    supportingText: (@Composable () -> Unit)? = null,
    isError: Boolean = false,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    singleLine: Boolean = false,
    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
    minLines: Int = 1,
    interactionSource: MutableInteractionSource? = null,
    shape: Shape = OutlinedTextFieldDefaults.shape,
    colors: TextFieldColors = OutlinedTextFieldDefaults.colors()
): Unit

Material Design outlined text field.

Text fields allow users to enter text into a UI. They typically appear in forms and dialogs. Outlined text fields have less visual emphasis than filled text fields. When they appear in places like forms, where many text fields are placed together, their reduced emphasis helps simplify the layout.

Outlined text field image

See example usage:

import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.TextFieldValue

var text by rememberSaveable(stateSaver = TextFieldValue.Saver) {
    mutableStateOf(TextFieldValue("example", TextRange(0, 7)))
}

OutlinedTextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Label") }
)

This overload provides access to the input text, cursor position and selection range and IME composition. If you only want to observe an input text change, use the OutlinedTextField overload with the String parameter instead.

Parameters
value: TextFieldValue

the input TextFieldValue to be shown in the text field

onValueChange: (TextFieldValue) -> Unit

the callback that is triggered when the input service updates values in TextFieldValue. An updated TextFieldValue comes as a parameter of the callback

modifier: Modifier = Modifier

the Modifier to be applied to this text field

enabled: Boolean = true

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

readOnly: Boolean = false

controls the editable state of the text field. When true, the text field cannot be modified. However, a user can focus it and copy text from it. Read-only text fields are usually used to display pre-filled forms that a user cannot edit.

textStyle: TextStyle = LocalTextStyle.current

the style to be applied to the input text. Defaults to LocalTextStyle.

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

the optional label to be displayed inside the text field container. The default text style for internal Text is Typography.bodySmall when the text field is in focus and Typography.bodyLarge when the text field is not in focus

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

the optional placeholder to be displayed when the text field is in focus and the input text is empty. The default text style for internal Text is Typography.bodyLarge

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

the optional leading icon to be displayed at the beginning of the text field container

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

the optional trailing icon to be displayed at the end of the text field container

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

the optional prefix to be displayed before the input text in the text field

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

the optional suffix to be displayed after the input text in the text field

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

the optional supporting text to be displayed below the text field

isError: Boolean = false

indicates if the text field's current value is in error state. If set to true, the label, bottom indicator and trailing icon by default will be displayed in error color

visualTransformation: VisualTransformation = VisualTransformation.None

transforms the visual representation of the input value For example, you can use PasswordVisualTransformation to create a password text field. By default, no visual transformation is applied.

keyboardOptions: KeyboardOptions = KeyboardOptions.Default

software keyboard options that contains configuration such as KeyboardType and ImeAction

keyboardActions: KeyboardActions = KeyboardActions.Default

when the input service emits an IME action, the corresponding callback is called. Note that this IME action may be different from what you specified in KeyboardOptions.imeAction

singleLine: Boolean = false

when true, this text field becomes a single horizontally scrolling text field instead of wrapping onto multiple lines. The keyboard will be informed to not show the return key as the ImeAction. Note that maxLines parameter will be ignored as the maxLines attribute will be automatically set to 1.

maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE

the maximum height in terms of maximum number of visible lines. It is required that 1 <= minLines<= maxLines. This parameter is ignored when singleLine is true.

minLines: Int = 1

the minimum height in terms of minimum number of visible lines. It is required that 1 <= minLines<= maxLines. This parameter is ignored when singleLine is true.

interactionSource: MutableInteractionSource? = null

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

shape: Shape = OutlinedTextFieldDefaults.shape

defines the shape of this text field's border

colors: TextFieldColors = OutlinedTextFieldDefaults.colors()

TextFieldColors that will be used to resolve the colors used for this text field in different states. See OutlinedTextFieldDefaults.colors.

PermanentDrawerSheet

@Composable
fun PermanentDrawerSheet(
    modifier: Modifier = Modifier,
    drawerShape: Shape = RectangleShape,
    drawerContainerColor: Color = DrawerDefaults.standardContainerColor,
    drawerContentColor: Color = contentColorFor(drawerContainerColor),
    drawerTonalElevation: Dp = DrawerDefaults.PermanentDrawerElevation,
    windowInsets: WindowInsets = DrawerDefaults.windowInsets,
    content: @Composable ColumnScope.() -> Unit
): Unit

Content inside of a permanent navigation drawer.

Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this drawer's content

drawerShape: Shape = RectangleShape

defines the shape of this drawer's container

drawerContainerColor: Color = DrawerDefaults.standardContainerColor

the color used for the background of this drawer. Use Color.Transparent to have no color.

drawerContentColor: Color = contentColorFor(drawerContainerColor)

the preferred color for content inside this drawer. Defaults to either the matching content color for drawerContainerColor, or to the current LocalContentColor if drawerContainerColor is not a color from the theme.

drawerTonalElevation: Dp = DrawerDefaults.PermanentDrawerElevation

when drawerContainerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

windowInsets: WindowInsets = DrawerDefaults.windowInsets

a window insets for the sheet.

content: @Composable ColumnScope.() -> Unit

content inside a permanent navigation drawer

PermanentNavigationDrawer

@Composable
fun PermanentNavigationDrawer(
    drawerContent: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
): Unit

Material Design navigation permanent drawer.

Navigation drawers provide ergonomic access to destinations in an app. They’re often next to app content and affect the screen’s layout grid.

Navigation drawer image

The permanent navigation drawer is always visible and usually used for frequently switching destinations. On mobile screens, use ModalNavigationDrawer instead.

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationDrawerItem
import androidx.compose.material3.PermanentDrawerSheet
import androidx.compose.material3.PermanentNavigationDrawer
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

// icons to mimic drawer destinations
val items = listOf(Icons.Default.Favorite, Icons.Default.Face, Icons.Default.Email)
val selectedItem = remember { mutableStateOf(items[0]) }
PermanentNavigationDrawer(
    drawerContent = {
        PermanentDrawerSheet(Modifier.width(240.dp)) {
            Spacer(Modifier.height(12.dp))
            items.forEach { item ->
                NavigationDrawerItem(
                    icon = { Icon(item, contentDescription = null) },
                    label = { Text(item.name) },
                    selected = item == selectedItem.value,
                    onClick = {
                        selectedItem.value = item
                    },
                    modifier = Modifier.padding(horizontal = 12.dp)
                )
            }
        }
    },
    content = {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(text = "Application content")
        }
    }
)
Parameters
drawerContent: @Composable () -> Unit

content inside this drawer

modifier: Modifier = Modifier

the Modifier to be applied to this drawer

content: @Composable () -> Unit

content of the rest of the UI

PrimaryScrollableTabRow

@ExperimentalMaterial3Api
@Composable
fun PrimaryScrollableTabRow(
    selectedTabIndex: Int,
    modifier: Modifier = Modifier,
    scrollState: ScrollState = rememberScrollState(),
    containerColor: Color = TabRowDefaults.primaryContainerColor,
    contentColor: Color = TabRowDefaults.primaryContentColor,
    edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding,
    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions -> if (selectedTabIndex < tabPositions.size) { val width by animateDpAsState(targetValue = tabPositions[selectedTabIndex].contentWidth) TabRowDefaults.PrimaryIndicator( Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]), width = width ) } },
    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },
    tabs: @Composable () -> Unit
): Unit

Material Design Scrollable Primary tabs

Primary tabs are placed at the top of the content pane under a top app bar. They display the main content destinations. When a set of tabs cannot fit on screen, use scrollable tabs. Scrollable tabs can use longer text labels and a larger number of tabs. They are best used for browsing on touch interfaces.

A scrollable tab row contains a row of Tabs, and displays an indicator underneath the currently selected tab. A scrollable tab row places its tabs offset from the starting edge, and allows scrolling to tabs that are placed off screen. For a fixed tab row that does not allow scrolling, and evenly places its tabs, see PrimaryTabRow.

Parameters
selectedTabIndex: Int

the index of the currently selected tab

modifier: Modifier = Modifier

the Modifier to be applied to this tab row

scrollState: ScrollState = rememberScrollState()

the ScrollState of this tab row

containerColor: Color = TabRowDefaults.primaryContainerColor

the color used for the background of this tab row. Use Color.Transparent to have no color.

contentColor: Color = TabRowDefaults.primaryContentColor

the preferred color for content inside this tab row. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding

the padding between the starting and ending edge of the scrollable tab row, and the tabs inside the row. This padding helps inform the user that this tab row can be scrolled, unlike a TabRow.

indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions -> if (selectedTabIndex < tabPositions.size) { val width by animateDpAsState(targetValue = tabPositions[selectedTabIndex].contentWidth) TabRowDefaults.PrimaryIndicator( Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]), width = width ) } }

the indicator that represents which tab is currently selected. By default this will be a TabRowDefaults.PrimaryIndicator, using a TabRowDefaults.tabIndicatorOffset modifier to animate its position.

divider: @Composable () -> Unit = @Composable { HorizontalDivider() }

the divider displayed at the bottom of the tab row. This provides a layer of separation between the tab row and the content displayed underneath.

tabs: @Composable () -> Unit

the tabs inside this tab row. Typically this will be multiple Tabs. Each element inside this lambda will be measured and placed evenly across the row, each taking up equal space.

@ExperimentalMaterial3Api
@Composable
fun PrimaryTabRow(
    selectedTabIndex: Int,
    modifier: Modifier = Modifier,
    containerColor: Color = TabRowDefaults.primaryContainerColor,
    contentColor: Color = TabRowDefaults.primaryContentColor,
    indicator: @Composable TabIndicatorScope.() -> Unit = { TabRowDefaults.PrimaryIndicator( modifier = Modifier.tabIndicatorOffset( selectedTabIndex, matchContentSize = true ), width = Dp.Unspecified, ) },
    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },
    tabs: @Composable () -> Unit
): Unit

Material Design Fixed Primary tabs

Primary tabs are placed at the top of the content pane under a top app bar. They display the main content destinations. Fixed tabs display all tabs in a set simultaneously. They are best for switching between related content quickly, such as between transportation methods in a map. To navigate between fixed tabs, tap an individual tab, or swipe left or right in the content area.

A TabRow contains a row of Tabs, and displays an indicator underneath the currently selected tab. A TabRow places its tabs evenly spaced along the entire row, with each tab taking up an equal amount of space. See PrimaryScrollableTabRow for a tab row that does not enforce equal size, and allows scrolling to tabs that do not fit on screen.

A simple example with text tabs looks like:

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.PrimaryTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var state by remember { mutableStateOf(0) }
val titles = listOf("Tab 1", "Tab 2", "Tab 3 with lots of text")
Column {
    PrimaryTabRow(selectedTabIndex = state) {
        titles.forEachIndexed { index, title ->
            Tab(
                selected = state == index,
                onClick = { state = index },
                text = { Text(text = title, maxLines = 2, overflow = TextOverflow.Ellipsis) }
            )
        }
    }
    Text(
        modifier = Modifier.align(Alignment.CenterHorizontally),
        text = "Primary tab ${state + 1} selected",
        style = MaterialTheme.typography.bodyLarge
    )
}

You can also provide your own custom tab, such as:

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.SecondaryTabRow
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var state by remember { mutableStateOf(0) }
val titles = listOf("Tab 1", "Tab 2", "Tab 3")
Column {
    SecondaryTabRow(selectedTabIndex = state) {
        titles.forEachIndexed { index, title ->
            FancyTab(
                title = title,
                onClick = { state = index },
                selected = (index == state)
            )
        }
    }
    Text(
        modifier = Modifier.align(Alignment.CenterHorizontally),
        text = "Fancy tab ${state + 1} selected",
        style = MaterialTheme.typography.bodyLarge
    )
}

Where the custom tab itself could look like:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
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.material3.Tab
import androidx.compose.material3.Text

Tab(selected, onClick) {
    Column(
        Modifier
            .padding(10.dp)
            .height(50.dp)
            .fillMaxWidth(),
        verticalArrangement = Arrangement.SpaceBetween
    ) {
        Box(
            Modifier
                .size(10.dp)
                .align(Alignment.CenterHorizontally)
                .background(
                    color = if (selected) MaterialTheme.colorScheme.primary
                    else MaterialTheme.colorScheme.background
                )
        )
        Text(
            text = title,
            style = MaterialTheme.typography.bodyLarge,
            modifier = Modifier.align(Alignment.CenterHorizontally)
        )
    }
}

As well as customizing the tab, you can also provide a custom indicator, to customize the indicator displayed for a tab. indicator will be placed to fill the entire TabRow, so it should internally take care of sizing and positioning the indicator to match changes to selectedTabIndex.

For example, given an indicator that draws a rounded rectangle near the edges of the Tab:

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape

// Draws a rounded rectangular with border around the Tab, with a 5.dp padding from the edges
// Color is passed in as a parameter [color]
Box(
    modifier
        .padding(5.dp)
        .fillMaxSize()
        .border(BorderStroke(2.dp, color), RoundedCornerShape(5.dp))
)

We can reuse TabRowDefaults.tabIndicatorOffset and just provide this indicator, as we aren't changing how the size and position of the indicator changes between tabs:

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.SecondaryTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var state by remember { mutableStateOf(0) }
val titles = listOf("Tab 1", "Tab 2", "Tab 3")

Column {
    SecondaryTabRow(
        selectedTabIndex = state,
        indicator = {
            FancyIndicator(
                MaterialTheme.colorScheme.primary,
                Modifier.tabIndicatorOffset(state)
            )
        }
    ) {
        titles.forEachIndexed { index, title ->
            Tab(
                selected = state == index,
                onClick = { state = index },
                text = { Text(title) }
            )
        }
    }
    Text(
        modifier = Modifier.align(Alignment.CenterHorizontally),
        text = "Fancy indicator tab ${state + 1} selected",
        style = MaterialTheme.typography.bodyLarge
    )
}

You may also want to use a custom transition, to allow you to dynamically change the appearance of the indicator as it animates between tabs, such as changing its color or size. indicator is stacked on top of the entire TabRow, so you just need to provide a custom transition that animates the offset of the indicator from the start of the TabRow. For example, take the following example that uses a transition to animate the offset, width, and color of the same FancyIndicator from before, also adding a physics based 'spring' effect to the indicator in the direction of motion:

import androidx.compose.animation.animateColor
import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.ui.unit.IntOffset

val colors = listOf(
    MaterialTheme.colorScheme.primary,
    MaterialTheme.colorScheme.secondary,
    MaterialTheme.colorScheme.tertiary,
)
val transition = updateTransition(selectedTabIndex, label = "")
val indicatorStart by transition.animateDp(
    transitionSpec = {
        // Handle directionality here, if we are moving to the right, we
        // want the right side of the indicator to move faster, if we are
        // moving to the left, we want the left side to move faster.
        if (initialState < targetState) {
            spring(dampingRatio = 1f, stiffness = 50f)
        } else {
            spring(dampingRatio = 1f, stiffness = 1000f)
        }
    }, label = "fancy_indicator"
) {
    tabPositions[it].left
}

val indicatorEnd by transition.animateDp(
    transitionSpec = {
        // Handle directionality here, if we are moving to the right, we
        // want the right side of the indicator to move faster, if we are
        // moving to the left, we want the left side to move faster.
        if (initialState < targetState) {
            spring(dampingRatio = 1f, stiffness = 1000f)
        } else {
            spring(dampingRatio = 1f, stiffness = 50f)
        }
    }, label = "indicator_position"
) {
    tabPositions[it].right
}

val indicatorColor by transition.animateColor(label = "indicator_color") {
    colors[it % colors.size]
}

FancyIndicator(
    // Pass the current color to the indicator
    indicatorColor,
    modifier = Modifier
        // Fill up the entire TabRow, and place the indicator at the start
        .fillMaxSize()
        .wrapContentSize(align = Alignment.BottomStart)
        // Apply an offset from the start to correctly position the indicator around the tab
        .offset { IntOffset(x = indicatorStart.roundToPx(), y = 0) }
        // Make the width of the indicator follow the animated width as we move between tabs
        .width(indicatorEnd - indicatorStart)
)

We can now just pass this indicator directly to TabRow:

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.SecondaryTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var state by remember { mutableStateOf(0) }
val titles = listOf("Tab 1", "Tab 2", "Tab 3")

Column {
    SecondaryTabRow(
        selectedTabIndex = state,
        indicator = { FancyAnimatedIndicatorWithModifier(state) }
    ) {
        titles.forEachIndexed { index, title ->
            Tab(
                selected = state == index,
                onClick = { state = index },
                text = { Text(title) }
            )
        }
    }
    Text(
        modifier = Modifier.align(Alignment.CenterHorizontally),
        text = "Fancy transition tab ${state + 1} selected",
        style = MaterialTheme.typography.bodyLarge
    )
}
Parameters
selectedTabIndex: Int

the index of the currently selected tab

modifier: Modifier = Modifier

the Modifier to be applied to this tab row

containerColor: Color = TabRowDefaults.primaryContainerColor

the color used for the background of this tab row. Use Color.Transparent to have no color.

contentColor: Color = TabRowDefaults.primaryContentColor

the preferred color for content inside this tab row. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

indicator: @Composable TabIndicatorScope.() -> Unit = { TabRowDefaults.PrimaryIndicator( modifier = Modifier.tabIndicatorOffset( selectedTabIndex, matchContentSize = true ), width = Dp.Unspecified, ) }

the indicator that represents which tab is currently selected. By default this will be a TabRowDefaults.PrimaryIndicator, using a TabRowDefaults.tabIndicatorOffset modifier to animate its position.

divider: @Composable () -> Unit = @Composable { HorizontalDivider() }

the divider displayed at the bottom of the tab row. This provides a layer of separation between the tab row and the content displayed underneath.

tabs: @Composable () -> Unit

the tabs inside this tab row. Typically this will be multiple Tabs. Each element inside this lambda will be measured and placed evenly across the row, each taking up equal space.

ProvideTextStyle

@Composable
fun ProvideTextStyle(value: TextStyle, content: @Composable () -> Unit): Unit

This function is used to set the current value of LocalTextStyle, merging the given style with the current style values for any missing attributes. Any Text components included in this component's content will be styled with this style unless styled explicitly.

See also
LocalTextStyle

RadioButton

@Composable
fun RadioButton(
    selected: Boolean,
    onClick: (() -> Unit)?,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    colors: RadioButtonColors = RadioButtonDefaults.colors(),
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design radio button.

Radio buttons allow users to select one option from a set.

Radio button image

import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.material3.RadioButton
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

// We have two radio buttons and only one can be selected
var state by remember { mutableStateOf(true) }
// Note that Modifier.selectableGroup() is essential to ensure correct accessibility behavior.
// We also set a content description for this sample, but note that a RadioButton would usually
// be part of a higher level component, such as a raw with text, and that component would need
// to provide an appropriate content description. See RadioGroupSample.
Row(Modifier.selectableGroup()) {
    RadioButton(
        selected = state,
        onClick = { state = true },
        modifier = Modifier.semantics { contentDescription = "Localized Description" }
    )
    RadioButton(
        selected = !state,
        onClick = { state = false },
        modifier = Modifier.semantics { contentDescription = "Localized Description" }
    )
}

RadioButtons can be combined together with Text in the desired layout (e.g. Column or Row) to achieve radio group-like behaviour, where the entire layout is selectable:

import androidx.compose.foundation.layout.Column
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.selection.selectable
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val radioOptions = listOf("Calls", "Missed", "Friends")
val (selectedOption, onOptionSelected) = remember { mutableStateOf(radioOptions[0]) }
// Note that Modifier.selectableGroup() is essential to ensure correct accessibility behavior
Column(Modifier.selectableGroup()) {
    radioOptions.forEach { text ->
        Row(
            Modifier
                .fillMaxWidth()
                .height(56.dp)
                .selectable(
                    selected = (text == selectedOption),
                    onClick = { onOptionSelected(text) },
                    role = Role.RadioButton
                )
                .padding(horizontal = 16.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            RadioButton(
                selected = (text == selectedOption),
                onClick = null // null recommended for accessibility with screenreaders
            )
            Text(
                text = text,
                style = MaterialTheme.typography.bodyLarge,
                modifier = Modifier.padding(start = 16.dp)
            )
        }
    }
}
Parameters
selected: Boolean

whether this radio button is selected or not

onClick: (() -> Unit)?

called when this radio button is clicked. If null, then this radio button will not be interactable, unless something else handles its input events and updates its state.

modifier: Modifier = Modifier

the Modifier to be applied to this radio button

enabled: Boolean = true

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

colors: RadioButtonColors = RadioButtonDefaults.colors()

RadioButtonColors that will be used to resolve the color used for this radio button in different states. See RadioButtonDefaults.colors.

interactionSource: MutableInteractionSource? = null

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

RangeSlider

@Composable
fun RangeSlider(
    value: ClosedFloatingPointRange<Float>,
    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
    steps: @IntRange(from = 0) Int = 0,
    onValueChangeFinished: (() -> Unit)? = null,
    colors: SliderColors = SliderDefaults.colors()
): Unit

Material Design Range slider.

Range Sliders expand upon Slider using the same concepts but allow the user to select 2 values.

The two values are still bounded by the value range but they also cannot cross each other.

Use continuous Range Sliders to allow users to make meaningful selections that don’t require a specific values:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.RangeSlider
import androidx.compose.material3.RangeSliderState
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

val rangeSliderState = remember {
    RangeSliderState(
        0f,
        100f,
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        }
    )
}
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    val rangeStart = "%.2f".format(rangeSliderState.activeRangeStart)
    val rangeEnd = "%.2f".format(rangeSliderState.activeRangeEnd)
    Text(text = "$rangeStart .. $rangeEnd")
    RangeSlider(
        state = rangeSliderState,
        modifier = Modifier.semantics { contentDescription = "Localized Description" }
    )
}

You can allow the user to choose only between predefined set of values by specifying the amount of steps between min and max values:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.RangeSlider
import androidx.compose.material3.RangeSliderState
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

val rangeSliderState = remember {
    RangeSliderState(
        0f,
        100f,
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        },
        steps = 4
    )
}
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    val rangeStart = rangeSliderState.activeRangeStart.roundToInt()
    val rangeEnd = rangeSliderState.activeRangeEnd.roundToInt()
    Text(text = "$rangeStart .. $rangeEnd")
    RangeSlider(
        state = rangeSliderState,
        modifier = Modifier.semantics { contentDescription = "Localized Description" }
    )
}
Parameters
value: ClosedFloatingPointRange<Float>

current values of the RangeSlider. If either value is outside of valueRange provided, it will be coerced to this range.

onValueChange: (ClosedFloatingPointRange<Float>) -> Unit

lambda in which values should be updated

modifier: Modifier = Modifier

modifiers for the Range Slider layout

enabled: Boolean = true

whether or not component is enabled and can we interacted with or not

valueRange: ClosedFloatingPointRange<Float> = 0f..1f

range of values that Range Slider values can take. Passed value will be coerced to this range

steps: @IntRange(from = 0) Int = 0

if greater than 0, specifies the amounts of discrete values, evenly distributed between across the whole value range. If 0, range slider will behave as a continuous slider and allow to choose any value from the range specified. Must not be negative.

onValueChangeFinished: (() -> Unit)? = null

lambda to be invoked when value change has ended. This callback shouldn't be used to update the range slider values (use onValueChange for that), but rather to know when the user has completed selecting a new value by ending a drag or a click.

colors: SliderColors = SliderDefaults.colors()

SliderColors that will be used to determine the color of the Range Slider parts in different state. See SliderDefaults.colors to customize.

RangeSlider

@Composable
@ExperimentalMaterial3Api
fun RangeSlider(
    state: RangeSliderState,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    colors: SliderColors = SliderDefaults.colors(),
    startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    startThumb: @Composable (RangeSliderState) -> Unit = { SliderDefaults.Thumb( interactionSource = startInteractionSource, colors = colors, enabled = enabled ) },
    endThumb: @Composable (RangeSliderState) -> Unit = { SliderDefaults.Thumb( interactionSource = endInteractionSource, colors = colors, enabled = enabled ) },
    track: @Composable (RangeSliderState) -> Unit = { rangeSliderState -> SliderDefaults.Track( colors = colors, enabled = enabled, rangeSliderState = rangeSliderState ) }
): Unit

Material Design Range slider.

Range Sliders expand upon Slider using the same concepts but allow the user to select 2 values.

The two values are still bounded by the value range but they also cannot cross each other.

It uses the provided startThumb for the slider's start thumb and endThumb for the slider's end thumb. It also uses the provided track for the slider's track. If nothing is passed for these parameters, it will use SliderDefaults.Thumb and SliderDefaults.Track for the thumbs and track.

Use continuous Range Sliders to allow users to make meaningful selections that don’t require a specific values:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.RangeSlider
import androidx.compose.material3.RangeSliderState
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

val rangeSliderState = remember {
    RangeSliderState(
        0f,
        100f,
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        }
    )
}
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    val rangeStart = "%.2f".format(rangeSliderState.activeRangeStart)
    val rangeEnd = "%.2f".format(rangeSliderState.activeRangeEnd)
    Text(text = "$rangeStart .. $rangeEnd")
    RangeSlider(
        state = rangeSliderState,
        modifier = Modifier.semantics { contentDescription = "Localized Description" }
    )
}

You can allow the user to choose only between predefined set of values by specifying the amount of steps between min and max values:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.RangeSlider
import androidx.compose.material3.RangeSliderState
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

val rangeSliderState = remember {
    RangeSliderState(
        0f,
        100f,
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        },
        steps = 4
    )
}
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    val rangeStart = rangeSliderState.activeRangeStart.roundToInt()
    val rangeEnd = rangeSliderState.activeRangeEnd.roundToInt()
    Text(text = "$rangeStart .. $rangeEnd")
    RangeSlider(
        state = rangeSliderState,
        modifier = Modifier.semantics { contentDescription = "Localized Description" }
    )
}

A custom start/end thumb and track can be provided:

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.Label
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.RangeSlider
import androidx.compose.material3.RangeSliderState
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

val rangeSliderState = remember {
    RangeSliderState(
        0f,
        100f,
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        }
    )
}
val startInteractionSource = remember { MutableInteractionSource() }
val endInteractionSource = remember { MutableInteractionSource() }
val startThumbAndTrackColors = SliderDefaults.colors(
    thumbColor = Color.Blue,
    activeTrackColor = Color.Red
)
val endThumbColors = SliderDefaults.colors(thumbColor = Color.Green)
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    RangeSlider(
        state = rangeSliderState,
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        startInteractionSource = startInteractionSource,
        endInteractionSource = endInteractionSource,
        startThumb = {
            Label(
                label = {
                    PlainTooltip(
                        modifier = Modifier
                            .requiredSize(45.dp, 25.dp)
                            .wrapContentWidth()
                    ) {
                        Text("%.2f".format(rangeSliderState.activeRangeStart))
                    }
                },
                interactionSource = startInteractionSource
            ) {
                SliderDefaults.Thumb(
                    interactionSource = startInteractionSource,
                    colors = startThumbAndTrackColors
                )
            }
        },
        endThumb = {
            Label(
                label = {
                    PlainTooltip(
                        modifier = Modifier
                            .requiredSize(45.dp, 25.dp)
                            .wrapContentWidth()
                    ) {
                        Text("%.2f".format(rangeSliderState.activeRangeEnd))
                    }
                },
                interactionSource = endInteractionSource
            ) {
                SliderDefaults.Thumb(
                    interactionSource = endInteractionSource,
                    colors = endThumbColors
                )
            }
        },
        track = { rangeSliderState ->
            SliderDefaults.Track(
                colors = startThumbAndTrackColors,
                rangeSliderState = rangeSliderState
            )
        }
    )
}
Parameters
state: RangeSliderState

RangeSliderState which contains the current values of the RangeSlider.

modifier: Modifier = Modifier

modifiers for the Range Slider layout

enabled: Boolean = true

whether or not component is enabled and can we interacted with or not

colors: SliderColors = SliderDefaults.colors()

SliderColors that will be used to determine the color of the Range Slider parts in different state. See SliderDefaults.colors to customize.

startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() }

the MutableInteractionSource representing the stream of Interactions for the start thumb. You can create and pass in your own remembered instance to observe.

endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() }

the MutableInteractionSource representing the stream of Interactions for the end thumb. You can create and pass in your own remembered instance to observe.

startThumb: @Composable (RangeSliderState) -> Unit = { SliderDefaults.Thumb( interactionSource = startInteractionSource, colors = colors, enabled = enabled ) }

the start thumb to be displayed on the Range Slider. The lambda receives a RangeSliderState which is used to obtain the current active track.

endThumb: @Composable (RangeSliderState) -> Unit = { SliderDefaults.Thumb( interactionSource = endInteractionSource, colors = colors, enabled = enabled ) }

the end thumb to be displayed on the Range Slider. The lambda receives a RangeSliderState which is used to obtain the current active track.

track: @Composable (RangeSliderState) -> Unit = { rangeSliderState -> SliderDefaults.Track( colors = colors, enabled = enabled, rangeSliderState = rangeSliderState ) }

the track to be displayed on the range slider, it is placed underneath the thumb. The lambda receives a RangeSliderState which is used to obtain the current active track.

RangeSlider

@Composable
@ExperimentalMaterial3Api
fun RangeSlider(
    value: ClosedFloatingPointRange<Float>,
    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
    onValueChangeFinished: (() -> Unit)? = null,
    colors: SliderColors = SliderDefaults.colors(),
    startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    startThumb: @Composable (RangeSliderState) -> Unit = { SliderDefaults.Thumb( interactionSource = startInteractionSource, colors = colors, enabled = enabled ) },
    endThumb: @Composable (RangeSliderState) -> Unit = { SliderDefaults.Thumb( interactionSource = endInteractionSource, colors = colors, enabled = enabled ) },
    track: @Composable (RangeSliderState) -> Unit = { rangeSliderState -> SliderDefaults.Track( colors = colors, enabled = enabled, rangeSliderState = rangeSliderState ) },
    steps: @IntRange(from = 0) Int = 0
): Unit

Material Design Range slider.

Range Sliders expand upon Slider using the same concepts but allow the user to select 2 values.

The two values are still bounded by the value range but they also cannot cross each other.

It uses the provided startThumb for the slider's start thumb and endThumb for the slider's end thumb. It also uses the provided track for the slider's track. If nothing is passed for these parameters, it will use SliderDefaults.Thumb and SliderDefaults.Track for the thumbs and track.

Use continuous Range Sliders to allow users to make meaningful selections that don’t require a specific values:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.RangeSlider
import androidx.compose.material3.RangeSliderState
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

val rangeSliderState = remember {
    RangeSliderState(
        0f,
        100f,
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        }
    )
}
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    val rangeStart = "%.2f".format(rangeSliderState.activeRangeStart)
    val rangeEnd = "%.2f".format(rangeSliderState.activeRangeEnd)
    Text(text = "$rangeStart .. $rangeEnd")
    RangeSlider(
        state = rangeSliderState,
        modifier = Modifier.semantics { contentDescription = "Localized Description" }
    )
}

You can allow the user to choose only between predefined set of values by specifying the amount of steps between min and max values:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.RangeSlider
import androidx.compose.material3.RangeSliderState
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

val rangeSliderState = remember {
    RangeSliderState(
        0f,
        100f,
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        },
        steps = 4
    )
}
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    val rangeStart = rangeSliderState.activeRangeStart.roundToInt()
    val rangeEnd = rangeSliderState.activeRangeEnd.roundToInt()
    Text(text = "$rangeStart .. $rangeEnd")
    RangeSlider(
        state = rangeSliderState,
        modifier = Modifier.semantics { contentDescription = "Localized Description" }
    )
}

A custom start/end thumb and track can be provided:

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.Label
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.RangeSlider
import androidx.compose.material3.RangeSliderState
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

val rangeSliderState = remember {
    RangeSliderState(
        0f,
        100f,
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        }
    )
}
val startInteractionSource = remember { MutableInteractionSource() }
val endInteractionSource = remember { MutableInteractionSource() }
val startThumbAndTrackColors = SliderDefaults.colors(
    thumbColor = Color.Blue,
    activeTrackColor = Color.Red
)
val endThumbColors = SliderDefaults.colors(thumbColor = Color.Green)
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    RangeSlider(
        state = rangeSliderState,
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        startInteractionSource = startInteractionSource,
        endInteractionSource = endInteractionSource,
        startThumb = {
            Label(
                label = {
                    PlainTooltip(
                        modifier = Modifier
                            .requiredSize(45.dp, 25.dp)
                            .wrapContentWidth()
                    ) {
                        Text("%.2f".format(rangeSliderState.activeRangeStart))
                    }
                },
                interactionSource = startInteractionSource
            ) {
                SliderDefaults.Thumb(
                    interactionSource = startInteractionSource,
                    colors = startThumbAndTrackColors
                )
            }
        },
        endThumb = {
            Label(
                label = {
                    PlainTooltip(
                        modifier = Modifier
                            .requiredSize(45.dp, 25.dp)
                            .wrapContentWidth()
                    ) {
                        Text("%.2f".format(rangeSliderState.activeRangeEnd))
                    }
                },
                interactionSource = endInteractionSource
            ) {
                SliderDefaults.Thumb(
                    interactionSource = endInteractionSource,
                    colors = endThumbColors
                )
            }
        },
        track = { rangeSliderState ->
            SliderDefaults.Track(
                colors = startThumbAndTrackColors,
                rangeSliderState = rangeSliderState
            )
        }
    )
}
Parameters
value: ClosedFloatingPointRange<Float>

current values of the RangeSlider. If either value is outside of valueRange provided, it will be coerced to this range.

onValueChange: (ClosedFloatingPointRange<Float>) -> Unit

lambda in which values should be updated

modifier: Modifier = Modifier

modifiers for the Range Slider layout

enabled: Boolean = true

whether or not component is enabled and can we interacted with or not

valueRange: ClosedFloatingPointRange<Float> = 0f..1f

range of values that Range Slider values can take. Passed value will be coerced to this range.

onValueChangeFinished: (() -> Unit)? = null

lambda to be invoked when value change has ended. This callback shouldn't be used to update the range slider values (use onValueChange for that), but rather to know when the user has completed selecting a new value by ending a drag or a click.

colors: SliderColors = SliderDefaults.colors()

SliderColors that will be used to determine the color of the Range Slider parts in different state. See SliderDefaults.colors to customize.

startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() }

the MutableInteractionSource representing the stream of Interactions for the start thumb. You can create and pass in your own remembered instance to observe.

endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() }

the MutableInteractionSource representing the stream of Interactions for the end thumb. You can create and pass in your own remembered instance to observe.

startThumb: @Composable (RangeSliderState) -> Unit = { SliderDefaults.Thumb( interactionSource = startInteractionSource, colors = colors, enabled = enabled ) }

the start thumb to be displayed on the Range Slider. The lambda receives a RangeSliderState which is used to obtain the current active track.

endThumb: @Composable (RangeSliderState) -> Unit = { SliderDefaults.Thumb( interactionSource = endInteractionSource, colors = colors, enabled = enabled ) }

the end thumb to be displayed on the Range Slider. The lambda receives a RangeSliderState which is used to obtain the current active track.

track: @Composable (RangeSliderState) -> Unit = { rangeSliderState -> SliderDefaults.Track( colors = colors, enabled = enabled, rangeSliderState = rangeSliderState ) }

the track to be displayed on the range slider, it is placed underneath the thumb. The lambda receives a RangeSliderState which is used to obtain the current active track.

steps: @IntRange(from = 0) Int = 0

if greater than 0, specifies the amounts of discrete values, evenly distributed between across the whole value range. If 0, range slider will behave as a continuous slider and allow to choose any value from the range specified. Must not be negative.

@Composable
fun Scaffold(
    modifier: Modifier = Modifier,
    topBar: @Composable () -> Unit = {},
    bottomBar: @Composable () -> Unit = {},
    snackbarHost: @Composable () -> Unit = {},
    floatingActionButton: @Composable () -> Unit = {},
    floatingActionButtonPosition: FabPosition = FabPosition.End,
    containerColor: Color = MaterialTheme.colorScheme.background,
    contentColor: Color = contentColorFor(containerColor),
    contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets,
    content: @Composable (PaddingValues) -> Unit
): Unit

Material Design layout.

Scaffold implements the basic material design visual layout structure.

This component provides API to put together several material components to construct your screen, by ensuring proper layout strategy for them and collecting necessary data so these components will work together correctly.

Simple example of a Scaffold with SmallTopAppBar, FloatingActionButton:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.ui.graphics.Color

val colors = listOf(
    Color(0xFFffd7d7.toInt()),
    Color(0xFFffe9d6.toInt()),
    Color(0xFFfffbd0.toInt()),
    Color(0xFFe3ffd9.toInt()),
    Color(0xFFd0fff8.toInt())
)

Scaffold(
    topBar = {
        TopAppBar(
            title = { Text("Simple Scaffold Screen") },
            navigationIcon = {
                IconButton(
                    onClick = { /* "Open nav drawer" */ }
                ) {
                    Icon(Icons.Filled.Menu, contentDescription = "Localized description")
                }
            }
        )
    },
    floatingActionButtonPosition = FabPosition.End,
    floatingActionButton = {
        ExtendedFloatingActionButton(
            onClick = { /* fab click handler */ }
        ) {
            Text("Inc")
        }
    },
    content = { innerPadding ->
        LazyColumn(
            // consume insets as scaffold doesn't do it by default
            modifier = Modifier.consumeWindowInsets(innerPadding),
            contentPadding = innerPadding
        ) {
            items(count = 100) {
                Box(
                    Modifier
                        .fillMaxWidth()
                        .height(50.dp)
                        .background(colors[it % colors.size])
                )
            }
        }
    }
)

To show a Snackbar, use SnackbarHostState.showSnackbar.

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    floatingActionButton = {
        var clickCount by remember { mutableStateOf(0) }
        ExtendedFloatingActionButton(
            onClick = {
                // show snackbar as a suspend function
                scope.launch {
                    snackbarHostState.showSnackbar(
                        "Snackbar # ${++clickCount}"
                    )
                }
            }
        ) { Text("Show snackbar") }
    },
    content = { innerPadding ->
        Text(
            text = "Body content",
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize()
                .wrapContentSize()
        )
    }
)
Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this scaffold

topBar: @Composable () -> Unit = {}

top app bar of the screen, typically a SmallTopAppBar

bottomBar: @Composable () -> Unit = {}

bottom bar of the screen, typically a NavigationBar

snackbarHost: @Composable () -> Unit = {}

component to host Snackbars that are pushed to be shown via SnackbarHostState.showSnackbar, typically a SnackbarHost

floatingActionButton: @Composable () -> Unit = {}

Main action button of the screen, typically a FloatingActionButton

floatingActionButtonPosition: FabPosition = FabPosition.End

position of the FAB on the screen. See FabPosition.

containerColor: Color = MaterialTheme.colorScheme.background

the color used for the background of this scaffold. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this scaffold. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets

window insets to be passed to content slot via PaddingValues params. Scaffold will take the insets into account from the top/bottom only if the topBar/ bottomBar are not present, as the scaffold expect topBar/bottomBar to handle insets instead. Any insets consumed by other insets padding modifiers or consumeWindowInsets on a parent layout will be excluded from contentWindowInsets.

content: @Composable (PaddingValues) -> Unit

content of the screen. The lambda receives a PaddingValues that should be applied to the content root via Modifier.padding and Modifier.consumeWindowInsets to properly offset top and bottom bars. If using Modifier.verticalScroll, apply this modifier to the child of the scroll, and not on the scroll itself.

ScrollableTabRow

@Composable
fun ScrollableTabRow(
    selectedTabIndex: Int,
    modifier: Modifier = Modifier,
    containerColor: Color = TabRowDefaults.primaryContainerColor,
    contentColor: Color = TabRowDefaults.primaryContentColor,
    edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding,
    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions -> TabRowDefaults.SecondaryIndicator( Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]) ) },
    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },
    tabs: @Composable () -> Unit
): Unit

Material Design tabs

Material Design scrollable tabs.

For primary indicator tabs, use PrimaryScrollableTabRow. For secondary indicator tabs, use SecondaryScrollableTabRow.

When a set of tabs cannot fit on screen, use scrollable tabs. Scrollable tabs can use longer text labels and a larger number of tabs. They are best used for browsing on touch interfaces.

A ScrollableTabRow contains a row of Tabs, and displays an indicator underneath the currently selected tab. A ScrollableTabRow places its tabs offset from the starting edge, and allows scrolling to tabs that are placed off screen. For a fixed tab row that does not allow scrolling, and evenly places its tabs, see TabRow.

Parameters
selectedTabIndex: Int

the index of the currently selected tab

modifier: Modifier = Modifier

the Modifier to be applied to this tab row

containerColor: Color = TabRowDefaults.primaryContainerColor

the color used for the background of this tab row. Use Color.Transparent to have no color.

contentColor: Color = TabRowDefaults.primaryContentColor

the preferred color for content inside this tab row. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding

the padding between the starting and ending edge of the scrollable tab row, and the tabs inside the row. This padding helps inform the user that this tab row can be scrolled, unlike a TabRow.

indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions -> TabRowDefaults.SecondaryIndicator( Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]) ) }

the indicator that represents which tab is currently selected. By default this will be a TabRowDefaults.SecondaryIndicator, using a TabRowDefaults.tabIndicatorOffset modifier to animate its position. Note that this indicator will be forced to fill up the entire tab row, so you should use TabRowDefaults.tabIndicatorOffset or similar to animate the actual drawn indicator inside this space, and provide an offset from the start.

divider: @Composable () -> Unit = @Composable { HorizontalDivider() }

the divider displayed at the bottom of the tab row. This provides a layer of separation between the tab row and the content displayed underneath.

tabs: @Composable () -> Unit

the tabs inside this tab row. Typically this will be multiple Tabs. Each element inside this lambda will be measured and placed evenly across the row, each taking up equal space.

@ExperimentalMaterial3Api
@Composable
fun SearchBar(
    query: String,
    onQueryChange: (String) -> Unit,
    onSearch: (String) -> Unit,
    active: Boolean,
    onActiveChange: (Boolean) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    placeholder: (@Composable () -> Unit)? = null,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    shape: Shape = SearchBarDefaults.inputFieldShape,
    colors: SearchBarColors = SearchBarDefaults.colors(),
    tonalElevation: Dp = SearchBarDefaults.TonalElevation,
    shadowElevation: Dp = SearchBarDefaults.ShadowElevation,
    windowInsets: WindowInsets = SearchBarDefaults.windowInsets,
    interactionSource: MutableInteractionSource? = null,
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design search.

A search bar represents a floating search field that allows users to enter a keyword or phrase and get relevant information. It can be used as a way to navigate through an app via search queries.

An active search bar expands into a search "view" and can be used to display dynamic suggestions.

Search bar image

A SearchBar expands to occupy the entirety of its allowed size when active. For full-screen behavior as specified by Material guidelines, parent layouts of the SearchBar must not pass any Constraints that limit its size, and the host activity should set WindowCompat.setDecorFitsSystemWindows(window, false).

If this expansion behavior is undesirable, for example on large tablet screens, DockedSearchBar can be used instead.

An example looks like:

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.SearchBar
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.semantics.semantics

var text by rememberSaveable { mutableStateOf("") }
var active by rememberSaveable { mutableStateOf(false) }

Box(Modifier.fillMaxSize().semantics { isTraversalGroup = true }) {
    SearchBar(
        modifier = Modifier
            .align(Alignment.TopCenter)
            .semantics { traversalIndex = -1f },
        query = text,
        onQueryChange = { text = it },
        onSearch = { active = false },
        active = active,
        onActiveChange = {
            active = it
        },
        placeholder = { Text("Hinted search text") },
        leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) },
        trailingIcon = { Icon(Icons.Default.MoreVert, contentDescription = null) },
    ) {
        repeat(4) { idx ->
            val resultText = "Suggestion $idx"
            ListItem(
                headlineContent = { Text(resultText) },
                supportingContent = { Text("Additional info") },
                leadingContent = { Icon(Icons.Filled.Star, contentDescription = null) },
                modifier = Modifier
                    .clickable {
                        text = resultText
                        active = false
                    }
                    .fillMaxWidth()
                    .padding(horizontal = 16.dp, vertical = 4.dp)
            )
        }
    }

    LazyColumn(
        contentPadding = PaddingValues(start = 16.dp, top = 72.dp, end = 16.dp, bottom = 16.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        val list = List(100) { "Text $it" }
        items(count = list.size) {
            Text(list[it], Modifier.fillMaxWidth().padding(horizontal = 16.dp))
        }
    }
}
Parameters
query: String

the query text to be shown in the search bar's input field

onQueryChange: (String) -> Unit

the callback to be invoked when the input service updates the query. An updated text comes as a parameter of the callback.

onSearch: (String) -> Unit

the callback to be invoked when the input service triggers the ImeAction.Search action. The current query comes as a parameter of the callback.

active: Boolean

whether this search bar is active

onActiveChange: (Boolean) -> Unit

the callback to be invoked when this search bar's active state is changed

modifier: Modifier = Modifier

the Modifier to be applied to this search bar

enabled: Boolean = true

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

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

the placeholder to be displayed when the search bar's query is empty.

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

the leading icon to be displayed at the beginning of the search bar container

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

the trailing icon to be displayed at the end of the search bar container

shape: Shape = SearchBarDefaults.inputFieldShape

the shape of this search bar when it is not active. When active, the shape will always be SearchBarDefaults.fullScreenShape.

colors: SearchBarColors = SearchBarDefaults.colors()

SearchBarColors that will be used to resolve the colors used for this search bar in different states. See SearchBarDefaults.colors.

tonalElevation: Dp = SearchBarDefaults.TonalElevation

when SearchBarColors.containerColor is ColorScheme.surface, a translucent primary color overlay is applied on top of the container. A higher tonal elevation value will result in a darker color in light theme and lighter color in dark theme. See also: Surface.

shadowElevation: Dp = SearchBarDefaults.ShadowElevation

the elevation for the shadow below the search bar

windowInsets: WindowInsets = SearchBarDefaults.windowInsets

the window insets that the search bar will respect

interactionSource: MutableInteractionSource? = null

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

content: @Composable ColumnScope.() -> Unit

the content of this search bar that will be displayed below the input field

SecondaryScrollableTabRow

@ExperimentalMaterial3Api
@Composable
fun SecondaryScrollableTabRow(
    selectedTabIndex: Int,
    modifier: Modifier = Modifier,
    scrollState: ScrollState = rememberScrollState(),
    containerColor: Color = TabRowDefaults.secondaryContainerColor,
    contentColor: Color = TabRowDefaults.secondaryContentColor,
    edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding,
    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions -> TabRowDefaults.SecondaryIndicator( Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]) ) },
    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },
    tabs: @Composable () -> Unit
): Unit

Material Design Scrollable Secondary tabs

Material Design scrollable tabs.

Secondary tabs are used within a content area to further separate related content and establish hierarchy. When a set of tabs cannot fit on screen, use scrollable tabs. Scrollable tabs can use longer text labels and a larger number of tabs. They are best used for browsing on touch interfaces.

A scrollabel tab row contains a row of Tabs, and displays an indicator underneath the currently selected tab. A scrollable tab row places its tabs offset from the starting edge, and allows scrolling to tabs that are placed off screen. For a fixed tab row that does not allow scrolling, and evenly places its tabs, see SecondaryTabRow.

Parameters
selectedTabIndex: Int

the index of the currently selected tab

modifier: Modifier = Modifier

the Modifier to be applied to this tab row

scrollState: ScrollState = rememberScrollState()

the ScrollState of this tab row

containerColor: Color = TabRowDefaults.secondaryContainerColor

the color used for the background of this tab row. Use Color.Transparent to have no color.

contentColor: Color = TabRowDefaults.secondaryContentColor

the preferred color for content inside this tab row. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding

the padding between the starting and ending edge of the scrollable tab row, and the tabs inside the row. This padding helps inform the user that this tab row can be scrolled, unlike a TabRow.

indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions -> TabRowDefaults.SecondaryIndicator( Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]) ) }

the indicator that represents which tab is currently selected. By default this will be a TabRowDefaults.SecondaryIndicator, using a TabRowDefaults.tabIndicatorOffset modifier to animate its position. Note that this indicator will be forced to fill up the entire tab row, so you should use TabRowDefaults.tabIndicatorOffset or similar to animate the actual drawn indicator inside this space, and provide an offset from the start.

divider: @Composable () -> Unit = @Composable { HorizontalDivider() }

the divider displayed at the bottom of the tab row. This provides a layer of separation between the tab row and the content displayed underneath.

tabs: @Composable () -> Unit

the tabs inside this tab row. Typically this will be multiple Tabs. Each element inside this lambda will be measured and placed evenly across the row, each taking up equal space.

SecondaryTabRow

@ExperimentalMaterial3Api
@Composable
fun SecondaryTabRow(
    selectedTabIndex: Int,
    modifier: Modifier = Modifier,
    containerColor: Color = TabRowDefaults.secondaryContainerColor,
    contentColor: Color = TabRowDefaults.secondaryContentColor,
    indicator: @Composable TabIndicatorScope.() -> Unit = @Composable { TabRowDefaults.SecondaryIndicator( Modifier.tabIndicatorOffset(selectedTabIndex, matchContentSize = false) ) },
    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },
    tabs: @Composable () -> Unit
): Unit

Material Design Fixed Secondary tabs

Secondary tabs are used within a content area to further separate related content and establish hierarchy. Fixed tabs display all tabs in a set simultaneously. To navigate between fixed tabs, tap an individual tab, or swipe left or right in the content area.

A TabRow contains a row of Tabs, and displays an indicator underneath the currently selected tab. A Fixed TabRow places its tabs evenly spaced along the entire row, with each tab taking up an equal amount of space. See SecondaryScrollableTabRow for a tab row that does not enforce equal size, and allows scrolling to tabs that do not fit on screen.

A simple example with text tabs looks like:

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.SecondaryTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var state by remember { mutableStateOf(0) }
val titles = listOf("Tab 1", "Tab 2", "Tab 3 with lots of text")
Column {
    SecondaryTabRow(selectedTabIndex = state) {
        titles.forEachIndexed { index, title ->
            Tab(
                selected = state == index,
                onClick = { state = index },
                text = { Text(text = title, maxLines = 2, overflow = TextOverflow.Ellipsis) }
            )
        }
    }
    Text(
        modifier = Modifier.align(Alignment.CenterHorizontally),
        text = "Secondary tab ${state + 1} selected",
        style = MaterialTheme.typography.bodyLarge
    )
}
Parameters
selectedTabIndex: Int

the index of the currently selected tab

modifier: Modifier = Modifier

the Modifier to be applied to this tab row

containerColor: Color = TabRowDefaults.secondaryContainerColor

the color used for the background of this tab row. Use Color.Transparent to have no color.

contentColor: Color = TabRowDefaults.secondaryContentColor

the preferred color for content inside this tab row. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

indicator: @Composable TabIndicatorScope.() -> Unit = @Composable { TabRowDefaults.SecondaryIndicator( Modifier.tabIndicatorOffset(selectedTabIndex, matchContentSize = false) ) }

the indicator that represents which tab is currently selected. By default this will be a TabRowDefaults.SecondaryIndicator, using a TabRowDefaults.tabIndicatorOffset modifier to animate its position. Note that this indicator will be forced to fill up the entire tab row, so you should use TabRowDefaults.tabIndicatorOffset or similar to animate the actual drawn indicator inside this space, and provide an offset from the start.

divider: @Composable () -> Unit = @Composable { HorizontalDivider() }

the divider displayed at the bottom of the tab row. This provides a layer of separation between the tab row and the content displayed underneath.

tabs: @Composable () -> Unit

the tabs inside this tab row. Typically this will be multiple Tabs. Each element inside this lambda will be measured and placed evenly across the row, each taking up equal space.

SingleChoiceSegmentedButtonRow

@Composable
@ExperimentalMaterial3Api
fun SingleChoiceSegmentedButtonRow(
    modifier: Modifier = Modifier,
    space: Dp = SegmentedButtonDefaults.BorderWidth,
    content: @Composable SingleChoiceSegmentedButtonRowScope.() -> Unit
): Unit

Material Segmented Button.

A Layout to correctly position and size SegmentedButtons in a Row. It handles overlapping items so that strokes of the item are correctly on top of each other. SingleChoiceSegmentedButtonRow is used when the selection only allows one value, for correct semantics.

import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var selectedIndex by remember { mutableStateOf(0) }
val options = listOf("Day", "Month", "Week")
SingleChoiceSegmentedButtonRow {
    options.forEachIndexed { index, label ->
        SegmentedButton(
            shape = SegmentedButtonDefaults.itemShape(index = index, count = options.size),
            onClick = { selectedIndex = index },
            selected = index == selectedIndex
        ) {
            Text(label)
        }
    }
}
Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this row

space: Dp = SegmentedButtonDefaults.BorderWidth

the dimension of the overlap between buttons. Should be equal to the stroke width used on the items.

content: @Composable SingleChoiceSegmentedButtonRowScope.() -> Unit

the content of this Segmented Button Row, typically a sequence of SegmentedButtons

@Composable
@ExperimentalMaterial3Api
fun Slider(
    state: SliderState,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    colors: SliderColors = SliderDefaults.colors(),
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    thumb: @Composable (SliderState) -> Unit = { SliderDefaults.Thumb( interactionSource = interactionSource, colors = colors, enabled = enabled ) },
    track: @Composable (SliderState) -> Unit = { sliderState -> SliderDefaults.Track( colors = colors, enabled = enabled, sliderState = sliderState ) }
): Unit

Material Design slider.

Sliders allow users to make selections from a range of values.

Sliders reflect a range of values along a bar, from which users may select a single value. They are ideal for adjusting settings such as volume, brightness, or applying image filters.

Sliders image

Use continuous sliders to allow users to make meaningful selections that don’t require a specific value:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var sliderPosition by remember { mutableStateOf(0f) }
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    Text(text = "%.2f".format(sliderPosition))
    Slider(
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        value = sliderPosition,
        onValueChange = { sliderPosition = it })
}

You can allow the user to choose only between predefined set of values by specifying the amount of steps between min and max values:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var sliderPosition by remember { mutableStateOf(0f) }
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    Text(text = sliderPosition.roundToInt().toString())
    Slider(
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        value = sliderPosition,
        onValueChange = { sliderPosition = it },
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        },
        steps = 4
    )
}

Slider using a custom thumb:

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.Icon
import androidx.compose.material3.Label
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var sliderPosition by remember { mutableStateOf(0f) }
val interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    Slider(
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        value = sliderPosition,
        onValueChange = { sliderPosition = it },
        valueRange = 0f..100f,
        interactionSource = interactionSource,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        },
        thumb = {
            Label(
                label = {
                    PlainTooltip(
                        modifier = Modifier
                            .requiredSize(45.dp, 25.dp)
                            .wrapContentWidth()
                    ) {
                        Text("%.2f".format(sliderPosition))
                    }
                },
                interactionSource = interactionSource
            ) {
                Icon(
                    imageVector = Icons.Filled.Favorite,
                    contentDescription = null,
                    modifier = Modifier.size(ButtonDefaults.IconSize),
                    tint = Color.Red
                )
            }
        }
    )
}

Slider using custom track and thumb:

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Slider
import androidx.compose.material3.SliderState
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

val sliderState = remember {
    SliderState(
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        }
    )
}
val interactionSource = remember { MutableInteractionSource() }
val colors = SliderDefaults.colors(thumbColor = Color.Red, activeTrackColor = Color.Red)
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    Text(text = "%.2f".format(sliderState.value))
    Slider(
        state = sliderState,
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        interactionSource = interactionSource,
        thumb = {
            SliderDefaults.Thumb(
                interactionSource = interactionSource,
                colors = colors
            )
        },
        track = {
            SliderDefaults.Track(
                colors = colors,
                sliderState = sliderState
            )
        }
    )
}
Parameters
state: SliderState

SliderState which contains the slider's current value.

modifier: Modifier = Modifier

the Modifier to be applied to this slider

enabled: Boolean = true

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

colors: SliderColors = SliderDefaults.colors()

SliderColors that will be used to resolve the colors used for this slider in different states. See SliderDefaults.colors.

interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }

the MutableInteractionSource representing the stream of Interactions for this slider. You can create and pass in your own remembered instance to observe Interactions and customize the appearance / behavior of this slider in different states.

thumb: @Composable (SliderState) -> Unit = { SliderDefaults.Thumb( interactionSource = interactionSource, colors = colors, enabled = enabled ) }

the thumb to be displayed on the slider, it is placed on top of the track. The lambda receives a SliderState which is used to obtain the current active track.

track: @Composable (SliderState) -> Unit = { sliderState -> SliderDefaults.Track( colors = colors, enabled = enabled, sliderState = sliderState ) }

the track to be displayed on the slider, it is placed underneath the thumb. The lambda receives a SliderState which is used to obtain the current active track.

@Composable
fun Slider(
    value: Float,
    onValueChange: (Float) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
    steps: @IntRange(from = 0) Int = 0,
    onValueChangeFinished: (() -> Unit)? = null,
    colors: SliderColors = SliderDefaults.colors(),
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
): Unit

Material Design slider.

Sliders allow users to make selections from a range of values.

It uses SliderDefaults.Thumb and SliderDefaults.Track as the thumb and track.

Sliders reflect a range of values along a bar, from which users may select a single value. They are ideal for adjusting settings such as volume, brightness, or applying image filters.

Sliders image

Use continuous sliders to allow users to make meaningful selections that don’t require a specific value:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var sliderPosition by remember { mutableStateOf(0f) }
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    Text(text = "%.2f".format(sliderPosition))
    Slider(
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        value = sliderPosition,
        onValueChange = { sliderPosition = it })
}

You can allow the user to choose only between predefined set of values by specifying the amount of steps between min and max values:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var sliderPosition by remember { mutableStateOf(0f) }
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    Text(text = sliderPosition.roundToInt().toString())
    Slider(
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        value = sliderPosition,
        onValueChange = { sliderPosition = it },
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        },
        steps = 4
    )
}
Parameters
value: Float

current value of the slider. If outside of valueRange provided, value will be coerced to this range.

onValueChange: (Float) -> Unit

callback in which value should be updated

modifier: Modifier = Modifier

the Modifier to be applied to this slider

enabled: Boolean = true

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

valueRange: ClosedFloatingPointRange<Float> = 0f..1f

range of values that this slider can take. The passed value will be coerced to this range.

steps: @IntRange(from = 0) Int = 0

if greater than 0, specifies the amount of discrete allowable values, evenly distributed across the whole value range. If 0, the slider will behave continuously and allow any value from the range specified. Must not be negative.

onValueChangeFinished: (() -> Unit)? = null

called when value change has ended. This should not be used to update the slider value (use onValueChange instead), but rather to know when the user has completed selecting a new value by ending a drag or a click.

colors: SliderColors = SliderDefaults.colors()

SliderColors that will be used to resolve the colors used for this slider in different states. See SliderDefaults.colors.

interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }

the MutableInteractionSource representing the stream of Interactions for this slider. You can create and pass in your own remembered instance to observe Interactions and customize the appearance / behavior of this slider in different states.

@Composable
@ExperimentalMaterial3Api
fun Slider(
    value: Float,
    onValueChange: (Float) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    onValueChangeFinished: (() -> Unit)? = null,
    colors: SliderColors = SliderDefaults.colors(),
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    steps: @IntRange(from = 0) Int = 0,
    thumb: @Composable (SliderState) -> Unit = { SliderDefaults.Thumb( interactionSource = interactionSource, colors = colors, enabled = enabled ) },
    track: @Composable (SliderState) -> Unit = { sliderState -> SliderDefaults.Track( colors = colors, enabled = enabled, sliderState = sliderState ) },
    valueRange: ClosedFloatingPointRange<Float> = 0f..1f
): Unit

Material Design slider.

Sliders allow users to make selections from a range of values.

Sliders reflect a range of values along a bar, from which users may select a single value. They are ideal for adjusting settings such as volume, brightness, or applying image filters.

Sliders image

Use continuous sliders to allow users to make meaningful selections that don’t require a specific value:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var sliderPosition by remember { mutableStateOf(0f) }
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    Text(text = "%.2f".format(sliderPosition))
    Slider(
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        value = sliderPosition,
        onValueChange = { sliderPosition = it })
}

You can allow the user to choose only between predefined set of values by specifying the amount of steps between min and max values:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var sliderPosition by remember { mutableStateOf(0f) }
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    Text(text = sliderPosition.roundToInt().toString())
    Slider(
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        value = sliderPosition,
        onValueChange = { sliderPosition = it },
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        },
        steps = 4
    )
}

Slider using a custom thumb:

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.Icon
import androidx.compose.material3.Label
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var sliderPosition by remember { mutableStateOf(0f) }
val interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    Slider(
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        value = sliderPosition,
        onValueChange = { sliderPosition = it },
        valueRange = 0f..100f,
        interactionSource = interactionSource,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        },
        thumb = {
            Label(
                label = {
                    PlainTooltip(
                        modifier = Modifier
                            .requiredSize(45.dp, 25.dp)
                            .wrapContentWidth()
                    ) {
                        Text("%.2f".format(sliderPosition))
                    }
                },
                interactionSource = interactionSource
            ) {
                Icon(
                    imageVector = Icons.Filled.Favorite,
                    contentDescription = null,
                    modifier = Modifier.size(ButtonDefaults.IconSize),
                    tint = Color.Red
                )
            }
        }
    )
}

Slider using custom track and thumb:

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Slider
import androidx.compose.material3.SliderState
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

val sliderState = remember {
    SliderState(
        valueRange = 0f..100f,
        onValueChangeFinished = {
            // launch some business logic update with the state you hold
            // viewModel.updateSelectedSliderValue(sliderPosition)
        }
    )
}
val interactionSource = remember { MutableInteractionSource() }
val colors = SliderDefaults.colors(thumbColor = Color.Red, activeTrackColor = Color.Red)
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
    Text(text = "%.2f".format(sliderState.value))
    Slider(
        state = sliderState,
        modifier = Modifier.semantics { contentDescription = "Localized Description" },
        interactionSource = interactionSource,
        thumb = {
            SliderDefaults.Thumb(
                interactionSource = interactionSource,
                colors = colors
            )
        },
        track = {
            SliderDefaults.Track(
                colors = colors,
                sliderState = sliderState
            )
        }
    )
}
Parameters
value: Float

current value of the slider. If outside of valueRange provided, value will be coerced to this range.

onValueChange: (Float) -> Unit

callback in which value should be updated

modifier: Modifier = Modifier

the Modifier to be applied to this slider

enabled: Boolean = true

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

onValueChangeFinished: (() -> Unit)? = null

called when value change has ended. This should not be used to update the slider value (use onValueChange instead), but rather to know when the user has completed selecting a new value by ending a drag or a click.

colors: SliderColors = SliderDefaults.colors()

SliderColors that will be used to resolve the colors used for this slider in different states. See SliderDefaults.colors.

interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }

the MutableInteractionSource representing the stream of Interactions for this slider. You can create and pass in your own remembered instance to observe Interactions and customize the appearance / behavior of this slider in different states.

steps: @IntRange(from = 0) Int = 0

if greater than 0, specifies the amount of discrete allowable values, evenly distributed across the whole value range. If 0, the slider will behave continuously and allow any value from the range specified. Must not be negative.

thumb: @Composable (SliderState) -> Unit = { SliderDefaults.Thumb( interactionSource = interactionSource, colors = colors, enabled = enabled ) }

the thumb to be displayed on the slider, it is placed on top of the track. The lambda receives a SliderState which is used to obtain the current active track.

track: @Composable (SliderState) -> Unit = { sliderState -> SliderDefaults.Track( colors = colors, enabled = enabled, sliderState = sliderState ) }

the track to be displayed on the slider, it is placed underneath the thumb. The lambda receives a SliderState which is used to obtain the current active track.

valueRange: ClosedFloatingPointRange<Float> = 0f..1f

range of values that this slider can take. The passed value will be coerced to this range.

SmallFloatingActionButton

@Composable
fun SmallFloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    shape: Shape = FloatingActionButtonDefaults.smallShape,
    containerColor: Color = FloatingActionButtonDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material Design small floating action button.

The FAB represents the most important action on a screen. It puts key actions within reach.

Small FAB image

import androidx.compose.material3.Icon
import androidx.compose.material3.SmallFloatingActionButton

SmallFloatingActionButton(
    onClick = { /* do something */ },
) {
    Icon(Icons.Filled.Add, contentDescription = "Localized description")
}
Parameters
onClick: () -> Unit

called when this FAB is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this FAB

shape: Shape = FloatingActionButtonDefaults.smallShape

defines the shape of this FAB's container and shadow (when using elevation)

containerColor: Color = FloatingActionButtonDefaults.containerColor

the color used for the background of this FAB. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(containerColor)

the preferred color for content inside this FAB. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation()

FloatingActionButtonElevation used to resolve the elevation for this FAB in different states. This controls the size of the shadow below the FAB. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. See also: Surface.

interactionSource: MutableInteractionSource? = null

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

content: @Composable () -> Unit

the content of this FAB, typically an Icon

SmallTopAppBar

@ExperimentalMaterial3Api
@Composable
fun SmallTopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    navigationIcon: @Composable () -> Unit = {},
    actions: @Composable RowScope.() -> Unit = {},
    windowInsets: WindowInsets = TopAppBarDefaults.windowInsets,
    colors: TopAppBarColors = TopAppBarDefaults.topAppBarColors(),
    scrollBehavior: TopAppBarScrollBehavior? = null
): Unit

Material Design small top app bar.

Top app bars display information and actions at the top of a screen.

This SmallTopAppBar has slots for a title, navigation icon, and actions.

Small top app bar image

A simple top app bar looks like:

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar

Scaffold(
    topBar = {
        TopAppBar(
            title = {
                Text(
                    "Simple TopAppBar",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
            },
            navigationIcon = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Menu,
                        contentDescription = "Localized description"
                    )
                }
            },
            actions = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Favorite,
                        contentDescription = "Localized description"
                    )
                }
            }
        )
    },
    content = { innerPadding ->
        LazyColumn(
            contentPadding = innerPadding,
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            val list = (0..75).map { it.toString() }
            items(count = list.size) {
                Text(
                    text = list[it],
                    style = MaterialTheme.typography.bodyLarge,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp)
                )
            }
        }
    }
)

A top app bar that uses a scrollBehavior to customize its nested scrolling behavior when working in conjunction with a scrolling content looks like:

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.ui.input.nestedscroll.nestedScroll

val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
Scaffold(
    modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
    topBar = {
        TopAppBar(
            title = {
                Text(
                    "TopAppBar",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
            },
            navigationIcon = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Menu,
                        contentDescription = "Localized description"
                    )
                }
            },
            actions = {
                // RowScope here, so these icons will be placed horizontally
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Favorite,
                        contentDescription = "Localized description"
                    )
                }
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Favorite,
                        contentDescription = "Localized description"
                    )
                }
            },
            scrollBehavior = scrollBehavior
        )
    },
    content = { innerPadding ->
        LazyColumn(
            contentPadding = innerPadding,
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            val list = (0..75).map { it.toString() }
            items(count = list.size) {
                Text(
                    text = list[it],
                    style = MaterialTheme.typography.bodyLarge,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp)
                )
            }
        }
    }
)
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.ui.input.nestedscroll.nestedScroll

val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
Scaffold(
    modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
    topBar = {
        TopAppBar(
            title = {
                Text(
                    "TopAppBar",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
            },
            navigationIcon = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Menu,
                        contentDescription = "Localized description"
                    )
                }
            },
            actions = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Favorite,
                        contentDescription = "Localized description"
                    )
                }
            },
            scrollBehavior = scrollBehavior
        )
    },
    content = { innerPadding ->
        LazyColumn(
            contentPadding = innerPadding,
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            val list = (0..75).map { it.toString() }
            items(count = list.size) {
                Text(
                    text = list[it],
                    style = MaterialTheme.typography.bodyLarge,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp)
                )
            }
        }
    }
)

use TopAppBar instead

Parameters
title: @Composable () -> Unit

the title to be displayed in the top app bar

modifier: Modifier = Modifier

the Modifier to be applied to this top app bar

navigationIcon: @Composable () -> Unit = {}

the navigation icon displayed at the start of the top app bar. This should typically be an IconButton or IconToggleButton.

actions: @Composable RowScope.() -> Unit = {}

the actions displayed at the end of the top app bar. This should typically be IconButtons. The default layout here is a Row, so icons inside will be placed horizontally.

windowInsets: WindowInsets = TopAppBarDefaults.windowInsets

a window insets that app bar will respect.

colors: TopAppBarColors = TopAppBarDefaults.topAppBarColors()

TopAppBarColors that will be used to resolve the colors used for this top app bar in different states. See TopAppBarDefaults.topAppBarColors.

scrollBehavior: TopAppBarScrollBehavior? = null

a TopAppBarScrollBehavior which holds various offset values that will be applied by this top app bar to set up its height and colors. A scroll behavior is designed to work in conjunction with a scrolled content to change the top app bar appearance as the content scrolls. See TopAppBarScrollBehavior.nestedScrollConnection.

@Composable
fun Snackbar(
    snackbarData: SnackbarData,
    modifier: Modifier = Modifier,
    actionOnNewLine: Boolean = false,
    shape: Shape = SnackbarDefaults.shape,
    containerColor: Color = SnackbarDefaults.color,
    contentColor: Color = SnackbarDefaults.contentColor,
    actionColor: Color = SnackbarDefaults.actionColor,
    actionContentColor: Color = SnackbarDefaults.actionContentColor,
    dismissActionContentColor: Color = SnackbarDefaults.dismissActionContentColor
): Unit

Material Design snackbar.

Snackbars provide brief messages about app processes at the bottom of the screen.

Snackbar image

Snackbars inform users of a process that an app has performed or will perform. They appear temporarily, towards the bottom of the screen. They shouldn’t interrupt the user experience, and they don’t require user input to disappear.

A Snackbar can contain a single action. "Dismiss" or "cancel" actions are optional.

Snackbars with an action should not timeout or self-dismiss until the user performs another action. Here, moving the keyboard focus indicator to navigate through interactive elements in a page is not considered an action.

This version of snackbar is designed to work with SnackbarData provided by the SnackbarHost, which is usually used inside of the Scaffold.

This components provides only the visuals of the Snackbar. If you need to show a Snackbar with defaults on the screen, use SnackbarHostState.showSnackbar:

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    floatingActionButton = {
        var clickCount by remember { mutableStateOf(0) }
        ExtendedFloatingActionButton(
            onClick = {
                // show snackbar as a suspend function
                scope.launch {
                    snackbarHostState.showSnackbar(
                        "Snackbar # ${++clickCount}"
                    )
                }
            }
        ) { Text("Show snackbar") }
    },
    content = { innerPadding ->
        Text(
            text = "Body content",
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize()
                .wrapContentSize()
        )
    }
)

If you want to customize appearance of the Snackbar, you can pass your own version as a child of the SnackbarHost to the Scaffold:

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

class SnackbarVisualsWithError(
    override val message: String,
    val isError: Boolean
) : SnackbarVisuals {
    override val actionLabel: String
        get() = if (isError) "Error" else "OK"
    override val withDismissAction: Boolean
        get() = false
    override val duration: SnackbarDuration
        get() = SnackbarDuration.Indefinite
}

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
    snackbarHost = {
        // reuse default SnackbarHost to have default animation and timing handling
        SnackbarHost(snackbarHostState) { data ->
            // custom snackbar with the custom action button color and border
            val isError = (data.visuals as? SnackbarVisualsWithError)?.isError ?: false
            val buttonColor = if (isError) {
                ButtonDefaults.textButtonColors(
                    containerColor = MaterialTheme.colorScheme.errorContainer,
                    contentColor = MaterialTheme.colorScheme.error
                )
            } else {
                ButtonDefaults.textButtonColors(
                    contentColor = MaterialTheme.colorScheme.inversePrimary
                )
            }

            Snackbar(
                modifier = Modifier
                    .border(2.dp, MaterialTheme.colorScheme.secondary)
                    .padding(12.dp),
                action = {
                    TextButton(
                        onClick = { if (isError) data.dismiss() else data.performAction() },
                        colors = buttonColor
                    ) { Text(data.visuals.actionLabel ?: "") }
                }
            ) {
                Text(data.visuals.message)
            }
        }
    },
    floatingActionButton = {
        var clickCount by remember { mutableStateOf(0) }
        ExtendedFloatingActionButton(
            onClick = {
                scope.launch {
                    snackbarHostState.showSnackbar(
                        SnackbarVisualsWithError(
                            "Snackbar # ${++clickCount}",
                            isError = clickCount % 2 != 0
                        )
                    )
                }
            }
        ) { Text("Show snackbar") }
    },
    content = { innerPadding ->
        Text(
            text = "Custom Snackbar Demo",
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize()
                .wrapContentSize()
        )
    }
)

When a SnackbarData.visuals sets the Snackbar's duration as SnackbarDuration.Indefinite, it's recommended to display an additional close affordance action. See SnackbarVisuals.withDismissAction:

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    floatingActionButton = {
        var clickCount by remember { mutableStateOf(0) }
        ExtendedFloatingActionButton(
            onClick = {
                // show snackbar as a suspend function
                scope.launch {
                    snackbarHostState.showSnackbar(
                        message = "Snackbar # ${++clickCount}",
                        actionLabel = "Action",
                        withDismissAction = true,
                        duration = SnackbarDuration.Indefinite
                    )
                }
            }
        ) { Text("Show snackbar") }
    },
    content = { innerPadding ->
        Text(
            text = "Body content",
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize()
                .wrapContentSize()
        )
    }
)
Parameters
snackbarData: SnackbarData

data about the current snackbar showing via SnackbarHostState

modifier: Modifier = Modifier

the Modifier to be applied to this snackbar

actionOnNewLine: Boolean = false

whether or not action should be put on a separate line. Recommended for action with long action text.

shape: Shape = SnackbarDefaults.shape

defines the shape of this snackbar's container

containerColor: Color = SnackbarDefaults.color

the color used for the background of this snackbar. Use Color.Transparent to have no color.

contentColor: Color = SnackbarDefaults.contentColor

the preferred color for content inside this snackbar

actionColor: Color = SnackbarDefaults.actionColor

the color of the snackbar's action

actionContentColor: Color = SnackbarDefaults.actionContentColor

the preferred content color for the optional action inside this snackbar. See SnackbarVisuals.actionLabel.

dismissActionContentColor: Color = SnackbarDefaults.dismissActionContentColor

the preferred content color for the optional dismiss action inside this snackbar. See SnackbarVisuals.withDismissAction.

@Composable
fun Snackbar(
    modifier: Modifier = Modifier,
    action: (@Composable () -> Unit)? = null,
    dismissAction: (@Composable () -> Unit)? = null,
    actionOnNewLine: Boolean = false,
    shape: Shape = SnackbarDefaults.shape,
    containerColor: Color = SnackbarDefaults.color,
    contentColor: Color = SnackbarDefaults.contentColor,
    actionContentColor: Color = SnackbarDefaults.actionContentColor,
    dismissActionContentColor: Color = SnackbarDefaults.dismissActionContentColor,
    content: @Composable () -> Unit
): Unit

Material Design snackbar.

Snackbars provide brief messages about app processes at the bottom of the screen.

Snackbar image

Snackbars inform users of a process that an app has performed or will perform. They appear temporarily, towards the bottom of the screen. They shouldn’t interrupt the user experience, and they don’t require user input to disappear.

A Snackbar can contain a single action. "Dismiss" or "cancel" actions are optional.

Snackbars with an action should not timeout or self-dismiss until the user performs another action. Here, moving the keyboard focus indicator to navigate through interactive elements in a page is not considered an action.

This component provides only the visuals of the Snackbar. If you need to show a Snackbar with defaults on the screen, use SnackbarHostState.showSnackbar:

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    floatingActionButton = {
        var clickCount by remember { mutableStateOf(0) }
        ExtendedFloatingActionButton(
            onClick = {
                // show snackbar as a suspend function
                scope.launch {
                    snackbarHostState.showSnackbar(
                        "Snackbar # ${++clickCount}"
                    )
                }
            }
        ) { Text("Show snackbar") }
    },
    content = { innerPadding ->
        Text(
            text = "Body content",
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize()
                .wrapContentSize()
        )
    }
)

If you want to customize appearance of the Snackbar, you can pass your own version as a child of the SnackbarHost to the Scaffold:

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

class SnackbarVisualsWithError(
    override val message: String,
    val isError: Boolean
) : SnackbarVisuals {
    override val actionLabel: String
        get() = if (isError) "Error" else "OK"
    override val withDismissAction: Boolean
        get() = false
    override val duration: SnackbarDuration
        get() = SnackbarDuration.Indefinite
}

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
    snackbarHost = {
        // reuse default SnackbarHost to have default animation and timing handling
        SnackbarHost(snackbarHostState) { data ->
            // custom snackbar with the custom action button color and border
            val isError = (data.visuals as? SnackbarVisualsWithError)?.isError ?: false
            val buttonColor = if (isError) {
                ButtonDefaults.textButtonColors(
                    containerColor = MaterialTheme.colorScheme.errorContainer,
                    contentColor = MaterialTheme.colorScheme.error
                )
            } else {
                ButtonDefaults.textButtonColors(
                    contentColor = MaterialTheme.colorScheme.inversePrimary
                )
            }

            Snackbar(
                modifier = Modifier
                    .border(2.dp, MaterialTheme.colorScheme.secondary)
                    .padding(12.dp),
                action = {
                    TextButton(
                        onClick = { if (isError) data.dismiss() else data.performAction() },
                        colors = buttonColor
                    ) { Text(data.visuals.actionLabel ?: "") }
                }
            ) {
                Text(data.visuals.message)
            }
        }
    },
    floatingActionButton = {
        var clickCount by remember { mutableStateOf(0) }
        ExtendedFloatingActionButton(
            onClick = {
                scope.launch {
                    snackbarHostState.showSnackbar(
                        SnackbarVisualsWithError(
                            "Snackbar # ${++clickCount}",
                            isError = clickCount % 2 != 0
                        )
                    )
                }
            }
        ) { Text("Show snackbar") }
    },
    content = { innerPadding ->
        Text(
            text = "Custom Snackbar Demo",
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize()
                .wrapContentSize()
        )
    }
)

For a multiline sample following the Material recommended spec of a maximum of 2 lines, see:

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
    snackbarHost = {
        SnackbarHost(snackbarHostState) { data ->
            Snackbar {
                // The Material spec recommends a maximum of 2 lines of text.
                Text(data.visuals.message, maxLines = 2, overflow = TextOverflow.Ellipsis)
            }
        }
    },
    floatingActionButton = {
        ExtendedFloatingActionButton(
            onClick = {
                scope.launch {
                    val longMessage =
                        "Very very very very very very very very very very very very very " +
                            "very very very very very very very very very very very very " +
                            "very very very very very very very very very very long message"
                    snackbarHostState.showSnackbar(longMessage)
                }
            }
        ) { Text("Show snackbar") }
    },
    content = { innerPadding ->
        Text(
            text = "Multiline Snackbar Demo",
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize()
                .wrapContentSize()
        )
    }
)
Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this snackbar

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

action / button component to add as an action to the snackbar. Consider using ColorScheme.inversePrimary as the color for the action, if you do not have a predefined color you wish to use instead.

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

action / button component to add as an additional close affordance action when a snackbar is non self-dismissive. Consider using ColorScheme.inverseOnSurface as the color for the action, if you do not have a predefined color you wish to use instead.

actionOnNewLine: Boolean = false

whether or not action should be put on a separate line. Recommended for action with long action text.

shape: Shape = SnackbarDefaults.shape

defines the shape of this snackbar's container

containerColor: Color = SnackbarDefaults.color

the color used for the background of this snackbar. Use Color.Transparent to have no color.

contentColor: Color = SnackbarDefaults.contentColor

the preferred color for content inside this snackbar

actionContentColor: Color = SnackbarDefaults.actionContentColor

the preferred content color for the optional action inside this snackbar

dismissActionContentColor: Color = SnackbarDefaults.dismissActionContentColor

the preferred content color for the optional dismissAction inside this snackbar

content: @Composable () -> Unit

content to show information about a process that an app has performed or will perform

SnackbarHost

@Composable
fun SnackbarHost(
    hostState: SnackbarHostState,
    modifier: Modifier = Modifier,
    snackbar: @Composable (SnackbarData) -> Unit = { Snackbar(it) }
): Unit

Host for Snackbars to be used in Scaffold to properly show, hide and dismiss items based on Material specification and the hostState.

This component with default parameters comes build-in with Scaffold, if you need to show a default Snackbar, use SnackbarHostState.showSnackbar.

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    floatingActionButton = {
        var clickCount by remember { mutableStateOf(0) }
        ExtendedFloatingActionButton(
            onClick = {
                // show snackbar as a suspend function
                scope.launch {
                    snackbarHostState.showSnackbar(
                        "Snackbar # ${++clickCount}"
                    )
                }
            }
        ) { Text("Show snackbar") }
    },
    content = { innerPadding ->
        Text(
            text = "Body content",
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize()
                .wrapContentSize()
        )
    }
)

If you want to customize appearance of the Snackbar, you can pass your own version as a child of the SnackbarHost to the Scaffold:

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

class SnackbarVisualsWithError(
    override val message: String,
    val isError: Boolean
) : SnackbarVisuals {
    override val actionLabel: String
        get() = if (isError) "Error" else "OK"
    override val withDismissAction: Boolean
        get() = false
    override val duration: SnackbarDuration
        get() = SnackbarDuration.Indefinite
}

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
    snackbarHost = {
        // reuse default SnackbarHost to have default animation and timing handling
        SnackbarHost(snackbarHostState) { data ->
            // custom snackbar with the custom action button color and border
            val isError = (data.visuals as? SnackbarVisualsWithError)?.isError ?: false
            val buttonColor = if (isError) {
                ButtonDefaults.textButtonColors(
                    containerColor = MaterialTheme.colorScheme.errorContainer,
                    contentColor = MaterialTheme.colorScheme.error
                )
            } else {
                ButtonDefaults.textButtonColors(
                    contentColor = MaterialTheme.colorScheme.inversePrimary
                )
            }

            Snackbar(
                modifier = Modifier
                    .border(2.dp, MaterialTheme.colorScheme.secondary)
                    .padding(12.dp),
                action = {
                    TextButton(
                        onClick = { if (isError) data.dismiss() else data.performAction() },
                        colors = buttonColor
                    ) { Text(data.visuals.actionLabel ?: "") }
                }
            ) {
                Text(data.visuals.message)
            }
        }
    },
    floatingActionButton = {
        var clickCount by remember { mutableStateOf(0) }
        ExtendedFloatingActionButton(
            onClick = {
                scope.launch {
                    snackbarHostState.showSnackbar(
                        SnackbarVisualsWithError(
                            "Snackbar # ${++clickCount}",
                            isError = clickCount % 2 != 0
                        )
                    )
                }
            }
        ) { Text("Show snackbar") }
    },
    content = { innerPadding ->
        Text(
            text = "Custom Snackbar Demo",
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize()
                .wrapContentSize()
        )
    }
)
Parameters
hostState: SnackbarHostState

state of this component to read and show Snackbars accordingly

modifier: Modifier = Modifier

the Modifier to be applied to this component

snackbar: @Composable (SnackbarData) -> Unit = { Snackbar(it) }

the instance of the Snackbar to be shown at the appropriate time with appearance based on the SnackbarData provided as a param

SuggestionChip

@Composable
fun SuggestionChip(
    onClick: () -> Unit,
    label: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    icon: (@Composable () -> Unit)? = null,
    shape: Shape = SuggestionChipDefaults.shape,
    colors: ChipColors = SuggestionChipDefaults.suggestionChipColors(),
    elevation: ChipElevation? = SuggestionChipDefaults.suggestionChipElevation(),
    border: BorderStroke? = SuggestionChipDefaults.suggestionChipBorder(enabled),
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design suggestion 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.

Suggestion chips help narrow a user's intent by presenting dynamically generated suggestions, such as possible responses or search filters.

Suggestion chip image

This suggestion chip is applied with a flat style. If you want an elevated style, use the ElevatedSuggestionChip.

Example of a flat SuggestionChip with a trailing icon:

import androidx.compose.material3.SuggestionChip
import androidx.compose.material3.Text

SuggestionChip(
    onClick = { /* Do something! */ },
    label = { Text("Suggestion Chip") }
)
Parameters
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.

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

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

shape: Shape = SuggestionChipDefaults.shape

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

colors: ChipColors = SuggestionChipDefaults.suggestionChipColors()

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

elevation: ChipElevation? = SuggestionChipDefaults.suggestionChipElevation()

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 SuggestionChipDefaults.suggestionChipElevation.

border: BorderStroke? = SuggestionChipDefaults.suggestionChipBorder(enabled)

the border to draw around the container of this chip. Pass null for no border. See SuggestionChipDefaults.suggestionChipBorder.

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.

@Composable
@NonRestartableComposable
fun Surface(
    modifier: Modifier = Modifier,
    shape: Shape = RectangleShape,
    color: Color = MaterialTheme.colorScheme.surface,
    contentColor: Color = contentColorFor(color),
    tonalElevation: Dp = 0.dp,
    shadowElevation: Dp = 0.dp,
    border: BorderStroke? = null,
    content: @Composable () -> Unit
): Unit

Material surface is the central metaphor in material design. Each surface exists at a given elevation, which influences how that piece of surface visually relates to other surfaces and how that surface is modified by tonal variance.

See the other overloads for clickable, selectable, and toggleable surfaces.

The Surface is responsible for:

  1. Clipping: Surface clips its children to the shape specified by shape

  2. Borders: If shape has a border, then it will also be drawn.

  3. Background: Surface fills the shape specified by shape with the color. If color is ColorScheme.surface a color overlay will be applied. The color of the overlay depends on the tonalElevation of this Surface, and the LocalAbsoluteTonalElevation set by any parent surfaces. This ensures that a Surface never appears to have a lower elevation overlay than its ancestors, by summing the elevation of all previous Surfaces.

  4. Content color: Surface uses contentColor to specify a preferred color for the content of this surface - this is used by the Text and Icon components as a default color.

If no contentColor is set, this surface will try and match its background color to a color defined in the theme ColorScheme, and return the corresponding content color. For example, if the color of this surface is ColorScheme.surface, contentColor will be set to ColorScheme.onSurface. If color is not part of the theme palette, contentColor will keep the same value set above this Surface.

To manually retrieve the content color inside a surface, use LocalContentColor.

  1. Blocking touch propagation behind the surface.

Surface sample:

import androidx.compose.material3.Surface
import androidx.compose.material3.Text

Surface {
    Text("Text on Surface")
}
Parameters
modifier: Modifier = Modifier

Modifier to be applied to the layout corresponding to the surface

shape: Shape = RectangleShape

Defines the surface's shape as well its shadow.

color: Color = MaterialTheme.colorScheme.surface

The background color. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(color)

The preferred content color provided by this Surface to its children. Defaults to either the matching content color for color, or if color is not a color from the theme, this will keep the same value set above this Surface.

tonalElevation: Dp = 0.dp

When color is ColorScheme.surface, a higher the elevation will result in a darker color in light theme and lighter color in dark theme.

shadowElevation: Dp = 0.dp

The size of the shadow below the surface. To prevent shadow creep, only apply shadow elevation when absolutely necessary, such as when the surface requires visual separation from a patterned background. Note that It will not affect z index of the Surface. If you want to change the drawing order you can use Modifier.zIndex.

border: BorderStroke? = null

Optional border to draw on top of the surface

@Composable
@NonRestartableComposable
fun Surface(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = RectangleShape,
    color: Color = MaterialTheme.colorScheme.surface,
    contentColor: Color = contentColorFor(color),
    tonalElevation: Dp = 0.dp,
    shadowElevation: Dp = 0.dp,
    border: BorderStroke? = null,
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material surface is the central metaphor in material design. Each surface exists at a given elevation, which influences how that piece of surface visually relates to other surfaces and how that surface is modified by tonal variance.

This version of Surface is responsible for a click handling as well as everything else that a regular Surface does:

This clickable Surface is responsible for:

  1. Clipping: Surface clips its children to the shape specified by shape

  2. Borders: If shape has a border, then it will also be drawn.

  3. Background: Surface fills the shape specified by shape with the color. If color is ColorScheme.surface a color overlay may be applied. The color of the overlay depends on the tonalElevation of this Surface, and the LocalAbsoluteTonalElevation set by any parent surfaces. This ensures that a Surface never appears to have a lower elevation overlay than its ancestors, by summing the elevation of all previous Surfaces.

  4. Content color: Surface uses contentColor to specify a preferred color for the content of this surface - this is used by the Text and Icon components as a default color. If no contentColor is set, this surface will try and match its background color to a color defined in the theme ColorScheme, and return the corresponding content color. For example, if the color of this surface is ColorScheme.surface, contentColor will be set to ColorScheme.onSurface. If color is not part of the theme palette, contentColor will keep the same value set above this Surface.

  5. Click handling. This version of surface will react to the clicks, calling onClick lambda, updating the interactionSource when PressInteraction occurs, and showing ripple indication in response to press events. If you don't need click handling, consider using the Surface function that doesn't require onClick param. If you need to set a custom label for the onClick, apply a Modifier.semantics { onClick(label = "YOUR_LABEL", action = null) } to the Surface.

  6. Semantics for clicks. Just like with Modifier.clickable, clickable version of Surface will produce semantics to indicate that it is clicked. No semantic role is set by default, you may specify one by passing a desired Role with a Modifier.semantics.

To manually retrieve the content color inside a surface, use LocalContentColor.

Clickable surface sample:

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

var count by remember { mutableStateOf(0) }
Surface(
    onClick = { count++ },
) {
    Text("Clickable Surface. Count: $count")
}
Parameters
onClick: () -> Unit

callback to be called when the surface is clicked

modifier: Modifier = Modifier

Modifier to be applied to the layout corresponding to the surface

enabled: Boolean = true

Controls the enabled state of the surface. When false, this surface will not be clickable

shape: Shape = RectangleShape

Defines the surface's shape as well its shadow. A shadow is only displayed if the tonalElevation is greater than zero.

color: Color = MaterialTheme.colorScheme.surface

The background color. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(color)

The preferred content color provided by this Surface to its children. Defaults to either the matching content color for color, or if color is not a color from the theme, this will keep the same value set above this Surface.

tonalElevation: Dp = 0.dp

When color is ColorScheme.surface, a higher the elevation will result in a darker color in light theme and lighter color in dark theme.

shadowElevation: Dp = 0.dp

The size of the shadow below the surface. Note that It will not affect z index of the Surface. If you want to change the drawing order you can use Modifier.zIndex.

border: BorderStroke? = null

Optional border to draw on top of the surface

interactionSource: MutableInteractionSource? = null

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

@Composable
@NonRestartableComposable
fun Surface(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = RectangleShape,
    color: Color = MaterialTheme.colorScheme.surface,
    contentColor: Color = contentColorFor(color),
    tonalElevation: Dp = 0.dp,
    shadowElevation: Dp = 0.dp,
    border: BorderStroke? = null,
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material surface is the central metaphor in material design. Each surface exists at a given elevation, which influences how that piece of surface visually relates to other surfaces and how that surface is modified by tonal variance.

This version of Surface is responsible for a toggling its checked state as well as everything else that a regular Surface does:

This toggleable Surface is responsible for:

  1. Clipping: Surface clips its children to the shape specified by shape

  2. Borders: If shape has a border, then it will also be drawn.

  3. Background: Surface fills the shape specified by shape with the color. If color is ColorScheme.surface a color overlay may be applied. The color of the overlay depends on the tonalElevation of this Surface, and the LocalAbsoluteTonalElevation set by any parent surfaces. This ensures that a Surface never appears to have a lower elevation overlay than its ancestors, by summing the elevation of all previous Surfaces.

  4. Content color: Surface uses contentColor to specify a preferred color for the content of this surface - this is used by the Text and Icon components as a default color. If no contentColor is set, this surface will try and match its background color to a color defined in the theme ColorScheme, and return the corresponding content color. For example, if the color of this surface is ColorScheme.surface, contentColor will be set to ColorScheme.onSurface. If color is not part of the theme palette, contentColor will keep the same value set above this Surface.

  5. Click handling. This version of surface will react to the check toggles, calling onCheckedChange lambda, updating the interactionSource when PressInteraction occurs, and showing ripple indication in response to press events. If you don't need check handling, consider using a Surface function that doesn't require onCheckedChange param.

  6. Semantics for toggle. Just like with Modifier.toggleable, toggleable version of Surface will produce semantics to indicate that it is checked. No semantic role is set by default, you may specify one by passing a desired Role with a Modifier.semantics.

To manually retrieve the content color inside a surface, use LocalContentColor.

Toggleable surface sample:

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

var checked by remember { mutableStateOf(false) }
Surface(
    checked = checked,
    onCheckedChange = { checked = !checked },
    color = if (checked) {
        MaterialTheme.colorScheme.surfaceVariant
    } else {
        MaterialTheme.colorScheme.surface
    }
) {
    Text(
        text = if (checked) "ON" else "OFF",
        textAlign = TextAlign.Center
    )
}
Parameters
checked: Boolean

whether or not this Surface is toggled on or off

onCheckedChange: (Boolean) -> Unit

callback to be invoked when the toggleable Surface is clicked

modifier: Modifier = Modifier

Modifier to be applied to the layout corresponding to the surface

enabled: Boolean = true

Controls the enabled state of the surface. When false, this surface will not be clickable

shape: Shape = RectangleShape

Defines the surface's shape as well its shadow. A shadow is only displayed if the tonalElevation is greater than zero.

color: Color = MaterialTheme.colorScheme.surface

The background color. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(color)

The preferred content color provided by this Surface to its children. Defaults to either the matching content color for color, or if color is not a color from the theme, this will keep the same value set above this Surface.

tonalElevation: Dp = 0.dp

When color is ColorScheme.surface, a higher the elevation will result in a darker color in light theme and lighter color in dark theme.

shadowElevation: Dp = 0.dp

The size of the shadow below the surface. Note that It will not affect z index of the Surface. If you want to change the drawing order you can use Modifier.zIndex.

border: BorderStroke? = null

Optional border to draw on top of the surface

interactionSource: MutableInteractionSource? = null

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

@Composable
@NonRestartableComposable
fun Surface(
    selected: Boolean,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = RectangleShape,
    color: Color = MaterialTheme.colorScheme.surface,
    contentColor: Color = contentColorFor(color),
    tonalElevation: Dp = 0.dp,
    shadowElevation: Dp = 0.dp,
    border: BorderStroke? = null,
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit
): Unit

Material surface is the central metaphor in material design. Each surface exists at a given elevation, which influences how that piece of surface visually relates to other surfaces and how that surface is modified by tonal variance.

This version of Surface is responsible for a selection handling as well as everything else that a regular Surface does:

This selectable Surface is responsible for:

  1. Clipping: Surface clips its children to the shape specified by shape

  2. Borders: If shape has a border, then it will also be drawn.

  3. Background: Surface fills the shape specified by shape with the color. If color is ColorScheme.surface a color overlay may be applied. The color of the overlay depends on the tonalElevation of this Surface, and the LocalAbsoluteTonalElevation set by any parent surfaces. This ensures that a Surface never appears to have a lower elevation overlay than its ancestors, by summing the elevation of all previous Surfaces.

  4. Content color: Surface uses contentColor to specify a preferred color for the content of this surface - this is used by the Text and Icon components as a default color. If no contentColor is set, this surface will try and match its background color to a color defined in the theme ColorScheme, and return the corresponding content color. For example, if the color of this surface is ColorScheme.surface, contentColor will be set to ColorScheme.onSurface. If color is not part of the theme palette, contentColor will keep the same value set above this Surface.

  5. Click handling. This version of surface will react to the clicks, calling onClick lambda, updating the interactionSource when PressInteraction occurs, and showing ripple indication in response to press events. If you don't need click handling, consider using the Surface function that doesn't require onClick param.

  6. Semantics for selection. Just like with Modifier.selectable, selectable version of Surface will produce semantics to indicate that it is selected. No semantic role is set by default, you may specify one by passing a desired Role with a Modifier.semantics.

To manually retrieve the content color inside a surface, use LocalContentColor.

Selectable surface sample:

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

var selected by remember { mutableStateOf(false) }
Surface(
    selected = selected,
    onClick = { selected = !selected },
) {
    Text(
        text = if (selected) "Selected" else "Not Selected",
        textAlign = TextAlign.Center
    )
}
Parameters
selected: Boolean

whether or not this Surface is selected

onClick: () -> Unit

callback to be called when the surface is clicked

modifier: Modifier = Modifier

Modifier to be applied to the layout corresponding to the surface

enabled: Boolean = true

Controls the enabled state of the surface. When false, this surface will not be clickable

shape: Shape = RectangleShape

Defines the surface's shape as well its shadow. A shadow is only displayed if the tonalElevation is greater than zero.

color: Color = MaterialTheme.colorScheme.surface

The background color. Use Color.Transparent to have no color.

contentColor: Color = contentColorFor(color)

The preferred content color provided by this Surface to its children. Defaults to either the matching content color for color, or if color is not a color from the theme, this will keep the same value set above this Surface.

tonalElevation: Dp = 0.dp

When color is ColorScheme.surface, a higher the elevation will result in a darker color in light theme and lighter color in dark theme.

shadowElevation: Dp = 0.dp

The size of the shadow below the surface. Note that It will not affect z index of the Surface. If you want to change the drawing order you can use Modifier.zIndex.

border: BorderStroke? = null

Optional border to draw on top of the surface

interactionSource: MutableInteractionSource? = null

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

SwipeToDismiss

@Composable
@ExperimentalMaterial3Api
fun SwipeToDismiss(
    state: SwipeToDismissBoxState,
    background: @Composable RowScope.() -> Unit,
    dismissContent: @Composable RowScope.() -> Unit,
    modifier: Modifier = Modifier,
    directions: Set<SwipeToDismissBoxValue> = setOf( SwipeToDismissBoxValue.EndToStart, SwipeToDismissBoxValue.StartToEnd )
): Unit

A composable that can be dismissed by swiping left or right.

import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.ListItem
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.SwipeToDismissBox
import androidx.compose.material3.Text
import androidx.compose.material3.rememberSwipeToDismissBoxState

val dismissState = rememberSwipeToDismissBoxState()
SwipeToDismissBox(
    state = dismissState,
    backgroundContent = {
        val color by animateColorAsState(
            when (dismissState.targetValue) {
                SwipeToDismissBoxValue.Settled -> Color.LightGray
                SwipeToDismissBoxValue.StartToEnd -> Color.Green
                SwipeToDismissBoxValue.EndToStart -> Color.Red
            }
        )
        Box(
            Modifier
                .fillMaxSize()
                .background(color)
        )
    }
) {
    OutlinedCard(shape = RectangleShape) {
        ListItem(
            headlineContent = {
                Text("Cupcake")
            },
            supportingContent = { Text("Swipe me left or right!") }
        )
    }
}
Parameters
state: SwipeToDismissBoxState

The state of this component.

background: @Composable RowScope.() -> Unit

A composable that is stacked behind the content and is exposed when the content is swiped. You can/should use the state to have different backgrounds on each side.

dismissContent: @Composable RowScope.() -> Unit

The content that can be dismissed.

modifier: Modifier = Modifier

Optional Modifier for this component.

directions: Set<SwipeToDismissBoxValue> = setOf( SwipeToDismissBoxValue.EndToStart, SwipeToDismissBoxValue.StartToEnd )

The set of directions in which the component can be dismissed.

SwipeToDismissBox

@Composable
@ExperimentalMaterial3Api
fun SwipeToDismissBox(
    state: SwipeToDismissBoxState,
    backgroundContent: @Composable RowScope.() -> Unit,
    modifier: Modifier = Modifier,
    enableDismissFromStartToEnd: Boolean = true,
    enableDismissFromEndToStart: Boolean = true,
    content: @Composable RowScope.() -> Unit
): Unit

A composable that can be dismissed by swiping left or right.

import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.ListItem
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.SwipeToDismissBox
import androidx.compose.material3.Text
import androidx.compose.material3.rememberSwipeToDismissBoxState

val dismissState = rememberSwipeToDismissBoxState()
SwipeToDismissBox(
    state = dismissState,
    backgroundContent = {
        val color by animateColorAsState(
            when (dismissState.targetValue) {
                SwipeToDismissBoxValue.Settled -> Color.LightGray
                SwipeToDismissBoxValue.StartToEnd -> Color.Green
                SwipeToDismissBoxValue.EndToStart -> Color.Red
            }
        )
        Box(
            Modifier
                .fillMaxSize()
                .background(color)
        )
    }
) {
    OutlinedCard(shape = RectangleShape) {
        ListItem(
            headlineContent = {
                Text("Cupcake")
            },
            supportingContent = { Text("Swipe me left or right!") }
        )
    }
}
Parameters
state: SwipeToDismissBoxState

The state of this component.

backgroundContent: @Composable RowScope.() -> Unit

A composable that is stacked behind the content and is exposed when the content is swiped. You can/should use the state to have different backgrounds on each side.

modifier: Modifier = Modifier

Optional Modifier for this component.

enableDismissFromStartToEnd: Boolean = true

Whether SwipeToDismissBox can be dismissed from start to end.

enableDismissFromEndToStart: Boolean = true

Whether SwipeToDismissBox can be dismissed from end to start.

content: @Composable RowScope.() -> Unit

The content that can be dismissed.

@Composable
fun Switch(
    checked: Boolean,
    onCheckedChange: ((Boolean) -> Unit)?,
    modifier: Modifier = Modifier,
    thumbContent: (@Composable () -> Unit)? = null,
    enabled: Boolean = true,
    colors: SwitchColors = SwitchDefaults.colors(),
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design Switch.

Switches toggle the state of a single item on or off.

Switch image

import androidx.compose.material3.Switch
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var checked by remember { mutableStateOf(true) }
Switch(
    modifier = Modifier.semantics { contentDescription = "Demo" },
    checked = checked,
    onCheckedChange = { checked = it })

Switch can be used with a custom icon via thumbContent parameter

import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
import androidx.compose.material3.Switch
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.semantics

var checked by remember { mutableStateOf(true) }
// Icon isn't focusable, no need for content description
val icon: (@Composable () -> Unit)? = if (checked) {
    {
        Icon(
            imageVector = Icons.Filled.Check,
            contentDescription = null,
            modifier = Modifier.size(SwitchDefaults.IconSize),
        )
    }
} else {
    null
}

Switch(
    modifier = Modifier.semantics { contentDescription = "Demo with icon" },
    checked = checked,
    onCheckedChange = { checked = it },
    thumbContent = icon
)
Parameters
checked: Boolean

whether or not this switch is checked

onCheckedChange: ((Boolean) -> Unit)?

called when this switch is clicked. If null, then this switch will not be interactable, unless something else handles its input events and updates its state.

modifier: Modifier = Modifier

the Modifier to be applied to this switch

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

content that will be drawn inside the thumb, expected to measure SwitchDefaults.IconSize

enabled: Boolean = true

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

colors: SwitchColors = SwitchDefaults.colors()

SwitchColors that will be used to resolve the colors used for this switch in different states. See SwitchDefaults.colors.

interactionSource: MutableInteractionSource? = null

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

@Composable
fun Tab(
    selected: Boolean,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    selectedContentColor: Color = LocalContentColor.current,
    unselectedContentColor: Color = selectedContentColor,
    interactionSource: MutableInteractionSource? = null,
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design tab.

Tabs organize content across different screens, data sets, and other interactions.

Tabs image

Generic Tab overload that is not opinionated about content / color. See the other overload for a Tab that has specific slots for text and / or an icon, as well as providing the correct colors for selected / unselected states.

A custom tab using this API may look like:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
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.material3.Tab
import androidx.compose.material3.Text

Tab(selected, onClick) {
    Column(
        Modifier
            .padding(10.dp)
            .height(50.dp)
            .fillMaxWidth(),
        verticalArrangement = Arrangement.SpaceBetween
    ) {
        Box(
            Modifier
                .size(10.dp)
                .align(Alignment.CenterHorizontally)
                .background(
                    color = if (selected) MaterialTheme.colorScheme.primary
                    else MaterialTheme.colorScheme.background
                )
        )
        Text(
            text = title,
            style = MaterialTheme.typography.bodyLarge,
            modifier = Modifier.align(Alignment.CenterHorizontally)
        )
    }
}
Parameters
selected: Boolean

whether this tab is selected or not

onClick: () -> Unit

called when this tab is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this tab

enabled: Boolean = true

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

selectedContentColor: Color = LocalContentColor.current

the color for the content of this tab when selected, and the color of the ripple.

unselectedContentColor: Color = selectedContentColor

the color for the content of this tab when not selected

interactionSource: MutableInteractionSource? = null

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

content: @Composable ColumnScope.() -> Unit

the content of this tab

@Composable
fun Tab(
    selected: Boolean,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    text: (@Composable () -> Unit)? = null,
    icon: (@Composable () -> Unit)? = null,
    selectedContentColor: Color = LocalContentColor.current,
    unselectedContentColor: Color = selectedContentColor,
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design tab.

A default Tab, also known as a Primary Navigation Tab. Tabs organize content across different screens, data sets, and other interactions.

Tabs image

A Tab represents a single page of content using a text label and/or icon. It represents its selected state by tinting the text label and/or image with selectedContentColor.

This should typically be used inside of a TabRow, see the corresponding documentation for example usage.

This Tab has slots for text and/or icon - see the other Tab overload for a generic Tab that is not opinionated about its content.

Parameters
selected: Boolean

whether this tab is selected or not

onClick: () -> Unit

called when this tab is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this tab

enabled: Boolean = true

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

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

the text label displayed in this tab

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

the icon displayed in this tab

selectedContentColor: Color = LocalContentColor.current

the color for the content of this tab when selected, and the color of the ripple.

unselectedContentColor: Color = selectedContentColor

the color for the content of this tab when not selected

interactionSource: MutableInteractionSource? = null

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

See also
LeadingIconTab
@Composable
fun TabRow(
    selectedTabIndex: Int,
    modifier: Modifier = Modifier,
    containerColor: Color = TabRowDefaults.primaryContainerColor,
    contentColor: Color = TabRowDefaults.primaryContentColor,
    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions -> if (selectedTabIndex < tabPositions.size) { TabRowDefaults.SecondaryIndicator( Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]) ) } },
    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },
    tabs: @Composable () -> Unit
): Unit

Material Design tabs

Material Design fixed tabs.

For primary indicator tabs, use PrimaryTabRow. For secondary indicator tabs, use SecondaryTabRow.

Fixed tabs display all tabs in a set simultaneously. They are best for switching between related content quickly, such as between transportation methods in a map. To navigate between fixed tabs, tap an individual tab, or swipe left or right in the content area.

A TabRow contains a row of Tabs, and displays an indicator underneath the currently selected tab. A TabRow places its tabs evenly spaced along the entire row, with each tab taking up an equal amount of space. See ScrollableTabRow for a tab row that does not enforce equal size, and allows scrolling to tabs that do not fit on screen.

A simple example with text tabs looks like:

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.PrimaryTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var state by remember { mutableStateOf(0) }
val titles = listOf("Tab 1", "Tab 2", "Tab 3 with lots of text")
Column {
    PrimaryTabRow(selectedTabIndex = state) {
        titles.forEachIndexed { index, title ->
            Tab(
                selected = state == index,
                onClick = { state = index },
                text = { Text(text = title, maxLines = 2, overflow = TextOverflow.Ellipsis) }
            )
        }
    }
    Text(
        modifier = Modifier.align(Alignment.CenterHorizontally),
        text = "Text tab ${state + 1} selected",
        style = MaterialTheme.typography.bodyLarge
    )
}

You can also provide your own custom tab, such as:

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.SecondaryTabRow
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var state by remember { mutableStateOf(0) }
val titles = listOf("Tab 1", "Tab 2", "Tab 3")
Column {
    SecondaryTabRow(selectedTabIndex = state) {
        titles.forEachIndexed { index, title ->
            FancyTab(
                title = title,
                onClick = { state = index },
                selected = (index == state)
            )
        }
    }
    Text(
        modifier = Modifier.align(Alignment.CenterHorizontally),
        text = "Fancy tab ${state + 1} selected",
        style = MaterialTheme.typography.bodyLarge
    )
}

Where the custom tab itself could look like:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
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.material3.Tab
import androidx.compose.material3.Text

Tab(selected, onClick) {
    Column(
        Modifier
            .padding(10.dp)
            .height(50.dp)
            .fillMaxWidth(),
        verticalArrangement = Arrangement.SpaceBetween
    ) {
        Box(
            Modifier
                .size(10.dp)
                .align(Alignment.CenterHorizontally)
                .background(
                    color = if (selected) MaterialTheme.colorScheme.primary
                    else MaterialTheme.colorScheme.background
                )
        )
        Text(
            text = title,
            style = MaterialTheme.typography.bodyLarge,
            modifier = Modifier.align(Alignment.CenterHorizontally)
        )
    }
}

As well as customizing the tab, you can also provide a custom indicator, to customize the indicator displayed for a tab. indicator will be placed to fill the entire TabRow, so it should internally take care of sizing and positioning the indicator to match changes to selectedTabIndex.

For example, given an indicator that draws a rounded rectangle near the edges of the Tab:

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape

// Draws a rounded rectangular with border around the Tab, with a 5.dp padding from the edges
// Color is passed in as a parameter [color]
Box(
    modifier
        .padding(5.dp)
        .fillMaxSize()
        .border(BorderStroke(2.dp, color), RoundedCornerShape(5.dp))
)

We can reuse TabRowDefaults.tabIndicatorOffset and just provide this indicator, as we aren't changing how the size and position of the indicator changes between tabs:

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.SecondaryTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var state by remember { mutableStateOf(0) }
val titles = listOf("Tab 1", "Tab 2", "Tab 3")

Column {
    SecondaryTabRow(
        selectedTabIndex = state,
        indicator = {
            FancyIndicator(
                MaterialTheme.colorScheme.primary,
                Modifier.tabIndicatorOffset(state)
            )
        }
    ) {
        titles.forEachIndexed { index, title ->
            Tab(
                selected = state == index,
                onClick = { state = index },
                text = { Text(title) }
            )
        }
    }
    Text(
        modifier = Modifier.align(Alignment.CenterHorizontally),
        text = "Fancy indicator tab ${state + 1} selected",
        style = MaterialTheme.typography.bodyLarge
    )
}

You may also want to use a custom transition, to allow you to dynamically change the appearance of the indicator as it animates between tabs, such as changing its color or size. indicator is stacked on top of the entire TabRow, so you just need to provide a custom transition that animates the offset of the indicator from the start of the TabRow. For example, take the following example that uses a transition to animate the offset, width, and color of the same FancyIndicator from before, also adding a physics based 'spring' effect to the indicator in the direction of motion:

import androidx.compose.animation.animateColor
import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.ui.unit.IntOffset

val colors = listOf(
    MaterialTheme.colorScheme.primary,
    MaterialTheme.colorScheme.secondary,
    MaterialTheme.colorScheme.tertiary,
)
val transition = updateTransition(selectedTabIndex, label = "")
val indicatorStart by transition.animateDp(
    transitionSpec = {
        // Handle directionality here, if we are moving to the right, we
        // want the right side of the indicator to move faster, if we are
        // moving to the left, we want the left side to move faster.
        if (initialState < targetState) {
            spring(dampingRatio = 1f, stiffness = 50f)
        } else {
            spring(dampingRatio = 1f, stiffness = 1000f)
        }
    }, label = "fancy_indicator"
) {
    tabPositions[it].left
}

val indicatorEnd by transition.animateDp(
    transitionSpec = {
        // Handle directionality here, if we are moving to the right, we
        // want the right side of the indicator to move faster, if we are
        // moving to the left, we want the left side to move faster.
        if (initialState < targetState) {
            spring(dampingRatio = 1f, stiffness = 1000f)
        } else {
            spring(dampingRatio = 1f, stiffness = 50f)
        }
    }, label = "indicator_position"
) {
    tabPositions[it].right
}

val indicatorColor by transition.animateColor(label = "indicator_color") {
    colors[it % colors.size]
}

FancyIndicator(
    // Pass the current color to the indicator
    indicatorColor,
    modifier = Modifier
        // Fill up the entire TabRow, and place the indicator at the start
        .fillMaxSize()
        .wrapContentSize(align = Alignment.BottomStart)
        // Apply an offset from the start to correctly position the indicator around the tab
        .offset { IntOffset(x = indicatorStart.roundToPx(), y = 0) }
        // Make the width of the indicator follow the animated width as we move between tabs
        .width(indicatorEnd - indicatorStart)
)

We can now just pass this indicator directly to TabRow:

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.SecondaryTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var state by remember { mutableStateOf(0) }
val titles = listOf("Tab 1", "Tab 2", "Tab 3")

Column {
    SecondaryTabRow(
        selectedTabIndex = state,
        indicator = { FancyAnimatedIndicatorWithModifier(state) }
    ) {
        titles.forEachIndexed { index, title ->
            Tab(
                selected = state == index,
                onClick = { state = index },
                text = { Text(title) }
            )
        }
    }
    Text(
        modifier = Modifier.align(Alignment.CenterHorizontally),
        text = "Fancy transition tab ${state + 1} selected",
        style = MaterialTheme.typography.bodyLarge
    )
}
Parameters
selectedTabIndex: Int

the index of the currently selected tab

modifier: Modifier = Modifier

the Modifier to be applied to this tab row

containerColor: Color = TabRowDefaults.primaryContainerColor

the color used for the background of this tab row. Use Color.Transparent to have no color.

contentColor: Color = TabRowDefaults.primaryContentColor

the preferred color for content inside this tab row. Defaults to either the matching content color for containerColor, or to the current LocalContentColor if containerColor is not a color from the theme.

indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions -> if (selectedTabIndex < tabPositions.size) { TabRowDefaults.SecondaryIndicator( Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]) ) } }

the indicator that represents which tab is currently selected. By default this will be a TabRowDefaults.SecondaryIndicator, using a TabRowDefaults.tabIndicatorOffset modifier to animate its position. Note that this indicator will be forced to fill up the entire tab row, so you should use TabRowDefaults.tabIndicatorOffset or similar to animate the actual drawn indicator inside this space, and provide an offset from the start.

divider: @Composable () -> Unit = @Composable { HorizontalDivider() }

the divider displayed at the bottom of the tab row. This provides a layer of separation between the tab row and the content displayed underneath.

tabs: @Composable () -> Unit

the tabs inside this tab row. Typically this will be multiple Tabs. Each element inside this lambda will be measured and placed evenly across the row, each taking up equal space.

@Composable
fun Text(
    text: String,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    fontSize: TextUnit = TextUnit.Unspecified,
    fontStyle: FontStyle? = null,
    fontWeight: FontWeight? = null,
    fontFamily: FontFamily? = null,
    letterSpacing: TextUnit = TextUnit.Unspecified,
    textDecoration: TextDecoration? = null,
    textAlign: TextAlign? = null,
    lineHeight: TextUnit = TextUnit.Unspecified,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    minLines: Int = 1,
    onTextLayout: ((TextLayoutResult) -> Unit)? = null,
    style: TextStyle = LocalTextStyle.current
): Unit

High level element that displays text and provides semantics / accessibility information.

The default style uses the LocalTextStyle provided by the MaterialTheme / components. If you are setting your own style, you may want to consider first retrieving LocalTextStyle, and using TextStyle.copy to keep any theme defined attributes, only modifying the specific attributes you want to override.

For ease of use, commonly used parameters from TextStyle are also present here. The order of precedence is as follows:

  • If a parameter is explicitly set here (i.e, it is not null or TextUnit.Unspecified), then this parameter will always be used.

  • If a parameter is not set, (null or TextUnit.Unspecified), then the corresponding value from style will be used instead.

Additionally, for color, if color is not set, and style does not have a color, then LocalContentColor will be used.

Parameters
text: String

the text to be displayed

modifier: Modifier = Modifier

the Modifier to be applied to this layout node

color: Color = Color.Unspecified

Color to apply to the text. If Color.Unspecified, and style has no color set, this will be LocalContentColor.

fontSize: TextUnit = TextUnit.Unspecified

the size of glyphs to use when painting the text. See TextStyle.fontSize.

fontStyle: FontStyle? = null

the typeface variant to use when drawing the letters (e.g., italic). See TextStyle.fontStyle.

fontWeight: FontWeight? = null

the typeface thickness to use when painting the text (e.g., FontWeight.Bold).

fontFamily: FontFamily? = null

the font family to be used when rendering the text. See TextStyle.fontFamily.

letterSpacing: TextUnit = TextUnit.Unspecified

the amount of space to add between each letter. See TextStyle.letterSpacing.

textDecoration: TextDecoration? = null

the decorations to paint on the text (e.g., an underline). See TextStyle.textDecoration.

textAlign: TextAlign? = null

the alignment of the text within the lines of the paragraph. See TextStyle.textAlign.

lineHeight: TextUnit = TextUnit.Unspecified

line height for the Paragraph in TextUnit unit, e.g. SP or EM. See TextStyle.lineHeight.

overflow: TextOverflow = TextOverflow.Clip

how visual overflow should be handled.

softWrap: Boolean = true

whether the text should break at soft line breaks. If false, the glyphs in the text will be positioned as if there was unlimited horizontal space. If softWrap is false, overflow and TextAlign may have unexpected effects.

maxLines: Int = Int.MAX_VALUE

An optional maximum number of lines for the text to span, wrapping if necessary. If the text exceeds the given number of lines, it will be truncated according to overflow and softWrap. It is required that 1 <= minLines<= maxLines.

minLines: Int = 1

The minimum height in terms of minimum number of visible lines. It is required that 1 <= minLines<= maxLines.

onTextLayout: ((TextLayoutResult) -> Unit)? = null

callback that is executed when a new text layout is calculated. A TextLayoutResult object that callback provides contains paragraph information, size of the text, baselines and other details. The callback can be used to add additional decoration or functionality to the text. For example, to draw selection around the text.

style: TextStyle = LocalTextStyle.current

style configuration for the text such as color, font, line height etc.

@Composable
fun Text(
    text: AnnotatedString,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    fontSize: TextUnit = TextUnit.Unspecified,
    fontStyle: FontStyle? = null,
    fontWeight: FontWeight? = null,
    fontFamily: FontFamily? = null,
    letterSpacing: TextUnit = TextUnit.Unspecified,
    textDecoration: TextDecoration? = null,
    textAlign: TextAlign? = null,
    lineHeight: TextUnit = TextUnit.Unspecified,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    minLines: Int = 1,
    inlineContent: Map<StringInlineTextContent> = mapOf(),
    onTextLayout: (TextLayoutResult) -> Unit = {},
    style: TextStyle = LocalTextStyle.current
): Unit

High level element that displays text and provides semantics / accessibility information.

The default style uses the LocalTextStyle provided by the MaterialTheme / components. If you are setting your own style, you may want to consider first retrieving LocalTextStyle, and using TextStyle.copy to keep any theme defined attributes, only modifying the specific attributes you want to override.

For ease of use, commonly used parameters from TextStyle are also present here. The order of precedence is as follows:

  • If a parameter is explicitly set here (i.e, it is not null or TextUnit.Unspecified), then this parameter will always be used.

  • If a parameter is not set, (null or TextUnit.Unspecified), then the corresponding value from style will be used instead.

Additionally, for color, if color is not set, and style does not have a color, then LocalContentColor will be used.

Parameters
text: AnnotatedString

the text to be displayed

modifier: Modifier = Modifier

the Modifier to be applied to this layout node

color: Color = Color.Unspecified

Color to apply to the text. If Color.Unspecified, and style has no color set, this will be LocalContentColor.

fontSize: TextUnit = TextUnit.Unspecified

the size of glyphs to use when painting the text. See TextStyle.fontSize.

fontStyle: FontStyle? = null

the typeface variant to use when drawing the letters (e.g., italic). See TextStyle.fontStyle.

fontWeight: FontWeight? = null

the typeface thickness to use when painting the text (e.g., FontWeight.Bold).

fontFamily: FontFamily? = null

the font family to be used when rendering the text. See TextStyle.fontFamily.

letterSpacing: TextUnit = TextUnit.Unspecified

the amount of space to add between each letter. See TextStyle.letterSpacing.

textDecoration: TextDecoration? = null

the decorations to paint on the text (e.g., an underline). See TextStyle.textDecoration.

textAlign: TextAlign? = null

the alignment of the text within the lines of the paragraph. See TextStyle.textAlign.

lineHeight: TextUnit = TextUnit.Unspecified

line height for the Paragraph in TextUnit unit, e.g. SP or EM. See TextStyle.lineHeight.

overflow: TextOverflow = TextOverflow.Clip

how visual overflow should be handled.

softWrap: Boolean = true

whether the text should break at soft line breaks. If false, the glyphs in the text will be positioned as if there was unlimited horizontal space. If softWrap is false, overflow and TextAlign may have unexpected effects.

maxLines: Int = Int.MAX_VALUE

An optional maximum number of lines for the text to span, wrapping if necessary. If the text exceeds the given number of lines, it will be truncated according to overflow and softWrap. It is required that 1 <= minLines<= maxLines.

minLines: Int = 1

The minimum height in terms of minimum number of visible lines. It is required that 1 <= minLines<= maxLines.

inlineContent: Map<StringInlineTextContent> = mapOf()

a map storing composables that replaces certain ranges of the text, used to insert composables into text layout. See InlineTextContent.

onTextLayout: (TextLayoutResult) -> Unit = {}

callback that is executed when a new text layout is calculated. A TextLayoutResult object that callback provides contains paragraph information, size of the text, baselines and other details. The callback can be used to add additional decoration or functionality to the text. For example, to draw selection around the text.

style: TextStyle = LocalTextStyle.current

style configuration for the text such as color, font, line height etc.

TextButton

@Composable
fun TextButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = ButtonDefaults.textShape,
    colors: ButtonColors = ButtonDefaults.textButtonColors(),
    elevation: ButtonElevation? = null,
    border: BorderStroke? = null,
    contentPadding: PaddingValues = ButtonDefaults.TextButtonContentPadding,
    interactionSource: MutableInteractionSource? = null,
    content: @Composable RowScope.() -> Unit
): Unit

Material Design text button.

Buttons help people initiate actions, from sending an email, to sharing a document, to liking a post.

Text button image

Text buttons are typically used for less-pronounced actions, including those located in dialogs and cards. In cards, text buttons help maintain an emphasis on card content. Text buttons are used for the lowest priority actions, especially when presenting multiple options.

import androidx.compose.material3.Text
import androidx.compose.material3.TextButton

TextButton(onClick = { /* Do something! */ }) { Text("Text Button") }

Choose the best button for an action based on the amount of emphasis it needs. The more important an action is, the higher emphasis its button should be.

The default text style for internal Text components will be set to Typography.labelLarge.

Parameters
onClick: () -> Unit

called when this button is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this button

enabled: Boolean = true

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

shape: Shape = ButtonDefaults.textShape

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

colors: ButtonColors = ButtonDefaults.textButtonColors()

ButtonColors that will be used to resolve the colors for this button in different states. See ButtonDefaults.textButtonColors.

elevation: ButtonElevation? = null

ButtonElevation used to resolve the elevation for this button in different states. This controls the size of the shadow below the button. Additionally, when the container color is ColorScheme.surface, this controls the amount of primary color applied as an overlay. A TextButton typically has no elevation, and the default value is null. See ElevatedButton for a button with elevation.

border: BorderStroke? = null

the border to draw around the container of this button

contentPadding: PaddingValues = ButtonDefaults.TextButtonContentPadding

the spacing values to apply internally between the container and the content

interactionSource: MutableInteractionSource? = null

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

TextField

@Composable
fun TextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    label: (@Composable () -> Unit)? = null,
    placeholder: (@Composable () -> Unit)? = null,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    prefix: (@Composable () -> Unit)? = null,
    suffix: (@Composable () -> Unit)? = null,
    supportingText: (@Composable () -> Unit)? = null,
    isError: Boolean = false,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    singleLine: Boolean = false,
    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
    minLines: Int = 1,
    interactionSource: MutableInteractionSource? = null,
    shape: Shape = TextFieldDefaults.shape,
    colors: TextFieldColors = TextFieldDefaults.colors()
): Unit

Material Design filled text field.

Text fields allow users to enter text into a UI. They typically appear in forms and dialogs. Filled text fields have more visual emphasis than outlined text fields, making them stand out when surrounded by other content and components.

Filled text field image

If you are looking for an outlined version, see OutlinedTextField.

A simple single line text field looks like:

import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable

var text by rememberSaveable { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Label") },
    singleLine = true
)

You may provide a placeholder:

import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable

var text by rememberSaveable { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Email") },
    placeholder = { Text("example@gmail.com") }
)

You can also provide leading and trailing icons:

import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable

var text by rememberSaveable { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Label") },
    leadingIcon = { Icon(Icons.Filled.Favorite, contentDescription = "Localized description") },
    trailingIcon = { Icon(Icons.Filled.Info, contentDescription = "Localized description") }
)

You can also provide a prefix or suffix to the text:

import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable

var text by rememberSaveable { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    singleLine = true,
    label = { Text("Label") },
    prefix = { Text("www.") },
    suffix = { Text(".com") },
    placeholder = { Text("google") },
)

To handle the error input state, use isError parameter:

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.semantics.error
import androidx.compose.ui.semantics.semantics

val errorMessage = "Text input too long"
var text by rememberSaveable { mutableStateOf("") }
var isError by rememberSaveable { mutableStateOf(false) }
val charLimit = 10

fun validate(text: String) {
    isError = text.length > charLimit
}

TextField(
    value = text,
    onValueChange = {
        text = it
        validate(text)
    },
    singleLine = true,
    label = { Text(if (isError) "Username*" else "Username") },
    supportingText = {
        Text(
            modifier = Modifier.fillMaxWidth(),
            text = "Limit: ${text.length}/$charLimit",
            textAlign = TextAlign.End,
        )
    },
    isError = isError,
    keyboardActions = KeyboardActions { validate(text) },
    modifier = Modifier.semantics {
        // Provide localized description of the error
        if (isError) error(errorMessage)
    }
)

Additionally, you may provide additional message at the bottom:

import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable

var text by rememberSaveable { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Label") },
    supportingText = {
        Text("Supporting text that is long and perhaps goes onto another line.")
    },
)

Password text field example:

import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.text.input.PasswordVisualTransformation

var password by rememberSaveable { mutableStateOf("") }
var passwordHidden by rememberSaveable { mutableStateOf(true) }
TextField(
    value = password,
    onValueChange = { password = it },
    singleLine = true,
    label = { Text("Enter password") },
    visualTransformation =
    if (passwordHidden) PasswordVisualTransformation() else VisualTransformation.None,
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
    trailingIcon = {
        IconButton(onClick = { passwordHidden = !passwordHidden }) {
            val visibilityIcon =
                if (passwordHidden) Icons.Filled.Visibility else Icons.Filled.VisibilityOff
            // Please provide localized description for accessibility services
            val description = if (passwordHidden) "Show password" else "Hide password"
            Icon(imageVector = visibilityIcon, contentDescription = description)
        }
    }
)

Hiding a software keyboard on IME action performed:

import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable

val keyboardController = LocalSoftwareKeyboardController.current
var text by rememberSaveable { mutableStateOf("") }
TextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Label") },
    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
    keyboardActions = KeyboardActions(
        onDone = {
            keyboardController?.hide()
            // do something here
        }
    )
)

If apart from input text change you also want to observe the cursor location, selection range, or IME composition use the TextField overload with the TextFieldValue parameter instead.

Parameters
value: String

the input text to be shown in the text field

onValueChange: (String) -> Unit

the callback that is triggered when the input service updates the text. An updated text comes as a parameter of the callback

modifier: Modifier = Modifier

the Modifier to be applied to this text field

enabled: Boolean = true

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

readOnly: Boolean = false

controls the editable state of the text field. When true, the text field cannot be modified. However, a user can focus it and copy text from it. Read-only text fields are usually used to display pre-filled forms that a user cannot edit.

textStyle: TextStyle = LocalTextStyle.current

the style to be applied to the input text. Defaults to LocalTextStyle.

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

the optional label to be displayed inside the text field container. The default text style for internal Text is Typography.bodySmall when the text field is in focus and Typography.bodyLarge when the text field is not in focus

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

the optional placeholder to be displayed when the text field is in focus and the input text is empty. The default text style for internal Text is Typography.bodyLarge

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

the optional leading icon to be displayed at the beginning of the text field container

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

the optional trailing icon to be displayed at the end of the text field container

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

the optional prefix to be displayed before the input text in the text field

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

the optional suffix to be displayed after the input text in the text field

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

the optional supporting text to be displayed below the text field

isError: Boolean = false

indicates if the text field's current value is in error. If set to true, the label, bottom indicator and trailing icon by default will be displayed in error color

visualTransformation: VisualTransformation = VisualTransformation.None

transforms the visual representation of the input value For example, you can use PasswordVisualTransformation to create a password text field. By default, no visual transformation is applied.

keyboardOptions: KeyboardOptions = KeyboardOptions.Default

software keyboard options that contains configuration such as KeyboardType and ImeAction.

keyboardActions: KeyboardActions = KeyboardActions.Default

when the input service emits an IME action, the corresponding callback is called. Note that this IME action may be different from what you specified in KeyboardOptions.imeAction.

singleLine: Boolean = false

when true, this text field becomes a single horizontally scrolling text field instead of wrapping onto multiple lines. The keyboard will be informed to not show the return key as the ImeAction. Note that maxLines parameter will be ignored as the maxLines attribute will be automatically set to 1.

maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE

the maximum height in terms of maximum number of visible lines. It is required that 1 <= minLines<= maxLines. This parameter is ignored when singleLine is true.

minLines: Int = 1

the minimum height in terms of minimum number of visible lines. It is required that 1 <= minLines<= maxLines. This parameter is ignored when singleLine is true.

interactionSource: MutableInteractionSource? = null

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

shape: Shape = TextFieldDefaults.shape

defines the shape of this text field's container

colors: TextFieldColors = TextFieldDefaults.colors()

TextFieldColors that will be used to resolve the colors used for this text field in different states. See TextFieldDefaults.colors.

TextField

@Composable
fun TextField(
    value: TextFieldValue,
    onValueChange: (TextFieldValue) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    label: (@Composable () -> Unit)? = null,
    placeholder: (@Composable () -> Unit)? = null,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    prefix: (@Composable () -> Unit)? = null,
    suffix: (@Composable () -> Unit)? = null,
    supportingText: (@Composable () -> Unit)? = null,
    isError: Boolean = false,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    singleLine: Boolean = false,
    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
    minLines: Int = 1,
    interactionSource: MutableInteractionSource? = null,
    shape: Shape = TextFieldDefaults.shape,
    colors: TextFieldColors = TextFieldDefaults.colors()
): Unit

Material Design filled text field.

Text fields allow users to enter text into a UI. They typically appear in forms and dialogs. Filled text fields have more visual emphasis than outlined text fields, making them stand out when surrounded by other content and components.

Filled text field image

If you are looking for an outlined version, see OutlinedTextField.

See example usage:

import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.TextFieldValue

var text by rememberSaveable(stateSaver = TextFieldValue.Saver) {
    mutableStateOf(TextFieldValue("example", TextRange(0, 7)))
}

TextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Label") }
)

This overload provides access to the input text, cursor position, selection range and IME composition. If you only want to observe an input text change, use the TextField overload with the String parameter instead.

Parameters
value: TextFieldValue

the input TextFieldValue to be shown in the text field

onValueChange: (TextFieldValue) -> Unit

the callback that is triggered when the input service updates values in TextFieldValue. An updated TextFieldValue comes as a parameter of the callback

modifier: Modifier = Modifier

the Modifier to be applied to this text field

enabled: Boolean = true

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

readOnly: Boolean = false

controls the editable state of the text field. When true, the text field cannot be modified. However, a user can focus it and copy text from it. Read-only text fields are usually used to display pre-filled forms that a user cannot edit.

textStyle: TextStyle = LocalTextStyle.current

the style to be applied to the input text. Defaults to LocalTextStyle.

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

the optional label to be displayed inside the text field container. The default text style for internal Text is Typography.bodySmall when the text field is in focus and Typography.bodyLarge when the text field is not in focus

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

the optional placeholder to be displayed when the text field is in focus and the input text is empty. The default text style for internal Text is Typography.bodyLarge

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

the optional leading icon to be displayed at the beginning of the text field container

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

the optional trailing icon to be displayed at the end of the text field container

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

the optional prefix to be displayed before the input text in the text field

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

the optional suffix to be displayed after the input text in the text field

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

the optional supporting text to be displayed below the text field

isError: Boolean = false

indicates if the text field's current value is in error state. If set to true, the label, bottom indicator and trailing icon by default will be displayed in error color

visualTransformation: VisualTransformation = VisualTransformation.None

transforms the visual representation of the input value. For example, you can use PasswordVisualTransformation to create a password text field. By default, no visual transformation is applied.

keyboardOptions: KeyboardOptions = KeyboardOptions.Default

software keyboard options that contains configuration such as KeyboardType and ImeAction.

keyboardActions: KeyboardActions = KeyboardActions.Default

when the input service emits an IME action, the corresponding callback is called. Note that this IME action may be different from what you specified in KeyboardOptions.imeAction.

singleLine: Boolean = false

when true, this text field becomes a single horizontally scrolling text field instead of wrapping onto multiple lines. The keyboard will be informed to not show the return key as the ImeAction. Note that maxLines parameter will be ignored as the maxLines attribute will be automatically set to 1.

maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE

the maximum height in terms of maximum number of visible lines. It is required that 1 <= minLines<= maxLines. This parameter is ignored when singleLine is true.

minLines: Int = 1

the minimum height in terms of minimum number of visible lines. It is required that 1 <= minLines<= maxLines. This parameter is ignored when singleLine is true.

interactionSource: MutableInteractionSource? = null

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

shape: Shape = TextFieldDefaults.shape

defines the shape of this text field's container

colors: TextFieldColors = TextFieldDefaults.colors()

TextFieldColors that will be used to resolve the colors used for this text field in different states. See TextFieldDefaults.colors.

TimeInput

@Composable
@ExperimentalMaterial3Api
fun TimeInput(
    state: TimePickerState,
    modifier: Modifier = Modifier,
    colors: TimePickerColors = TimePickerDefaults.colors()
): Unit

Time pickers help users select and set a specific time.

Shows a time input that allows the user to enter the time via two text fields, one for minutes and one for hours Subscribe to updates through TimePickerState

import androidx.compose.foundation.layout.Box
import androidx.compose.material3.Button
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TimeInput
import androidx.compose.material3.rememberTimePickerState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

var showTimePicker by remember { mutableStateOf(false) }
val state = rememberTimePickerState()
val formatter = remember { SimpleDateFormat("hh:mm a", Locale.getDefault()) }
val snackState = remember { SnackbarHostState() }
val snackScope = rememberCoroutineScope()

Box(propagateMinConstraints = false) {
    Button(
        modifier = Modifier.align(Alignment.Center),
        onClick = { showTimePicker = true }
    ) {
        Text("Set Time")
    }
    SnackbarHost(hostState = snackState)
}

if (showTimePicker) {
    TimePickerDialog(
        onCancel = { showTimePicker = false },
        onConfirm = {
            val cal = Calendar.getInstance()
            cal.set(Calendar.HOUR_OF_DAY, state.hour)
            cal.set(Calendar.MINUTE, state.minute)
            cal.isLenient = false
            snackScope.launch {
                snackState.showSnackbar("Entered time: ${formatter.format(cal.time)}")
            }
            showTimePicker = false
        },
    ) {
        TimeInput(state = state)
    }
}
Parameters
state: TimePickerState

state for this timepicker, allows to subscribe to changes to TimePickerState.hour and TimePickerState.minute, and set the initial time for this picker.

modifier: Modifier = Modifier

the Modifier to be applied to this time input

colors: TimePickerColors = TimePickerDefaults.colors()

colors TimePickerColors that will be used to resolve the colors used for this time input in different states. See TimePickerDefaults.colors.

@Composable
@ExperimentalMaterial3Api
fun TimePicker(
    state: TimePickerState,
    modifier: Modifier = Modifier,
    colors: TimePickerColors = TimePickerDefaults.colors(),
    layoutType: TimePickerLayoutType = TimePickerDefaults.layoutType()
): Unit

Material Design time picker.

Time pickers help users select and set a specific time.

Shows a picker that allows the user to select time. Subscribe to updates through TimePickerState

Time picker image

import androidx.compose.foundation.layout.Box
import androidx.compose.material3.Button
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TimePicker
import androidx.compose.material3.rememberTimePickerState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

var showTimePicker by remember { mutableStateOf(false) }
val state = rememberTimePickerState()
val formatter = remember { SimpleDateFormat("hh:mm a", Locale.getDefault()) }
val snackState = remember { SnackbarHostState() }
val snackScope = rememberCoroutineScope()

Box(propagateMinConstraints = false) {
    Button(
        modifier = Modifier.align(Alignment.Center),
        onClick = { showTimePicker = true }
    ) {
        Text("Set Time")
    }
    SnackbarHost(hostState = snackState)
}

if (showTimePicker) {
    TimePickerDialog(
        onCancel = { showTimePicker = false },
        onConfirm = {
            val cal = Calendar.getInstance()
            cal.set(Calendar.HOUR_OF_DAY, state.hour)
            cal.set(Calendar.MINUTE, state.minute)
            cal.isLenient = false
            snackScope.launch {
                snackState.showSnackbar("Entered time: ${formatter.format(cal.time)}")
            }
            showTimePicker = false
        },
    ) {
        TimePicker(state = state)
    }
}
import androidx.compose.foundation.layout.Box
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TimeInput
import androidx.compose.material3.TimePicker
import androidx.compose.material3.rememberTimePickerState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope

var showTimePicker by remember { mutableStateOf(false) }
val state = rememberTimePickerState()
val formatter = remember { SimpleDateFormat("hh:mm a", Locale.getDefault()) }
val snackState = remember { SnackbarHostState() }
val showingPicker = remember { mutableStateOf(true) }
val snackScope = rememberCoroutineScope()
val configuration = LocalConfiguration.current

Box(propagateMinConstraints = false) {
    Button(
        modifier = Modifier.align(Alignment.Center),
        onClick = { showTimePicker = true }
    ) {
        Text("Set Time")
    }
    SnackbarHost(hostState = snackState)
}

if (showTimePicker) {
    TimePickerDialog(
        title = if (showingPicker.value) {
            "Select Time "
        } else {
            "Enter Time"
        },
        onCancel = { showTimePicker = false },
        onConfirm = {
            val cal = Calendar.getInstance()
            cal.set(Calendar.HOUR_OF_DAY, state.hour)
            cal.set(Calendar.MINUTE, state.minute)
            cal.isLenient = false
            snackScope.launch {
                snackState.showSnackbar("Entered time: ${formatter.format(cal.time)}")
            }
            showTimePicker = false
        },
        toggle = {
            if (configuration.screenHeightDp > 400) {
                IconButton(onClick = { showingPicker.value = !showingPicker.value }) {
                    val icon = if (showingPicker.value) {
                        Icons.Outlined.Keyboard
                    } else {
                        Icons.Outlined.Schedule
                    }
                    Icon(
                        icon,
                        contentDescription = if (showingPicker.value) {
                            "Switch to Text Input"
                        } else {
                            "Switch to Touch Input"
                        }
                    )
                }
            }
        }
    ) {
        if (showingPicker.value && configuration.screenHeightDp > 400) {
            TimePicker(state = state)
        } else {
            TimeInput(state = state)
        }
    }
}

state state for this timepicker, allows to subscribe to changes to TimePickerState.hour and TimePickerState.minute, and set the initial time for this picker.

Parameters
state: TimePickerState

state for this time input, allows to subscribe to changes to TimePickerState.hour and TimePickerState.minute, and set the initial time for this input.

modifier: Modifier = Modifier

the Modifier to be applied to this time input

colors: TimePickerColors = TimePickerDefaults.colors()

colors TimePickerColors that will be used to resolve the colors used for this time picker in different states. See TimePickerDefaults.colors.

layoutType: TimePickerLayoutType = TimePickerDefaults.layoutType()

, the different TimePickerLayoutType supported by this time picker, it will change the position and sizing of different components of the timepicker.

TooltipBox

@Composable
@ExperimentalMaterial3Api
fun TooltipBox(
    positionProvider: PopupPositionProvider,
    tooltip: @Composable CaretScope.() -> Unit,
    state: TooltipState,
    modifier: Modifier = Modifier,
    focusable: Boolean = true,
    enableUserInput: Boolean = true,
    content: @Composable () -> Unit
): Unit

Material TooltipBox that wraps a composable with a tooltip.

tooltips provide a descriptive message for an anchor. It can be used to call the users attention to the anchor.

Tooltip that is invoked when the anchor is long pressed:

import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.rememberTooltipState

TooltipBox(
    positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
    tooltip = {
        PlainTooltip {
            Text("Add to favorites")
        }
    },
    state = rememberTooltipState()
) {
    IconButton(
        onClick = { /* Icon button's click event */ }
    ) {
        Icon(
            imageVector = Icons.Filled.Favorite,
            contentDescription = "Localized Description"
        )
    }
}

If control of when the tooltip is shown is desired please see

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.rememberCoroutineScope

val tooltipState = rememberTooltipState()
val scope = rememberCoroutineScope()
Column(
    horizontalAlignment = Alignment.CenterHorizontally
) {
    TooltipBox(
        positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
        tooltip = {
            PlainTooltip {
                Text("Add to list")
            }
        },
        state = tooltipState
    ) {
        Icon(
            imageVector = Icons.Filled.AddCircle,
            contentDescription = "Localized Description"
        )
    }
    Spacer(Modifier.requiredHeight(30.dp))
    OutlinedButton(
        onClick = { scope.launch { tooltipState.show() } }
    ) {
        Text("Display tooltip")
    }
}

Plain tooltip with caret shown on long press:

import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.rememberTooltipState

TooltipBox(
    positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
    tooltip = {
        PlainTooltip(
            caretProperties = TooltipDefaults.caretProperties
        ) {
            Text("Add to favorites")
        }
    },
    state = rememberTooltipState()
) {
    IconButton(
        onClick = { /* Icon button's click event */ }
    ) {
        Icon(
            imageVector = Icons.Filled.Favorite,
            contentDescription = "Localized Description"
        )
    }
}

Plain tooltip shown on long press with a custom CaretProperties

import androidx.compose.material3.CaretProperties
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.rememberTooltipState

TooltipBox(
    positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
    tooltip = {
        PlainTooltip(
            caretProperties = CaretProperties(12.dp, 24.dp)
        ) {
            Text("Add to favorites")
        }
    },
    state = rememberTooltipState()
) {
    IconButton(
        onClick = { /* Icon button's click event */ }
    ) {
        Icon(
            imageVector = Icons.Filled.Favorite,
            contentDescription = "Localized Description"
        )
    }
}

Tooltip that is invoked when the anchor is long pressed:

import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.RichTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.rememberCoroutineScope

val tooltipState = rememberTooltipState(isPersistent = true)
val scope = rememberCoroutineScope()
TooltipBox(
    positionProvider = TooltipDefaults.rememberRichTooltipPositionProvider(),
    tooltip = {
        RichTooltip(
            title = { Text(richTooltipSubheadText) },
            action = {
                TextButton(
                    onClick = { scope.launch { tooltipState.dismiss() } }
                ) { Text(richTooltipActionText) }
            }
        ) {
            Text(richTooltipText)
        }
    },
    state = tooltipState
) {
    IconButton(
        onClick = { /* Icon button's click event */ }
    ) {
        Icon(
            imageVector = Icons.Filled.Info,
            contentDescription = "Localized Description"
        )
    }
}

If control of when the tooltip is shown is desired please see

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.RichTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.rememberCoroutineScope

val tooltipState = rememberTooltipState(isPersistent = true)
val scope = rememberCoroutineScope()
Column(
    horizontalAlignment = Alignment.CenterHorizontally
) {
    TooltipBox(
        positionProvider = TooltipDefaults.rememberRichTooltipPositionProvider(),
        tooltip = {
            RichTooltip(
                title = { Text(richTooltipSubheadText) },
                action = {
                    TextButton(
                        onClick = {
                            scope.launch {
                                tooltipState.dismiss()
                            }
                        }
                    ) { Text(richTooltipActionText) }
                }
            ) { Text(richTooltipText) }
        },
        state = tooltipState
    ) {
        Icon(
            imageVector = Icons.Filled.Info,
            contentDescription = "Localized Description"
        )
    }
    Spacer(Modifier.requiredHeight(30.dp))
    OutlinedButton(
        onClick = { scope.launch { tooltipState.show() } }
    ) {
        Text("Display tooltip")
    }
}

Rich tooltip with caret shown on long press:

import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.RichTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.rememberCoroutineScope

val tooltipState = rememberTooltipState(isPersistent = true)
val scope = rememberCoroutineScope()
TooltipBox(
    positionProvider = TooltipDefaults.rememberRichTooltipPositionProvider(),
    tooltip = {
        RichTooltip(
            title = { Text(richTooltipSubheadText) },
            action = {
                TextButton(
                    onClick = { scope.launch { tooltipState.dismiss() } }
                ) { Text(richTooltipActionText) }
            },
            caretProperties = TooltipDefaults.caretProperties
        ) {
            Text(richTooltipText)
        }
    },
    state = tooltipState
) {
    IconButton(
        onClick = { /* Icon button's click event */ }
    ) {
        Icon(
            imageVector = Icons.Filled.Info,
            contentDescription = "Localized Description"
        )
    }
}

Rich tooltip shown on long press with a custom CaretProperties

import androidx.compose.material3.CaretProperties
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.RichTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.rememberCoroutineScope

val tooltipState = rememberTooltipState(isPersistent = true)
val scope = rememberCoroutineScope()
TooltipBox(
    positionProvider = TooltipDefaults.rememberRichTooltipPositionProvider(),
    tooltip = {
        RichTooltip(
            title = { Text(richTooltipSubheadText) },
            action = {
                TextButton(
                    onClick = { scope.launch { tooltipState.dismiss() } }
                ) { Text(richTooltipActionText) }
            },
            caretProperties = CaretProperties(16.dp, 32.dp)
        ) {
            Text(richTooltipText)
        }
    },
    state = tooltipState
) {
    IconButton(
        onClick = { /* Icon button's click event */ }
    ) {
        Icon(
            imageVector = Icons.Filled.Info,
            contentDescription = "Localized Description"
        )
    }
}
Parameters
positionProvider: PopupPositionProvider

PopupPositionProvider that will be used to place the tooltip relative to the anchor content.

tooltip: @Composable CaretScope.() -> Unit

the composable that will be used to populate the tooltip's content.

state: TooltipState

handles the state of the tooltip's visibility.

modifier: Modifier = Modifier

the Modifier to be applied to the TooltipBox.

focusable: Boolean = true

Boolean that determines if the tooltip is focusable. When true, the tooltip will consume touch events while it's shown and will have accessibility focus move to the first element of the component. When false, the tooltip won't consume touch events while it's shown but assistive-tech users will need to swipe or drag to get to the first element of the component.

enableUserInput: Boolean = true

Boolean which determines if this TooltipBox will handle long press and mouse hover to trigger the tooltip through the state provided.

content: @Composable () -> Unit

the composable that the tooltip will anchor to.

TooltipState

@ExperimentalMaterial3Api
fun TooltipState(
    initialIsVisible: Boolean = false,
    isPersistent: Boolean = true,
    mutatorMutex: MutatorMutex = BasicTooltipDefaults.GlobalMutatorMutex
): TooltipState

Constructor extension function for TooltipState

Parameters
initialIsVisible: Boolean = false

the initial value for the tooltip's visibility when drawn.

isPersistent: Boolean = true

Boolean that determines if the tooltip associated with this will be persistent or not. If isPersistent is true, then the tooltip will only be dismissed when the user clicks outside the bounds of the tooltip or if TooltipState.dismiss is called. When isPersistent is false, the tooltip will dismiss after a short duration. Ideally, this should be set to true when there is actionable content being displayed within a tooltip.

mutatorMutex: MutatorMutex = BasicTooltipDefaults.GlobalMutatorMutex

MutatorMutex used to ensure that for all of the tooltips associated with the mutator mutex, only one will be shown on the screen at any time.

TopAppBar

@ExperimentalMaterial3Api
@Composable
fun TopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    navigationIcon: @Composable () -> Unit = {},
    actions: @Composable RowScope.() -> Unit = {},
    windowInsets: WindowInsets = TopAppBarDefaults.windowInsets,
    colors: TopAppBarColors = TopAppBarDefaults.topAppBarColors(),
    scrollBehavior: TopAppBarScrollBehavior? = null
): Unit

Material Design small top app bar.

Top app bars display information and actions at the top of a screen.

This small TopAppBar has slots for a title, navigation icon, and actions.

Small top app bar image

A simple top app bar looks like:

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar

Scaffold(
    topBar = {
        TopAppBar(
            title = {
                Text(
                    "Simple TopAppBar",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
            },
            navigationIcon = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Menu,
                        contentDescription = "Localized description"
                    )
                }
            },
            actions = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Favorite,
                        contentDescription = "Localized description"
                    )
                }
            }
        )
    },
    content = { innerPadding ->
        LazyColumn(
            contentPadding = innerPadding,
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            val list = (0..75).map { it.toString() }
            items(count = list.size) {
                Text(
                    text = list[it],
                    style = MaterialTheme.typography.bodyLarge,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp)
                )
            }
        }
    }
)

A top app bar that uses a scrollBehavior to customize its nested scrolling behavior when working in conjunction with a scrolling content looks like:

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.ui.input.nestedscroll.nestedScroll

val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
Scaffold(
    modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
    topBar = {
        TopAppBar(
            title = {
                Text(
                    "TopAppBar",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
            },
            navigationIcon = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Menu,
                        contentDescription = "Localized description"
                    )
                }
            },
            actions = {
                // RowScope here, so these icons will be placed horizontally
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Favorite,
                        contentDescription = "Localized description"
                    )
                }
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Favorite,
                        contentDescription = "Localized description"
                    )
                }
            },
            scrollBehavior = scrollBehavior
        )
    },
    content = { innerPadding ->
        LazyColumn(
            contentPadding = innerPadding,
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            val list = (0..75).map { it.toString() }
            items(count = list.size) {
                Text(
                    text = list[it],
                    style = MaterialTheme.typography.bodyLarge,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp)
                )
            }
        }
    }
)
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.ui.input.nestedscroll.nestedScroll

val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
Scaffold(
    modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
    topBar = {
        TopAppBar(
            title = {
                Text(
                    "TopAppBar",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
            },
            navigationIcon = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Menu,
                        contentDescription = "Localized description"
                    )
                }
            },
            actions = {
                IconButton(onClick = { /* doSomething() */ }) {
                    Icon(
                        imageVector = Icons.Filled.Favorite,
                        contentDescription = "Localized description"
                    )
                }
            },
            scrollBehavior = scrollBehavior
        )
    },
    content = { innerPadding ->
        LazyColumn(
            contentPadding = innerPadding,
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            val list = (0..75).map { it.toString() }
            items(count = list.size) {
                Text(
                    text = list[it],
                    style = MaterialTheme.typography.bodyLarge,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp)
                )
            }
        }
    }
)
Parameters
title: @Composable () -> Unit

the title to be displayed in the top app bar

modifier: Modifier = Modifier

the Modifier to be applied to this top app bar

navigationIcon: @Composable () -> Unit = {}

the navigation icon displayed at the start of the top app bar. This should typically be an IconButton or IconToggleButton.

actions: @Composable RowScope.() -> Unit = {}

the actions displayed at the end of the top app bar. This should typically be IconButtons. The default layout here is a Row, so icons inside will be placed horizontally.

windowInsets: WindowInsets = TopAppBarDefaults.windowInsets

a window insets that app bar will respect.

colors: TopAppBarColors = TopAppBarDefaults.topAppBarColors()

TopAppBarColors that will be used to resolve the colors used for this top app bar in different states. See TopAppBarDefaults.topAppBarColors.

scrollBehavior: TopAppBarScrollBehavior? = null

a TopAppBarScrollBehavior which holds various offset values that will be applied by this top app bar to set up its height and colors. A scroll behavior is designed to work in conjunction with a scrolled content to change the top app bar appearance as the content scrolls. See TopAppBarScrollBehavior.nestedScrollConnection.

TriStateCheckbox

@Composable
fun TriStateCheckbox(
    state: ToggleableState,
    onClick: (() -> Unit)?,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    colors: CheckboxColors = CheckboxDefaults.colors(),
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design checkbox parent.

Checkboxes can have a parent-child relationship with other checkboxes. When the parent checkbox is checked, all child checkboxes are checked. If a parent checkbox is unchecked, all child checkboxes are unchecked. If some, but not all, child checkboxes are checked, the parent checkbox becomes an indeterminate checkbox.

Checkbox image

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Checkbox
import androidx.compose.material3.TriStateCheckbox
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

Column {
    // define dependent checkboxes states
    val (state, onStateChange) = remember { mutableStateOf(true) }
    val (state2, onStateChange2) = remember { mutableStateOf(true) }

    // TriStateCheckbox state reflects state of dependent checkboxes
    val parentState = remember(state, state2) {
        if (state && state2) ToggleableState.On
        else if (!state && !state2) ToggleableState.Off
        else ToggleableState.Indeterminate
    }
    // click on TriStateCheckbox can set state for dependent checkboxes
    val onParentClick = {
        val s = parentState != ToggleableState.On
        onStateChange(s)
        onStateChange2(s)
    }

    // The sample below composes just basic checkboxes which are not fully accessible on their
    // own. See the CheckboxWithTextSample as a way to ensure your checkboxes are fully
    // accessible.
    TriStateCheckbox(
        state = parentState,
        onClick = onParentClick,
    )
    Spacer(Modifier.size(25.dp))
    Column(Modifier.padding(10.dp, 0.dp, 0.dp, 0.dp)) {
        Checkbox(state, onStateChange)
        Spacer(Modifier.size(25.dp))
        Checkbox(state2, onStateChange2)
    }
}
Parameters
state: ToggleableState

whether this checkbox is checked, unchecked, or in an indeterminate state

onClick: (() -> Unit)?

called when this checkbox is clicked. If null, then this checkbox will not be interactable, unless something else handles its input events and updates its state.

modifier: Modifier = Modifier

the Modifier to be applied to this checkbox

enabled: Boolean = true

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

colors: CheckboxColors = CheckboxDefaults.colors()

CheckboxColors that will be used to resolve the colors used for this checkbox in different states. See CheckboxDefaults.colors.

interactionSource: MutableInteractionSource? = null

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

See also
Checkbox

if you want a simple component that represents Boolean state

VerticalDivider

@Composable
fun VerticalDivider(
    modifier: Modifier = Modifier,
    thickness: Dp = DividerDefaults.Thickness,
    color: Color = DividerDefaults.color
): Unit

Material Design divider.

A divider is a thin line that groups content in lists and layouts.

Divider image

Parameters
modifier: Modifier = Modifier

the Modifier to be applied to this divider line.

thickness: Dp = DividerDefaults.Thickness

thickness of this divider line. Using Dp.Hairline will produce a single pixel divider regardless of screen density.

color: Color = DividerDefaults.color

color of this divider line.

contentColorFor

@Composable
fun contentColorFor(backgroundColor: Color): Color

The Material color system contains pairs of colors that are typically used for the background and content color inside a component. For example, a Button typically uses primary for its background, and onPrimary for the color of its content (usually text or iconography).

This function tries to match the provided backgroundColor to a 'background' color in this ColorScheme, and then will return the corresponding color used for content. For example, when backgroundColor is ColorScheme.primary, this will return ColorScheme.onPrimary.

If backgroundColor does not match a background color in the theme, this will return the current value of LocalContentColor as a best-effort color.

Returns
Color

the matching content color for backgroundColor. If backgroundColor is not present in the theme's ColorScheme, then returns the current value of LocalContentColor.

See also
contentColorFor

darkColorScheme

fun darkColorScheme(
    primary: Color = ColorDarkTokens.Primary,
    onPrimary: Color = ColorDarkTokens.OnPrimary,
    primaryContainer: Color = ColorDarkTokens.PrimaryContainer,
    onPrimaryContainer: Color = ColorDarkTokens.OnPrimaryContainer,
    inversePrimary: Color = ColorDarkTokens.InversePrimary,
    secondary: Color = ColorDarkTokens.Secondary,
    onSecondary: Color = ColorDarkTokens.OnSecondary,
    secondaryContainer: Color = ColorDarkTokens.SecondaryContainer,
    onSecondaryContainer: Color = ColorDarkTokens.OnSecondaryContainer,
    tertiary: Color = ColorDarkTokens.Tertiary,
    onTertiary: Color = ColorDarkTokens.OnTertiary,
    tertiaryContainer: Color = ColorDarkTokens.TertiaryContainer,
    onTertiaryContainer: Color = ColorDarkTokens.OnTertiaryContainer,
    background: Color = ColorDarkTokens.Background,
    onBackground: Color = ColorDarkTokens.OnBackground,
    surface: Color = ColorDarkTokens.Surface,
    onSurface: Color = ColorDarkTokens.OnSurface,
    surfaceVariant: Color = ColorDarkTokens.SurfaceVariant,
    onSurfaceVariant: Color = ColorDarkTokens.OnSurfaceVariant,
    surfaceTint: Color = primary,
    inverseSurface: Color = ColorDarkTokens.InverseSurface,
    inverseOnSurface: Color = ColorDarkTokens.InverseOnSurface,
    error: Color = ColorDarkTokens.Error,
    onError: Color = ColorDarkTokens.OnError,
    errorContainer: Color = ColorDarkTokens.ErrorContainer,
    onErrorContainer: Color = ColorDarkTokens.OnErrorContainer,
    outline: Color = ColorDarkTokens.Outline,
    outlineVariant: Color = ColorDarkTokens.OutlineVariant,
    scrim: Color = ColorDarkTokens.Scrim,
    surfaceBright: Color = ColorDarkTokens.SurfaceBright,
    surfaceContainer: Color = ColorDarkTokens.SurfaceContainer,
    surfaceContainerHigh: Color = ColorDarkTokens.SurfaceContainerHigh,
    surfaceContainerHighest: Color = ColorDarkTokens.SurfaceContainerHighest,
    surfaceContainerLow: Color = ColorDarkTokens.SurfaceContainerLow,
    surfaceContainerLowest: Color = ColorDarkTokens.SurfaceContainerLowest,
    surfaceDim: Color = ColorDarkTokens.SurfaceDim
): ColorScheme

Returns a dark Material color scheme.

dynamicDarkColorScheme

@RequiresApi(value = 31)
fun dynamicDarkColorScheme(context: Context): ColorScheme

Creates a dark dynamic color scheme.

Use this function to create a color scheme based off the system wallpaper. If the developer changes the wallpaper this color scheme will change accordingly. This dynamic scheme is a dark theme variant.

Parameters
context: Context

The context required to get system resource data.

dynamicLightColorScheme

@RequiresApi(value = 31)
fun dynamicLightColorScheme(context: Context): ColorScheme

Creates a light dynamic color scheme.

Use this function to create a color scheme based off the system wallpaper. If the developer changes the wallpaper this color scheme will change accordingly. This dynamic scheme is a light theme variant.

Parameters
context: Context

The context required to get system resource data.

lightColorScheme

fun lightColorScheme(
    primary: Color = ColorLightTokens.Primary,
    onPrimary: Color = ColorLightTokens.OnPrimary,
    primaryContainer: Color = ColorLightTokens.PrimaryContainer,
    onPrimaryContainer: Color = ColorLightTokens.OnPrimaryContainer,
    inversePrimary: Color = ColorLightTokens.InversePrimary,
    secondary: Color = ColorLightTokens.Secondary,
    onSecondary: Color = ColorLightTokens.OnSecondary,
    secondaryContainer: Color = ColorLightTokens.SecondaryContainer,
    onSecondaryContainer: Color = ColorLightTokens.OnSecondaryContainer,
    tertiary: Color = ColorLightTokens.Tertiary,
    onTertiary: Color = ColorLightTokens.OnTertiary,
    tertiaryContainer: Color = ColorLightTokens.TertiaryContainer,
    onTertiaryContainer: Color = ColorLightTokens.OnTertiaryContainer,
    background: Color = ColorLightTokens.Background,
    onBackground: Color = ColorLightTokens.OnBackground,
    surface: Color = ColorLightTokens.Surface,
    onSurface: Color = ColorLightTokens.OnSurface,
    surfaceVariant: Color = ColorLightTokens.SurfaceVariant,
    onSurfaceVariant: Color = ColorLightTokens.OnSurfaceVariant,
    surfaceTint: Color = primary,
    inverseSurface: Color = ColorLightTokens.InverseSurface,
    inverseOnSurface: Color = ColorLightTokens.InverseOnSurface,
    error: Color = ColorLightTokens.Error,
    onError: Color = ColorLightTokens.OnError,
    errorContainer: Color = ColorLightTokens.ErrorContainer,
    onErrorContainer: Color = ColorLightTokens.OnErrorContainer,
    outline: Color = ColorLightTokens.Outline,
    outlineVariant: Color = ColorLightTokens.OutlineVariant,
    scrim: Color = ColorLightTokens.Scrim,
    surfaceBright: Color = ColorLightTokens.SurfaceBright,
    surfaceContainer: Color = ColorLightTokens.SurfaceContainer,
    surfaceContainerHigh: Color = ColorLightTokens.SurfaceContainerHigh,
    surfaceContainerHighest: Color = ColorLightTokens.SurfaceContainerHighest,
    surfaceContainerLow: Color = ColorLightTokens.SurfaceContainerLow,
    surfaceContainerLowest: Color = ColorLightTokens.SurfaceContainerLowest,
    surfaceDim: Color = ColorLightTokens.SurfaceDim
): ColorScheme

Returns a light Material color scheme.

rememberBottomAppBarState

@ExperimentalMaterial3Api
@Composable
fun rememberBottomAppBarState(
    initialHeightOffsetLimit: Float = -Float.MAX_VALUE,
    initialHeightOffset: Float = 0.0f,
    initialContentOffset: Float = 0.0f
): BottomAppBarState

Creates a BottomAppBarState that is remembered across compositions.

Parameters
initialHeightOffsetLimit: Float = -Float.MAX_VALUE

the initial value for BottomAppBarState.heightOffsetLimit, which represents the pixel limit that a bottom app bar is allowed to collapse when the scrollable content is scrolled

initialHeightOffset: Float = 0.0f

the initial value for BottomAppBarState.heightOffset. The initial offset height offset should be between zero and initialHeightOffsetLimit.

initialContentOffset: Float = 0.0f

the initial value for BottomAppBarState.contentOffset

rememberBottomSheetScaffoldState

@Composable
@ExperimentalMaterial3Api
fun rememberBottomSheetScaffoldState(
    bottomSheetState: SheetState = rememberStandardBottomSheetState(),
    snackbarHostState: SnackbarHostState = remember { SnackbarHostState() }
): BottomSheetScaffoldState

Create and remember a BottomSheetScaffoldState.

Parameters
bottomSheetState: SheetState = rememberStandardBottomSheetState()

the state of the standard bottom sheet. See rememberStandardBottomSheetState

snackbarHostState: SnackbarHostState = remember { SnackbarHostState() }

the SnackbarHostState used to show snackbars inside the scaffold

rememberDatePickerState

@Composable
@ExperimentalMaterial3Api
fun rememberDatePickerState(
    initialSelectedDateMillis: Long? = null,
    initialDisplayedMonthMillis: Long? = initialSelectedDateMillis,
    yearRange: IntRange = DatePickerDefaults.YearRange,
    initialDisplayMode: DisplayMode = DisplayMode.Picker,
    selectableDates: SelectableDates = DatePickerDefaults.AllDates
): DatePickerState

Creates a DatePickerState for a DatePicker that is remembered across compositions.

To create a date picker state outside composition, see the DatePickerState function.

Parameters
initialSelectedDateMillis: Long? = null

timestamp in UTC milliseconds from the epoch that represents an initial selection of a date. Provide a null to indicate no selection.

initialDisplayedMonthMillis: Long? = initialSelectedDateMillis

timestamp in UTC milliseconds from the epoch that represents an initial selection of a month to be displayed to the user. By default, in case an initialSelectedDateMillis is provided, the initial displayed month would be the month of the selected date. Otherwise, in case null is provided, the displayed month would be the current one.

yearRange: IntRange = DatePickerDefaults.YearRange

an IntRange that holds the year range that the date picker will be limited to

initialDisplayMode: DisplayMode = DisplayMode.Picker

an initial DisplayMode that this state will hold

selectableDates: SelectableDates = DatePickerDefaults.AllDates

a SelectableDates that is consulted to check if a date is allowed. In case a date is not allowed to be selected, it will appear disabled in the UI.

rememberDateRangePickerState

@Composable
@ExperimentalMaterial3Api
fun rememberDateRangePickerState(
    initialSelectedStartDateMillis: Long? = null,
    initialSelectedEndDateMillis: Long? = null,
    initialDisplayedMonthMillis: Long? = initialSelectedStartDateMillis,
    yearRange: IntRange = DatePickerDefaults.YearRange,
    initialDisplayMode: DisplayMode = DisplayMode.Picker,
    selectableDates: SelectableDates = DatePickerDefaults.AllDates
): DateRangePickerState

Creates a DateRangePickerState for a DateRangePicker that is remembered across compositions.

To create a date range picker state outside composition, see the DateRangePickerState function.

Parameters
initialSelectedStartDateMillis: Long? = null

timestamp in UTC milliseconds from the epoch that represents an initial selection of a start date. Provide a null to indicate no selection.

initialSelectedEndDateMillis: Long? = null

timestamp in UTC milliseconds from the epoch that represents an initial selection of an end date. Provide a null to indicate no selection.

initialDisplayedMonthMillis: Long? = initialSelectedStartDateMillis

timestamp in UTC milliseconds from the epoch that represents an initial selection of a month to be displayed to the user. By default, in case an initialSelectedStartDateMillis is provided, the initial displayed month would be the month of the selected date. Otherwise, in case null is provided, the displayed month would be the current one.

yearRange: IntRange = DatePickerDefaults.YearRange

an IntRange that holds the year range that the date range picker will be limited to

initialDisplayMode: DisplayMode = DisplayMode.Picker

an initial DisplayMode that this state will hold

selectableDates: SelectableDates = DatePickerDefaults.AllDates

a SelectableDates that is consulted to check if a date is allowed. In case a date is not allowed to be selected, it will appear disabled in the UI.

rememberDrawerState

@Composable
fun rememberDrawerState(
    initialValue: DrawerValue,
    confirmStateChange: (DrawerValue) -> Boolean = { true }
): DrawerState

Create and remember a DrawerState.

Parameters
initialValue: DrawerValue

The initial value of the state.

confirmStateChange: (DrawerValue) -> Boolean = { true }

Optional callback invoked to confirm or veto a pending state change.

rememberModalBottomSheetState

@Composable
@ExperimentalMaterial3Api
fun rememberModalBottomSheetState(
    skipPartiallyExpanded: Boolean = false,
    confirmValueChange: (SheetValue) -> Boolean = { true }
): SheetState

Create and remember a SheetState for ModalBottomSheet.

Parameters
skipPartiallyExpanded: Boolean = false

Whether the partially expanded state, if the sheet is tall enough, should be skipped. If true, the sheet will always expand to the Expanded state and move to the Hidden state when hiding the sheet, either programmatically or by user interaction.

confirmValueChange: (SheetValue) -> Boolean = { true }

Optional callback invoked to confirm or veto a pending state change.

rememberStandardBottomSheetState

@Composable
@ExperimentalMaterial3Api
fun rememberStandardBottomSheetState(
    initialValue: SheetValue = PartiallyExpanded,
    confirmValueChange: (SheetValue) -> Boolean = { true },
    skipHiddenState: Boolean = true
): SheetState

Create and remember a SheetState for BottomSheetScaffold.

Parameters
initialValue: SheetValue = PartiallyExpanded

the initial value of the state. Should be either PartiallyExpanded or Expanded if skipHiddenState is true

confirmValueChange: (SheetValue) -> Boolean = { true }

optional callback invoked to confirm or veto a pending state change

skipHiddenState: Boolean = true

whether Hidden state is skipped for BottomSheetScaffold

rememberSwipeToDismissBoxState

@Composable
@ExperimentalMaterial3Api
fun rememberSwipeToDismissBoxState(
    initialValue: SwipeToDismissBoxValue = SwipeToDismissBoxValue.Settled,
    confirmValueChange: (SwipeToDismissBoxValue) -> Boolean = { true },
    positionalThreshold: (totalDistance: Float) -> Float = SwipeToDismissBoxDefaults.positionalThreshold
): SwipeToDismissBoxState

Create and remember a SwipeToDismissBoxState.

Parameters
initialValue: SwipeToDismissBoxValue = SwipeToDismissBoxValue.Settled

The initial value of the state.

confirmValueChange: (SwipeToDismissBoxValue) -> Boolean = { true }

Optional callback invoked to confirm or veto a pending state change.

positionalThreshold: (totalDistance: Float) -> Float = SwipeToDismissBoxDefaults.positionalThreshold

The positional threshold to be used when calculating the target state while a swipe is in progress and when settling after the swipe ends. This is the distance from the start of a transition. It will be, depending on the direction of the interaction, added or subtracted from/to the origin offset. It should always be a positive value.

rememberTimePickerState

@Composable
@ExperimentalMaterial3Api
fun rememberTimePickerState(
    initialHour: Int = 0,
    initialMinute: Int = 0,
    is24Hour: Boolean = is24HourFormat
): TimePickerState

Creates a TimePickerState for a time picker that is remembered across compositions and configuration changes.

Parameters
initialHour: Int = 0

starting hour for this state, will be displayed in the time picker when launched Ranges from 0 to 23

initialMinute: Int = 0

starting minute for this state, will be displayed in the time picker when launched. Ranges from 0 to 59

is24Hour: Boolean = is24HourFormat

The format for this time picker. false for 12 hour format with an AM/PM toggle or true for 24 hour format without toggle. Defaults to follow system setting.

rememberTooltipState

@Composable
@ExperimentalMaterial3Api
fun rememberTooltipState(
    initialIsVisible: Boolean = false,
    isPersistent: Boolean = false,
    mutatorMutex: MutatorMutex = BasicTooltipDefaults.GlobalMutatorMutex
): TooltipState

Create and remember the default TooltipState for TooltipBox.

Parameters
initialIsVisible: Boolean = false

the initial value for the tooltip's visibility when drawn.

isPersistent: Boolean = false

Boolean that determines if the tooltip associated with this will be persistent or not. If isPersistent is true, then the tooltip will only be dismissed when the user clicks outside the bounds of the tooltip or if TooltipState.dismiss is called. When isPersistent is false, the tooltip will dismiss after a short duration. Ideally, this should be set to true when there is actionable content being displayed within a tooltip.

mutatorMutex: MutatorMutex = BasicTooltipDefaults.GlobalMutatorMutex

MutatorMutex used to ensure that for all of the tooltips associated with the mutator mutex, only one will be shown on the screen at any time.

rememberTopAppBarState

@ExperimentalMaterial3Api
@Composable
fun rememberTopAppBarState(
    initialHeightOffsetLimit: Float = -Float.MAX_VALUE,
    initialHeightOffset: Float = 0.0f,
    initialContentOffset: Float = 0.0f
): TopAppBarState

Creates a TopAppBarState that is remembered across compositions.

Parameters
initialHeightOffsetLimit: Float = -Float.MAX_VALUE

the initial value for TopAppBarState.heightOffsetLimit, which represents the pixel limit that a top app bar is allowed to collapse when the scrollable content is scrolled

initialHeightOffset: Float = 0.0f

the initial value for TopAppBarState.heightOffset. The initial offset height offset should be between zero and initialHeightOffsetLimit.

initialContentOffset: Float = 0.0f

the initial value for TopAppBarState.contentOffset

fun ripple(
    bounded: Boolean = true,
    radius: Dp = Dp.Unspecified,
    color: Color = Color.Unspecified
): IndicationNodeFactory

Creates a Ripple using the provided values and values inferred from the theme.

A Ripple is a Material implementation of Indication that expresses different Interactions by drawing ripple animations and state layers.

A Ripple responds to PressInteraction.Press by starting a new ripple animation, and responds to other Interactions by showing a fixed state layer with varying alpha values depending on the Interaction.

MaterialTheme provides Ripples using androidx.compose.foundation.LocalIndication, so a Ripple will be used as the default Indication inside components such as androidx.compose.foundation.clickable and androidx.compose.foundation.indication, in addition to Material provided components that use a Ripple as well.

You can also explicitly create a Ripple and provide it to custom components in order to change the parameters from the default, such as to create an unbounded ripple with a fixed size.

To create a Ripple with a manually defined color that can change over time, see the other ripple overload with a ColorProducer parameter. This will avoid unnecessary recompositions when changing the color, and preserve existing ripple state when the color changes.

Parameters
bounded: Boolean = true

If true, ripples are clipped by the bounds of the target layout. Unbounded ripples always animate from the target layout center, bounded ripples animate from the touch position.

radius: Dp = Dp.Unspecified

the radius for the ripple. If Dp.Unspecified is provided then the size will be calculated based on the target layout size.

color: Color = Color.Unspecified

the color of the ripple. This color is usually the same color used by the text or iconography in the component. This color will then have RippleDefaults.RippleAlpha applied to calculate the final color used to draw the ripple. If Color.Unspecified is provided the color used will be LocalContentColor instead.

fun ripple(
    color: ColorProducer,
    bounded: Boolean = true,
    radius: Dp = Dp.Unspecified
): IndicationNodeFactory

Creates a Ripple using the provided values and values inferred from the theme.

A Ripple is a Material implementation of Indication that expresses different Interactions by drawing ripple animations and state layers.

A Ripple responds to PressInteraction.Press by starting a new ripple animation, and responds to other Interactions by showing a fixed state layer with varying alpha values depending on the Interaction.

MaterialTheme provides Ripples using androidx.compose.foundation.LocalIndication, so a Ripple will be used as the default Indication inside components such as androidx.compose.foundation.clickable and androidx.compose.foundation.indication, in addition to Material provided components that use a Ripple as well.

You can also explicitly create a Ripple and provide it to custom components in order to change the parameters from the default, such as to create an unbounded ripple with a fixed size.

To create a Ripple with a static color, see the ripple overload with a Color parameter. This overload is optimized for Ripples that have dynamic colors that change over time, to reduce unnecessary recompositions.

Parameters
color: ColorProducer

the color of the ripple. This color is usually the same color used by the text or iconography in the component. This color will then have RippleDefaults.RippleAlpha applied to calculate the final color used to draw the ripple. If you are creating this ColorProducer outside of composition (where it will be automatically remembered), make sure that its instance is stable (such as by remembering the object that holds it), or remember the returned ripple object to make sure that ripple nodes are not being created each recomposition.

bounded: Boolean = true

If true, ripples are clipped by the bounds of the target layout. Unbounded ripples always animate from the target layout center, bounded ripples animate from the touch position.

radius: Dp = Dp.Unspecified

the radius for the ripple. If Dp.Unspecified is provided then the size will be calculated based on the target layout size.

Extension functions

NavigationBarItem

@Composable
fun RowScope.NavigationBarItem(
    selected: Boolean,
    onClick: () -> Unit,
    icon: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    label: (@Composable () -> Unit)? = null,
    alwaysShowLabel: Boolean = true,
    colors: NavigationBarItemColors = NavigationBarItemDefaults.colors(),
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design navigation bar item.

Navigation bars offer a persistent and convenient way to switch between primary destinations in an app.

The recommended configuration for a NavigationBarItem depends on how many items there are inside a NavigationBar:

  • Three destinations: Display icons and text labels for all destinations.

  • Four destinations: Active destinations display an icon and text label. Inactive destinations display icons, and text labels are recommended.

  • Five destinations: Active destinations display an icon and text label. Inactive destinations use icons, and use text labels if space permits.

A NavigationBarItem always shows text labels (if it exists) when selected. Showing text labels if not selected is controlled by alwaysShowLabel.

Parameters
selected: Boolean

whether this item is selected

onClick: () -> Unit

called when this item is clicked

icon: @Composable () -> Unit

icon for this item, typically an Icon

modifier: Modifier = Modifier

the Modifier to be applied to this item

enabled: Boolean = true

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

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

optional text label for this item

alwaysShowLabel: Boolean = true

whether to always show the label for this item. If false, the label will only be shown when this item is selected.

colors: NavigationBarItemColors = NavigationBarItemDefaults.colors()

NavigationBarItemColors that will be used to resolve the colors used for this item in different states. See NavigationBarItemDefaults.colors.

interactionSource: MutableInteractionSource? = null

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

PlainTooltip

@Composable
@ExperimentalMaterial3Api
fun CaretScope.PlainTooltip(
    modifier: Modifier = Modifier,
    caretProperties: CaretProperties? = null,
    shape: Shape = TooltipDefaults.plainTooltipContainerShape,
    contentColor: Color = TooltipDefaults.plainTooltipContentColor,
    containerColor: Color = TooltipDefaults.plainTooltipContainerColor,
    tonalElevation: Dp = 0.dp,
    shadowElevation: Dp = 0.dp,
    content: @Composable () -> Unit
): Unit

Plain tooltip that provides a descriptive message.

Usually used with TooltipBox.

Parameters
modifier: Modifier = Modifier

the Modifier to be applied to the tooltip.

caretProperties: CaretProperties? = null

CaretProperties for the caret of the tooltip, if a default caret is desired with a specific dimension. Please see TooltipDefaults.caretProperties to see the default dimensions. Pass in null for this parameter if no caret is desired.

shape: Shape = TooltipDefaults.plainTooltipContainerShape

the Shape that should be applied to the tooltip container.

contentColor: Color = TooltipDefaults.plainTooltipContentColor

Color that will be applied to the tooltip's content.

containerColor: Color = TooltipDefaults.plainTooltipContainerColor

Color that will be applied to the tooltip's container.

tonalElevation: Dp = 0.dp

the tonal elevation of the tooltip.

shadowElevation: Dp = 0.dp

the shadow elevation of the tooltip.

content: @Composable () -> Unit

the composable that will be used to populate the tooltip's content.

RichTooltip

@Composable
@ExperimentalMaterial3Api
fun CaretScope.RichTooltip(
    modifier: Modifier = Modifier,
    title: (@Composable () -> Unit)? = null,
    action: (@Composable () -> Unit)? = null,
    caretProperties: CaretProperties? = null,
    shape: Shape = TooltipDefaults.richTooltipContainerShape,
    colors: RichTooltipColors = TooltipDefaults.richTooltipColors(),
    tonalElevation: Dp = ElevationTokens.Level0,
    shadowElevation: Dp = RichTooltipTokens.ContainerElevation,
    text: @Composable () -> Unit
): Unit

Rich text tooltip that allows the user to pass in a title, text, and action. Tooltips are used to provide a descriptive message.

Usually used with TooltipBox

Parameters
modifier: Modifier = Modifier

the Modifier to be applied to the tooltip.

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

An optional title for the tooltip.

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

An optional action for the tooltip.

caretProperties: CaretProperties? = null

CaretProperties for the caret of the tooltip, if a default caret is desired with a specific dimension. Pass in null for this parameter if no caret is desired.

shape: Shape = TooltipDefaults.richTooltipContainerShape

the Shape that should be applied to the tooltip container.

colors: RichTooltipColors = TooltipDefaults.richTooltipColors()

RichTooltipColors that will be applied to the tooltip's container and content.

tonalElevation: Dp = ElevationTokens.Level0

the tonal elevation of the tooltip.

shadowElevation: Dp = RichTooltipTokens.ContainerElevation

the shadow elevation of the tooltip.

text: @Composable () -> Unit

the composable that will be used to populate the rich tooltip's text.

SegmentedButton

@Composable
@ExperimentalMaterial3Api
fun MultiChoiceSegmentedButtonRowScope.SegmentedButton(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    shape: Shape,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    colors: SegmentedButtonColors = SegmentedButtonDefaults.colors(),
    border: BorderStroke = SegmentedButtonDefaults.borderStroke( colors.borderColor(enabled, checked) ),
    interactionSource: MutableInteractionSource? = null,
    icon: @Composable () -> Unit = { SegmentedButtonDefaults.Icon(checked) },
    label: @Composable () -> Unit
): Unit

Material Segmented Button. Segmented buttons help people select options, switch views, or sort elements.

A default Toggleable Segmented Button. Also known as Outlined Segmented Button. See Modifier.toggleable.

Toggleable segmented buttons should be used for cases where the selection is not mutually exclusive.

This should typically be used inside of a MultiChoiceSegmentedButtonRow

For a sample showing Segmented button with only checked icons see:

import androidx.compose.foundation.layout.size
import androidx.compose.material.Icon
import androidx.compose.material3.MultiChoiceSegmentedButtonRow
import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember

val checkedList = remember { mutableStateListOf<Int>() }
val options = listOf("Favorites", "Trending", "Saved")
val icons = listOf(
    Icons.Filled.StarBorder,
    Icons.AutoMirrored.Filled.TrendingUp,
    Icons.Filled.BookmarkBorder
)
MultiChoiceSegmentedButtonRow {
    options.forEachIndexed { index, label ->
        SegmentedButton(
            shape = SegmentedButtonDefaults.itemShape(index = index, count = options.size),
            icon = {
                SegmentedButtonDefaults.Icon(active = index in checkedList) {
                    Icon(
                        imageVector = icons[index],
                        contentDescription = null,
                        modifier = Modifier.size(SegmentedButtonDefaults.IconSize)
                    )
                }
            },
            onCheckedChange = {
                if (index in checkedList) {
                    checkedList.remove(index)
                } else {
                    checkedList.add(index)
                }
            },
            checked = index in checkedList
        ) {
            Text(label)
        }
    }
}
Parameters
checked: Boolean

whether this button is checked or not

onCheckedChange: (Boolean) -> Unit

callback to be invoked when the button is clicked. therefore the change of checked state in requested.

shape: Shape

the shape for this button

modifier: Modifier = Modifier

the Modifier to be applied to this button

enabled: Boolean = true

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

colors: SegmentedButtonColors = SegmentedButtonDefaults.colors()

SegmentedButtonColors that will be used to resolve the colors used for this

border: BorderStroke = SegmentedButtonDefaults.borderStroke( colors.borderColor(enabled, checked) )

the border for this button, see SegmentedButtonColors Button in different states

interactionSource: MutableInteractionSource? = null

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

icon: @Composable () -> Unit = { SegmentedButtonDefaults.Icon(checked) }

the icon slot for this button, you can pass null in unchecked, in which case the content will displace to show the checked icon, or pass different icon lambdas for unchecked and checked in which case the icons will crossfade.

label: @Composable () -> Unit

content to be rendered inside this button

SegmentedButton

@Composable
@ExperimentalMaterial3Api
fun SingleChoiceSegmentedButtonRowScope.SegmentedButton(
    selected: Boolean,
    onClick: () -> Unit,
    shape: Shape,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    colors: SegmentedButtonColors = SegmentedButtonDefaults.colors(),
    border: BorderStroke = SegmentedButtonDefaults.borderStroke( colors.borderColor(enabled, selected) ),
    interactionSource: MutableInteractionSource? = null,
    icon: @Composable () -> Unit = { SegmentedButtonDefaults.Icon(selected) },
    label: @Composable () -> Unit
): Unit

Material Segmented Button. Segmented buttons help people select options, switch views, or sort elements.

A default Toggleable Segmented Button. Also known as Outlined Segmented Button. See Modifier.selectable.

Selectable segmented buttons should be used for cases where the selection is mutually exclusive, when only one button can be selected at a time.

This should typically be used inside of a SingleChoiceSegmentedButtonRow

For a sample showing Segmented button with only checked icons see:

import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var selectedIndex by remember { mutableStateOf(0) }
val options = listOf("Day", "Month", "Week")
SingleChoiceSegmentedButtonRow {
    options.forEachIndexed { index, label ->
        SegmentedButton(
            shape = SegmentedButtonDefaults.itemShape(index = index, count = options.size),
            onClick = { selectedIndex = index },
            selected = index == selectedIndex
        ) {
            Text(label)
        }
    }
}
Parameters
selected: Boolean

whether this button is selected or not

onClick: () -> Unit

callback to be invoked when the button is clicked. therefore the change of checked state in requested.

shape: Shape

the shape for this button

modifier: Modifier = Modifier

the Modifier to be applied to this button

enabled: Boolean = true

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

colors: SegmentedButtonColors = SegmentedButtonDefaults.colors()

SegmentedButtonColors that will be used to resolve the colors used for this

border: BorderStroke = SegmentedButtonDefaults.borderStroke( colors.borderColor(enabled, selected) )

the border for this button, see SegmentedButtonColors Button in different states

interactionSource: MutableInteractionSource? = null

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

icon: @Composable () -> Unit = { SegmentedButtonDefaults.Icon(selected) }

the icon slot for this button, you can pass null in unchecked, in which case the content will displace to show the checked icon, or pass different icon lambdas for unchecked and checked in which case the icons will crossfade.

label: @Composable () -> Unit

content to be rendered inside this button

contentColorFor

fun ColorScheme.contentColorFor(backgroundColor: Color): Color

The Material color system contains pairs of colors that are typically used for the background and content color inside a component. For example, a Button typically uses primary for its background, and onPrimary for the color of its content (usually text or iconography).

This function tries to match the provided backgroundColor to a 'background' color in this ColorScheme, and then will return the corresponding color used for content. For example, when backgroundColor is ColorScheme.primary, this will return ColorScheme.onPrimary.

If backgroundColor does not match a background color in the theme, this will return Color.Unspecified.

Returns
Color

the matching content color for backgroundColor. If backgroundColor is not present in the theme's ColorScheme, then returns Color.Unspecified.

See also
contentColorFor

drawStopIndicator

fun DrawScope.drawStopIndicator(
    stopSize: Dp,
    color: Color,
    strokeCap: StrokeCap
): Unit

Draws the stop indicator at the end of the track.

Parameters
stopSize: Dp

size of this stop indicator, it cannot be bigger than the track's height

color: Color

color of this stop indicator

strokeCap: StrokeCap

stroke cap to use for the ends of this stop indicator

minimumInteractiveComponentSize

fun Modifier.minimumInteractiveComponentSize(): Modifier

Reserves at least 48.dp in size to disambiguate touch interactions if the element would measure smaller.

https://m3.material.io/foundations/accessible-design/accessibility-basics#28032e45-c598-450c-b355-f9fe737b1cd8

This uses the Material recommended minimum size of 48.dp x 48.dp, which may not the same as the system enforced minimum size. The minimum clickable / touch target size (48.dp by default) is controlled by the system via ViewConfiguration` and automatically expanded at the touch input layer.

This modifier is not needed for touch target expansion to happen. It only affects layout, to make sure there is adequate space for touch target expansion.

surfaceColorAtElevation

fun ColorScheme.surfaceColorAtElevation(elevation: Dp): Color

Computes the surface tonal color at different elevation levels e.g. surface1 through surface5.

Parameters
elevation: Dp

Elevation value used to compute alpha of the color overlay layer.

Returns
Color

the ColorScheme.surface color with an alpha of the ColorScheme.surfaceTint color overlaid on top of it.

Top-level properties

LocalAbsoluteTonalElevation

val LocalAbsoluteTonalElevationProvidableCompositionLocal<Dp>

CompositionLocal containing the current absolute elevation provided by Surface components. This absolute elevation is a sum of all the previous elevations. Absolute elevation is only used for calculating surface tonal colors, and is not used for drawing the shadow in a Surface.

LocalContentColor

val LocalContentColorProvidableCompositionLocal<Color>

CompositionLocal containing the preferred content color for a given position in the hierarchy. This typically represents the on color for a color in ColorScheme. For example, if the background color is ColorScheme.surface, this color is typically set to ColorScheme.onSurface.

This color should be used for any typography / iconography, to ensure that the color of these adjusts when the background color changes. For example, on a dark background, text should be light, and on a light background, text should be dark.

Defaults to Color.Black if no color has been explicitly set.

LocalMinimumInteractiveComponentEnforcement

@ExperimentalMaterial3Api
val LocalMinimumInteractiveComponentEnforcementProvidableCompositionLocal<Boolean>

CompositionLocal that configures whether Material components that have a visual size that is lower than the minimum touch target size for accessibility (such as Button) will include extra space outside the component to ensure that they are accessible. If set to false there will be no extra space, and so it is possible that if the component is placed near the edge of a layout / near to another component without any padding, there will not be enough space for an accessible touch target.

LocalMinimumTouchTargetEnforcement

@ExperimentalMaterial3Api
val LocalMinimumTouchTargetEnforcementProvidableCompositionLocal<Boolean>

CompositionLocal that configures whether Material components that have a visual size that is lower than the minimum touch target size for accessibility (such as Button) will include extra space outside the component to ensure that they are accessible. If set to false there will be no extra space, and so it is possible that if the component is placed near the edge of a layout / near to another component without any padding, there will not be enough space for an accessible touch target.

LocalRippleConfiguration

@ExperimentalMaterial3Api
val LocalRippleConfigurationProvidableCompositionLocal<RippleConfiguration>

CompositionLocal used for providing RippleConfiguration down the tree. This acts as a tree-local 'override' for ripples used inside components that you cannot directly control, such as to change the color of a specific component's ripple, or disable it entirely.

In most cases you should rely on the default theme behavior for consistency with other components

  • this exists as an escape hatch for individual components and is not intended to be used for full theme customization across an application. For this use case you should instead build your own custom ripple that queries your design system theme values directly using createRippleModifierNode.

LocalTextStyle

val LocalTextStyleProvidableCompositionLocal<TextStyle>

CompositionLocal containing the preferred TextStyle that will be used by Text components by default. To set the value for this CompositionLocal, see ProvideTextStyle which will merge any missing TextStyle properties with the existing TextStyle set in this CompositionLocal.

See also
ProvideTextStyle

LocalTonalElevationEnabled

val LocalTonalElevationEnabledProvidableCompositionLocal<Boolean>

Composition Local used to check if ColorScheme.applyTonalElevation will be applied down the tree.

Setting this value to false will cause all subsequent surfaces down the tree to not apply tonalElevation.

LocalUseFallbackRippleImplementation

@ExperimentalMaterial3Api
val LocalUseFallbackRippleImplementationProvidableCompositionLocal<Boolean>

Temporary CompositionLocal to allow configuring whether the old ripple implementation that uses the deprecated androidx.compose.material.ripple.RippleTheme API should be used in Material components and LocalIndication, instead of the new ripple API. This flag defaults to false, and will be removed after one stable release: it should only be used to temporarily unblock upgrading.

Provide this CompositionLocal before you provide MaterialTheme to make sure it is correctly provided through LocalIndication.

ScaffoldSubcomposeInMeasureFix

@ExperimentalMaterial3Api
var ScaffoldSubcomposeInMeasureFixBoolean

Flag indicating if Scaffold should subcompose and measure its children during measurement or during placement. Set this flag to false to keep Scaffold's old measurement behavior (measuring in placement).

This flag will be removed in Compose 1.6.0-beta01. If you encounter any issues with the new behavior, please file an issue at: issuetracker.google.com/issues/new?component=742043