use topcoat::{
Result,
view::{Attributes, Child, StaticClass, View, class, component, view},
};
#[component]
pub async fn radio_group(
#[default] mut attrs: Attributes,
#[default] child: Child<'_>,
) -> Result<impl View> {
Ok(view! {
<div
role="radiogroup"
class=(class!("grid gap-3", attrs.remove("class")))
(attrs)
>
(child)
</div>
})
}
const RADIO: StaticClass = class!(
"peer size-4 shrink-0 appearance-none rounded-full border border-border",
"bg-background transition-colors outline-none checked:border-primary",
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"focus-visible:ring-offset-background disabled:pointer-events-none",
);
const DOT: StaticClass = class!(
"pointer-events-none absolute inset-0 m-auto size-2 rounded-full bg-primary",
"opacity-0 transition-opacity peer-checked:opacity-100",
);
#[component]
pub async fn radio_group_item(#[default] mut attrs: Attributes) -> Result<impl View> {
Ok(view! {
<span
class=(class!(
"peer relative inline-flex shrink-0 has-[:disabled]:opacity-50",
attrs.remove("class"),
))
>
<input type="radio" class=(RADIO) (attrs)>
<span class=(DOT)></span>
</span>
})
}