mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-27 20:49:53 +08:00
type: Checkbox.Group type infer (#46423)
* feat: CheckboxGroup type infer fix: fix type error fix: define type infer chore: opti type * Update type.test.tsx Signed-off-by: lijianan <574980606@qq.com> * Update Group.tsx Signed-off-by: lijianan <574980606@qq.com> --------- Signed-off-by: lijianan <574980606@qq.com> Co-authored-by: gushuo <gushuo@yoycol.com> Co-authored-by: lijianan <574980606@qq.com>
This commit is contained in:
parent
924f46fd88
commit
0647f56856
@ -11,9 +11,9 @@ import useStyle from './style';
|
||||
|
||||
export type CheckboxValueType = string | number | boolean;
|
||||
|
||||
export interface CheckboxOptionType {
|
||||
export interface CheckboxOptionType<T extends CheckboxValueType = CheckboxValueType> {
|
||||
label: React.ReactNode;
|
||||
value: CheckboxValueType;
|
||||
value: T;
|
||||
style?: React.CSSProperties;
|
||||
disabled?: boolean;
|
||||
title?: string;
|
||||
@ -22,27 +22,29 @@ export interface CheckboxOptionType {
|
||||
required?: boolean;
|
||||
}
|
||||
|
||||
export interface AbstractCheckboxGroupProps {
|
||||
export interface AbstractCheckboxGroupProps<T extends CheckboxValueType = CheckboxValueType> {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
rootClassName?: string;
|
||||
options?: Array<CheckboxOptionType | string | number>;
|
||||
options?: (CheckboxOptionType<T> | string | number)[];
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export interface CheckboxGroupProps extends AbstractCheckboxGroupProps {
|
||||
export interface CheckboxGroupProps<T extends CheckboxValueType = CheckboxValueType>
|
||||
extends AbstractCheckboxGroupProps<T> {
|
||||
name?: string;
|
||||
defaultValue?: Array<CheckboxValueType>;
|
||||
value?: Array<CheckboxValueType>;
|
||||
onChange?: (checkedValue: Array<CheckboxValueType>) => void;
|
||||
defaultValue?: T[];
|
||||
value?: T[];
|
||||
onChange?: (checkedValue: T[]) => void;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const InternalGroup: React.ForwardRefRenderFunction<HTMLDivElement, CheckboxGroupProps> = (
|
||||
props,
|
||||
ref,
|
||||
) => {
|
||||
const CheckboxGroup = React.forwardRef(
|
||||
<T extends CheckboxValueType = CheckboxValueType>(
|
||||
props: CheckboxGroupProps<T>,
|
||||
ref: React.ForwardedRef<HTMLDivElement>,
|
||||
) => {
|
||||
const {
|
||||
defaultValue,
|
||||
children,
|
||||
@ -56,10 +58,8 @@ const InternalGroup: React.ForwardRefRenderFunction<HTMLDivElement, CheckboxGrou
|
||||
} = props;
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
|
||||
const [value, setValue] = React.useState<CheckboxValueType[]>(
|
||||
restProps.value || defaultValue || [],
|
||||
);
|
||||
const [registeredValues, setRegisteredValues] = React.useState<CheckboxValueType[]>([]);
|
||||
const [value, setValue] = React.useState<T[]>(restProps.value || defaultValue || []);
|
||||
const [registeredValues, setRegisteredValues] = React.useState<T[]>([]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if ('value' in restProps) {
|
||||
@ -67,9 +67,9 @@ const InternalGroup: React.ForwardRefRenderFunction<HTMLDivElement, CheckboxGrou
|
||||
}
|
||||
}, [restProps.value]);
|
||||
|
||||
const memoOptions = React.useMemo(
|
||||
const memoOptions = React.useMemo<CheckboxOptionType<T>[]>(
|
||||
() =>
|
||||
options.map<CheckboxOptionType>((option) => {
|
||||
options.map<CheckboxOptionType<T>>((option: CheckboxOptionType<T>) => {
|
||||
if (typeof option === 'string' || typeof option === 'number') {
|
||||
return { label: option, value: option };
|
||||
}
|
||||
@ -78,15 +78,15 @@ const InternalGroup: React.ForwardRefRenderFunction<HTMLDivElement, CheckboxGrou
|
||||
[options],
|
||||
);
|
||||
|
||||
const cancelValue = (val: string) => {
|
||||
const cancelValue = (val: T) => {
|
||||
setRegisteredValues((prevValues) => prevValues.filter((v) => v !== val));
|
||||
};
|
||||
|
||||
const registerValue = (val: string) => {
|
||||
const registerValue = (val: T) => {
|
||||
setRegisteredValues((prevValues) => [...prevValues, val]);
|
||||
};
|
||||
|
||||
const toggleOption = (option: CheckboxOptionType) => {
|
||||
const toggleOption = (option: CheckboxOptionType<T>) => {
|
||||
const optionIndex = value.indexOf(option.value);
|
||||
const newValue = [...value];
|
||||
if (optionIndex === -1) {
|
||||
@ -162,11 +162,12 @@ const InternalGroup: React.ForwardRefRenderFunction<HTMLDivElement, CheckboxGrou
|
||||
<GroupContext.Provider value={context}>{childrenNode}</GroupContext.Provider>
|
||||
</div>,
|
||||
);
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export type { CheckboxGroupContext } from './GroupContext';
|
||||
export { GroupContext };
|
||||
|
||||
const CheckboxGroup = React.forwardRef<HTMLDivElement, CheckboxGroupProps>(InternalGroup);
|
||||
|
||||
export default React.memo(CheckboxGroup);
|
||||
export default CheckboxGroup as <T extends CheckboxValueType = CheckboxValueType>(
|
||||
props: CheckboxGroupProps<T> & React.RefAttributes<HTMLDivElement>,
|
||||
) => React.ReactNode;
|
||||
|
@ -1,13 +1,13 @@
|
||||
import React from 'react';
|
||||
import type { CheckboxOptionType } from './Group';
|
||||
import type { CheckboxOptionType, CheckboxValueType } from './Group';
|
||||
|
||||
export interface CheckboxGroupContext {
|
||||
export interface CheckboxGroupContext<T extends CheckboxValueType = CheckboxValueType> {
|
||||
name?: string;
|
||||
toggleOption?: (option: CheckboxOptionType) => void;
|
||||
value?: any;
|
||||
disabled?: boolean;
|
||||
registerValue: (val: string) => void;
|
||||
cancelValue: (val: string) => void;
|
||||
registerValue: (val: T) => void;
|
||||
cancelValue: (val: T) => void;
|
||||
}
|
||||
|
||||
const GroupContext = React.createContext<CheckboxGroupContext | null>(null);
|
||||
|
@ -13,11 +13,17 @@ describe('Checkbox.typescript', () => {
|
||||
|
||||
it('Checkbox.Group', () => {
|
||||
const group = (
|
||||
<Checkbox.Group>
|
||||
<Checkbox.Group<'test-type-1' | 'test-type-2' | 'test-type-3'>
|
||||
options={[
|
||||
{
|
||||
label: <span>test</span>,
|
||||
value: 'test-type-1',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
</Checkbox.Group>
|
||||
);
|
||||
|
||||
expect(group).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user