分析 antd – Button – Ts
尝试反向推导 button 组件 源码如下
样式文件使用 antd 的 css
import React, { useEffect, useState, ReactNode } from "react";
import { LoadingOutlined } from "@ant-design/icons";
import Class from "classnames";
interface Props {
children?: ReactNode;
type?: "primary" | "ghost" | "dashed" | "link" | "text" | "default";
icon?: ReactNode;
shape?: "default" | "circle" | "round";
size?: "large" | "middle" | "small";
ghost?: Boolean;
loading?: Boolean;
block?: Boolean;
danger?: Boolean;
props?: any;
}
const Button = ({
children,
type,
icon,
shape,
size,
ghost,
loading,
block,
danger,
...props
}: Props) => {
const [classNames, setClassNames] = useState(["ant-btn"]);
useEffect(() => {
const classArr: string[] = []; // 收集类名
const prefix = classNames[0]; // 获取前缀
// 设置按钮类型 primary | ghost | dashed | link | text | default default
if (type) {
classArr.push(`${prefix}-${type}`);
}
// 设置按钮形状 default | circle | round 'default'
if (shape) {
classArr.push(`${prefix}-${shape}`);
}
// size 设置按钮大小 large | middle | small middle
if (size && size !== 'middle') {
const sizeTypes: { large: string; small: string } = {
large: "lg",
small: "sm",
};
sizeTypes[size] && classArr.push(`${prefix}-${sizeTypes[size]}`);
}
// 幽灵属性,使按钮背景透明 boolean false
if (ghost) {
classArr.push(`${prefix}-background-ghost`);
}
// 设置按钮载入状态 boolean | { delay: number } false
if (loading) {
classArr.push(`${prefix}-loading`);
}
// 将按钮宽度调整为其父宽度的选项 boolean false
if (block) {
classArr.push(`${prefix}-block`);
}
// 设置危险按钮 boolean false
if (danger) {
classArr.push(`${prefix}-dangerous`);
}
setClassNames((state) => {
return state.concat(classArr);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<button {...props} className={Class(classNames)}>
{loading && (
<span className="ant-btn-loading-icon">
<LoadingOutlined />
</span>
)}
<span>
{icon}
{children}
</span>
</button>
);
};
export default Button;
欢迎点赞、评论、收藏,谢谢 ( 。ớ ₃ờ)ھ