@react-chess-tools/react-chess-puzzle 0.6.2 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,128 @@
1
+ import * as React from 'react';
2
+ import React__default from 'react';
3
+ import { DeepPartial, ChessGameTheme, ChessGame } from '@react-chess-tools/react-chess-game';
4
+
5
+ /**
6
+ * Puzzle-specific state colors (RGBA color strings)
7
+ */
8
+ interface PuzzleStateTheme {
9
+ /** Background color for successful moves */
10
+ success: string;
11
+ /** Background color for failed moves */
12
+ failure: string;
13
+ /** Background color for hint squares */
14
+ hint: string;
15
+ }
16
+ /**
17
+ * Complete theme configuration for ChessPuzzle component.
18
+ * Extends ChessGameTheme with puzzle-specific colors.
19
+ */
20
+ interface ChessPuzzleTheme extends ChessGameTheme {
21
+ puzzle: PuzzleStateTheme;
22
+ }
23
+ /**
24
+ * Partial theme for puzzle customization - allows overriding only specific properties
25
+ */
26
+ type PartialChessPuzzleTheme = DeepPartial<ChessPuzzleTheme>;
27
+
28
+ type Status = "not-started" | "in-progress" | "solved" | "failed";
29
+ type Hint = "none" | "piece" | "move";
30
+ type Puzzle = {
31
+ fen: string;
32
+ moves: string[];
33
+ makeFirstMove?: boolean;
34
+ };
35
+
36
+ interface HintProps extends Omit<React__default.ButtonHTMLAttributes<HTMLButtonElement>, "onClick"> {
37
+ asChild?: boolean;
38
+ /**
39
+ * The puzzle statuses in which the hint button should be visible.
40
+ * @default ["not-started", "in-progress"]
41
+ */
42
+ showOn?: Status[];
43
+ }
44
+
45
+ interface ResetProps extends Omit<React__default.ButtonHTMLAttributes<HTMLButtonElement>, "onReset"> {
46
+ asChild?: boolean;
47
+ puzzle?: Puzzle;
48
+ onReset?: (puzzleContext: ChessPuzzleContextType) => void;
49
+ /**
50
+ * The puzzle statuses in which the reset button should be visible.
51
+ * @default ["failed", "solved"]
52
+ */
53
+ showOn?: Status[];
54
+ }
55
+
56
+ interface PuzzleBoardProps extends React__default.ComponentProps<typeof ChessGame.Board> {
57
+ }
58
+
59
+ type ChessPuzzleContextType = {
60
+ status: Status;
61
+ changePuzzle: (puzzle: Puzzle) => void;
62
+ resetPuzzle: () => void;
63
+ puzzle: Puzzle;
64
+ hint: Hint;
65
+ nextMove?: string | null;
66
+ isPlayerTurn: boolean;
67
+ onHint: () => void;
68
+ puzzleState: Status;
69
+ movesPlayed: number;
70
+ totalMoves: number;
71
+ };
72
+
73
+ interface RootProps {
74
+ puzzle: Puzzle;
75
+ onSolve?: (puzzleContext: ChessPuzzleContextType) => void;
76
+ onFail?: (puzzleContext: ChessPuzzleContextType) => void;
77
+ /** Optional theme configuration. Supports partial themes - only override the colors you need. */
78
+ theme?: PartialChessPuzzleTheme;
79
+ }
80
+
81
+ declare const ChessPuzzle: {
82
+ Root: React.FC<React.PropsWithChildren<RootProps>>;
83
+ Board: React.ForwardRefExoticComponent<Omit<PuzzleBoardProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
84
+ Reset: React.ForwardRefExoticComponent<ResetProps & {
85
+ children?: React.ReactNode | undefined;
86
+ } & React.RefAttributes<HTMLElement>>;
87
+ Hint: React.ForwardRefExoticComponent<HintProps & {
88
+ children?: React.ReactNode | undefined;
89
+ } & React.RefAttributes<HTMLElement>>;
90
+ };
91
+
92
+ declare const useChessPuzzleContext: () => ChessPuzzleContextType;
93
+
94
+ /**
95
+ * Default theme for ChessPuzzle component.
96
+ * Extends the default game theme with puzzle-specific colors.
97
+ * These values match the original hardcoded colors for backward compatibility.
98
+ */
99
+ declare const defaultPuzzleTheme: ChessPuzzleTheme;
100
+
101
+ /**
102
+ * Deep merges a partial puzzle theme with the default puzzle theme.
103
+ * Allows users to override only specific theme properties while keeping defaults for the rest.
104
+ *
105
+ * @param partialTheme - Partial theme with only the properties to override
106
+ * @returns Complete puzzle theme with overridden properties merged with defaults
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * const customTheme = mergePuzzleTheme({
111
+ * puzzle: { hint: "rgba(0, 255, 255, 0.5)" }
112
+ * });
113
+ * // Returns full puzzle theme with only hint color changed
114
+ * ```
115
+ */
116
+ declare const mergePuzzleTheme: (partialTheme?: PartialChessPuzzleTheme) => ChessPuzzleTheme;
117
+
118
+ /**
119
+ * Context for ChessPuzzle theme
120
+ */
121
+ declare const ChessPuzzleThemeContext: React__default.Context<ChessPuzzleTheme>;
122
+ /**
123
+ * Hook to access the current ChessPuzzle theme.
124
+ * Returns the default puzzle theme if no ThemeProvider is present.
125
+ */
126
+ declare const useChessPuzzleTheme: () => ChessPuzzleTheme;
127
+
128
+ export { ChessPuzzle, type ChessPuzzleContextType, type ChessPuzzleTheme, ChessPuzzleThemeContext, type Hint, type HintProps, type PartialChessPuzzleTheme, type Puzzle, type PuzzleBoardProps, type PuzzleStateTheme, type ResetProps, type RootProps, type Status, defaultPuzzleTheme, mergePuzzleTheme, useChessPuzzleContext, useChessPuzzleTheme };
@@ -0,0 +1,128 @@
1
+ import * as React from 'react';
2
+ import React__default from 'react';
3
+ import { DeepPartial, ChessGameTheme, ChessGame } from '@react-chess-tools/react-chess-game';
4
+
5
+ /**
6
+ * Puzzle-specific state colors (RGBA color strings)
7
+ */
8
+ interface PuzzleStateTheme {
9
+ /** Background color for successful moves */
10
+ success: string;
11
+ /** Background color for failed moves */
12
+ failure: string;
13
+ /** Background color for hint squares */
14
+ hint: string;
15
+ }
16
+ /**
17
+ * Complete theme configuration for ChessPuzzle component.
18
+ * Extends ChessGameTheme with puzzle-specific colors.
19
+ */
20
+ interface ChessPuzzleTheme extends ChessGameTheme {
21
+ puzzle: PuzzleStateTheme;
22
+ }
23
+ /**
24
+ * Partial theme for puzzle customization - allows overriding only specific properties
25
+ */
26
+ type PartialChessPuzzleTheme = DeepPartial<ChessPuzzleTheme>;
27
+
28
+ type Status = "not-started" | "in-progress" | "solved" | "failed";
29
+ type Hint = "none" | "piece" | "move";
30
+ type Puzzle = {
31
+ fen: string;
32
+ moves: string[];
33
+ makeFirstMove?: boolean;
34
+ };
35
+
36
+ interface HintProps extends Omit<React__default.ButtonHTMLAttributes<HTMLButtonElement>, "onClick"> {
37
+ asChild?: boolean;
38
+ /**
39
+ * The puzzle statuses in which the hint button should be visible.
40
+ * @default ["not-started", "in-progress"]
41
+ */
42
+ showOn?: Status[];
43
+ }
44
+
45
+ interface ResetProps extends Omit<React__default.ButtonHTMLAttributes<HTMLButtonElement>, "onReset"> {
46
+ asChild?: boolean;
47
+ puzzle?: Puzzle;
48
+ onReset?: (puzzleContext: ChessPuzzleContextType) => void;
49
+ /**
50
+ * The puzzle statuses in which the reset button should be visible.
51
+ * @default ["failed", "solved"]
52
+ */
53
+ showOn?: Status[];
54
+ }
55
+
56
+ interface PuzzleBoardProps extends React__default.ComponentProps<typeof ChessGame.Board> {
57
+ }
58
+
59
+ type ChessPuzzleContextType = {
60
+ status: Status;
61
+ changePuzzle: (puzzle: Puzzle) => void;
62
+ resetPuzzle: () => void;
63
+ puzzle: Puzzle;
64
+ hint: Hint;
65
+ nextMove?: string | null;
66
+ isPlayerTurn: boolean;
67
+ onHint: () => void;
68
+ puzzleState: Status;
69
+ movesPlayed: number;
70
+ totalMoves: number;
71
+ };
72
+
73
+ interface RootProps {
74
+ puzzle: Puzzle;
75
+ onSolve?: (puzzleContext: ChessPuzzleContextType) => void;
76
+ onFail?: (puzzleContext: ChessPuzzleContextType) => void;
77
+ /** Optional theme configuration. Supports partial themes - only override the colors you need. */
78
+ theme?: PartialChessPuzzleTheme;
79
+ }
80
+
81
+ declare const ChessPuzzle: {
82
+ Root: React.FC<React.PropsWithChildren<RootProps>>;
83
+ Board: React.ForwardRefExoticComponent<Omit<PuzzleBoardProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
84
+ Reset: React.ForwardRefExoticComponent<ResetProps & {
85
+ children?: React.ReactNode | undefined;
86
+ } & React.RefAttributes<HTMLElement>>;
87
+ Hint: React.ForwardRefExoticComponent<HintProps & {
88
+ children?: React.ReactNode | undefined;
89
+ } & React.RefAttributes<HTMLElement>>;
90
+ };
91
+
92
+ declare const useChessPuzzleContext: () => ChessPuzzleContextType;
93
+
94
+ /**
95
+ * Default theme for ChessPuzzle component.
96
+ * Extends the default game theme with puzzle-specific colors.
97
+ * These values match the original hardcoded colors for backward compatibility.
98
+ */
99
+ declare const defaultPuzzleTheme: ChessPuzzleTheme;
100
+
101
+ /**
102
+ * Deep merges a partial puzzle theme with the default puzzle theme.
103
+ * Allows users to override only specific theme properties while keeping defaults for the rest.
104
+ *
105
+ * @param partialTheme - Partial theme with only the properties to override
106
+ * @returns Complete puzzle theme with overridden properties merged with defaults
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * const customTheme = mergePuzzleTheme({
111
+ * puzzle: { hint: "rgba(0, 255, 255, 0.5)" }
112
+ * });
113
+ * // Returns full puzzle theme with only hint color changed
114
+ * ```
115
+ */
116
+ declare const mergePuzzleTheme: (partialTheme?: PartialChessPuzzleTheme) => ChessPuzzleTheme;
117
+
118
+ /**
119
+ * Context for ChessPuzzle theme
120
+ */
121
+ declare const ChessPuzzleThemeContext: React__default.Context<ChessPuzzleTheme>;
122
+ /**
123
+ * Hook to access the current ChessPuzzle theme.
124
+ * Returns the default puzzle theme if no ThemeProvider is present.
125
+ */
126
+ declare const useChessPuzzleTheme: () => ChessPuzzleTheme;
127
+
128
+ export { ChessPuzzle, type ChessPuzzleContextType, type ChessPuzzleTheme, ChessPuzzleThemeContext, type Hint, type HintProps, type PartialChessPuzzleTheme, type Puzzle, type PuzzleBoardProps, type PuzzleStateTheme, type ResetProps, type RootProps, type Status, defaultPuzzleTheme, mergePuzzleTheme, useChessPuzzleContext, useChessPuzzleTheme };
@@ -3,11 +3,20 @@ import React3 from "react";
3
3
 
