# Radio Group

A radio group is a UI component that groups multiple radio buttons together, allowing users to select one option from a set of mutually exclusive choices.

Note that the radio component can only be used within a radio group.

## Example

```python
from deephaven import ui


my_radio_group_basic = ui.radio_group(
    ui.radio("Dogs", value="dogs"),
    ui.radio("Cats", value="cats"),
    ui.radio("Lizard", value="lizard"),
    ui.radio("Fish", value="fish"),
    label="What is the best type of pet",
)
```

## UI Recommendations

Recommendations for creating radio groups:

1. Every radio group should have a [label]() specified. Without one, the radio group is ambiguous. In the rare case that context is sufficient, the label is unnecessary; you must still include an aria-label via the `aria_label` prop.
2. Use radio groups when the options in a list are mutually exclusive.
3. Emphasized radio buttons are ideal for forms and settings where they need to stand out, while non-emphasized radio buttons are best for monochrome application panels to keep the focus on the application.
4. The label, options, and help text should all be in sentence case.
5. Identify which radio groups are required or optional, and use the `is_required` field or the `necessity_indicator` to mark them accordingly.

Consider using a [`checkbox_group`](checkbox_group.md) to manage multiple selections or no selections within a group at once. If you need to display a list of items driven by a Deephaven table, use a [`list_view`](list_view.md) to dynamically generate the checkboxes with `selection_mode="single"` to mimic radio behavior.

## Value

A radio group’s value is not set by default, but a single initial, uncontrolled value can be set using the `default_value` prop, or a controlled value can be set via the `value` prop.

```python
from deephaven import ui


@ui.component
def radio_group_value_examples():
    selected, set_selected = ui.use_state("yes")
    return [
        ui.radio_group(
            ui.radio("Yes", value="yes"),
            ui.radio("No", value="no"),
            label="Are you a wizard? (no value set)?",
        ),
        ui.radio_group(
            ui.radio("Yes", value="yes"),
            ui.radio("No", value="no"),
            label="Are you a wizard? (uncontrolled)?",
            default_value="yes",
        ),
        ui.radio_group(
            ui.radio("Yes", value="yes"),
            ui.radio("No", value="no"),
            label="Are you a wizard? (controlled)?",
            value=selected,
            on_change=set_selected,
        ),
    ]


my_radio_group_value_examples = radio_group_value_examples()
```

## HTML Forms

Radio groups can support a `name` prop for integration with HTML forms, allowing for easy identification of a value on form submission.

```python
from deephaven import ui


my_radio_group_name_example = ui.form(
    ui.radio_group(
        ui.radio("Yes", value="yes"),
        ui.radio("No", value="no"),
        label="Is your favorite color blue?",
    ),
)
```

## Labeling

The radio group can be labeled using the `label` prop, and if no label is provided, an `aria_label` must be provided to identify the control for accessibility purposes.

```python
from deephaven import ui


@ui.component
def ui_radio_group_label_examples():
    return [
        ui.radio_group(
            ui.radio("Wizard", value="wizard"),
            ui.radio("Dragon", value="dragon"),
            label="Favorite avatar",
        ),
        ui.radio_group(
            ui.radio("Wizard", value="wizard"),
            ui.radio("Dragon", value="dragon"),
            aria_label="Favorite avatar",
        ),
    ]


my_radio_group_label_examples = ui_radio_group_label_examples()
```

The `is_required` prop and the `necessity_indicator` props can be used to show whether selecting an option in the radio group is required or optional.

When the `necessity_indicator` prop is set to “label”, a localized string will be generated for “(required)” or “(optional)” automatically.

```python
from deephaven import ui


@ui.component
def ui_radio_group_required_examples():
    return [
        ui.radio_group(
            ui.radio("Wizard", value="wizard"),
            ui.radio("Dragon", value="dragon"),
            label="Favorite avatar",
            is_required=True,
        ),
        ui.radio_group(
            ui.radio("Wizard", value="wizard"),
            ui.radio("Dragon", value="dragon"),
            label="Favorite avatar",
            is_required=True,
            necessity_indicator="label",
        ),
        ui.radio_group(
            ui.radio("Wizard", value="wizard"),
            ui.radio("Dragon", value="dragon"),
            label="Favorite avatar",
            necessity_indicator="label",
        ),
    ]


my_radio_group_required_examples = ui_radio_group_required_examples()
```

## Events

The `on_change` property is triggered whenever the value in the radio group selection is changed.

