import type { Meta } from "@storybook/react-vite"; import React, { useState } from "react"; import { ChessPuzzle } from "./index"; import { defaultPuzzleTheme } from "../../theme/defaults"; import type { ChessPuzzleTheme } from "../../theme/types"; import { ColorInput, copyToClipboard } from "@story-helpers"; const meta: Meta = { title: "Packages/react-chess-puzzle/Theming/Playground", component: ChessPuzzle.Root, tags: ["theme", "puzzle"], decorators: [ (Story) => (
), ], }; export default meta; const samplePuzzle = { fen: "4kb1r/p2r1ppp/4qn2/1B2p1B1/4P3/1Q6/PPP2PPP/2KR4 w k - 0 1", moves: ["Bxd7+", "Nxd7", "Qb8+", "Nxb8", "Rd8#"], makeFirstMove: false, }; export const PuzzlePlayground = () => { const [theme, setTheme] = useState(defaultPuzzleTheme); const [copied, setCopied] = useState(false); const [copyError, setCopyError] = useState(false); const updatePuzzleColor = ( key: keyof ChessPuzzleTheme["puzzle"], value: string, ) => { setTheme((prev) => ({ ...prev, puzzle: { ...prev.puzzle, [key]: value, }, })); }; const themeCode = `const myPuzzleTheme: PartialChessPuzzleTheme = { puzzle: ${JSON.stringify(theme.puzzle, null, 4)} };`; const handleCopy = async () => { const success = await copyToClipboard(themeCode); if (success) { setCopied(true); setCopyError(false); setTimeout(() => setCopied(false), 2000); } else { setCopyError(true); setTimeout(() => setCopyError(false), 3000); } }; return (
{/* Top row: Preview + Controls */}
{/* Preview */}

Preview

Solution: Bxd7+, Nxd7, Qb8+, Nxb8, Rd8#

{/* Controls */}

Puzzle Colors

updatePuzzleColor("success", v)} /> updatePuzzleColor("failure", v)} /> updatePuzzleColor("hint", v)} />

How to test:

  • Click "Hint" to see the hint color
  • Make a correct move to see success color
  • Make a wrong move to see failure color
{/* Bottom: Generated Code */}

Generated Code

            {themeCode}
          
); }; export const PuzzleThemeExamples = () => { const customThemes = { default: defaultPuzzleTheme, neon: { ...defaultPuzzleTheme, puzzle: { success: "rgba(0, 255, 127, 0.6)", failure: "rgba(255, 0, 127, 0.6)", hint: "rgba(0, 191, 255, 0.6)", }, }, pastel: { ...defaultPuzzleTheme, puzzle: { success: "rgba(152, 251, 152, 0.6)", failure: "rgba(255, 182, 193, 0.6)", hint: "rgba(173, 216, 230, 0.6)", }, }, }; return (

Puzzle Theme Examples

{Object.entries(customThemes).map(([name, theme]) => (

{name}

))}
); }; export const PartialPuzzleTheme = () => { // Only override puzzle colors, inherit game colors from default const partialTheme = { puzzle: { hint: "rgba(255, 215, 0, 0.6)", // Gold }, }; return (

Partial Puzzle Theme

Only override the hint color to gold. Success and failure use defaults.

View theme code
          {JSON.stringify(partialTheme, null, 2)}
        
); };