Files
community-rule/app/components/controls/RadioGroup/RadioGroup.view.tsx
T
adilallo ca928e306b Match the 3 Nov color ramps and size-based strokes, and replace leftover palette hex with tokens.
Drop Cookies Settings from the footer, link the Home features that already have pages, and give leftover routes their own descriptions.
2026-11-05 15:37:55 -07:00

89 lines
2.5 KiB
TypeScript

import RadioButton from "../RadioButton";
import type { RadioGroupViewProps } from "./RadioGroup.types";
export function RadioGroupView({
groupId,
value,
mode,
state,
disabled,
options,
className,
ariaLabel,
onOptionChange,
}: RadioGroupViewProps) {
return (
<div
className={`space-y-[8px] ${className}`}
role="radiogroup"
aria-label={ariaLabel}
>
{options.map((option) => {
const isSelected = value === option.value;
// If there's subtext, render radio button without label and handle layout separately
if (option.subtext) {
return (
<div key={option.value} className="flex gap-[8px] items-start">
<RadioButton
checked={isSelected}
mode={mode}
state={state}
disabled={disabled}
name={groupId}
value={option.value}
ariaLabel={option.ariaLabel || option.label}
onChange={({ checked }) => {
if (checked) {
onOptionChange(option.value);
}
}}
/>
<div className="flex flex-col gap-[4px] flex-1">
<span
className={`text-small-paragraph ${
mode === "inverse"
? "text-[var(--color-content-invert-primary)]"
: "text-[var(--color-content-default-primary)]"
}`}
>
{option.label}
</span>
<span
className={`text-small-paragraph ${
mode === "inverse"
? "text-[var(--color-content-invert-secondary)]"
: "text-[var(--color-content-default-secondary)]"
}`}
>
{option.subtext}
</span>
</div>
</div>
);
}
// If no subtext, use RadioButton's built-in label
return (
<RadioButton
key={option.value}
checked={isSelected}
mode={mode}
state={state}
disabled={disabled}
label={option.label}
name={groupId}
value={option.value}
ariaLabel={option.ariaLabel}
onChange={({ checked }) => {
if (checked) {
onOptionChange(option.value);
}
}}
/>
);
})}
</div>
);
}