mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 02:59:58 +08:00
refactor(tag): rewrite with hook (#23466)
* refactor(tag): rewrite with hook * fix lint
This commit is contained in:
parent
d7e97aa996
commit
cf3d611f59
@ -17,7 +17,7 @@ export interface PageHeaderProps {
|
|||||||
subTitle?: React.ReactNode;
|
subTitle?: React.ReactNode;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
breadcrumb?: BreadcrumbProps;
|
breadcrumb?: BreadcrumbProps;
|
||||||
tags?: React.ReactElement<Tag> | React.ReactElement<Tag>[];
|
tags?: typeof Tag | typeof Tag[];
|
||||||
footer?: React.ReactNode;
|
footer?: React.ReactNode;
|
||||||
extra?: React.ReactNode;
|
extra?: React.ReactNode;
|
||||||
avatar?: AvatarProps;
|
avatar?: AvatarProps;
|
||||||
|
@ -10,16 +10,16 @@ export interface CheckableTagProps {
|
|||||||
onChange?: (checked: boolean) => void;
|
onChange?: (checked: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class CheckableTag extends React.Component<CheckableTagProps> {
|
const CheckableTag: React.FC<CheckableTagProps> = props => {
|
||||||
handleClick = () => {
|
const handleClick = () => {
|
||||||
const { checked, onChange } = this.props;
|
const { checked, onChange } = props;
|
||||||
if (onChange) {
|
if (onChange) {
|
||||||
onChange(!checked);
|
onChange(!checked);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
renderCheckableTag = ({ getPrefixCls }: ConfigConsumerProps) => {
|
const renderCheckableTag = ({ getPrefixCls }: ConfigConsumerProps) => {
|
||||||
const { prefixCls: customizePrefixCls, className, checked, ...restProps } = this.props;
|
const { prefixCls: customizePrefixCls, className, checked, ...restProps } = props;
|
||||||
const prefixCls = getPrefixCls('tag', customizePrefixCls);
|
const prefixCls = getPrefixCls('tag', customizePrefixCls);
|
||||||
const cls = classNames(
|
const cls = classNames(
|
||||||
prefixCls,
|
prefixCls,
|
||||||
@ -31,10 +31,10 @@ export default class CheckableTag extends React.Component<CheckableTagProps> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
delete (restProps as any).onChange; // TypeScript cannot check delete now.
|
delete (restProps as any).onChange; // TypeScript cannot check delete now.
|
||||||
return <span {...(restProps as any)} className={cls} onClick={this.handleClick} />;
|
return <span {...(restProps as any)} className={cls} onClick={handleClick} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
return <ConfigConsumer>{renderCheckableTag}</ConfigConsumer>;
|
||||||
return <ConfigConsumer>{this.renderCheckableTag}</ConfigConsumer>;
|
};
|
||||||
}
|
|
||||||
}
|
export default CheckableTag;
|
||||||
|
@ -27,61 +27,57 @@ export interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|||||||
icon?: React.ReactNode;
|
icon?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TagState {
|
|
||||||
visible: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PresetColorRegex = new RegExp(`^(${PresetColorTypes.join('|')})(-inverse)?$`);
|
const PresetColorRegex = new RegExp(`^(${PresetColorTypes.join('|')})(-inverse)?$`);
|
||||||
const PresetStatusColorRegex = new RegExp(`^(${PresetStatusColorTypes.join('|')})$`);
|
const PresetStatusColorRegex = new RegExp(`^(${PresetStatusColorTypes.join('|')})$`);
|
||||||
|
|
||||||
class Tag extends React.Component<TagProps, TagState> {
|
interface TagType extends React.FC<TagProps> {
|
||||||
static CheckableTag = CheckableTag;
|
CheckableTag: typeof CheckableTag;
|
||||||
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
const Tag: TagType = props => {
|
||||||
closable: false,
|
const [visible, setVisible] = React.useState(true);
|
||||||
};
|
|
||||||
|
|
||||||
static getDerivedStateFromProps(nextProps: TagProps) {
|
React.useEffect(() => {
|
||||||
if ('visible' in nextProps) {
|
if ('visible' in props) {
|
||||||
return {
|
setVisible(props.visible!);
|
||||||
visible: nextProps.visible,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return null;
|
}, [props.visible]);
|
||||||
}
|
|
||||||
|
|
||||||
state = {
|
const isPresetColor = (): boolean => {
|
||||||
visible: true,
|
const { color } = props;
|
||||||
|
if (!color) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return PresetColorRegex.test(color) || PresetStatusColorRegex.test(color);
|
||||||
};
|
};
|
||||||
|
|
||||||
getTagStyle() {
|
const getTagStyle = () => {
|
||||||
const { color, style } = this.props;
|
const { color, style } = props;
|
||||||
const isPresetColor = this.isPresetColor();
|
|
||||||
return {
|
return {
|
||||||
backgroundColor: color && !isPresetColor ? color : undefined,
|
backgroundColor: color && !isPresetColor() ? color : undefined,
|
||||||
...style,
|
...style,
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
getTagClassName({ getPrefixCls, direction }: ConfigConsumerProps) {
|
const getTagClassName = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
|
||||||
const { prefixCls: customizePrefixCls, className, color } = this.props;
|
const { prefixCls: customizePrefixCls, className, color } = props;
|
||||||
const { visible } = this.state;
|
const presetColor = isPresetColor();
|
||||||
const isPresetColor = this.isPresetColor();
|
|
||||||
const prefixCls = getPrefixCls('tag', customizePrefixCls);
|
const prefixCls = getPrefixCls('tag', customizePrefixCls);
|
||||||
return classNames(
|
return classNames(
|
||||||
prefixCls,
|
prefixCls,
|
||||||
{
|
{
|
||||||
[`${prefixCls}-${color}`]: isPresetColor,
|
[`${prefixCls}-${color}`]: presetColor,
|
||||||
[`${prefixCls}-has-color`]: color && !isPresetColor,
|
[`${prefixCls}-has-color`]: color && !presetColor,
|
||||||
[`${prefixCls}-hidden`]: !visible,
|
[`${prefixCls}-hidden`]: !visible,
|
||||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||||
},
|
},
|
||||||
className,
|
className,
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
setVisible(visible: boolean, e: React.MouseEvent<HTMLElement>) {
|
const handleIconClick = (e: React.MouseEvent<HTMLElement>) => {
|
||||||
const { onClose } = this.props;
|
e.stopPropagation();
|
||||||
|
const { onClose } = props;
|
||||||
if (onClose) {
|
if (onClose) {
|
||||||
onClose(e);
|
onClose(e);
|
||||||
}
|
}
|
||||||
@ -89,31 +85,18 @@ class Tag extends React.Component<TagProps, TagState> {
|
|||||||
if (e.defaultPrevented) {
|
if (e.defaultPrevented) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!('visible' in this.props)) {
|
if (!('visible' in props)) {
|
||||||
this.setState({ visible });
|
setVisible(false);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
handleIconClick = (e: React.MouseEvent<HTMLElement>) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
this.setVisible(false, e);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
isPresetColor(): boolean {
|
const renderCloseIcon = () => {
|
||||||
const { color } = this.props;
|
const { closable } = props;
|
||||||
if (!color) {
|
return closable ? <CloseOutlined onClick={handleIconClick} /> : null;
|
||||||
return false;
|
};
|
||||||
}
|
|
||||||
return PresetColorRegex.test(color) || PresetStatusColorRegex.test(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderCloseIcon() {
|
const renderTag = (configProps: ConfigConsumerProps) => {
|
||||||
const { closable } = this.props;
|
const { children, icon, ...otherProps } = props;
|
||||||
return closable ? <CloseOutlined onClick={this.handleIconClick} /> : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderTag = (configProps: ConfigConsumerProps) => {
|
|
||||||
const { children, icon, ...otherProps } = this.props;
|
|
||||||
const isNeedWave =
|
const isNeedWave =
|
||||||
'onClick' in otherProps || (children && (children as React.ReactElement<any>).type === 'a');
|
'onClick' in otherProps || (children && (children as React.ReactElement<any>).type === 'a');
|
||||||
const tagProps = omit(otherProps, ['onClose', 'color', 'visible', 'closable', 'prefixCls']);
|
const tagProps = omit(otherProps, ['onClose', 'color', 'visible', 'closable', 'prefixCls']);
|
||||||
@ -129,26 +112,26 @@ class Tag extends React.Component<TagProps, TagState> {
|
|||||||
|
|
||||||
return isNeedWave ? (
|
return isNeedWave ? (
|
||||||
<Wave>
|
<Wave>
|
||||||
<span
|
<span {...tagProps} className={getTagClassName(configProps)} style={getTagStyle()}>
|
||||||
{...tagProps}
|
|
||||||
className={this.getTagClassName(configProps)}
|
|
||||||
style={this.getTagStyle()}
|
|
||||||
>
|
|
||||||
{kids}
|
{kids}
|
||||||
{this.renderCloseIcon()}
|
{renderCloseIcon()}
|
||||||
</span>
|
</span>
|
||||||
</Wave>
|
</Wave>
|
||||||
) : (
|
) : (
|
||||||
<span {...tagProps} className={this.getTagClassName(configProps)} style={this.getTagStyle()}>
|
<span {...tagProps} className={getTagClassName(configProps)} style={getTagStyle()}>
|
||||||
{kids}
|
{kids}
|
||||||
{this.renderCloseIcon()}
|
{renderCloseIcon()}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
return <ConfigConsumer>{renderTag}</ConfigConsumer>;
|
||||||
return <ConfigConsumer>{this.renderTag}</ConfigConsumer>;
|
};
|
||||||
}
|
|
||||||
}
|
Tag.defaultProps = {
|
||||||
|
closable: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
Tag.CheckableTag = CheckableTag;
|
||||||
|
|
||||||
export default Tag;
|
export default Tag;
|
||||||
|
Loading…
Reference in New Issue
Block a user