Files
chinese-family-tree-2/components/ui/chinese-card.tsx
T
freedakgmail 86e889cc2a 0.3.1.2
2025-11-30 19:10:30 +08:00

208 lines
4.5 KiB
TypeScript

import * as React from 'react'
import { cn } from '@/lib/utils'
/**
* 中国风卡片组件
* 提供多种传统中国设计风格变体
*/
type ChineseCardVariant = 'default' | 'scroll' | 'plaque' | 'portrait' | 'bamboo'
interface ChineseCardProps extends React.ComponentProps<'div'> {
variant?: ChineseCardVariant
/** 是否显示角饰 */
cornerOrnament?: boolean
/** 是否显示顶部装饰条 */
headerDecoration?: boolean
}
function ChineseCard({
className,
variant = 'default',
cornerOrnament = false,
headerDecoration = false,
children,
...props
}: ChineseCardProps) {
return (
<div
data-slot="chinese-card"
data-variant={variant}
className={cn(
// 基础样式
'relative bg-card text-card-foreground flex flex-col',
// 变体样式
variant === 'default' && 'chinese-card-default',
variant === 'scroll' && 'chinese-card-scroll',
variant === 'plaque' && 'chinese-card-plaque',
variant === 'portrait' && 'chinese-card-portrait',
variant === 'bamboo' && 'chinese-card-bamboo',
// 角饰
cornerOrnament && 'chinese-card-corner-ornament',
className,
)}
{...props}
>
{/* 顶部装饰条 */}
{headerDecoration && (
<div className="chinese-card-header-decoration" />
)}
{/* 角饰元素 */}
{cornerOrnament && (
<>
<span className="chinese-corner chinese-corner-tl" />
<span className="chinese-corner chinese-corner-tr" />
<span className="chinese-corner chinese-corner-bl" />
<span className="chinese-corner chinese-corner-br" />
</>
)}
{children}
</div>
)
}
function ChineseCardHeader({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="chinese-card-header"
className={cn(
'flex flex-col gap-1.5 px-5 pt-5 pb-3',
className,
)}
{...props}
/>
)
}
function ChineseCardTitle({ className, ...props }: React.ComponentProps<'h3'>) {
return (
<h3
data-slot="chinese-card-title"
className={cn(
'font-serif text-lg font-semibold leading-tight tracking-wide',
className,
)}
{...props}
/>
)
}
function ChineseCardDescription({ className, ...props }: React.ComponentProps<'p'>) {
return (
<p
data-slot="chinese-card-description"
className={cn(
'font-serif text-sm text-muted-foreground',
className,
)}
{...props}
/>
)
}
function ChineseCardContent({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="chinese-card-content"
className={cn('px-5 pb-5', className)}
{...props}
/>
)
}
function ChineseCardFooter({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="chinese-card-footer"
className={cn(
'flex items-center px-5 pb-5 pt-0',
className,
)}
{...props}
/>
)
}
/**
* 中国风分隔线
*/
function ChineseDivider({
className,
variant = 'wave',
...props
}: React.ComponentProps<'div'> & {
variant?: 'wave' | 'cloud' | 'meander' | 'simple'
}) {
return (
<div
data-slot="chinese-divider"
className={cn(
'chinese-divider',
variant === 'wave' && 'chinese-divider-wave',
variant === 'cloud' && 'chinese-divider-cloud',
variant === 'meander' && 'chinese-divider-meander',
variant === 'simple' && 'chinese-divider-simple',
className,
)}
{...props}
/>
)
}
/**
* 统计数字组件 - 用于展示大数字
*/
function ChineseStatNumber({
className,
children,
...props
}: React.ComponentProps<'span'>) {
return (
<span
className={cn(
'text-3xl font-serif font-bold tracking-tight text-foreground',
className,
)}
{...props}
>
{children}
</span>
)
}
/**
* 统计标签组件
*/
function ChineseStatLabel({
className,
children,
...props
}: React.ComponentProps<'span'>) {
return (
<span
className={cn(
'text-sm font-medium text-muted-foreground uppercase tracking-wider',
className,
)}
{...props}
>
{children}
</span>
)
}
export {
ChineseCard,
ChineseCardHeader,
ChineseCardTitle,
ChineseCardDescription,
ChineseCardContent,
ChineseCardFooter,
ChineseDivider,
ChineseStatNumber,
ChineseStatLabel,
type ChineseCardVariant,
}