Radio Group
Example:
Standard spacing for most use cases.
More space between elements.
Minimal spacing for dense layouts.
Code example:
from htmy import ComponentType, html
from htmui.basecoat.radio_group import radio_group, radio_input
def example() -> ComponentType:
return html.div(
radio_group(
radio_input(
"Default",
name="density",
value="default",
description="Standard spacing for most use cases.",
),
radio_input(
"Comfortable",
name="density",
value="comfortable",
checked=True,
description="More space between elements.",
),
radio_input(
"Compact",
name="density",
value="compact",
description="Minimal spacing for dense layouts.",
),
aria_label="View density",
),
radio_group(
radio_input("Email only", name="notify", value="email", invalid=True),
radio_input("SMS only", name="notify", value="sms", invalid=True),
radio_input(
"Both",
name="notify",
value="both",
checked=True,
disabled=True,
),
aria_label="Notification preferences",
),
class_="flex flex-col gap-6",
)
Component implementation:
For more details, see the BasecoatUI documentation.
from htmy import ComponentType, PropertyValue, XBool, html, join_classes
__version__ = "0.2.0"
__framework__ = "BasecoatUI"
__framework_version__ = "1"
__framework_url__ = "https://basecoatui.com/components/radio-group/"
def radio_input(
*children: ComponentType,
name: str,
value: str,
description: ComponentType | None = None,
checked: bool = False,
disabled: bool = False,
invalid: bool = False,
class_: str | None = None,
**kwargs: PropertyValue,
) -> ComponentType:
"""
Radio option, a horizontal field with input and label.
Arguments:
*children: Label content.
name: The name of the input.
value: Value submitted when this option is selected.
description: Optional description shown under the label.
checked: Whether the option is initially selected.
disabled: Whether the option is disabled.
invalid: Whether to mark the option as invalid.
class_: Extra CSS classes for the field wrapper.
**kwargs: Extra attributes for the input element.
"""
input_id = f"{name}-{value}"
if checked:
kwargs["checked"] = XBool.true
if disabled:
kwargs["disabled"] = XBool.true
if invalid:
kwargs["aria_invalid"] = "true"
label = html.label(*children, for_=input_id)
content: ComponentType = html.section(label, html.p(description)) if description is not None else label
field_attrs: dict[str, PropertyValue] = {
"role": "group",
"data_orientation": "horizontal",
}
if disabled:
field_attrs["data_disabled"] = "true"
if invalid:
field_attrs["data_invalid"] = "true"
return html.div(
html.input_(
type="radio",
id=input_id,
name=name,
value=value,
class_="input",
**kwargs,
),
content,
class_=join_classes("field", class_),
**field_attrs,
)
def radio_group(
*children: ComponentType,
class_: str | None = None,
**kwargs: PropertyValue,
) -> ComponentType:
"""
Radio group container.
Arguments:
*children: The components in the group.
class_: Extra CSS classes for the root element.
**kwargs: Extra attributes for the root element.
"""
return html.div(*children, class_=class_, role="radiogroup", data_slot="radio-group", **kwargs)