Radio Button
A radio button: a ring that is selected or not, and the label it is the ring of. One of several, of which one is chosen.
import com.pantrixui.components.elements.radiobutton.PantrixRadioButton
- Options. An option is a
RadioOption: its value, its label, the text under the label that says what it is, whether it can be selected, and its automation key. - One under another or side by side.
orientationlays the options out one under another (Orientation.Vertical, the default) or side by side (Orientation.Horizontal): as many on a line as the width takes, and the rest on the next line. - One target. The ring, the label and the text under it are one target: a press on the words selects too. However small the ring is, the row takes up the platform's touch target.
- Error.
errorturns the rings and the text under the group to the theme'sdangerrole; the group tells a screen reader of the error, once. - Form. The
PantrixRadioGroupthat takes afieldgets its selection, its error and its name from the form's field. A choice that has to be made is built with a field that starts at null andRules.required. - Disabled and read-only.
RadioOption(enabled = false)disables a single option, and the group'senabled = falseall of them. APantrixRadioButtonwhoseonClickis null is read-only: it takes no press and no focus, and says whether it is selected. - Its own colours and style.
RadioColorsgives the colour of the selected ring and of the unselected one;RadioStylegives the size of the ring, the size of the dot in it and the thickness of the line. The ring is 20dp and its dot 10dp; on iOS, 22dp and 12dp. - The ring at the end.
controlPosition = ControlPosition.Endputs the ring at the end of the label; in a group one under another, the options take the group's width and the rings stand in a column. - Motion. The dot of a ring that is selected grows, and the ring turns to the
primarycolour with it. In a theme with reduced motion both happen at once.
Examples
Disabled and read-only
The group's enabled = false disables every option; the label and the supporting text are written in the disabled text colour too. Which option is selected can still be seen.
A PantrixRadioButton given onClick = null is read-only: it takes no press and no focus, its colours do not change, and it still says its name and that it is selected.
PantrixRadioGroup(
options = listOf(
RadioOption("card", "Card", tagKey = "card"),
RadioOption("transfer", "Bank transfer", tagKey = "transfer")
),
selected = "card",
onSelect = {},
orientation = Orientation.Horizontal,
enabled = false,
label = "Payment",
supportingText = "Disabled: your saved card will be charged",
tagKey = "payment"
)
PantrixRadioButton(
selected = true,
onClick = null,
label = "Read-only",
supportingText = "Cannot be pressed; it only shows what was chosen",
tagKey = "read_only"
)
On its own: inside cards
On its own, PantrixRadioButton is for a layout a group cannot make: here each option is inside a card. The caller holds the selection: each button is told whether it is selected through selected, and asks through onClick when it is pressed.
The buttons are in a column that carries Modifier.selectableGroup(): a screen reader hears them as one choice. Moving with the arrow keys is the group's work, and there is none of it here: each button is a separate stop for Tab.
var plan by rememberSaveable { mutableStateOf("monthly") }
Column(
modifier = Modifier.widthIn(max = 360.dp).selectableGroup(),
verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)
) {
PantrixCard(modifier = Modifier.fillMaxWidth(), variant = CardVariant.Outlined) {
PantrixRadioButton(
selected = plan == "monthly",
onClick = { plan = "monthly" },
modifier = Modifier.fillMaxWidth(),
label = "Monthly",
supportingText = "Renews every month; you can cancel at any time",
tagKey = "plan_monthly"
)
}
PantrixCard(modifier = Modifier.fillMaxWidth(), variant = CardVariant.Outlined) {
PantrixRadioButton(
selected = plan == "yearly",
onClick = { plan = "yearly" },
modifier = Modifier.fillMaxWidth(),
label = "Yearly",
supportingText = "Paid once a year",
tagKey = "plan_yearly"
)
}
}
API
selected
A radio button: a ring that is selected or not, and the label it is the ring of. One of several, of which one is chosen.
| Parameter | Type | Default | What it is |
|---|---|---|---|
selected | Boolean | whether this is the option chosen. | |
onClick | (() -> Unit)? | called when the user presses the radio button, selected already or not. The radio button changes nothing by itself: it is selected when selected says so. Null makes it read-only. | |
modifier | Modifier | Modifier | the row's modifier. |
enabled | Boolean | true | whether the radio button can be selected. One that cannot is drawn in the disabled colours and says so. |
label | String? | null | the text beside the ring: part of the target, and the radio button's name for a screen reader. |
supportingText | String? | null | help under the label, in a smaller type: the message, while error is true. |
error | Boolean | false | whether the choice is wrong or missing: the ring and the supporting text turn to the danger role, and a screen reader is told the input is invalid. |
style | RadioStyle? | null | this call's own style: over every enclosing one and under the density. Only the fields it sets change, on every platform. |
colors | RadioColors? | null | this radio button's own colours: the ones it sets, with the theme's for the rest. A disabled ring and one in error keep the theme's. |
contentDescription | String? | null | what a screen reader says for the radio button: its name where it has no label, as in a card that is the option, or in place of the label. |
tagKey | String? | null | the radio button's automation key: the row is RadioButton_<tagKey>. A press is reported as a RadioButton event, and never by its label. |
interactionSource | MutableInteractionSource? | null | the radio button's interactions, hoisted. It keeps a source of its own when this is null. |
controlPosition | ControlPosition | ControlPosition.Start | where the ring stands: before the label, as a list of choices has it, or after it. After it, the ring is at the end of the width the row is given, Modifier.fillMaxWidth() lining it up with the others, or right after the label where the row is given none; the label wraps in what the ring leaves. |
RadioStyle
PantrixRadioButton's ring and the dot in it: how large each is, and how thick the ring.
| Parameter | Type | Default | What it is |
|---|---|---|---|
size | Dp | Dp.Unspecified | The ring's width and height, its line included. |
dotSize | Dp | Dp.Unspecified | The width and height of the dot in a selected ring. |
strokeWidth | Dp | Dp.Unspecified | How thick the ring's line is. |
RadioColors
What PantrixRadioButton and the options of PantrixRadioGroup are painted with, for ones that do not take the theme's: a colour that is set is used, and one that is left out stays the theme's role.
| Parameter | Type | Default | What it is |
|---|---|---|---|
selected | Color | Color.Unspecified | The ring and the dot of the option that is chosen. The theme's primary. |
unselected | Color | Color.Unspecified | The ring of an option that is not. The theme's borderStrong: an empty ring is nothing but its line. |
Accessibility
- Keyboard. The group is one stop for Tab: the focus comes to the selected option, or to the first option that can be selected while none is. The arrow keys select the next and the previous option, wrap around from the last to the first and skip one that cannot be selected; in a right-to-left layout left and right change places.
- Screen reader. Each option is a radio button that says whether it is selected; the group's name is
label. Buttons used on their own are wrapped inModifier.selectableGroup(), so that they are heard as one choice.