```python
from deephaven import ui


@ui.component
def ui_radio_group_on_change_example():
    value, set_value = ui.use_state("")
    return [
        ui.radio_group(
            ui.radio("Yes", value="Yes"),
            ui.radio("No", value="No"),
            label="Is vanilla the best flavor of ice cream?",
            value=value,
            on_change=set_value,
        ),
        ui.text(f"You have selected: {value}"),
    ]


my_radio_group_on_change_example = ui_radio_group_on_change_example()
```

## Validation

The `is_required` prop ensures that the user selects an option. The related `validation_behaviour` prop allows the user to specify aria or native verification.

When the prop is set to “native”, the validation errors block form submission and are displayed as help text automatically.

```python
from deephaven import ui


@ui.component
def ui_radio_group_validation_behaviour_example():
    return ui.form(
        ui.radio_group(
            ui.radio("Yes", value="Yes"),
            ui.radio("No", value="No"),
            label="Is vanilla the best flavor of ice cream?",
            validation_behavior="aria",
            is_required=True,
        )
    )


my_radio_group_validation_behaviour_example = (
    ui_radio_group_validation_behaviour_example()
)
```

## Orientation

While aligned vertically by default, the axis the radio buttons align with can be changed via the `orientation` prop.

```python
from deephaven import ui


my_radio_group_orientation_example = ui.radio_group(
    ui.radio("Wizard", value="wizard"),
    ui.radio("Dragon", value="dragon"),
    label="Favorite avatar",
    orientation="horizontal",
)
```

## Label position

By default, the position of a radio group’s label is above the radio group, but it can be changed to the side using the `label_position` prop.

```python
from deephaven import ui


my_radio_group_label_position_example = ui.radio_group(
    ui.radio("Wizard", value="wizard"),
    ui.radio("Dragon", value="dragon"),
    label="Favorite avatar",
    label_position="side",
)
```

## Help text

A radio group can have both a `description` and an `error_message`. Use the error message to offer specific guidance on how to correct the input.

The `is_invalid` prop can be used to set whether the current radio group state is valid or invalid.

```python
from deephaven import ui


@ui.component
def ui_radio_group_help_text_examples():
    return [
        ui.radio_group(
            ui.radio("Wizard", value="wizard"),
            ui.radio("Dragon", value="dragon"),
            label="Favorite avatar",
            description="Select an avatar from the two options.",
        ),
        ui.radio_group(
            ui.radio("Wizard", value="wizard"),
            ui.radio("Dragon", value="dragon"),
            label="Favorite avatar",
            description="Select an avatar from the two options.",
            error_message="Sample invalid error message.",
            is_invalid=True,
        ),
    ]


my_radio_group_help_text_examples = ui_radio_group_help_text_examples()
```

## Contextual Help

Using the `contextual_help` prop, a `ui.contextual_help` can be placed next to the label to provide additional information about the radio group.

```python
from deephaven import ui


my_radio_group_contextual_help_example = ui.radio_group(
    ui.radio("Wizard", value="wizard"),
    ui.radio("Dragon", value="dragon"),
    label="Favorite avatar",
    contextual_help=ui.contextual_help(ui.heading("Content tips")),
)
```

## Disabled state

The `is_disabled` prop disables a radio group to prevent user interaction. This is useful when the radio group should be visible but not available for selection.

```python
from deephaven import ui


my_radio_group_is_disabled_example = ui.radio_group(
    ui.radio("Wizard", value="wizard"),
    ui.radio("Dragon", value="dragon"),
    label="Favorite avatar",
    is_disabled=True,
)
```

## Read only

The `is_read_only` prop makes radio groups read-only to prevent user interaction. This is different from setting the `is_disabled` prop since the radio group remains focusable and its options remain visible.

```python
from deephaven import ui


my_radio_group_is_read_only_example = ui.radio_group(
    ui.radio("Wizard", value="wizard"),
    ui.radio("Dragon", value="dragon"),
    label="Favorite avatar",
    default_value="dragon",
    is_read_only=True,
)
```

## Emphasized

The `is_emphasized` prop makes the selected radio button the user’s accent color, adding a visual prominence to the selection.

```python
from deephaven import ui


my_radio_group_is_emphasized_example = ui.radio_group(
    ui.radio("Wizard", value="wizard"),
    ui.radio("Dragon", value="dragon"),
    label="Favorite avatar",
    default_value="dragon",
    is_emphasized=True,
)
```

## API Reference

Radio buttons allow users to select a single option from a list of mutually
exclusive options. All possible options are exposed up front for users to
compare.

**Returns:** `Element` The rendered radio group component.

