@react-chess-tools/react-chess-puzzle 0.1.0

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.
package/README.MD ADDED
@@ -0,0 +1,94 @@
1
+ <div align="center">
2
+ A lightweight, customizable React component library for rendering and interacting with chess puzzles.
3
+ </div>
4
+
5
+ ## Project Description
6
+
7
+ This project is a React-based chess puzzle component that allows users to solve chess puzzles online. It is part of the `react-chess-tools` package and is designed to be easy to use and customizable. It is built on top of `react-chess-game` component.
8
+
9
+ ## Preview
10
+
11
+ Visit the [demo](https://react-chess-tools.vercel.app/) to see the `react-chess-puzzle` component in action.
12
+
13
+ ## Installation
14
+
15
+ To install the `react-chess-puzzle` package, run the following command:
16
+
17
+ ```bash
18
+ $ npm install @react-chess-tools/react-chess-puzzle
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ To use the `react-chess-puzzle` package, you can import the `ChessPuzzle` component and use it as follows:
24
+
25
+ ```tsx
26
+ import { ChessPuzzle } from "@react-chess-tools/react-chess-puzzle";
27
+
28
+ const App = () => {
29
+ <ChessPuzzle.Root puzzle={...}>
30
+ <ChessPuzzle.Board />
31
+ </ChessPuzzle.Root>;
32
+ };
33
+ ```
34
+
35
+ ## Documentation
36
+
37
+ The `react-chess-puzzle` package provides a set of components that you can use to build your chess app. The following sections describe the components and their usage.
38
+
39
+ ### ChessPuzzle.Root
40
+
41
+ The `ChessPuzzle.Root` component is the root component of the `react-chess-puzzle` package. It is used to provide the `ChessPuzzleContext` to the rest of the components. It accept a `puzzle` prop that is used to instantiate the puzzle.
42
+
43
+ #### Props
44
+
45
+ The `ChessPuzzle.Root` component accepts the following props:
46
+
47
+ | Name | Type | Default | Description |
48
+ | ----------- | ----------- | ------- | --------------------------- |
49
+ | `puzzle` | `Puzzle` | | The puzzle to be solved |
50
+ | `children?` | `ReactNode` | | The children to be rendered |
51
+
52
+ the `puzzle` prop contains the following properties:
53
+
54
+ | Name | Type | Default | Description |
55
+ | --------------- | ---------- | ------- | -------------------------------------------------------------------------- |
56
+ | `fen` | `string` | | The FEN string of the puzzle |
57
+ | `moves` | `string[]` | | The moves of the puzzle |
58
+ | `makeFirstMove` | `boolean` | `false` | Whether the first move is part of the problem or must be played by the CPU |
59
+
60
+ ### ChessPuzzle.Board
61
+
62
+ The `ChessPuzzle.Board` component is used to render the chess board. It is a wrapper around the `ChessGame.Board` component and accepts the same props.
63
+
64
+ ### `Puzzle.Reset`
65
+
66
+ A button that changes the puzzle. It can be used, for example, to restart the puzzle or move to the next puzzle.
67
+
68
+ #### Props
69
+
70
+ | Name | Type | Default | Description |
71
+ | --------- | ---------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
72
+ | `puzzle` | `Puzzle` | | The puzzle object containing the FEN string and moves sequence. If not provided, the current puzzle is reset. |
73
+ | `onReset` | `() => void` | | A callback function that is called when the puzzle is reset. |
74
+ | `showOn` | `"not-started" \| "in-progress" \| "solved" \| "failed"[]` | | The state(s) in which the button is shown. |
75
+ | `asChild` | `boolean` | `false` | Change the component to the HTML tag or custom component of the only child. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node. |
76
+
77
+ ### `Puzzle.Hint`
78
+
79
+ A button that shows the next move of the puzzle.
80
+
81
+ #### Props
82
+
83
+ | Name | Type | Default | Description |
84
+ | --------- | ---------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
85
+ | `showOn` | `"not-started" \| "in-progress" \| "solved" \| "failed"[]` | | The state(s) in which the button is shown. |
86
+ | `asChild` | `boolean` | `false` | Change the component to the HTML tag or custom component of the only child. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node. |
87
+
88
+ ## 📝 License
89
+
90
+ This project is [MIT](https://opensource.org/licenses/MIT) licensed.
91
+
92
+ ## Show your support
93
+
94
+ Give a ⭐️ if this project helped you!
@@ -0,0 +1,51 @@
1
+ import * as React from 'react';
2
+ import React__default from 'react';
3
+ import { ChessGame } from '@react-chess-tools/react-chess-game';
4
+
5
+ type Status = "not-started" | "in-progress" | "solved" | "failed";
6
+ type Hint = "none" | "piece" | "move";
7
+ type Puzzle = {
8
+ fen: string;
9
+ moves: string[];
10
+ makeFirstMove?: boolean;
11
+ };
12
+
13
+ interface HintProps {
14
+ asChild?: boolean;
15
+ showOn?: Status[];
16
+ }
17
+
18
+ interface ResetProps {
19
+ asChild?: boolean;
20
+ puzzle?: Puzzle;
21
+ onReset?: () => void;
22
+ showOn?: Status[];
23
+ }
24
+
25
+ interface PuzzleBoardProps extends React__default.ComponentProps<typeof ChessGame.Board> {
26
+ }
27
+
28
+ interface RootProps {
29
+ puzzle: Puzzle;
30
+ onSolve?: (changePuzzle: (puzzle: Puzzle) => void) => void;
31
+ onFail?: (changePuzzle: (puzzle: Puzzle) => void) => void;
32
+ }
33
+
34
+ declare const ChessPuzzle: {
35
+ Root: React.FC<React.PropsWithChildren<RootProps>>;
36
+ Board: React.FC<PuzzleBoardProps>;
37
+ Reset: React.FC<React.PropsWithChildren<ResetProps>>;
38
+ Hint: React.FC<React.PropsWithChildren<HintProps>>;
39
+ };
40
+
41
+ declare const useChessPuzzleContext: () => {
42
+ status: Status;
43
+ changePuzzle: (puzzle: Puzzle) => void;
44
+ puzzle: Puzzle;
45
+ hint: Hint;
46
+ onHint: () => void;
47
+ nextMove: string | null | undefined;
48
+ isPlayerTurn: boolean;
49
+ };
50
+
51
+ export { ChessPuzzle, useChessPuzzleContext };
package/dist/index.mjs ADDED
@@ -0,0 +1,390 @@
1
+ // src/components/ChessPuzzle/parts/Root.tsx
2
+ import React3 from "react";
3
+
4
+ // src/utils/index.ts
5
+ import { Chess } from "chess.js";
6
+ import React from "react";
7
+ import last from "lodash/last";
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)";
11
+ var getOrientation = (puzzle) => {
12
+ const fen = puzzle.fen;
13
+ const game = new Chess(fen);
14
+ if (puzzle.makeFirstMove) {
15
+ game.move(puzzle.moves[0]);
16
+ }
17
+ return game.turn();
18
+ };
19
+ var isClickableElement = (element) => React.isValidElement(element);
20
+ var getCustomSquareStyles = (status, hint, isPlayerTurn, game, nextMove) => {
21
+ const customSquareStyles = {};
22
+ const lastMove = last(game.history({ verbose: true }));
23
+ if (status === "failed" && lastMove) {
24
+ customSquareStyles[lastMove.from] = {
25
+ backgroundColor: FAIL_COLOR
26
+ };
27
+ customSquareStyles[lastMove.to] = {
28
+ backgroundColor: FAIL_COLOR
29
+ };
30
+ }
31
+ if (lastMove && (status === "solved" || status !== "failed" && !isPlayerTurn)) {
32
+ customSquareStyles[lastMove.from] = {
33
+ backgroundColor: SUCCESS_COLOR
34
+ };
35
+ customSquareStyles[lastMove.to] = {
36
+ backgroundColor: SUCCESS_COLOR
37
+ };
38
+ }
39
+ if (hint === "piece") {
40
+ if (nextMove) {
41
+ customSquareStyles[nextMove.from] = {
42
+ backgroundColor: HINT_COLOR
43
+ };
44
+ }
45
+ }
46
+ if (hint === "move") {
47
+ if (nextMove) {
48
+ customSquareStyles[nextMove.from] = {
49
+ backgroundColor: HINT_COLOR
50
+ };
51
+ customSquareStyles[nextMove.to] = {
52
+ backgroundColor: HINT_COLOR
53
+ };
54
+ }
55
+ }
56
+ return customSquareStyles;
57
+ };
58
+ var stringToMove = (game, move) => {
59
+ const copy = new Chess(game.fen());
60
+ if (move === null || move === void 0) {
61
+ return null;
62
+ }
63
+ try {
64
+ return copy.move(move);
65
+ } catch (e) {
66
+ return null;
67
+ }
68
+ };
69
+
70
+ // src/hooks/useChessPuzzle.ts
71
+ import { useEffect, useReducer } from "react";
72
+
73
+ // src/hooks/reducer.ts
74
+ var initializePuzzle = ({
75
+ puzzle,
76
+ setPosition
77
+ }) => {
78
+ setPosition(puzzle.fen, getOrientation(puzzle));
79
+ return {
80
+ puzzle,
81
+ currentMoveIndex: 0,
82
+ status: "not-started",
83
+ nextMove: puzzle.moves[0],
84
+ hint: "none",
85
+ needCpuMove: !!puzzle.makeFirstMove,
86
+ isPlayerTurn: !puzzle.makeFirstMove
87
+ };
88
+ };
89
+ var reducer = (state, action) => {
90
+ var _a, _b;
91
+ switch (action.type) {
92
+ case "INITIALIZE":
93
+ return {
94
+ ...state,
95
+ ...initializePuzzle(action.payload)
96
+ };
97
+ case "RESET":
98
+ return {
99
+ ...state,
100
+ ...initializePuzzle({
101
+ puzzle: state.puzzle,
102
+ setPosition: action.payload.setPosition
103
+ })
104
+ };
105
+ case "TOGGLE_HINT":
106
+ if (state.hint === "none") {
107
+ return { ...state, hint: "piece" };
108
+ }
109
+ return { ...state, hint: "move" };
110
+ case "CPU_MOVE":
111
+ if (state.isPlayerTurn) {
112
+ return state;
113
+ }
114
+ if (["solved", "failed"].includes(state.status)) {
115
+ return state;
116
+ }
117
+ if (state.nextMove) {
118
+ (_b = (_a = action.payload).makeMove) == null ? void 0 : _b.call(_a, state.nextMove);
119
+ }
120
+ return {
121
+ ...state,
122
+ currentMoveIndex: state.currentMoveIndex + 1,
123
+ nextMove: state.currentMoveIndex < state.puzzle.moves.length - 1 ? state.puzzle.moves[state.currentMoveIndex + 1] : null,
124
+ needCpuMove: false,
125
+ isPlayerTurn: true,
126
+ status: "in-progress"
127
+ };
128
+ case "PLAYER_MOVE": {
129
+ const { move, onSolve, onFail, changePuzzle } = action.payload;
130
+ const isMoveRight = [move == null ? void 0 : move.san, move == null ? void 0 : move.lan].includes(
131
+ (state == null ? void 0 : state.nextMove) || ""
132
+ );
133
+ const isPuzzleSolved = state.currentMoveIndex === state.puzzle.moves.length - 1;
134
+ if (!isMoveRight) {
135
+ if (onFail) {
136
+ onFail(changePuzzle);
137
+ }
138
+ return {
139
+ ...state,
140
+ status: "failed",
141
+ nextMove: null,
142
+ hint: "none",
143
+ isPlayerTurn: false
144
+ };
145
+ }
146
+ if (isPuzzleSolved) {
147
+ if (onSolve) {
148
+ onSolve(changePuzzle);
149
+ }
150
+ return {
151
+ ...state,
152
+ status: "solved",
153
+ nextMove: null,
154
+ hint: "none",
155
+ isPlayerTurn: false
156
+ };
157
+ }
158
+ return {
159
+ ...state,
160
+ hint: "none",
161
+ currentMoveIndex: state.currentMoveIndex + 1,
162
+ nextMove: state.puzzle.moves[state.currentMoveIndex + 1],
163
+ status: "in-progress",
164
+ needCpuMove: true,
165
+ isPlayerTurn: false
166
+ };
167
+ }
168
+ default:
169
+ return state;
170
+ }
171
+ };
172
+
173
+ // src/hooks/useChessPuzzle.ts
174
+ import { useChessGameContext } from "@react-chess-tools/react-chess-game";
175
+ var useChessPuzzle = (puzzle, onSolve, onFail) => {
176
+ var _a;
177
+ const gameContext = useChessGameContext();
178
+ const [state, dispatch] = useReducer(
179
+ reducer,
180
+ { puzzle, setPosition: (gameContext == null ? void 0 : gameContext.methods.setPosition) ?? (() => {
181
+ }) },
182
+ initializePuzzle
183
+ );
184
+ const {
185
+ game,
186
+ methods: { makeMove, setPosition }
187
+ } = gameContext;
188
+ useEffect(() => {
189
+ if (gameContext && game.fen() === puzzle.fen && state.needCpuMove) {
190
+ setTimeout(
191
+ () => dispatch({
192
+ type: "CPU_MOVE",
193
+ payload: {
194
+ makeMove
195
+ }
196
+ }),
197
+ 0
198
+ );
199
+ }
200
+ }, [gameContext, state.needCpuMove]);
201
+ if (!gameContext) {
202
+ throw new Error("useChessPuzzle must be used within a ChessGameContext");
203
+ }
204
+ const changePuzzle = (puzzle2) => {
205
+ dispatch({ type: "INITIALIZE", payload: { puzzle: puzzle2, setPosition } });
206
+ };
207
+ useEffect(() => {
208
+ var _a2, _b, _c;
209
+ if (((_a2 = game == null ? void 0 : game.history()) == null ? void 0 : _a2.length) <= 0 + (puzzle.makeFirstMove ? 1 : 0)) {
210
+ return;
211
+ }
212
+ if (game.history().length % 2 === (puzzle.makeFirstMove ? 0 : 1)) {
213
+ dispatch({
214
+ type: "PLAYER_MOVE",
215
+ payload: {
216
+ move: ((_c = (_b = gameContext == null ? void 0 : gameContext.game) == null ? void 0 : _b.history({ verbose: true })) == null ? void 0 : _c.pop()) ?? null,
217
+ onSolve,
218
+ onFail,
219
+ changePuzzle,
220
+ game
221
+ }
222
+ });
223
+ dispatch({
224
+ type: "CPU_MOVE",
225
+ payload: {
226
+ makeMove
227
+ }
228
+ });
229
+ }
230
+ }, [(_a = game == null ? void 0 : game.history()) == null ? void 0 : _a.length]);
231
+ const onHint = () => {
232
+ dispatch({ type: "TOGGLE_HINT" });
233
+ };
234
+ return {
235
+ status: state.status,
236
+ changePuzzle,
237
+ puzzle,
238
+ hint: state.hint,
239
+ onHint,
240
+ nextMove: state.nextMove,
241
+ isPlayerTurn: state.isPlayerTurn
242
+ };
243
+ };
244
+
245
+ // src/components/ChessPuzzle/parts/Root.tsx
246
+ import { ChessGame } from "@react-chess-tools/react-chess-game";
247
+
248
+ // src/hooks/useChessPuzzleContext.ts
249
+ import React2 from "react";
250
+ var ChessPuzzleContext = React2.createContext(null);
251
+ var useChessPuzzleContext = () => {
252
+ const context = React2.useContext(ChessPuzzleContext);
253
+ if (!context) {
254
+ throw new Error(
255
+ "useChessGameContext must be used within a ChessGameProvider"
256
+ );
257
+ }
258
+ return context;
259
+ };
260
+
261
+ // src/components/ChessPuzzle/parts/Root.tsx
262
+ var PuzzleRoot = ({
263
+ puzzle,
264
+ onSolve,
265
+ onFail,
266
+ children
267
+ }) => {
268
+ const context = useChessPuzzle(puzzle, onSolve, onFail);
269
+ return /* @__PURE__ */ React3.createElement(ChessPuzzleContext.Provider, { value: context }, children);
270
+ };
271
+ var Root = ({
272
+ puzzle,
273
+ onSolve,
274
+ onFail,
275
+ children
276
+ }) => {
277
+ return /* @__PURE__ */ React3.createElement(ChessGame.Root, { fen: puzzle.fen, orientation: getOrientation(puzzle) }, /* @__PURE__ */ React3.createElement(PuzzleRoot, { puzzle, onSolve, onFail }, children));
278
+ };
279
+
280
+ // src/components/ChessPuzzle/parts/PuzzleBoard.tsx
281
+ import React4 from "react";
282
+ import {
283
+ ChessGame as ChessGame2,
284
+ useChessGameContext as useChessGameContext2
285
+ } from "@react-chess-tools/react-chess-game";
286
+ var PuzzleBoard = ({ ...rest }) => {
287
+ const puzzleContext = useChessPuzzleContext();
288
+ const gameContext = useChessGameContext2();
289
+ if (!puzzleContext) {
290
+ throw new Error("PuzzleContext not found");
291
+ }
292
+ if (!gameContext) {
293
+ throw new Error("ChessGameContext not found");
294
+ }
295
+ const { game } = gameContext;
296
+ const { status, hint, isPlayerTurn, nextMove } = puzzleContext;
297
+ return /* @__PURE__ */ React4.createElement(
298
+ ChessGame2.Board,
299
+ {
300
+ customSquareStyles: getCustomSquareStyles(
301
+ status,
302
+ hint,
303
+ isPlayerTurn,
304
+ game,
305
+ stringToMove(game, nextMove)
306
+ ),
307
+ ...rest
308
+ }
309
+ );
310
+ };
311
+
312
+ // src/components/ChessPuzzle/parts/Reset.tsx
313
+ import React5 from "react";
314
+ var defaultShowOn = ["failed", "solved"];
315
+ var Reset = ({
316
+ children,
317
+ asChild,
318
+ puzzle,
319
+ onReset,
320
+ showOn = defaultShowOn
321
+ }) => {
322
+ const puzzleContext = useChessPuzzleContext();
323
+ if (!puzzleContext) {
324
+ throw new Error("PuzzleContext not found");
325
+ }
326
+ const { changePuzzle, status } = puzzleContext;
327
+ const handleClick = () => {
328
+ changePuzzle(puzzle || puzzleContext.puzzle);
329
+ onReset == null ? void 0 : onReset();
330
+ };
331
+ if (!showOn.includes(status)) {
332
+ return null;
333
+ }
334
+ if (asChild) {
335
+ const child = React5.Children.only(children);
336
+ if (isClickableElement(child)) {
337
+ return React5.cloneElement(child, {
338
+ onClick: handleClick
339
+ });
340
+ } else {
341
+ throw new Error("Change child must be a clickable element");
342
+ }
343
+ }
344
+ return /* @__PURE__ */ React5.createElement("button", { type: "button", onClick: handleClick }, children);
345
+ };
346
+
347
+ // src/components/ChessPuzzle/parts/Hint.tsx
348
+ import React6 from "react";
349
+ var defaultShowOn2 = ["not-started", "in-progress"];
350
+ var Hint = ({
351
+ children,
352
+ asChild,
353
+ showOn = defaultShowOn2
354
+ }) => {
355
+ const puzzleContext = useChessPuzzleContext();
356
+ if (!puzzleContext) {
357
+ throw new Error("PuzzleContext not found");
358
+ }
359
+ const { onHint, status } = puzzleContext;
360
+ const handleClick = () => {
361
+ onHint();
362
+ };
363
+ if (!showOn.includes(status)) {
364
+ return null;
365
+ }
366
+ if (asChild) {
367
+ const child = React6.Children.only(children);
368
+ if (isClickableElement(child)) {
369
+ return React6.cloneElement(child, {
370
+ onClick: handleClick
371
+ });
372
+ } else {
373
+ throw new Error("Change child must be a clickable element");
374
+ }
375
+ }
376
+ return /* @__PURE__ */ React6.createElement("button", { type: "button", onClick: handleClick }, children);
377
+ };
378
+
379
+ // src/components/ChessPuzzle/index.ts
380
+ var ChessPuzzle = {
381
+ Root,
382
+ Board: PuzzleBoard,
383
+ Reset,
384
+ Hint
385
+ };
386
+ export {
387
+ ChessPuzzle,
388
+ useChessPuzzleContext
389
+ };
390
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ChessPuzzle/parts/Root.tsx","../src/utils/index.ts","../src/hooks/useChessPuzzle.ts","../src/hooks/reducer.ts","../src/hooks/useChessPuzzleContext.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 { useChessPuzzle } from \"../../../hooks/useChessPuzzle\";\nimport { ChessGame } from \"@react-chess-tools/react-chess-game\";\nimport { ChessPuzzleContext } from \"../../../hooks/useChessPuzzleContext\";\n\nexport interface RootProps {\n puzzle: Puzzle;\n onSolve?: (changePuzzle: (puzzle: Puzzle) => void) => void;\n onFail?: (changePuzzle: (puzzle: Puzzle) => void) => void;\n}\n\nconst PuzzleRoot: React.FC<React.PropsWithChildren<RootProps>> = ({\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 children,\n}) => {\n return (\n <ChessGame.Root fen={puzzle.fen} orientation={getOrientation(puzzle)}>\n <PuzzleRoot puzzle={puzzle} onSolve={onSolve} onFail={onFail}>\n {children}\n </PuzzleRoot>\n </ChessGame.Root>\n );\n};\n","import { type Color, Chess, Move } from \"chess.js\";\nimport React, { CSSProperties, ReactElement, ReactNode } from \"react\";\nimport last from \"lodash/last\";\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\nconst FAIL_COLOR = \"rgba(201, 52, 48, 0.5)\";\nconst SUCCESS_COLOR = \"rgba(172, 206, 89, 0.5)\";\nconst HINT_COLOR = \"rgba(27, 172, 166, 0.5)\";\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\ninterface ClickableElement extends ReactElement {\n props: {\n onClick?: () => void;\n };\n}\n\nexport const isClickableElement = (\n element: ReactNode,\n): element is ClickableElement => React.isValidElement(element);\n\nexport const getCustomSquareStyles = (\n status: Status,\n hint: Hint,\n isPlayerTurn: boolean,\n game: Chess,\n nextMove?: Move | null,\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: FAIL_COLOR,\n };\n customSquareStyles[lastMove.to] = {\n backgroundColor: FAIL_COLOR,\n };\n }\n\n if (\n lastMove &&\n (status === \"solved\" || (status !== \"failed\" && !isPlayerTurn))\n ) {\n customSquareStyles[lastMove.from] = {\n backgroundColor: SUCCESS_COLOR,\n };\n customSquareStyles[lastMove.to] = {\n backgroundColor: SUCCESS_COLOR,\n };\n }\n\n if (hint === \"piece\") {\n if (nextMove) {\n customSquareStyles[nextMove.from] = {\n backgroundColor: HINT_COLOR,\n };\n }\n }\n\n if (hint === \"move\") {\n if (nextMove) {\n customSquareStyles[nextMove.from] = {\n backgroundColor: HINT_COLOR,\n };\n customSquareStyles[nextMove.to] = {\n backgroundColor: HINT_COLOR,\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 { useEffect, useReducer } from \"react\";\nimport { initializePuzzle, reducer } from \"./reducer\";\nimport { type Puzzle } from \"../utils\";\nimport { useChessGameContext } from \"@react-chess-tools/react-chess-game\";\n\nexport const useChessPuzzle = (\n puzzle: Puzzle,\n onSolve?: (changePuzzle: (puzzle: Puzzle) => void) => void,\n onFail?: (changePuzzle: (puzzle: Puzzle) => void) => void,\n) => {\n const gameContext = useChessGameContext();\n\n const [state, dispatch] = useReducer(\n reducer,\n { puzzle, setPosition: gameContext?.methods.setPosition ?? (() => {}) },\n initializePuzzle,\n );\n\n const {\n game,\n methods: { makeMove, setPosition },\n } = gameContext;\n\n useEffect(() => {\n if (gameContext && game.fen() === puzzle.fen && state.needCpuMove) {\n setTimeout(\n () =>\n dispatch({\n type: \"CPU_MOVE\",\n payload: {\n makeMove,\n },\n }),\n 0,\n );\n }\n }, [gameContext, state.needCpuMove]);\n\n if (!gameContext) {\n throw new Error(\"useChessPuzzle must be used within a ChessGameContext\");\n }\n\n const changePuzzle = (puzzle: Puzzle) => {\n dispatch({ type: \"INITIALIZE\", payload: { puzzle, setPosition } });\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 onSolve,\n onFail,\n changePuzzle,\n game: game,\n },\n });\n\n dispatch({\n type: \"CPU_MOVE\",\n payload: {\n makeMove,\n },\n });\n }\n }, [game?.history()?.length]);\n\n const onHint = () => {\n dispatch({ type: \"TOGGLE_HINT\" });\n };\n\n return {\n status: state.status,\n changePuzzle,\n puzzle,\n hint: state.hint,\n onHint,\n nextMove: state.nextMove,\n isPlayerTurn: state.isPlayerTurn,\n };\n};\n","import { Chess, Move } from \"chess.js\";\nimport { useChessGame } from \"@react-chess-tools/react-chess-game\";\nimport { getOrientation, type Puzzle, type Hint, type Status } from \"../utils\";\n\nexport type State = {\n puzzle: Puzzle;\n currentMoveIndex: number;\n status: Status;\n nextMove?: string | null;\n hint: Hint;\n needCpuMove: boolean;\n isPlayerTurn: boolean;\n};\n\nexport type Action =\n | {\n type: \"INITIALIZE\";\n payload: {\n puzzle: Puzzle;\n setPosition: ReturnType<typeof useChessGame>[\"methods\"][\"setPosition\"];\n };\n }\n | {\n type: \"RESET\";\n payload: {\n setPosition: ReturnType<typeof useChessGame>[\"methods\"][\"setPosition\"];\n };\n }\n | { type: \"TOGGLE_HINT\" }\n | {\n type: \"CPU_MOVE\";\n payload: {\n makeMove?: ReturnType<typeof useChessGame>[\"methods\"][\"makeMove\"];\n };\n }\n | {\n type: \"PLAYER_MOVE\";\n payload: {\n move?: Move | null;\n onSolve?: (changePuzzle: (puzzle: Puzzle) => void) => void;\n onFail?: (changePuzzle: (puzzle: Puzzle) => void) => void;\n changePuzzle: (puzzle: Puzzle) => void;\n game: Chess;\n };\n };\n\nexport const initializePuzzle = ({\n puzzle,\n setPosition,\n}: {\n puzzle: Puzzle;\n setPosition: ReturnType<typeof useChessGame>[\"methods\"][\"setPosition\"];\n}): State => {\n setPosition(puzzle.fen, getOrientation(puzzle));\n return {\n puzzle,\n currentMoveIndex: 0,\n status: \"not-started\",\n nextMove: puzzle.moves[0],\n hint: \"none\",\n needCpuMove: !!puzzle.makeFirstMove,\n isPlayerTurn: !puzzle.makeFirstMove,\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 setPosition: action.payload.setPosition,\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 if (state.nextMove) {\n action.payload.makeMove?.(state.nextMove);\n }\n\n return {\n ...state,\n currentMoveIndex: state.currentMoveIndex + 1,\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, onSolve, onFail, changePuzzle } = 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 if (onFail) {\n onFail(changePuzzle);\n }\n return {\n ...state,\n status: \"failed\",\n nextMove: null,\n hint: \"none\",\n isPlayerTurn: false,\n };\n }\n\n if (isPuzzleSolved) {\n if (onSolve) {\n onSolve(changePuzzle);\n }\n\n return {\n ...state,\n status: \"solved\",\n nextMove: null,\n hint: \"none\",\n isPlayerTurn: 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 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 \"useChessGameContext must be used within a ChessGameProvider\",\n );\n }\n return context;\n};\n","import React from \"react\";\nimport {\n ChessGame,\n useChessGameContext,\n} from \"@react-chess-tools/react-chess-game\";\nimport { getCustomSquareStyles, stringToMove } from \"../../../utils\";\nimport { useChessPuzzleContext } from \"../../..\";\n\nexport interface PuzzleBoardProps\n extends React.ComponentProps<typeof ChessGame.Board> {}\nexport const PuzzleBoard: React.FC<PuzzleBoardProps> = ({ ...rest }) => {\n const puzzleContext = useChessPuzzleContext();\n const gameContext = useChessGameContext();\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 return (\n <ChessGame.Board\n customSquareStyles={getCustomSquareStyles(\n status,\n hint,\n isPlayerTurn,\n game,\n stringToMove(game, nextMove),\n )}\n {...rest}\n />\n );\n};\n","import React from \"react\";\nimport { isClickableElement, type Puzzle, type Status } from \"../../../utils\";\nimport { useChessPuzzleContext } from \"../../..\";\n\nexport interface ResetProps {\n asChild?: boolean;\n puzzle?: Puzzle;\n onReset?: () => void;\n showOn?: Status[];\n}\n\nconst defaultShowOn: Status[] = [\"failed\", \"solved\"];\n\nexport const Reset: React.FC<React.PropsWithChildren<ResetProps>> = ({\n children,\n asChild,\n puzzle,\n onReset,\n showOn = defaultShowOn,\n}) => {\n const puzzleContext = useChessPuzzleContext();\n if (!puzzleContext) {\n throw new Error(\"PuzzleContext not found\");\n }\n const { changePuzzle, status } = puzzleContext;\n const handleClick = () => {\n changePuzzle(puzzle || puzzleContext.puzzle);\n onReset?.();\n };\n\n if (!showOn.includes(status)) {\n return null;\n }\n\n if (asChild) {\n const child = React.Children.only(children);\n if (isClickableElement(child)) {\n return React.cloneElement(child, {\n onClick: handleClick,\n });\n } else {\n throw new Error(\"Change child must be a clickable element\");\n }\n }\n\n return (\n <button type=\"button\" onClick={handleClick}>\n {children}\n </button>\n );\n};\n","import React from \"react\";\nimport { Status, isClickableElement } from \"../../../utils\";\nimport { useChessPuzzleContext } from \"../../..\";\n\nexport interface HintProps {\n asChild?: boolean;\n showOn?: Status[];\n}\n\nconst defaultShowOn: Status[] = [\"not-started\", \"in-progress\"];\n\nexport const Hint: React.FC<React.PropsWithChildren<HintProps>> = ({\n children,\n asChild,\n showOn = defaultShowOn,\n}) => {\n const puzzleContext = useChessPuzzleContext();\n if (!puzzleContext) {\n throw new Error(\"PuzzleContext not found\");\n }\n const { onHint, status } = puzzleContext;\n const handleClick = () => {\n onHint();\n };\n\n if (!showOn.includes(status)) {\n return null;\n }\n\n if (asChild) {\n const child = React.Children.only(children);\n if (isClickableElement(child)) {\n return React.cloneElement(child, {\n onClick: handleClick,\n });\n } else {\n throw new Error(\"Change child must be a clickable element\");\n }\n }\n\n return (\n <button type=\"button\" onClick={handleClick}>\n {children}\n </button>\n );\n};\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","ChessGame","useChessGameContext","useChessGameContext","React","ChessGame","React","React","React","defaultShowOn","React"]}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@react-chess-tools/react-chess-puzzle",
3
+ "version": "0.1.0",
4
+ "description": "A lightweight, customizable React component library for rendering and interacting with chess puzzles.",
5
+ "main": "dist/index.mjs",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.mts",
8
+ "scripts": {
9
+ "build": "tsup src/index.ts",
10
+ "release": "npm run build && release-it --npm.publish=true",
11
+ "test": "echo \"Error: no test specified\" && exit 1"
12
+ },
13
+ "keywords": [
14
+ "chess",
15
+ "react",
16
+ "board",
17
+ "game",
18
+ "chess.js",
19
+ "react-chessboard",
20
+ "component",
21
+ "play",
22
+ "strategy",
23
+ "checkmate",
24
+ "interactive",
25
+ "UI",
26
+ "boardgame",
27
+ "puzzle",
28
+ "puzzles"
29
+ ],
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "author": "Daniele Cammareri <daniele.cammareri@gmail.com>",
34
+ "license": "MIT",
35
+ "dependencies": {
36
+ "@react-chess-tools/react-chess-game": "^0.0.2",
37
+ "chess.js": "^1.0.0-beta.6",
38
+ "lodash": "^4.17.21"
39
+ },
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/dancamma/react-chess-tools.git"
43
+ },
44
+ "bugs": {
45
+ "url": "https://github.com/dancamma/react-chess-tools/issues"
46
+ },
47
+ "homepage": "https://github.com/dancamma/react-chess-tools#readme"
48
+ }