卡片组件
一个灵活、可组合的卡片组件,支持多种变体和尺寸,用于展示结构化信息。
安装
npx
npx hb-design-cli add card
预览
默认卡片
默认卡片
标准样式的卡片组件
这是一张默认样式的卡片。
默认卡片
悬浮卡片
悬浮卡片
带有阴影效果的卡片
这张卡片有阴影效果,鼠标悬停时阴影会加深。
悬浮卡片
描边卡片
描边卡片
只有边框的透明卡片
这张卡片只有边框,背景是透明的。
描边卡片
小尺寸卡片
小尺寸卡片
紧凑的卡片布局
这是一张小尺寸的卡片,内部间距更小。
小尺寸卡片
大尺寸卡片
大尺寸卡片
宽敞的卡片布局
这是一张大尺寸的卡片,内部间距更大,内容更突出。
大尺寸卡片
自定义卡片
自定义样式
带渐变背景的卡片
通过className属性可以自定义卡片的样式。
自定义样式卡片
组件源码
Card 组件源码
import React, { forwardRef } from 'react';
import { cn } from '@/lib/utils';
export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
variant?: 'default' | 'elevated' | 'outlined';
size?: 'sm' | 'md' | 'lg';
className?: string;
}
export const Card = forwardRef<HTMLDivElement, CardProps>(
({ className, variant = 'default', size = 'md', children, ...props }, ref) => {
const baseClasses = "rounded-lg transition-all duration-200 overflow-hidden";
const variantClasses = {
default: "bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800",
elevated: "bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 shadow-md hover:shadow-lg",
outlined: "bg-transparent border border-gray-300 dark:border-gray-700"
};
const sizeClasses = {
sm: "p-4",
md: "p-6",
lg: "p-8"
};
const classes = cn(
baseClasses,
variantClasses[variant],
sizeClasses[size],
className
);
return (
<div
ref={ref}
className={classes}
{...props}
>
{children}
</div>
);
}
);
Card.displayName = 'Card';
export interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
className?: string;
}
export const CardHeader = forwardRef<HTMLDivElement, CardHeaderProps>(
({ className, children, ...props }, ref) => {
const classes = cn(
"space-y-2",
className
);
return (
<div ref={ref} className={classes} {...props}>
{children}
</div>
);
}
);
CardHeader.displayName = 'CardHeader';
export interface CardTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {
className?: string;
asChild?: boolean;
}
export const CardTitle = forwardRef<HTMLHeadingElement, CardTitleProps>(
({ className, asChild = false, children, ...props }, ref) => {
const classes = cn(
"text-xl font-bold tracking-tight",
className
);
const TitleComponent = asChild ? 'div' : 'h3';
return (
<TitleComponent ref={ref} className={classes} {...props}>
{children}
</TitleComponent>
);
}
);
CardTitle.displayName = 'CardTitle';
export interface CardDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {
className?: string;
}
export const CardDescription = forwardRef<HTMLParagraphElement, CardDescriptionProps>(
({ className, children, ...props }, ref) => {
const classes = cn(
"text-sm text-gray-500 dark:text-gray-400",
className
);
return (
<p ref={ref} className={classes} {...props}>
{children}
</p>
);
}
);
CardDescription.displayName = 'CardDescription';
export interface CardContentProps extends React.HTMLAttributes<HTMLDivElement> {
className?: string;
}
export const CardContent = forwardRef<HTMLDivElement, CardContentProps>(
({ className, children, ...props }, ref) => {
const classes = cn(
"space-y-4",
className
);
return (
<div ref={ref} className={classes} {...props}>
{children}
</div>
);
}
);
CardContent.displayName = 'CardContent';
export interface CardFooterProps extends React.HTMLAttributes<HTMLDivElement> {
className?: string;
}
export const CardFooter = forwardRef<HTMLDivElement, CardFooterProps>(
({ className, children, ...props }, ref) => {
const classes = cn(
"flex items-center justify-end space-x-4 pt-2",
className
);
return (
<div ref={ref} className={classes} {...props}>
{children}
</div>
);
}
);
CardFooter.displayName = 'CardFooter';属性说明
| 属性名 | 类型 | 默认值 | 说明 |
| variant | 'default' | 'elevated' | 'outlined' | 'default' | 卡片样式变体 |
| size | string | md | 卡片尺寸 |
| className | string | 自定义类名 |