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