4
4
  // src/utils/index.ts
5
5
  import { Chess } from "chess.js";
6
- import React from "react";
7
6
  import _ from "lodash";
8
- var FAIL_COLOR = "rgba(201, 52, 48, 0.5)";
9
- var SUCCESS_COLOR = "rgba(172, 206, 89, 0.5)";
10
- var HINT_COLOR = "rgba(27, 172, 166, 0.5)";
7
+
8
+ // src/theme/defaults.ts
9
+ import { defaultGameTheme } from "@react-chess-tools/react-chess-game";
10
+ var defaultPuzzleTheme = {
11
+ ...defaultGameTheme,
12
+ puzzle: {
13
+ success: "rgba(172, 206, 89, 0.5)",
14
+ failure: "rgba(201, 52, 48, 0.5)",
15
+ hint: "rgba(27, 172, 166, 0.5)"
16
+ }
17
+ };
18
+
19
+ // src/utils/index.ts
11
20
  var getOrientation = (puzzle) => {
12
21
  const fen = puzzle.fen;
13
22
  const game = new Chess(fen);
@@ -16,40 +25,39 @@ var getOrientation = (puzzle) => {
16
25
  }
17
26
  return game.turn();
18
27
  };
19
- var isClickableElement = (element) => React.isValidElement(element);
20
- var getCustomSquareStyles = (status, hint, isPlayerTurn, game, nextMove) => {
28
+ var getCustomSquareStyles = (status, hint, isPlayerTurn, game, nextMove, theme = defaultPuzzleTheme) => {
21
29
  const customSquareStyles = {};
22
30
  const lastMove = _.last(game.history({ verbose: true }));
23
31
  if (status === "failed" && lastMove) {
24
32
  customSquareStyles[lastMove.from] = {
25
- backgroundColor: FAIL_COLOR
33
+ backgroundColor: theme.puzzle.failure
26
34
  };
27
35
  customSquareStyles[lastMove.to] = {
28
- backgroundColor: FAIL_COLOR
36
+ backgroundColor: theme.puzzle.failure
29
37
  };
30
38
  }
31
39
  if (lastMove && (status === "solved" || status !== "failed" && !isPlayerTurn)) {
32
40
  customSquareStyles[lastMove.from] = {
33
- backgroundColor: SUCCESS_COLOR
41
+ backgroundColor: theme.puzzle.success
34
42
  };
35
43
  customSquareStyles[lastMove.to] = {
36
- backgroundColor: SUCCESS_COLOR
44
+ backgroundColor: theme.puzzle.success
37
45
  };
38
46
  }
39
47
  if (hint === "piece") {
40
48
  if (nextMove) {
41
49
  customSquareStyles[nextMove.from] = {
42
- backgroundColor: HINT_COLOR
50
+ backgroundColor: theme.puzzle.hint
43
51
  };
44
52
  }
45
53
  }
46
54
  if (hint === "move") {
47
55
  if (nextMove) {
48
56
  customSquareStyles[nextMove.from] = {
49
- backgroundColor: HINT_COLOR
57
+ backgroundColor: theme.puzzle.hint
50
58
  };
51
59
  customSquareStyles[nextMove.to] = {
52
- backgroundColor: HINT_COLOR
60
+ backgroundColor: theme.puzzle.hint
53
61
  };
54
62
  }
55
63
  }
@@ -279,10 +287,10 @@ var useChessPuzzle = (puzzle, onSolve, onFail) => {
279
287
  import { ChessGame } from "@react-chess-tools/react-chess-game";
280
288
 
281
289
  // src/hooks/useChessPuzzleContext.ts
282
- import React2 from "react";
283
- var ChessPuzzleContext = React2.createContext(null);
290
+ import React from "react";
291
+ var ChessPuzzleContext = React.createContext(null);
284
292
  var useChessPuzzleContext = () => {
285
- const context = React2.useContext(ChessPuzzleContext);
293
+ const context = React.useContext(ChessPuzzleContext);
286
294
  if (!context) {
287
295
  throw new Error(
288
296
  `useChessPuzzleContext must be used within a ChessPuzzle component. Make sure your component is wrapped with <ChessPuzzle.Root> or ensure the ChessPuzzle component is properly rendered in the component tree.`
@@ -291,8 +299,30 @@ var useChessPuzzleContext = () => {
291
299
  return context;
292
300
  };
293
301
 
302
+ // src/theme/context.tsx
303
+ import React2, { createContext, useContext } from "react";
304
+ var ChessPuzzleThemeContext = createContext(defaultPuzzleTheme);
305
+ var useChessPuzzleTheme = () => {
306
+ return useContext(ChessPuzzleThemeContext);
307
+ };
308
+ var PuzzleThemeProvider = ({
309
+ theme,
310
+ children
311
+ }) => {
312
+ return /* @__PURE__ */ React2.createElement(ChessPuzzleThemeContext.Provider, { value: theme }, children);
313
+ };
314
+
315
+ // src/theme/utils.ts
316
+ import { merge } from "lodash";
317
+ var mergePuzzleTheme = (partialTheme) => {
318
+ if (!partialTheme) {
319
+ return { ...defaultPuzzleTheme };
320
+ }
321
+ return merge({}, defaultPuzzleTheme, partialTheme);
322
+ };
323
+
294
324
  // src/components/ChessPuzzle/parts/Root.tsx
295
- var PuzzleRoot = ({
325
+ var PuzzleRootInner = ({
296
326
  puzzle,
297
327
  onSolve,
298
328
  onFail,
@@ -305,10 +335,21 @@ var Root = ({
305
335
  puzzle,
306
336
  onSolve,
307
337
  onFail,
338
+ theme,
308
339
  children
309
340
  }) => {
310
- return /* @__PURE__ */ React3.createElement(ChessGame.Root, { fen: puzzle.fen, orientation: getOrientation(puzzle) }, /* @__PURE__ */ React3.createElement(PuzzleRoot, { puzzle, onSolve, onFail }, children));
341
+ const mergedTheme = React3.useMemo(() => mergePuzzleTheme(theme), [theme]);
342
+ return /* @__PURE__ */ React3.createElement(
343
+ ChessGame.Root,
344
+ {
345
+ fen: puzzle.fen,
346
+ orientation: getOrientation(puzzle),
347
+ theme: mergedTheme
348
+ },
349
+ /* @__PURE__ */ React3.createElement(PuzzleThemeProvider, { theme: mergedTheme }, /* @__PURE__ */ React3.createElement(PuzzleRootInner, { puzzle, onSolve, onFail }, children))
350
+ );
311
351
  };
352
+ Root.displayName = "ChessPuzzle.Root";
312
353
 
313
354
  // src/components/ChessPuzzle/parts/PuzzleBoard.tsx
314
355
  import React4 from "react";
@@ -317,98 +358,104 @@ import {
317
358
  deepMergeChessboardOptions,
318
359
  useChessGameContext as useChessGameContext2
319
360
  } from "@react-chess-tools/react-chess-game";
320
- var PuzzleBoard = ({
321
- options = {},
322
- ...rest
323
- }) => {
324
- const puzzleContext = useChessPuzzleContext();
325
- const gameContext = useChessGameContext2();
326
- if (!puzzleContext) {
327
- throw new Error("PuzzleContext not found");
328
- }
329
- if (!gameContext) {
330
- throw new Error("ChessGameContext not found");
361
+ var PuzzleBoard = React4.forwardRef(
362
+ ({ options, ...rest }, ref) => {
363
+ const puzzleContext = useChessPuzzleContext();
364
+ const gameContext = useChessGameContext2();
365
+ const theme = useChessPuzzleTheme();
366
+ if (!puzzleContext) {
367
+ throw new Error("PuzzleContext not found");
368
+ }
369
+ if (!gameContext) {
370
+ throw new Error("ChessGameContext not found");
371
+ }
372
+ const { game } = gameContext;
373
+ const { status, hint, isPlayerTurn, nextMove } = puzzleContext;
374
+ const mergedOptions = deepMergeChessboardOptions(options || {}, {
375
+ squareStyles: getCustomSquareStyles(
376
+ status,
377
+ hint,
378
+ isPlayerTurn,
379
+ game,
380
+ stringToMove(game, nextMove),
381
+ theme
382
+ )
383
+ });
384
+ return /* @__PURE__ */ React4.createElement(ChessGame2.Board, { ref, ...rest, options: mergedOptions });
331
385
  }
332
- const { game } = gameContext;
333
- const { status, hint, isPlayerTurn, nextMove } = puzzleContext;
334
- const mergedOptions = deepMergeChessboardOptions(options, {
335
- squareStyles: getCustomSquareStyles(
336
- status,
337
- hint,
338
- isPlayerTurn,
339
- game,
340
- stringToMove(game, nextMove)
341
- )
342
- });
343
- return /* @__PURE__ */ React4.createElement(ChessGame2.Board, { ...rest, options: mergedOptions });
344
- };
386
+ );
387
+ PuzzleBoard.displayName = "ChessPuzzle.PuzzleBoard";
345
388
 
346
389
  // src/components/ChessPuzzle/parts/Reset.tsx
347
390
  import React5 from "react";
391
+ import { Slot } from "@radix-ui/react-slot";
348
392
  var defaultShowOn = ["failed", "solved"];
349
- var Reset = ({
350
- children,
351
- asChild,
352
- puzzle,
353
- onReset,
354
- showOn = defaultShowOn
355
- }) => {
356
- const puzzleContext = useChessPuzzleContext();
357
- if (!puzzleContext) {
358
- throw new Error("PuzzleContext not found");
359
- }
360
- const { changePuzzle, status } = puzzleContext;
361
- const handleClick = () => {
362
- changePuzzle(puzzle || puzzleContext.puzzle);
363
- onReset == null ? void 0 : onReset(puzzleContext);
364
- };
365
- if (!showOn.includes(status)) {
366
- return null;
367
- }
368
- if (asChild) {
369
- const child = React5.Children.only(children);
370
- if (isClickableElement(child)) {
371
- return React5.cloneElement(child, {
372
- onClick: handleClick
373
- });
374
- } else {
375
- throw new Error("Change child must be a clickable element");
393
+ var Reset = React5.forwardRef(
394
+ ({
395
+ children,
396
+ asChild,
397
+ puzzle,
398
+ onReset,
399
+ showOn = defaultShowOn,
400
+ className,
401
+ ...rest
402
+ }, ref) => {
403
+ const puzzleContext = useChessPuzzleContext();
404
+ if (!puzzleContext) {
405
+ throw new Error("PuzzleContext not found");
406
+ }
407
+ const { changePuzzle, puzzle: contextPuzzle, status } = puzzleContext;
408
+ const handleClick = React5.useCallback(() => {
409
+ changePuzzle(puzzle || contextPuzzle);
410
+ onReset == null ? void 0 : onReset(puzzleContext);
411
+ }, [changePuzzle, puzzle, contextPuzzle, puzzleContext, onReset]);
412
+ if (!showOn.includes(status)) {
413
+ return null;
376
414
  }
415
+ return asChild ? /* @__PURE__ */ React5.createElement(Slot, { ref, onClick: handleClick, className, ...rest }, children) : /* @__PURE__ */ React5.createElement(
416
+ "button",
417
+ {
418
+ ref,
419
+ type: "button",
420
+ className,
421
+ onClick: handleClick,
422
+ ...rest
423
+ },
424
+ children
425
+ );
377
426
  }
378
- return /* @__PURE__ */ React5.createElement("button", { type: "button", onClick: handleClick }, children);
379
- };
427
+ );
428
+ Reset.displayName = "ChessPuzzle.Reset";
380
429
 
381
430
  // src/components/ChessPuzzle/parts/Hint.tsx
382
431
  import React6 from "react";
432
+ import { Slot as Slot2 } from "@radix-ui/react-slot";
383
433
  var defaultShowOn2 = ["not-started", "in-progress"];
384
- var Hint = ({
385
- children,
386
- asChild,
387
- showOn = defaultShowOn2
388
- }) => {
434
+ var Hint = React6.forwardRef(({ children, asChild, showOn = defaultShowOn2, className, ...rest }, ref) => {
389
435
  const puzzleContext = useChessPuzzleContext();
390
436
  if (!puzzleContext) {
391
437
  throw new Error("PuzzleContext not found");
392
438
  }
393
439
  const { onHint, status } = puzzleContext;
394
- const handleClick = () => {
440
+ const handleClick = React6.useCallback(() => {
395
441
  onHint();
396
- };
442
+ }, [onHint]);
397
443
  if (!showOn.includes(status)) {
398
444
  return null;
399
445
  }
400
- if (asChild) {
401
- const child = React6.Children.only(children);
402
- if (isClickableElement(child)) {
403
- return React6.cloneElement(child, {
404
- onClick: handleClick
405
- });
406
- } else {
407
- throw new Error("Change child must be a clickable element");
408
- }
409
- }
410
- return /* @__PURE__ */ React6.createElement("button", { type: "button", onClick: handleClick }, children);
411
- };
446
+ return asChild ? /* @__PURE__ */ React6.createElement(Slot2, { ref, onClick: handleClick, className, ...rest }, children) : /* @__PURE__ */ React6.createElement(
447
+ "button",
448
+ {
449
+ ref,
450
+ type: "button",
451
+ className,
452
+ onClick: handleClick,
453
+ ...rest
454
+ },
455
+ children
456
+ );
457
+ });
458
+ Hint.displayName = "ChessPuzzle.Hint";
412
459
 
413
460
  // src/components/ChessPuzzle/index.ts
414
461
  var ChessPuzzle = {
@@ -419,6 +466,10 @@ var ChessPuzzle = {
419
466
  };
420
467
  export {
421
468
  ChessPuzzle,
422
- useChessPuzzleContext
469
+ ChessPuzzleThemeContext,
470
+ defaultPuzzleTheme,
471
+ mergePuzzleTheme,
472
+ useChessPuzzleContext,
473
+ useChessPuzzleTheme
423
474
  };
424
- //# sourceMappingURL=index.mjs.map
475
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ChessPuzzle/parts/Root.tsx","../src/utils/index.ts","../src/theme/defaults.ts","../src/hooks/useChessPuzzle.ts","../src/hooks/reducer.ts","../src/hooks/useChessPuzzleContext.ts","../src/theme/context.tsx","../src/theme/utils.ts","../src/components/ChessPuzzle/parts/PuzzleBoard.tsx","../src/components/ChessPuzzle/parts/Reset.tsx","../src/components/ChessPuzzle/parts/Hint.tsx","../src/components/ChessPuzzle/index.ts"],"sourcesContent":["import React from \"react\";\nimport { Puzzle, getOrientation } from \"../../../utils\";\nimport {\n ChessPuzzleContextType,\n useChessPuzzle,\n} from \"../../../hooks/useChessPuzzle\";\nimport { ChessGame } from \"@react-chess-tools/react-chess-game\";\nimport { ChessPuzzleContext } from \"../../../hooks/useChessPuzzleContext\";\nimport { PuzzleThemeProvider } from \"../../../theme/context\";\nimport { mergePuzzleTheme } from \"../../../theme/utils\";\nimport type { PartialChessPuzzleTheme } from \"../../../theme/types\";\n\nexport interface RootProps {\n puzzle: Puzzle;\n onSolve?: (puzzleContext: ChessPuzzleContextType) => void;\n onFail?: (puzzleContext: ChessPuzzleContextType) => void;\n /** Optional theme configuration. Supports partial themes - only override the colors you need. */\n theme?: PartialChessPuzzleTheme;\n}\n\ninterface PuzzleRootInnerProps {\n puzzle: Puzzle;\n onSolve?: (puzzleContext: ChessPuzzleContextType) => void;\n onFail?: (puzzleContext: ChessPuzzleContextType) => void;\n children: React.ReactNode;\n}\n\nconst PuzzleRootInner: React.FC<PuzzleRootInnerProps> = ({\n puzzle,\n onSolve,\n onFail,\n children,\n}) => {\n const context = useChessPuzzle(puzzle, onSolve, onFail);\n\n return (\n <ChessPuzzleContext.Provider value={context}>\n {children}\n </ChessPuzzleContext.Provider>\n );\n};\n\nexport const Root: React.FC<React.PropsWithChildren<RootProps>> = ({\n puzzle,\n onSolve,\n onFail,\n theme,\n children,\n}) => {\n // Merge partial theme with defaults\n const mergedTheme = React.useMemo(() => mergePuzzleTheme(theme), [theme]);\n\n return (\n <ChessGame.Root\n fen={puzzle.fen}\n orientation={getOrientation(puzzle)}\n theme={mergedTheme}\n >\n <PuzzleThemeProvider theme={mergedTheme}>\n <PuzzleRootInner puzzle={puzzle} onSolve={onSolve} onFail={onFail}>\n {children}\n </PuzzleRootInner>\n </PuzzleThemeProvider>\n </ChessGame.Root>\n );\n};\n\nRoot.displayName = \"ChessPuzzle.Root\";\n","import { type Color, Chess, Move } from \"chess.js\";\nimport React, { CSSProperties, ReactElement, ReactNode } from \"react\";\nimport _ from \"lodash\";\nimport type { ChessPuzzleTheme } from \"../theme/types\";\nimport { defaultPuzzleTheme } from \"../theme/defaults\";\n\nexport type Status = \"not-started\" | \"in-progress\" | \"solved\" | \"failed\";\n\nexport type Hint = \"none\" | \"piece\" | \"move\";\n\nexport type Puzzle = {\n fen: string;\n moves: string[];\n // if the first move of the puzzle has to be made by the cpu, as in chess.com puzzles\n makeFirstMove?: boolean;\n};\n\nexport const getOrientation = (puzzle: Puzzle): Color => {\n const fen = puzzle.fen;\n const game = new Chess(fen);\n if (puzzle.makeFirstMove) {\n game.move(puzzle.moves[0]);\n }\n return game.turn();\n};\n\n/**\n * Generates custom square styles for puzzle states based on theme.\n *\n * @param status - Current puzzle status\n * @param hint - Current hint level\n * @param isPlayerTurn - Whether it's the player's turn\n * @param game - Chess.js game instance\n * @param nextMove - The next expected move (for hints)\n * @param theme - Theme configuration (defaults to defaultPuzzleTheme)\n * @returns Record of square names to CSS properties\n */\nexport const getCustomSquareStyles = (\n status: Status,\n hint: Hint,\n isPlayerTurn: boolean,\n game: Chess,\n nextMove?: Move | null,\n theme: ChessPuzzleTheme = defaultPuzzleTheme,\n) => {\n const customSquareStyles: Record<string, CSSProperties> = {};\n\n const lastMove = _.last(game.history({ verbose: true }));\n\n if (status === \"failed\" && lastMove) {\n customSquareStyles[lastMove.from] = {\n backgroundColor: theme.puzzle.failure,\n };\n customSquareStyles[lastMove.to] = {\n backgroundColor: theme.puzzle.failure,\n };\n }\n\n if (\n lastMove &&\n (status === \"solved\" || (status !== \"failed\" && !isPlayerTurn))\n ) {\n customSquareStyles[lastMove.from] = {\n backgroundColor: theme.puzzle.success,\n };\n customSquareStyles[lastMove.to] = {\n backgroundColor: theme.puzzle.success,\n };\n }\n\n if (hint === \"piece\") {\n if (nextMove) {\n customSquareStyles[nextMove.from] = {\n backgroundColor: theme.puzzle.hint,\n };\n }\n }\n\n if (hint === \"move\") {\n if (nextMove) {\n customSquareStyles[nextMove.from] = {\n backgroundColor: theme.puzzle.hint,\n };\n customSquareStyles[nextMove.to] = {\n backgroundColor: theme.puzzle.hint,\n };\n }\n }\n\n return customSquareStyles;\n};\n\nexport const stringToMove = (game: Chess, move: string | null | undefined) => {\n const copy = new Chess(game.fen());\n if (move === null || move === undefined) {\n return null;\n }\n try {\n return copy.move(move);\n } catch (e) {\n return null;\n }\n};\n","import { defaultGameTheme } from \"@react-chess-tools/react-chess-game\";\nimport type { ChessPuzzleTheme } from \"./types\";\n\n/**\n * Default theme for ChessPuzzle component.\n * Extends the default game theme with puzzle-specific colors.\n * These values match the original hardcoded colors for backward compatibility.\n */\nexport const defaultPuzzleTheme: ChessPuzzleTheme = {\n ...defaultGameTheme,\n puzzle: {\n success: \"rgba(172, 206, 89, 0.5)\",\n failure: \"rgba(201, 52, 48, 0.5)\",\n hint: \"rgba(27, 172, 166, 0.5)\",\n },\n};\n","import { useEffect, useReducer, useCallback, useMemo } from \"react\";\nimport { initializePuzzle, reducer } from \"./reducer\";\nimport { getOrientation, type Puzzle, type Hint, type Status } from \"../utils\";\nimport { useChessGameContext } from \"@react-chess-tools/react-chess-game\";\n\nexport type ChessPuzzleContextType = {\n status: Status;\n changePuzzle: (puzzle: Puzzle) => void;\n resetPuzzle: () => void;\n puzzle: Puzzle;\n hint: Hint;\n nextMove?: string | null;\n isPlayerTurn: boolean;\n onHint: () => void;\n puzzleState: Status;\n movesPlayed: number;\n totalMoves: number;\n};\n\nexport const useChessPuzzle = (\n puzzle: Puzzle,\n onSolve?: (puzzleContext: ChessPuzzleContextType) => void,\n onFail?: (puzzleContext: ChessPuzzleContextType) => void,\n): ChessPuzzleContextType => {\n const gameContext = useChessGameContext();\n\n const [state, dispatch] = useReducer(reducer, { puzzle }, initializePuzzle);\n\n const {\n game,\n methods: { makeMove, setPosition },\n } = gameContext;\n\n const changePuzzle = useCallback(\n (puzzle: Puzzle) => {\n setPosition(puzzle.fen, getOrientation(puzzle));\n dispatch({ type: \"INITIALIZE\", payload: { puzzle } });\n },\n [setPosition],\n );\n\n useEffect(() => {\n changePuzzle(puzzle);\n }, [JSON.stringify(puzzle), changePuzzle]);\n\n useEffect(() => {\n if (gameContext && game.fen() === puzzle.fen && state.needCpuMove) {\n setTimeout(\n () =>\n dispatch({\n type: \"CPU_MOVE\",\n }),\n 0,\n );\n }\n }, [gameContext, state.needCpuMove]);\n\n useEffect(() => {\n if (state.cpuMove) {\n makeMove(state.cpuMove);\n }\n }, [state.cpuMove]);\n\n if (!gameContext) {\n throw new Error(\"useChessPuzzle must be used within a ChessGameContext\");\n }\n\n const onHint = useCallback(() => {\n dispatch({ type: \"TOGGLE_HINT\" });\n }, []);\n\n const resetPuzzle = useCallback(() => {\n changePuzzle(puzzle);\n }, [changePuzzle, puzzle]);\n\n const puzzleContext: ChessPuzzleContextType = useMemo(\n () => ({\n status: state.status,\n changePuzzle,\n resetPuzzle,\n puzzle,\n hint: state.hint,\n onHint,\n nextMove: state.nextMove,\n isPlayerTurn: state.isPlayerTurn,\n puzzleState: state.status,\n movesPlayed: state.currentMoveIndex,\n totalMoves: puzzle.moves.length,\n }),\n [\n state.status,\n changePuzzle,\n resetPuzzle,\n puzzle,\n state.hint,\n onHint,\n state.nextMove,\n state.isPlayerTurn,\n state.currentMoveIndex,\n ],\n );\n\n useEffect(() => {\n if (game?.history()?.length <= 0 + (puzzle.makeFirstMove ? 1 : 0)) {\n return;\n }\n if (game.history().length % 2 === (puzzle.makeFirstMove ? 0 : 1)) {\n dispatch({\n type: \"PLAYER_MOVE\",\n payload: {\n move: gameContext?.game?.history({ verbose: true })?.pop() ?? null,\n puzzleContext,\n game: game,\n },\n });\n\n dispatch({\n type: \"CPU_MOVE\",\n });\n }\n }, [game?.history()?.length]);\n\n useEffect(() => {\n if (state.status === \"solved\" && !state.onSolveInvoked && onSolve) {\n onSolve(puzzleContext);\n dispatch({ type: \"MARK_SOLVE_INVOKED\" });\n }\n }, [state.status, state.onSolveInvoked]);\n\n useEffect(() => {\n if (state.status === \"failed\" && !state.onFailInvoked && onFail) {\n onFail(puzzleContext);\n dispatch({ type: \"MARK_FAIL_INVOKED\" });\n }\n }, [state.status, state.onFailInvoked]);\n\n return puzzleContext;\n};\n","import { Chess, Move } from \"chess.js\";\nimport { type Puzzle, type Hint, type Status } from \"../utils\";\nimport { ChessPuzzleContextType } from \"./useChessPuzzle\";\n\nexport type State = {\n puzzle: Puzzle;\n currentMoveIndex: number;\n status: Status;\n cpuMove?: string | null;\n nextMove?: string | null;\n hint: Hint;\n needCpuMove: boolean;\n isPlayerTurn: boolean;\n onSolveInvoked: boolean;\n onFailInvoked: boolean;\n};\n\nexport type Action =\n | {\n type: \"INITIALIZE\";\n payload: {\n puzzle: Puzzle;\n };\n }\n | {\n type: \"RESET\";\n }\n | { type: \"TOGGLE_HINT\" }\n | {\n type: \"CPU_MOVE\";\n }\n | {\n type: \"PLAYER_MOVE\";\n payload: {\n move?: Move | null;\n puzzleContext: ChessPuzzleContextType;\n game: Chess;\n };\n }\n | { type: \"MARK_SOLVE_INVOKED\" }\n | { type: \"MARK_FAIL_INVOKED\" };\n\nexport const initializePuzzle = ({ puzzle }: { puzzle: Puzzle }): State => {\n return {\n puzzle,\n currentMoveIndex: 0,\n status: \"not-started\",\n nextMove: puzzle.moves[0],\n hint: \"none\",\n cpuMove: null,\n needCpuMove: !!puzzle.makeFirstMove,\n isPlayerTurn: !puzzle.makeFirstMove,\n onSolveInvoked: false,\n onFailInvoked: false,\n };\n};\n\nexport const reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case \"INITIALIZE\":\n return {\n ...state,\n ...initializePuzzle(action.payload),\n };\n case \"RESET\":\n return {\n ...state,\n ...initializePuzzle({\n puzzle: state.puzzle,\n }),\n };\n case \"TOGGLE_HINT\":\n if (state.hint === \"none\") {\n return { ...state, hint: \"piece\" };\n }\n return { ...state, hint: \"move\" };\n case \"CPU_MOVE\":\n if (state.isPlayerTurn) {\n return state;\n }\n if ([\"solved\", \"failed\"].includes(state.status)) {\n return state;\n }\n\n return {\n ...state,\n currentMoveIndex: state.currentMoveIndex + 1,\n cpuMove: state.puzzle.moves[state.currentMoveIndex],\n nextMove:\n state.currentMoveIndex < state.puzzle.moves.length - 1\n ? state.puzzle.moves[state.currentMoveIndex + 1]\n : null,\n needCpuMove: false,\n isPlayerTurn: true,\n status: \"in-progress\",\n };\n\n case \"PLAYER_MOVE\": {\n const { move } = action.payload;\n\n const isMoveRight = [move?.san, move?.lan].includes(\n state?.nextMove || \"\",\n );\n const isPuzzleSolved =\n state.currentMoveIndex === state.puzzle.moves.length - 1;\n\n if (!isMoveRight) {\n return {\n ...state,\n status: \"failed\",\n nextMove: null,\n hint: \"none\",\n isPlayerTurn: false,\n onFailInvoked: false,\n };\n }\n\n if (isPuzzleSolved) {\n return {\n ...state,\n status: \"solved\",\n nextMove: null,\n hint: \"none\",\n isPlayerTurn: false,\n onSolveInvoked: false,\n };\n }\n\n return {\n ...state,\n hint: \"none\",\n currentMoveIndex: state.currentMoveIndex + 1,\n nextMove: state.puzzle.moves[state.currentMoveIndex + 1],\n status: \"in-progress\",\n needCpuMove: true,\n isPlayerTurn: false,\n };\n }\n\n case \"MARK_SOLVE_INVOKED\":\n return {\n ...state,\n onSolveInvoked: true,\n };\n\n case \"MARK_FAIL_INVOKED\":\n return {\n ...state,\n onFailInvoked: true,\n };\n\n default:\n return state;\n }\n};\n","import React from \"react\";\nimport { useChessPuzzle } from \"./useChessPuzzle\";\n\nexport const ChessPuzzleContext = React.createContext<ReturnType<\n typeof useChessPuzzle\n> | null>(null);\n\nexport const useChessPuzzleContext = () => {\n const context = React.useContext(ChessPuzzleContext);\n if (!context) {\n throw new Error(\n `useChessPuzzleContext must be used within a ChessPuzzle component. Make sure your component is wrapped with <ChessPuzzle.Root> or ensure the ChessPuzzle component is properly rendered in the component tree.`,\n );\n }\n return context;\n};\n","import React, { createContext, useContext } from \"react\";\nimport type { ChessPuzzleTheme } from \"./types\";\nimport { defaultPuzzleTheme } from \"./defaults\";\n\n/**\n * Context for ChessPuzzle theme\n */\nexport const ChessPuzzleThemeContext =\n createContext<ChessPuzzleTheme>(defaultPuzzleTheme);\n\n/**\n * Hook to access the current ChessPuzzle theme.\n * Returns the default puzzle theme if no ThemeProvider is present.\n */\nexport const useChessPuzzleTheme = (): ChessPuzzleTheme => {\n return useContext(ChessPuzzleThemeContext);\n};\n\nexport interface PuzzleThemeProviderProps {\n theme: ChessPuzzleTheme;\n children: React.ReactNode;\n}\n\n/**\n * Internal provider component used by Puzzle Root when a theme prop is provided.\n */\nexport const PuzzleThemeProvider: React.FC<PuzzleThemeProviderProps> = ({\n theme,\n children,\n}) => {\n return (\n <ChessPuzzleThemeContext.Provider value={theme}>\n {children}\n </ChessPuzzleThemeContext.Provider>\n );\n};\n","import { merge } from \"lodash\";\nimport type { ChessPuzzleTheme, PartialChessPuzzleTheme } from \"./types\";\nimport { defaultPuzzleTheme } from \"./defaults\";\n\n/**\n * Deep merges a partial puzzle theme with the default puzzle theme.\n * Allows users to override only specific theme properties while keeping defaults for the rest.\n *\n * @param partialTheme - Partial theme with only the properties to override\n * @returns Complete puzzle theme with overridden properties merged with defaults\n *\n * @example\n * ```typescript\n * const customTheme = mergePuzzleTheme({\n * puzzle: { hint: \"rgba(0, 255, 255, 0.5)\" }\n * });\n * // Returns full puzzle theme with only hint color changed\n * ```\n */\nexport const mergePuzzleTheme = (\n partialTheme?: PartialChessPuzzleTheme,\n): ChessPuzzleTheme => {\n if (!partialTheme) {\n return { ...defaultPuzzleTheme };\n }\n\n return merge({}, defaultPuzzleTheme, partialTheme);\n};\n","import React from \"react\";\nimport {\n ChessGame,\n deepMergeChessboardOptions,\n useChessGameContext,\n} from \"@react-chess-tools/react-chess-game\";\nimport { getCustomSquareStyles, stringToMove } from \"../../../utils\";\nimport { useChessPuzzleContext } from \"../../..\";\nimport { useChessPuzzleTheme } from \"../../../theme/context\";\n\nexport interface PuzzleBoardProps extends React.ComponentProps<\n typeof ChessGame.Board\n> {}\n\nexport const PuzzleBoard = React.forwardRef<HTMLDivElement, PuzzleBoardProps>(\n ({ options, ...rest }, ref) => {\n const puzzleContext = useChessPuzzleContext();\n const gameContext = useChessGameContext();\n const theme = useChessPuzzleTheme();\n\n if (!puzzleContext) {\n throw new Error(\"PuzzleContext not found\");\n }\n if (!gameContext) {\n throw new Error(\"ChessGameContext not found\");\n }\n\n const { game } = gameContext;\n const { status, hint, isPlayerTurn, nextMove } = puzzleContext;\n\n const mergedOptions = deepMergeChessboardOptions(options || {}, {\n squareStyles: getCustomSquareStyles(\n status,\n hint,\n isPlayerTurn,\n game,\n stringToMove(game, nextMove),\n theme,\n ),\n });\n\n return <ChessGame.Board ref={ref} {...rest} options={mergedOptions} />;\n },\n);\n\nPuzzleBoard.displayName = \"ChessPuzzle.PuzzleBoard\";\n","import React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { type Puzzle, type Status } from \"../../../utils\";\nimport { useChessPuzzleContext, type ChessPuzzleContextType } from \"../../..\";\n\nexport interface ResetProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"onReset\"\n> {\n asChild?: boolean;\n puzzle?: Puzzle;\n onReset?: (puzzleContext: ChessPuzzleContextType) => void;\n /**\n * The puzzle statuses in which the reset button should be visible.\n * @default [\"failed\", \"solved\"]\n */\n showOn?: Status[];\n}\n\nconst defaultShowOn: Status[] = [\"failed\", \"solved\"];\n\nexport const Reset = React.forwardRef<\n HTMLElement,\n React.PropsWithChildren<ResetProps>\n>(\n (\n {\n children,\n asChild,\n puzzle,\n onReset,\n showOn = defaultShowOn,\n className,\n ...rest\n },\n ref,\n ) => {\n const puzzleContext = useChessPuzzleContext();\n if (!puzzleContext) {\n throw new Error(\"PuzzleContext not found\");\n }\n const { changePuzzle, puzzle: contextPuzzle, status } = puzzleContext;\n\n const handleClick = React.useCallback(() => {\n changePuzzle(puzzle || contextPuzzle);\n onReset?.(puzzleContext);\n }, [changePuzzle, puzzle, contextPuzzle, puzzleContext, onReset]);\n\n if (!showOn.includes(status)) {\n return null;\n }\n\n return asChild ? (\n <Slot ref={ref} onClick={handleClick} className={className} {...rest}>\n {children}\n </Slot>\n ) : (\n <button\n ref={ref as React.RefObject<HTMLButtonElement>}\n type=\"button\"\n className={className}\n onClick={handleClick}\n {...rest}\n >\n {children}\n </button>\n );\n },\n);\n\nReset.displayName = \"ChessPuzzle.Reset\";\n","import React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { Status } from \"../../../utils\";\nimport { useChessPuzzleContext } from \"../../..\";\n\nexport interface HintProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"onClick\"\n> {\n asChild?: boolean;\n /**\n * The puzzle statuses in which the hint button should be visible.\n * @default [\"not-started\", \"in-progress\"]\n */\n showOn?: Status[];\n}\n\nconst defaultShowOn: Status[] = [\"not-started\", \"in-progress\"];\n\nexport const Hint = React.forwardRef<\n HTMLElement,\n React.PropsWithChildren<HintProps>\n>(({ children, asChild, showOn = defaultShowOn, className, ...rest }, ref) => {\n const puzzleContext = useChessPuzzleContext();\n if (!puzzleContext) {\n throw new Error(\"PuzzleContext not found\");\n }\n const { onHint, status } = puzzleContext;\n\n const handleClick = React.useCallback(() => {\n onHint();\n }, [onHint]);\n\n if (!showOn.includes(status)) {\n return null;\n }\n\n return asChild ? (\n <Slot ref={ref} onClick={handleClick} className={className} {...rest}>\n {children}\n </Slot>\n ) : (\n <button\n ref={ref as React.RefObject<HTMLButtonElement>}\n type=\"button\"\n className={className}\n onClick={handleClick}\n {...rest}\n >\n {children}\n </button>\n );\n});\n\nHint.displayName = \"ChessPuzzle.Hint\";\n","import { Root } from \"./parts/Root\";\nimport { PuzzleBoard } from \"./parts/PuzzleBoard\";\nimport { Reset } from \"./parts/Reset\";\nimport { Hint } from \"./parts/Hint\";\n\nexport const ChessPuzzle = {\n Root,\n Board: PuzzleBoard,\n Reset,\n Hint,\n};\n"],"mappings":"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","names":["React","puzzle","_a","React","React","React","React","ChessGame","useChessGameContext","React","useChessGameContext","ChessGame","React","React","React","Slot","defaultShowOn","React","Slot"]}