Files
mtdb_movie/common/resources/client/ui/forms/segmented-radio-group/segmented-radio-group.tsx
maher 703f50a09d
Some checks failed
Build / run (push) Has been cancelled
first commit
2025-10-29 11:42:25 +01:00

65 lines
1.8 KiB
TypeScript
Executable File

import {
Children,
cloneElement,
forwardRef,
isValidElement,
useId,
useRef,
} from 'react';
import {RadioGroupProps} from '../radio-group/radio-group';
import {SegmentedRadioProps} from './segmented-radio';
import {ActiveIndicator} from './active-indicator';
import {useControlledState} from '@react-stately/utils';
import clsx from 'clsx';
export interface SegmentedRadioGroupProps
extends Omit<RadioGroupProps, 'orientation'> {
value?: string;
onChange?: (value: string) => void;
defaultValue?: string;
width?: string;
}
export const SegmentedRadioGroup = forwardRef<
HTMLFieldSetElement,
SegmentedRadioGroupProps
>((props, ref) => {
const {children, size, className} = props;
const id = useId();
const name = props.name || id;
const labelsRef = useRef<Record<string, HTMLLabelElement>>({});
const [selectedValue, setSelectedValue] = useControlledState(
props.value,
props.defaultValue,
props.onChange,
);
return (
<fieldset ref={ref} className={clsx(className, props.width ?? 'w-min')}>
<div className="relative isolate flex rounded bg-chip p-4">
<ActiveIndicator selectedValue={selectedValue} labelsRef={labelsRef} />
{Children.map(children, (child, index) => {
if (isValidElement<SegmentedRadioProps>(child)) {
return cloneElement<SegmentedRadioProps>(child, {
isFirst: index === 0,
name,
size,
onChange: e => {
setSelectedValue(e.target.value);
child.props.onChange?.(e);
},
labelRef: el => {
if (el) {
labelsRef.current[child.props.value] = el;
}
},
isSelected: selectedValue === child.props.value,
});
}
})}
</div>
</fieldset>
);
});