// components/ui/RadioGroup.tsx 'use client'; import * as React from 'react'; import clsx from 'clsx'; export type RadioGroupOption = { value: string; label: React.ReactNode; description?: React.ReactNode; disabled?: boolean; className?: string; }; export type RadioGroupVariant = | 'simple' // Radio links, Label rechts | 'withDescription' // Label + Description untereinander | 'right' // Label links, Radio rechts | 'panel'; // Segment-Panel (Pricing/Privacy-Style) type RadioGroupProps = { name?: string; legend?: React.ReactNode; helpText?: React.ReactNode; options: RadioGroupOption[]; /** Kontrollierter Wert (oder null für nichts gewählt) */ value: string | null; onChange: (value: string) => void; orientation?: 'vertical' | 'horizontal'; // nur relevant für simple variant?: RadioGroupVariant; className?: string; optionClassName?: string; idPrefix?: string; }; const baseRadioClasses = 'relative size-4 appearance-none rounded-full border border-gray-300 bg-white ' + 'before:absolute before:inset-1 before:rounded-full before:bg-white ' + 'not-checked:before:hidden checked:border-indigo-600 checked:bg-indigo-600 ' + 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 ' + 'disabled:border-gray-300 disabled:bg-gray-100 disabled:before:bg-gray-400 ' + 'dark:border-white/10 dark:bg-white/5 dark:checked:border-indigo-500 dark:checked:bg-indigo-500 ' + 'dark:focus-visible:outline-indigo-500 dark:disabled:border-white/5 dark:disabled:bg-white/10 ' + 'dark:disabled:before:bg-white/20 forced-colors:appearance-auto forced-colors:before:hidden'; export function RadioGroup({ name, legend, helpText, options, value, onChange, orientation = 'vertical', variant = 'simple', className, optionClassName, idPrefix = 'rg', }: RadioGroupProps) { const internalName = React.useId(); const groupName = name ?? internalName; const isHorizontal = orientation === 'horizontal'; const handleChange = (nextValue: string) => { if (nextValue !== value) { onChange(nextValue); } }; const renderSimple = () => (
{opt.description}
)}{opt.description}
)}