Radio Group

A foundational component used to create accessible radio groups in Jetpack Compose and Compose Multiplatform.

Comes with full accessibility features and keyboard navigation, while letting you handle the styling to your liking.

Installation

repositories {
    mavenCentral()
}

dependencies {
    implementation("com.composables:core:1.37.0")
}

Basic Example

To create a radio group use the RadioGroup component. Each radio option should be represented using the Radio component.

The radio group handles its own state and sets important accessibility semantics.

You are free to represent a radio as anything you like, such as a checkbox icon or a typical radio like the following example:

val values = listOf("Light", "Dark", "System")
val groupState = rememberRadioGroupState(initialValue = values[0])

RadioGroup(
    state = groupState,
    contentDescription = "Theme selection"
) {
    Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
        values.forEach { text ->
            val selected = groupState.selectedOption == text
            Radio(
                value = text,
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier.fillMaxWidth(),
                contentPadding = PaddingValues(vertical = 12.dp, horizontal = 16.dp),
                shape = RoundedCornerShape(8.dp),
            ) {
                Box(
                    modifier = Modifier
                        .size(20.dp)
                        .shadow(elevation = 4.dp, RoundedCornerShape(8.dp))
                        .clip(CircleShape)
                        .background(
                            if (selected) Color(0xFFB23A48) else Color.White
                        ),
                    contentAlignment = Alignment.Center
                ) {
                    Box(
                        Modifier
                            .size(8.dp)
                            .clip(CircleShape)
                            .alpha(if (selected) 1f else 0f)
                            .background(Color.White)
                    )
                }
                Spacer(Modifier.width(16.dp))
                Text(text)
            }
        }
    }
}

Styling

Every component in Compose Unstyled is renderless. They handle all UX pattern logic, internal state, accessibility ( according to ARIA standards), and keyboard interactions for you, but they do not render any UI to the screen.

This is by design so that you can style your components exactly to your needs.

Most of the time, styling is done using Modifiers of your choice. However, sometimes this is not enough due to the order of the Modifiers affecting the visual outcome.

For such cases we provide specific styling parameters.

Code Example

Toggle radio manually

You can control selection yourself by using the Radio overload with the selected/onSelectedChange params.

RadioGroup(
    state = groupState,
    contentDescription = "Theme selection"
) {
    Column(
        horizontalAlignment = Alignment.Start,
        verticalArrangement = Arrangement.spacedBy(8.dp),
        modifier = Modifier.fillMaxWidth()
    ) {
        values.forEach { text ->
            val selected = groupState.selectedOption == text
            Radio(
                selected = groupState.selectedOption == text,
                onSelectedChange = { groupState.selectedOption = text },
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier.fillMaxWidth(),
                contentPadding = PaddingValues(vertical = 12.dp, horizontal = 16.dp),
                shape = RoundedCornerShape(8.dp),
            ) {
                Box(
                    modifier = Modifier
                        .size(20.dp)
                        .shadow(elevation = 4.dp, RoundedCornerShape(8.dp))
                        .clip(CircleShape)
                        .background(
                            if (selected) Color(0xFFB23A48) else Color.White
                        ),
                    contentAlignment = Alignment.Center
                ) {
                    Box(
                        Modifier
                            .size(8.dp)
                            .clip(CircleShape)
                            .alpha(if (selected) 1f else 0f)
                            .background(Color.White)
                    )
                }
                Spacer(Modifier.width(16.dp))
                Text(text)
            }
        }
    }
}

Keyboard Interactions

KeyDescription
Enter
Selects the radio button, triggering its onSelectedChange callback
Space
Selects the radio button, triggering its onSelectedChange callback
Moves focus to the next radio button. If focus is on the last button, it moves to the first button.
Moves focus to the next radio button. If focus is on the last button, it moves to the first button.
Moves focus to the previous radio button. If focus is on the first button, it moves to the last button.
Moves focus to the previous radio button. If focus is on the first button, it moves to the last button.

Component API

RadioGroupState

ParameterDescription
selectedOptionThe currently selected option in the radio group.

rememberRadioGroupState

ParameterDescription
initialValueThe initial selected option for the radio group state.

RadioGroup

ParameterDescription
stateThe state of the radio group, managing the selected option.
contentDescriptionAccessibility description of the radio group.
modifierModifier to be applied to the radio group.
contentComposable function to define the radio buttons.

Radio

ParameterDescription
valueThe value associated with the radio button.
modifierModifier to be applied to the radio button.
backgroundColorBackground color of the radio button.
contentColorColor of the content inside the radio button.
selectedColorColor when the radio button is selected.
enabledWhether the radio button is enabled.
shapeShape of the radio button.
borderColorColor of the border.
borderWidthWidth of the border.
contentPaddingPadding inside the radio button.
interactionSourceInteraction source for the radio button.
indicationVisual indication for interactions.
horizontalArrangementHorizontal arrangement of the content.
verticalAlignmentVertical alignment of the content.
contentComposable function to define the content of the radio button.