Skip to content

Commit ac34c5d

Browse files
committed
refactor: rewrite using typescript
1 parent 906206d commit ac34c5d

File tree

5 files changed

+127
-178
lines changed

5 files changed

+127
-178
lines changed

.editorconfig

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
# top-most EditorConfig file
1+
# 🎨 editorconfig.org
2+
23
root = true
34

4-
# Unix-style newlines with a newline ending every file
5-
[*.{js,css}]
5+
[*]
6+
charset = utf-8
67
end_of_line = lf
7-
insert_final_newline = true
88
indent_style = space
99
indent_size = 2
10+
trim_trailing_whitespace = true
11+
insert_final_newline = true

src/index.d.ts

-25
This file was deleted.

src/index.jsx

-149
This file was deleted.

src/index.tsx

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import * as React from 'react';
2+
import { forwardRef, useImperativeHandle, useRef } from 'react';
3+
import useMergedState from 'rc-util/lib/hooks/useMergedState';
4+
import classNames from 'classnames';
5+
6+
export interface CheckboxChangeEvent {
7+
target: CheckboxChangeEventTarget;
8+
stopPropagation: () => void;
9+
preventDefault: () => void;
10+
nativeEvent: React.ChangeEvent<HTMLInputElement>['nativeEvent'];
11+
}
12+
13+
export interface CheckboxChangeEventTarget extends CheckboxProps {
14+
checked: boolean;
15+
}
16+
17+
export interface CheckboxRef {
18+
focus: () => void;
19+
blur: () => void;
20+
input: HTMLInputElement | null;
21+
}
22+
23+
export interface CheckboxProps
24+
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
25+
prefixCls?: string;
26+
onChange?: (e: CheckboxChangeEvent) => void;
27+
}
28+
29+
export const Checkbox = forwardRef<CheckboxRef, CheckboxProps>((props, ref) => {
30+
const {
31+
prefixCls = 'rc-checkbox',
32+
className,
33+
style,
34+
checked,
35+
disabled,
36+
defaultChecked = false,
37+
type = 'checkbox',
38+
onChange,
39+
...inputProps
40+
} = props;
41+
42+
const inputRef = useRef<HTMLInputElement>(null);
43+
const [rawValue, setRawValue] = useMergedState(defaultChecked, {
44+
value: checked,
45+
});
46+
47+
useImperativeHandle(ref, () => ({
48+
focus: () => {
49+
inputRef.current?.focus();
50+
},
51+
blur: () => {
52+
inputRef.current?.blur();
53+
},
54+
input: inputRef.current,
55+
}));
56+
57+
const classString = classNames(prefixCls, className, {
58+
[`${prefixCls}-checked`]: rawValue,
59+
[`${prefixCls}-disabled`]: disabled,
60+
});
61+
62+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
63+
if (disabled) {
64+
return;
65+
}
66+
67+
const checked = e.target.checked;
68+
69+
if (!('checked' in props)) {
70+
setRawValue(checked);
71+
}
72+
73+
onChange?.({
74+
target: {
75+
...props,
76+
checked,
77+
},
78+
stopPropagation() {
79+
e.stopPropagation();
80+
},
81+
preventDefault() {
82+
e.preventDefault();
83+
},
84+
nativeEvent: e.nativeEvent,
85+
});
86+
};
87+
88+
return (
89+
<span className={classString} style={style}>
90+
<input
91+
{...inputProps}
92+
className={`${prefixCls}-input`}
93+
ref={inputRef}
94+
onChange={handleChange}
95+
disabled={disabled}
96+
checked={!!rawValue}
97+
type={type}
98+
/>
99+
<span className={`${prefixCls}-inner`} />
100+
</span>
101+
);
102+
});
103+
104+
export default Checkbox;

tsconfig.json

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"compilerOptions": {
3+
"target": "esnext",
4+
"moduleResolution": "node",
5+
"baseUrl": "./",
6+
"strict": true,
7+
"jsx": "preserve",
8+
"declaration": true,
9+
"skipLibCheck": true,
10+
"esModuleInterop": true,
11+
"paths": {
12+
"@/*": ["src/*"],
13+
"@@/*": ["src/.umi/*"],
14+
"rc-checkbox": ["src/index.tsx"]
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)