Files
community-rule/app/components/controls/RadioButton/RadioButton.view.tsx
T
2026-03-02 22:12:50 -07:00

73 lines
2.0 KiB
TypeScript

import type { RadioButtonViewProps } from "./RadioButton.types";
export function RadioButtonView({
radioId,
checked,
mode,
disabled,
label,
name,
value,
ariaLabel,
className,
combinedBoxStyles,
labelColor,
onToggle,
onKeyDown,
}: RadioButtonViewProps) {
return (
<label
className={`inline-flex items-center gap-[8px] cursor-pointer select-none ${
disabled ? "opacity-60 cursor-not-allowed" : ""
} ${className}`}
onMouseDown={(e) => e.preventDefault()}
onClick={onToggle}
>
<span
onKeyDown={onKeyDown}
className={`group ${combinedBoxStyles} ${disabled ? "" : "cursor-pointer"}`}
tabIndex={disabled ? -1 : 0}
role="radio"
aria-checked={checked}
{...(disabled && { "aria-disabled": true })}
{...(ariaLabel && { "aria-label": ariaLabel })}
{...(label && !ariaLabel && { "aria-labelledby": `${radioId}-label` })}
id={radioId}
>
{/* Radio dot - 16px size per Figma */}
{/* Selected hover state: darker dot color (#333000) per Figma */}
<div
className={`w-[16px] h-[16px] rounded-full transition-all duration-200 ${
checked && mode === "standard"
? "bg-[var(--color-content-default-brand-primary,#fefcc9)] group-hover:!bg-[#333000]"
: checked && mode === "inverse"
? "bg-[var(--color-content-default-primary,#000000)]"
: "bg-transparent"
}`}
/>
</span>
{label && (
<span
id={`${radioId}-label`}
className="font-inter text-[14px] leading-[18px]"
style={{ color: labelColor }}
>
{label}
</span>
)}
{/* Hidden input for form submission */}
<input
type="radio"
name={name}
value={value}
checked={checked}
onChange={() => {}}
disabled={disabled}
className="sr-only"
tabIndex={-1}
aria-hidden="true"
/>
</label>
);
}