47 lines
1.1 KiB
TypeScript
47 lines
1.1 KiB
TypeScript
import { cn } from "@/shared/lib/utils";
|
|
import { useEffect, useState } from "react";
|
|
|
|
interface FlipCardProps {
|
|
word: string;
|
|
flipped: boolean;
|
|
onFlip: () => void;
|
|
}
|
|
|
|
export function FlipCard({ word, flipped, onFlip }: FlipCardProps) {
|
|
const [instant, setInstant] = useState(false);
|
|
|
|
// When word changes (new player), instantly reset to front without animation.
|
|
// word is intentionally a dependency — we want to trigger on player change.
|
|
// biome-ignore lint/correctness/useExhaustiveDependencies: word triggers the reset
|
|
useEffect(() => {
|
|
setInstant(true);
|
|
requestAnimationFrame(() => {
|
|
requestAnimationFrame(() => {
|
|
setInstant(false);
|
|
});
|
|
});
|
|
}, [word]);
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"flip-card",
|
|
flipped && "flipped",
|
|
instant && "flip-card--instant",
|
|
)}
|
|
onClick={onFlip}
|
|
onKeyDown={(e) => {
|
|
if (e.key === "Enter" || e.key === " ") onFlip();
|
|
}}
|
|
role="button"
|
|
tabIndex={0}
|
|
aria-label={flipped ? word : "Karte antippen zum Aufdecken"}
|
|
>
|
|
<div className="flip-card-inner">
|
|
<div className="flip-card-front">Antippen</div>
|
|
<div className="flip-card-back">{word}</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|