@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 +94 -0
- package/dist/index.d.mts +51 -0
- package/dist/index.mjs +390 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +48 -0
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!
|
package/dist/index.d.mts
ADDED
|
@@ -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
|
+
}
|