Files
HokmPlay/src/components/PlayingCard.tsx
T

107 lines
2.7 KiB
TypeScript
Raw Normal View History

"use client";
import { cn } from "@/lib/cn";
import { Card, SUIT_IS_RED, SUIT_SYMBOL, rankLabel } from "@/lib/hokm/types";
const SIZES = {
sm: { w: 44, h: 62, rank: "text-base", pip: "text-lg", center: "text-2xl" },
md: { w: 60, h: 84, rank: "text-lg", pip: "text-xl", center: "text-3xl" },
lg: { w: 74, h: 104, rank: "text-xl", pip: "text-2xl", center: "text-4xl" },
} as const;
export type CardSize = keyof typeof SIZES;
interface CardBack {
c1: string;
c2: string;
accent: string;
}
interface Props {
card?: Card;
faceDown?: boolean;
size?: CardSize;
className?: string;
dimmed?: boolean;
back?: CardBack;
}
export function PlayingCard({
card,
faceDown,
size = "md",
className,
dimmed,
back,
}: Props) {
const s = SIZES[size];
if (faceDown || !card) {
const styled = back
? {
width: s.w,
height: s.h,
borderRadius: 8,
background: `repeating-linear-gradient(45deg, ${back.accent}40 0 6px, transparent 6px 12px), linear-gradient(160deg, ${back.c1}, ${back.c2})`,
border: `1px solid ${back.accent}80`,
boxShadow: "0 6px 14px rgba(0,0,0,0.4)",
}
: { width: s.w, height: s.h };
return (
<div
className={cn(!back && "card-back", "rounded-lg shrink-0", className)}
style={styled}
aria-hidden
>
<div className="h-full w-full rounded-lg flex items-center justify-center">
<div
className={cn("text-lg font-bold", !back && "text-gold-500/70")}
style={back ? { color: `${back.accent}cc` } : undefined}
>
</div>
</div>
</div>
);
}
const red = SUIT_IS_RED[card.suit];
const color = red ? "text-rose-600" : "text-slate-900";
const symbol = SUIT_SYMBOL[card.suit];
return (
<div
className={cn(
"card-face rounded-lg shrink-0 relative select-none transition-opacity",
dimmed && "opacity-45",
className
)}
style={{ width: s.w, height: s.h }}
>
<div className={cn("absolute top-1 left-1.5 leading-none font-bold", color, s.rank)}>
<div>{rankLabel(card.rank)}</div>
<div className={s.rank}>{symbol}</div>
</div>
<div
className={cn(
"absolute inset-0 flex items-center justify-center font-bold",
color,
s.center
)}
>
{symbol}
</div>
<div
className={cn(
"absolute bottom-1 right-1.5 leading-none font-bold rotate-180",
color,
s.rank
)}
>
<div>{rankLabel(card.rank)}</div>
<div className={s.rank}>{symbol}</div>
</div>
</div>
);
}