<ParamTable param={{"module_name": "deephaven.ui.", "name": "radio_group", "parameters": [{"name": "*children", "type": "Any", "description": "The Radio(s) contained within the RadioGroup."}, {"name": "is_emphasized", "type": "bool | None", "description": "By default, radio button are not emphasized (gray). The emphasized version provides visual prominence.", "default": "None"}, {"name": "orientation", "type": "Literal['horizontal', 'vertical']", "description": "The axis the Radio Buttons should align with.", "default": "'vertical'"}, {"name": "value", "type": "str | None", "description": "The value of the selected radio button.", "default": "None"}, {"name": "default_value", "type": "str | None", "description": "The default value of the radio button.", "default": "None"}, {"name": "is_disabled", "type": "bool | None", "description": "Whether the radio button is disabled.", "default": "None"}, {"name": "is_read_only", "type": "bool | None", "description": "Whether the radio button can be selected but not changed by the user.", "default": "None"}, {"name": "name", "type": "str | None", "description": "The name of the radio button, used when submitting and HTML form.", "default": "None"}, {"name": "is_required", "type": "bool | None", "description": "Whether the radio button is required on the input before form submission.", "default": "None"}, {"name": "is_invalid", "type": "bool | None", "description": "Whether the radio button is in an invalid state.", "default": "None"}, {"name": "validation_behavior", "type": "Literal['aria', 'native'] | None", "description": "Whether to use native HTML form validation to prevent form submission when the value is missing or invalid, or mark the field as required or invalid via ARIA.", "default": "None"}, {"name": "label", "type": "Any | None", "description": "The content to display as the label.", "default": "None"}, {"name": "description", "type": "Any | None", "description": "A description for the field. Provides a hint such as specific requirements for what to choose.", "default": "None"}, {"name": "error_message", "type": "Any | None", "description": "An error message for the field.", "default": "None"}, {"name": "label_position", "type": "Literal['top', 'side']", "description": "The position of the label relative to the radio button.", "default": "'top'"}, {"name": "label_align", "type": "Literal['start', 'end'] | None", "description": "The horizontal alignment of the label relative to the radio button.", "default": "None"}, {"name": "necessity_indicator", "type": "Literal['icon', 'label'] | None", "description": "Whether the required state should be shown as an icon or text.", "default": "None"}, {"name": "contextual_help", "type": "Any | None", "description": "A ContextualHelp element to place next to the label.", "default": "None"}, {"name": "show_error_icon", "type": "bool | None", "description": "Whether an error icon is rendered.", "default": "None"}, {"name": "on_change", "type": "Callable[[str], None] | None", "description": "Handler that is called when the radio button value changes.", "default": "None"}, {"name": "on_focus", "type": "Callable[[FocusEvent], None] | None", "description": "Handler that is called when the radio button is focused.", "default": "None"}, {"name": "on_blur", "type": "Callable[[FocusEvent], None] | None", "description": "Handler that is called when the radio button loses focus.", "default": "None"}, {"name": "on_focus_change", "type": "Callable[[bool], None] | None", "description": "Handler that is called when the radio button gains or loses focus.", "default": "None"}, {"name": "flex", "type": "str | float | bool | None", "description": "When used in a flex layout, specifies how the element will grow or shrink to fit the space available.", "default": "None"}, {"name": "flex_grow", "type": "float | None", "description": "When used in a flex layout, specifies how the element will grow to fit the space available.", "default": "None"}, {"name": "flex_shrink", "type": "float | None", "description": "When used in a flex layout, specifies how the element will shrink to fit the space available.", "default": "None"}, {"name": "flex_basis", "type": "str | float | None", "description": "When used in a flex layout, specifies the initial main size of the element.", "default": "None"}, {"name": "align_self", "type": "Literal['auto', 'normal', 'start', 'end', 'center', 'flex-start', 'flex-end', 'self-start', 'self-end', 'stretch'] | None", "description": "Overrides the alignItems property of a flex or grid container.", "default": "None"}, {"name": "justify_self", "type": "Literal['auto', 'normal', 'start', 'end', 'flex-start', 'flex-end', 'self-start', 'self-end', 'center', 'left', 'right', 'stretch'] | None", "description": "Species how the element is justified inside a flex or grid container.", "default": "None"}, {"name": "order", "type": "int | None", "description": "The layout order for the element within a flex or grid container.", "default": "None"}, {"name": "grid_area", "type": "str | None", "description": "When used in a grid layout specifies, specifies the named grid area that the element should be placed in within the grid.", "default": "None"}, {"name": "grid_row", "type": "str | None", "description": "When used in a grid layout, specifies the row the element should be placed in within the grid.", "default": "None"}, {"name": "grid_column", "type": "str | None", "description": "When used in a grid layout, specifies the column the element should be placed in within the grid.", "default": "None"}, {"name": "grid_row_start", "type": "str | None", "description": "When used in a grid layout, specifies the starting row to span within the grid.", "default": "None"}, {"name": "grid_row_end", "type": "str | None", "description": "When used in a grid layout, specifies the ending row to span within the grid.", "default": "None"}, {"name": "grid_column_start", "type": "str | None", "description": "When used in a grid layout, specifies the starting column to span within the grid.", "default": "None"}, {"name": "grid_column_end", "type": "str | None", "description": "When used in a grid layout, specifies the ending column to span within the grid.", "default": "None"}, {"name": "margin", "type": "str | float | None", "description": "The margin for all four sides of the element.", "default": "None"}, {"name": "margin_top", "type": "str | float | None", "description": "The margin for the top side of the element.", "default": "None"}, {"name": "margin_bottom", "type": "str | float | None", "description": "The margin for the bottom side of the element.", "default": "None"}, {"name": "margin_start", "type": "str | float | None", "description": "The margin for the logical start side of the element, depending on layout direction.", "default": "None"}, {"name": "margin_end", "type": "str | float | None", "description": "The margin for the logical end side of the element, depending on layout direction.", "default": "None"}, {"name": "margin_x", "type": "str | float | None", "description": "The margin for the left and right sides of the element.", "default": "None"}, {"name": "margin_y", "type": "str | float | None", "description": "The margin for the top and bottom sides of the element.", "default": "None"}, {"name": "width", "type": "str | float | None", "description": "The width of the element.", "default": "None"}, {"name": "min_width", "type": "str | float | None", "description": "The minimum width of the element.", "default": "None"}, {"name": "max_width", "type": "str | float | None", "description": "The maximum width of the element.", "default": "None"}, {"name": "height", "type": "str | float | None", "description": "The height of the element.", "default": "None"}, {"name": "min_height", "type": "str | float | None", "description": "The minimum height of the element.", "default": "None"}, {"name": "max_height", "type": "str | float | None", "description": "The maximum height of the element.", "default": "None"}, {"name": "position", "type": "Literal['static', 'relative', 'absolute', 'fixed', 'sticky'] | None", "description": "The position of the element.", "default": "None"}, {"name": "top", "type": "str | float | None", "description": "The distance from the top of the containing element.", "default": "None"}, {"name": "bottom", "type": "str | float | None", "description": "The distance from the bottom of the containing element.", "default": "None"}, {"name": "left", "type": "str | float | None", "description": "The distance from the left of the containing element.", "default": "None"}, {"name": "right", "type": "str | float | None", "description": "The distance from the right of the containing element.", "default": "None"}, {"name": "start", "type": "str | float | None", "description": "The distance from the start of the containing element, depending on layout direction.", "default": "None"}, {"name": "end", "type": "str | float | None", "description": "The distance from the end of the containing element, depending on layout direction.", "default": "None"}, {"name": "z_index", "type": "int | None", "description": "The stack order of the element.", "default": "None"}, {"name": "is_hidden", "type": "bool | None", "description": "Whether the element is hidden.", "default": "None"}, {"name": "id", "type": "str | None", "description": "The unique identifier of the element.", "default": "None"}, {"name": "aria_label", "type": "str | None", "description": "Defines a string value that labels the current element.", "default": "None"}, {"name": "aria_labelledby", "type": "str | None", "description": "Identifies the element (or elements) that labels the current element.", "default": "None"}, {"name": "aria_describedby", "type": "str | None", "description": "Identifies the element (or elements) that describes the object.", "default": "None"}, {"name": "aria_details", "type": "str | None", "description": "Identifies the element (or elements) that provide a detailed, extended description for the object.", "default": "None"}, {"name": "aria_errormessage", "type": "str | None", "description": "Identifies the element that provides an error message for the object.", "default": "None"}, {"name": "UNSAFE_class_name", "type": "str | None", "description": "Set the CSS className for the element. Only use as a last resort. Use style props instead.", "default": "None"}, {"name": "UNSAFE_style", "type": "Dict[str, Any] | None", "description": "Set the inline style for the element. Only use as a last resort. Use style props instead.", "default": "None"}, {"name": "key", "type": "str | None", "description": "A unique identifier used by React to render elements in a list.", "default": "None"}]}} />
