import type { ComponentProps, DetailedHTMLProps, InputHTMLAttributes, LabelHTMLAttributes, } from "react"; import Row from "../layout/Row"; import twuiSlugify from "../utils/slugify"; import twuiSlugToNormalText from "../utils/slug-to-normal-text"; import { twMerge } from "tailwind-merge"; type Value = { value: string; title?: string; default?: boolean; }; export type TWUI_FORM_RADIO_PROPS = { values: Value[]; name: string; inputProps?: DetailedHTMLProps< InputHTMLAttributes, HTMLInputElement >; labelProps?: DetailedHTMLProps< LabelHTMLAttributes, HTMLLabelElement >; wrapperProps?: ComponentProps; changeHandler?: (value: string) => void; /** * Let each radio's label wrap onto multiple lines. By default every * radio stays on one line with its label clamped to a single line with * an ellipsis, and the full text is shown as the radio's `title` on * hover. */ wrap?: boolean; }; /** * # Form Radios Component * @className twui-radios * @className twui-radio * @className twui-radio-label * @className twui-radio-indicator - the custom circle; the native input is * visually hidden right before it, so target the checked state with * `.twui-radio input:checked + .twui-radio-indicator` */ export default function Radios({ values, name, inputProps, labelProps, wrapperProps, changeHandler, wrap, }: TWUI_FORM_RADIO_PROPS) { const finalName = twuiSlugify(name); const finalTitle = twuiSlugToNormalText(finalName); return ( {values.map((v, i) => { const valueName = twuiSlugify(`${finalName}-${v.value}`); const valueTitle = v.title || twuiSlugToNormalText(v.value); return ( ); })} ); }