Material3 ‐ Selection UI components - devrath/Material-3-Design-Kit GitHub Wiki

Contents
Demo representation
Checkboxes
Switches
Radio Buttons

Demo representation

Light Theme Dark Theme

Checkboxes

Code

data class ToggleCheckBoxData(
    val isChecked: Boolean = false,
    val text: String = ""
)

@Composable
fun CheckBoxes() {
    // Create a collection of checkboxes as mutableState list in remember block
    val checkboxes = remember {
        mutableStateListOf(
            ToggleCheckBoxData(isChecked = false, text = "Type-1"),
            ToggleCheckBoxData(isChecked = false, text = "Type-2"),
            ToggleCheckBoxData(isChecked = false, text = "Type-3")
        )
    }

    var triState by remember {
        // Indeterminate is the state when its either checked or unchecked
        mutableStateOf(ToggleableState.Indeterminate)
    }

    val toggleTriState = {
        triState = when (triState) {
            ToggleableState.Indeterminate -> ToggleableState.On
            ToggleableState.On -> ToggleableState.Off
            else -> ToggleableState.On
        }
        // If the triState is On when we updated triState - We will turn on all the checkbox to On
        checkboxes.indices.forEach { index ->
            checkboxes[index] = checkboxes[index].copy(
                isChecked = (triState == ToggleableState.On)
            )
        }
    }

    Row(
        verticalAlignment = Alignment.CenterVertically,
        modifier = Modifier
            .clickable {
                toggleTriState()
            }
            .padding(end = 16.dp)
    ) {
        TriStateCheckbox(state = triState, onClick = toggleTriState)
        Text(text = "All Types")
    }

    // Loop the checkboxes
    checkboxes.forEachIndexed { index, info ->
        Row(
            verticalAlignment = Alignment.CenterVertically,
            modifier = Modifier
                .padding(start = 32.dp)
                .clickable {
                    checkboxes[index] = info.copy(
                        isChecked = !info.isChecked
                    )
                }
                .padding(end = 16.dp)
        ) {
            // Check box - item
            Checkbox(
                checked = info.isChecked,
                onCheckedChange = { newValue ->
                    // On check box selected - Update the index of collection
                    checkboxes[index] = info.copy(
                        isChecked = newValue
                    )
                }
            )
            // Check box - text
            Text(text = info.text)
        }
    }
}

Description

  • We pick this UI when selecting one or more related objects.
  • We can even add a parent level to check/uncheck all the children's checkboxes at once.

Switches

Code

data class ToggleSwitchData(
    val isChecked : Boolean = true, val text : String = "Dark Mode"
)

@Composable
fun SwitchCustom() {

    var switchState by remember {
        mutableStateOf(ToggleSwitchData())
    }

    Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text(text = switchState.text)
        Spacer(modifier = Modifier.weight(1f))
        Switch(
            checked = switchState.isChecked,
            onCheckedChange = { isChecked ->
                switchState = if(isChecked){
                    switchState.copy(
                        isChecked = isChecked, text = "Dark Mode"
                    )
                }else{
                    switchState.copy(
                        isChecked = isChecked, text = "Light Mode"
                    )
                }
            }
        )
    }
}

Description

  • Switches are similar to checkboxes with an on and an off state.
  • We use it in scenarios where it's independent and not dependent on other states.

Radio Buttons

Code

data class RadioButtonData(
    val isSelected: Boolean = false, val text: String = ""
)

@Composable
fun RadioButtonCustom() {

    val radioButtonStates = remember {
        mutableStateListOf(
            RadioButtonData(isSelected = true, text = "Type-1"),
            RadioButtonData(isSelected = false, text = "Type-2"),
            RadioButtonData(isSelected = false, text = "Type-3")
        )
    }

    radioButtonStates.forEachIndexed { index, info ->

        Row(
            verticalAlignment = Alignment.CenterVertically,
            modifier = Modifier
                .wrapContentWidth()
                .clickable {
                    radioButtonStates.replaceAll {
                        it.copy(
                            isSelected = it.text == info.text
                        )
                    }
                }
                .padding(end = 16.dp)
        ) {
            RadioButton(
                selected = info.isSelected,
                onClick = {
                    radioButtonStates.replaceAll {
                        it.copy(
                            isSelected = it.text == info.text
                        )
                    }
                }
            )
            Text(text = info.text)
        }
    }
}

Description

  • The radio button is used if the user has to pick exactly one and only one option in a group of options
⚠️ **GitHub.com Fallback** ⚠️