turash/bugulma/frontend/components/ui/RadioGroup.tsx
2025-12-15 10:06:41 +01:00

86 lines
2.1 KiB
TypeScript

import React from 'react';
import { clsx } from 'clsx';
export interface RadioOption {
value: string;
label: string;
description?: string;
disabled?: boolean;
}
export interface RadioGroupProps {
options: RadioOption[];
value?: string;
onChange?: (value: string) => void;
name: string;
className?: string;
orientation?: 'horizontal' | 'vertical';
}
/**
* Radio group component
*/
export const RadioGroup = ({
options,
value,
onChange,
name,
className,
orientation = 'vertical',
}: RadioGroupProps) => {
return (
<div
className={clsx(
'flex gap-4',
{
'flex-col': orientation === 'vertical',
'flex-row flex-wrap': orientation === 'horizontal',
},
className
)}
role="radiogroup"
>
{options.map((option) => (
<label
key={option.value}
className={clsx('flex items-start gap-3 cursor-pointer', 'group', {
'opacity-50 cursor-not-allowed': option.disabled,
})}
>
<input
type="radio"
name={name}
value={option.value}
checked={value === option.value}
onChange={(e) => {
if (!option.disabled) {
onChange?.(e.target.value);
}
}}
disabled={option.disabled}
className="mt-0.5 h-4 w-4 text-primary focus:ring-2 focus:ring-primary focus:ring-offset-2 cursor-pointer disabled:cursor-not-allowed"
/>
<div className="flex flex-col">
<span
className={clsx('text-sm font-medium', {
'text-muted-foreground': option.disabled,
})}
>
{option.label}
</span>
{option.description && (
<span
className={clsx('text-xs text-muted-foreground mt-0.5', {
'opacity-70': option.disabled,
})}
>
{option.description}
</span>
)}
</div>
</label>
))}
</div>
);
};