84 lines
2.0 KiB
TypeScript
84 lines
2.0 KiB
TypeScript
|
|
"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 Props {
|
||
|
|
card?: Card;
|
||
|
|
faceDown?: boolean;
|
||
|
|
size?: CardSize;
|
||
|
|
className?: string;
|
||
|
|
dimmed?: boolean;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function PlayingCard({
|
||
|
|
card,
|
||
|
|
faceDown,
|
||
|
|
size = "md",
|
||
|
|
className,
|
||
|
|
dimmed,
|
||
|
|
}: Props) {
|
||
|
|
const s = SIZES[size];
|
||
|
|
|
||
|
|
if (faceDown || !card) {
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
className={cn("card-back rounded-lg shrink-0", className)}
|
||
|
|
style={{ width: s.w, height: s.h }}
|
||
|
|
aria-hidden
|
||
|
|
>
|
||
|
|
<div className="h-full w-full rounded-lg flex items-center justify-center">
|
||
|
|
<div className="text-gold-500/70 text-lg font-bold">✦</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>
|
||
|
|
);
|
||
|
|
}
|