63 lines
1.5 KiB
TypeScript
63 lines
1.5 KiB
TypeScript
import { theme } from "antd";
|
||
import { ReactNode, CSSProperties } from "react";
|
||
import { motion } from "framer-motion";
|
||
|
||
export default function DashboardCard({
|
||
children,
|
||
title,
|
||
className,
|
||
contentClassName,
|
||
titleClassName,
|
||
extra,
|
||
style,
|
||
contentStyle,
|
||
}: {
|
||
contentClassName?: string;
|
||
contentStyle?: CSSProperties;
|
||
extra?: ReactNode;
|
||
title?: ReactNode;
|
||
children?: ReactNode;
|
||
titleClassName?: string;
|
||
className?: string;
|
||
style?: CSSProperties;
|
||
}) {
|
||
const { token } = theme.useToken();
|
||
|
||
return (
|
||
<motion.div
|
||
className={`rounded-xl p-4 flex-col flex hover:bg-white bg-gray-50 transition-all ease-in-out shadow-elegant border-white border-2 ${className}`}
|
||
style={style}
|
||
initial={{ opacity: 0, scale: 0.8, x: -20 }} // 添加x轴位移,让动画有入场效果
|
||
animate={{
|
||
opacity: 1,
|
||
scale: 1.0,
|
||
x: 0, // 回到原位
|
||
transition: {
|
||
duration: 0.3, // 增加动画持续时间
|
||
ease: "easeOut", // 使用easeOut缓动函数,让动画结束时减速
|
||
},
|
||
}}>
|
||
<div className="flex justify-between items-center">
|
||
<div
|
||
className={titleClassName}
|
||
style={{
|
||
lineHeight: token.lineHeightLG,
|
||
fontSize: token.fontSizeLG,
|
||
fontWeight: "bold",
|
||
color: token.colorPrimaryText,
|
||
}}>
|
||
{title}
|
||
</div>
|
||
{extra && <div>{extra}</div>}
|
||
</div>
|
||
{children && (
|
||
<div
|
||
style={contentStyle}
|
||
className={`${contentClassName} flex-grow`}>
|
||
{children}
|
||
</div>
|
||
)}
|
||
</motion.div>
|
||
);
|
||
}
|