feat(components): 添加 RadioGroup 组件
- 实现了一个新的 RadioGroup 组件,用于管理一组单选按钮 - 组件支持 name、options、value、disabled 和 onChange 属性 - 使用 Solid.js 的信号和效果来处理选中值和禁用状态 - 添加了隐藏输入字段以支持表单提交
This commit is contained in:
74
src/components/RadioGroup.tsx
Normal file
74
src/components/RadioGroup.tsx
Normal 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;
|
Reference in New Issue
Block a user