feat(components): 添加 Check 复选框组件
- 实现了一个新的复选框组件 Check - 支持基本的复选框功能,包括选中、未选中和禁用状态 - 使用图标库来渲染选中和未选中状态 - 添加了隐藏的 input 元素,以便在表单中使用 - 组件具有良好的可定制性和扩展性
This commit is contained in:
62
src/components/Check.tsx
Normal file
62
src/components/Check.tsx
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { Icon } from '@iconify-icon/solid';
|
||||||
|
import { isNotNil } from 'es-toolkit';
|
||||||
|
import {
|
||||||
|
createEffect,
|
||||||
|
createMemo,
|
||||||
|
createSignal,
|
||||||
|
mergeProps,
|
||||||
|
ParentComponent,
|
||||||
|
ParentProps,
|
||||||
|
Show,
|
||||||
|
} from 'solid-js';
|
||||||
|
|
||||||
|
interface CheckBoxProps {
|
||||||
|
name?: string;
|
||||||
|
checked?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
onChange?: (checked: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Check: ParentComponent<CheckBoxProps> = (props) => {
|
||||||
|
const mProps = mergeProps<ParentProps<CheckBoxProps>[]>(
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
console.debug('[Check]before', internalChecked());
|
||||||
|
setInternalChecked((prev) => !prev);
|
||||||
|
console.debug('[Check]after', internalChecked());
|
||||||
|
mProps.onChange?.(internalChecked());
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="flex flex-row items-center gap-2 cursor-pointer" onClick={handleClick}>
|
||||||
|
<Icon
|
||||||
|
icon={internalChecked() ? 'hugeicons:checkmark-square-03' : 'hugeicons:square'}
|
||||||
|
class="text-[14px] stroke-1"
|
||||||
|
classList={{ 'text-primary': internalChecked() }}
|
||||||
|
/>
|
||||||
|
<div>{mProps.children}</div>
|
||||||
|
<Show when={isNotNil(mProps.name)}>
|
||||||
|
<input type="hidden" name={mProps.name} value={internalChecked()} />
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Check;
|
Reference in New Issue
Block a user