Files
community-rule/app/components/controls/RadioButton/RadioButton.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

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: --color-surface-default-brand-primary (#333000 / yellow-1000) per Figma */}
<div
className={`w-[16px] h-[16px] rounded-full transition-all duration-200 ${
checked && mode === "standard"
? "bg-[var(--color-content-default-brand-primary)] group-hover:!bg-[var(--color-surface-default-brand-primary)]"
: checked && mode === "inverse"
? "bg-[var(--color-content-default-primary)]"
: "bg-transparent"
}`}
/>
</span>
{label && (
<span
id={`${radioId}-label`}
className="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>
);
}