208 lines
4.5 KiB
TypeScript
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,
|
|
}
|