Files
comfy-downloader/src/components/Radio.tsx
Vixalie b864f62170 refactor(Radio): 重构 Radio 组件中的图标渲染逻辑
- 使用 Dynamic 组件动态渲染 RadioIcon 数组中的图标组件
- 通过数组索引选择适当的图标,简化了图标切换逻辑
- 移除了原有的条件渲染代码,提高了组件的可读性和性能
2025-08-12 14:30:31 +08:00

63 lines
1.6 KiB
TypeScript

import { Icon } from '@iconify-icon/solid';
import { isNotNil } from 'es-toolkit';
import {
createEffect,
createMemo,
createSignal,
mergeProps,
ParentComponent,
ParentProps,
Show,
} from 'solid-js';
import { Dynamic } from 'solid-js/web';
interface RadioProps {
name?: string;
checked?: boolean;
disabled?: boolean;
onChange?: (value?: boolean) => void;
}
const RadioIcon = [
() => <Icon icon="hugeicons:circle" class="text-[14px] stroke-1" />,
() => <Icon icon="hugeicons:checkmark-circle-03" class="text-[14px] stroke-1 text-primary" />,
];
const Radio: ParentComponent<RadioProps> = (props) => {
const mProps = mergeProps<ParentProps<RadioProps>[]>(
{
disabled: false,
},
props,
);
const originalChecked = createMemo(() => mProps.checked);
const [internalChecked, setInternalChecked] = createSignal<boolean | undefined>(undefined);
createEffect(() => {
if (isNotNil(originalChecked()) && originalChecked() !== internalChecked()) {
setInternalChecked(originalChecked());
}
});
const handleClick = () => {
if (mProps.disabled) {
return;
}
setInternalChecked((prev) => !prev);
mProps.onChange?.(internalChecked());
};
return (
<div class="flex flex-row items-center gap-2 cursor-pointer" onClick={handleClick}>
<Dynamic component={RadioIcon[internalChecked() ? 1 : 0]} />
<div>{mProps.children}</div>
<Show when={isNotNil(mProps.name)}>
<input type="hidden" name={mProps.name} value={internalChecked()} />
</Show>
</div>
);
};
export default Radio;