lila/apps/web/src/components/game/OptionButton.tsx
2026-04-19 19:25:55 +02:00

44 lines
1.9 KiB
TypeScript

type OptionButtonProps = {
text: string;
state: "idle" | "selected" | "disabled" | "correct" | "wrong";
onSelect: () => void;
};
export const OptionButton = ({ text, state, onSelect }: OptionButtonProps) => {
const base =
"group relative w-full overflow-hidden py-3 px-6 rounded-2xl text-lg font-semibold transition-all duration-200 border cursor-pointer text-left";
const styles = {
idle: "bg-white text-(--color-primary-dark) border-(--color-primary-light) hover:bg-(--color-surface) hover:-translate-y-0.5 active:translate-y-0",
selected:
"bg-(--color-surface) text-(--color-primary-dark) border-(--color-primary) ring-2 ring-(--color-primary)",
disabled:
"bg-(--color-surface) text-(--color-primary-light) border-(--color-primary-light) cursor-default",
correct:
"bg-emerald-400/90 text-white border-emerald-600 ring-2 ring-emerald-300 scale-[1.01]",
wrong: "bg-pink-500/90 text-white border-pink-700 ring-2 ring-pink-300",
};
const motion =
state === "correct" ? "lila-pop" : state === "wrong" ? "lila-shake" : "";
return (
<button
className={`${base} ${styles[state]} ${motion}`}
onClick={onSelect}
disabled={
state === "disabled" || state === "correct" || state === "wrong"
}
>
<span className="absolute inset-0 -z-10 opacity-0 group-hover:opacity-100 transition-opacity">
<span className="absolute -top-10 -right-12 h-24 w-24 rounded-full bg-(--color-primary) opacity-[0.10] blur-2xl" />
<span className="absolute -bottom-10 -left-12 h-24 w-24 rounded-full bg-(--color-accent) opacity-[0.10] blur-2xl" />
</span>
<span className="flex items-center justify-between gap-3">
<span className="truncate">{text}</span>
{state === "correct" && <span aria-hidden></span>}
{state === "wrong" && <span aria-hidden></span>}
</span>
</button>
);
};