fix: Radio.Group focus and blur should work (#36041)

This commit is contained in:
MadCcc 2022-06-14 14:00:33 +08:00 committed by GitHub
parent 0b2b27341c
commit e3974850fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 91 additions and 79 deletions

View File

@ -1,6 +1,6 @@
import React from 'react';
import { mount, render } from 'enzyme';
import { render as testLibRender } from '@testing-library/react';
import { fireEvent, render as testLibRender } from '@testing-library/react';
import Radio from '..';
describe('Radio Group', () => {
@ -224,4 +224,16 @@ describe('Radio Group', () => {
});
});
});
it('onBlur & onFocus should work', () => {
const handleBlur = jest.fn();
const handleFocus = jest.fn();
const { container } = testLibRender(
<Radio.Group options={['1', '2', '3']} onBlur={handleBlur} onFocus={handleFocus} />,
);
fireEvent.focus(container.firstChild);
expect(handleFocus).toHaveBeenCalledTimes(1);
fireEvent.blur(container.firstChild);
expect(handleBlur).toHaveBeenCalledTimes(1);
});
});

View File

@ -28,93 +28,91 @@ const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>((props, ref
}
};
const renderGroup = () => {
const {
prefixCls: customizePrefixCls,
className = '',
options,
buttonStyle = 'outline' as RadioGroupButtonStyle,
disabled,
children,
size: customizeSize,
style,
id,
onMouseEnter,
onMouseLeave,
} = props;
const prefixCls = getPrefixCls('radio', customizePrefixCls);
const groupPrefixCls = `${prefixCls}-group`;
let childrenToRender = children;
// 如果存在 options, 优先使用
if (options && options.length > 0) {
childrenToRender = options.map(option => {
if (typeof option === 'string' || typeof option === 'number') {
// 此处类型自动推导为 string
return (
<Radio
key={option.toString()}
prefixCls={prefixCls}
disabled={disabled}
value={option}
checked={value === option}
>
{option}
</Radio>
);
}
// 此处类型自动推导为 { label: string value: string }
const {
prefixCls: customizePrefixCls,
className = '',
options,
buttonStyle = 'outline' as RadioGroupButtonStyle,
disabled,
children,
size: customizeSize,
style,
id,
onMouseEnter,
onMouseLeave,
onFocus,
onBlur,
} = props;
const prefixCls = getPrefixCls('radio', customizePrefixCls);
const groupPrefixCls = `${prefixCls}-group`;
let childrenToRender = children;
// 如果存在 options, 优先使用
if (options && options.length > 0) {
childrenToRender = options.map(option => {
if (typeof option === 'string' || typeof option === 'number') {
// 此处类型自动推导为 string
return (
<Radio
key={`radio-group-value-options-${option.value}`}
key={option.toString()}
prefixCls={prefixCls}
disabled={option.disabled || disabled}
value={option.value}
checked={value === option.value}
style={option.style}
disabled={disabled}
value={option}
checked={value === option}
>
{option.label}
{option}
</Radio>
);
});
}
}
// 此处类型自动推导为 { label: string value: string }
return (
<Radio
key={`radio-group-value-options-${option.value}`}
prefixCls={prefixCls}
disabled={option.disabled || disabled}
value={option.value}
checked={value === option.value}
style={option.style}
>
{option.label}
</Radio>
);
});
}
const mergedSize = customizeSize || size;
const classString = classNames(
groupPrefixCls,
`${groupPrefixCls}-${buttonStyle}`,
{
[`${groupPrefixCls}-${mergedSize}`]: mergedSize,
[`${groupPrefixCls}-rtl`]: direction === 'rtl',
},
className,
);
return (
<div
{...getDataOrAriaProps(props)}
className={classString}
style={style}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
id={id}
ref={ref}
const mergedSize = customizeSize || size;
const classString = classNames(
groupPrefixCls,
`${groupPrefixCls}-${buttonStyle}`,
{
[`${groupPrefixCls}-${mergedSize}`]: mergedSize,
[`${groupPrefixCls}-rtl`]: direction === 'rtl',
},
className,
);
return (
<div
{...getDataOrAriaProps(props)}
className={classString}
style={style}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onFocus={onFocus}
onBlur={onBlur}
id={id}
ref={ref}
>
<RadioGroupContextProvider
value={{
onChange: onRadioChange,
value,
disabled: props.disabled,
name: props.name,
optionType: props.optionType,
}}
>
{childrenToRender}
</div>
);
};
return (
<RadioGroupContextProvider
value={{
onChange: onRadioChange,
value,
disabled: props.disabled,
name: props.name,
optionType: props.optionType,
}}
>
{renderGroup()}
</RadioGroupContextProvider>
</RadioGroupContextProvider>
</div>
);
});

View File

@ -20,6 +20,8 @@ export interface RadioGroupProps extends AbstractCheckboxGroupProps {
id?: string;
optionType?: RadioGroupOptionType;
buttonStyle?: RadioGroupButtonStyle;
onFocus?: React.FocusEventHandler<HTMLDivElement>;
onBlur?: React.FocusEventHandler<HTMLDivElement>;
}
export interface RadioGroupContextProps {