feat(components): 添加 RadioGroup 组件

- 实现了一个新的 RadioGroup 组件,用于管理一组单选按钮
- 组件支持 name、options、value、disabled 和 onChange 属性
- 使用 Solid.js 的信号和效果来处理选中值和禁用状态
- 添加了隐藏输入字段以支持表单提交
This commit is contained in:
Vixalie
2025-08-12 14:50:09 +08:00
parent b864f62170
commit 722c7b075d

View File

@@ -0,0 +1,74 @@
import { isNotNil } from 'es-toolkit';
import {
Component,
createEffect,
createMemo,
createSignal,
Index,
JSX,
mergeProps,
Show,
} from 'solid-js';
import Radio from './Radio';
type Option = {
label: string | JSX.Element;
value: string | number | symbol | boolean;
};
interface RadioGroupProps {
name?: string;
options?: Option[];
value?: Option['value'];
disabled?: boolean;
onChange?: (value?: Option['value']) => void;
}
const RadioGroup: Component<RadioGroupProps> = (props) => {
const mProps = mergeProps<RadioGroupProps[]>(
{
options: [],
disabled: false,
},
props,
);
const originalValue = createMemo(() => mProps.value);
const [selectedValue, setSelectedValue] = createSignal<Option['value'] | undefined>(undefined);
createEffect(() => {
if (isNotNil(originalValue()) && originalValue() !== selectedValue()) {
setSelectedValue(originalValue());
}
});
const handleSelect = (value: Option['value']) => {
if (mProps.disabled) {
return;
}
setSelectedValue(value);
mProps.onChange?.(selectedValue());
};
return (
<>
<Index each={mProps.options}>
{(option) => (
<Radio
checked={selectedValue() === option().value}
disabled={mProps.disabled}
onChange={() => {
handleSelect(option().value);
}}>
{option().label}
</Radio>
)}
</Index>
<Show when={isNotNil(mProps.name)}>
<input type="hidden" name={mProps.name} value={selectedValue()} />
</Show>
</>
);
};
export default RadioGroup;