@react-chess-tools/react-chess-puzzle 0.6.1 → 1.0.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/CHANGELOG.md +28 -0
- package/dist/index.cjs +510 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +116 -0
- package/dist/index.d.ts +116 -0
- package/dist/{index.mjs → index.js} +89 -43
- package/dist/index.js.map +1 -0
- package/package.json +18 -9
- package/src/components/ChessPuzzle/ChessPuzzle.stories.tsx +27 -0
- package/src/components/ChessPuzzle/ThemePuzzle.stories.tsx +300 -0
- package/src/components/ChessPuzzle/parts/PuzzleBoard.tsx +23 -18
- package/src/components/ChessPuzzle/parts/Root.tsx +27 -5
- package/src/docs/Theming.mdx +255 -0
- package/src/index.ts +14 -0
- package/src/theme/__tests__/context.test.tsx +66 -0
- package/src/theme/__tests__/defaults.test.ts +48 -0
- package/src/theme/__tests__/utils.test.ts +76 -0
- package/src/theme/context.tsx +36 -0
- package/src/theme/defaults.ts +16 -0
- package/src/theme/index.ts +20 -0
- package/src/theme/types.ts +29 -0
- package/src/theme/utils.ts +28 -0
- package/src/utils/index.ts +21 -11
- package/dist/index.d.mts +0 -57
- package/dist/index.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @react-chess-tools/react-chess-puzzle
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- b8f72df: Add comprehensive theming system with ThemeProvider, preset themes (Default, Lichess, Chess.com), Storybook documentation with interactive playgrounds, and comprehensive tests.
|
|
8
|
+
|
|
9
|
+
### Minor Changes
|
|
10
|
+
|
|
11
|
+
- 8f16568: Add dual package ESM + CJS support with conditional exports for better compatibility across different environments and build tools.
|
|
12
|
+
- 15482ec: Upgrade dependencies including ESLint 9, TypeScript-ESLint 8, Jest 30, React 19.2.3, chess.js 1.4.0, and more.
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- b38be2f: Add automated release workflow with modern CI/CD pipeline. Fix changesets config and simplify package.json scripts.
|
|
17
|
+
- Updated dependencies [8f16568]
|
|
18
|
+
- Updated dependencies [b38be2f]
|
|
19
|
+
- Updated dependencies [b8f72df]
|
|
20
|
+
- Updated dependencies [15482ec]
|
|
21
|
+
- @react-chess-tools/react-chess-game@1.0.0
|
|
22
|
+
|
|
23
|
+
## 0.6.2
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- 9d33423: Fix PuzzleBoard options merging
|
|
28
|
+
- Updated dependencies [9d33423]
|
|
29
|
+
- @react-chess-tools/react-chess-game@0.5.2
|
|
30
|
+
|
|
3
31
|
## 0.6.1
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
ChessPuzzle: () => ChessPuzzle,
|
|
34
|
+
ChessPuzzleThemeContext: () => ChessPuzzleThemeContext,
|
|
35
|
+
defaultPuzzleTheme: () => defaultPuzzleTheme,
|
|
36
|
+
mergePuzzleTheme: () => mergePuzzleTheme,
|
|
37
|
+
useChessPuzzleContext: () => useChessPuzzleContext,
|
|
38
|
+
useChessPuzzleTheme: () => useChessPuzzleTheme
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(index_exports);
|
|
41
|
+
|
|
42
|
+
// src/components/ChessPuzzle/parts/Root.tsx
|
|
43
|
+
var import_react5 = __toESM(require("react"), 1);
|
|
44
|
+
|
|
45
|
+
// src/utils/index.ts
|
|
46
|
+
var import_chess = require("chess.js");
|
|
47
|
+
var import_react = __toESM(require("react"), 1);
|
|
48
|
+
var import_lodash = __toESM(require("lodash"), 1);
|
|
49
|
+
|
|
50
|
+
// src/theme/defaults.ts
|
|
51
|
+
var import_react_chess_game = require("@react-chess-tools/react-chess-game");
|
|
52
|
+
var defaultPuzzleTheme = {
|
|
53
|
+
...import_react_chess_game.defaultGameTheme,
|
|
54
|
+
puzzle: {
|
|
55
|
+
success: "rgba(172, 206, 89, 0.5)",
|
|
56
|
+
failure: "rgba(201, 52, 48, 0.5)",
|
|
57
|
+
hint: "rgba(27, 172, 166, 0.5)"
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// src/utils/index.ts
|
|
62
|
+
var getOrientation = (puzzle) => {
|
|
63
|
+
const fen = puzzle.fen;
|
|
64
|
+
const game = new import_chess.Chess(fen);
|
|
65
|
+
if (puzzle.makeFirstMove) {
|
|
66
|
+
game.move(puzzle.moves[0]);
|
|
67
|
+
}
|
|
68
|
+
return game.turn();
|
|
69
|
+
};
|
|
70
|
+
var isClickableElement = (element) => import_react.default.isValidElement(element);
|
|
71
|
+
var getCustomSquareStyles = (status, hint, isPlayerTurn, game, nextMove, theme = defaultPuzzleTheme) => {
|
|
72
|
+
const customSquareStyles = {};
|
|
73
|
+
const lastMove = import_lodash.default.last(game.history({ verbose: true }));
|
|
74
|
+
if (status === "failed" && lastMove) {
|
|
75
|
+
customSquareStyles[lastMove.from] = {
|
|
76
|
+
backgroundColor: theme.puzzle.failure
|
|
77
|
+
};
|
|
78
|
+
customSquareStyles[lastMove.to] = {
|
|
79
|
+
backgroundColor: theme.puzzle.failure
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
if (lastMove && (status === "solved" || status !== "failed" && !isPlayerTurn)) {
|
|
83
|
+
customSquareStyles[lastMove.from] = {
|
|
84
|
+
backgroundColor: theme.puzzle.success
|
|
85
|
+
};
|
|
86
|
+
customSquareStyles[lastMove.to] = {
|
|
87
|
+
backgroundColor: theme.puzzle.success
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (hint === "piece") {
|
|
91
|
+
if (nextMove) {
|
|
92
|
+
customSquareStyles[nextMove.from] = {
|
|
93
|
+
backgroundColor: theme.puzzle.hint
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (hint === "move") {
|
|
98
|
+
if (nextMove) {
|
|
99
|
+
customSquareStyles[nextMove.from] = {
|
|
100
|
+
backgroundColor: theme.puzzle.hint
|
|
101
|
+
};
|
|
102
|
+
customSquareStyles[nextMove.to] = {
|
|
103
|
+
backgroundColor: theme.puzzle.hint
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return customSquareStyles;
|
|
108
|
+
};
|
|
109
|
+
var stringToMove = (game, move) => {
|
|
110
|
+
const copy = new import_chess.Chess(game.fen());
|
|
111
|
+
if (move === null || move === void 0) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
return copy.move(move);
|
|
116
|
+
} catch (e) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// src/hooks/useChessPuzzle.ts
|
|
122
|
+
var import_react2 = require("react");
|
|
123
|
+
|
|
124
|
+
// src/hooks/reducer.ts
|
|
125
|
+
var initializePuzzle = ({ puzzle }) => {
|
|
126
|
+
return {
|
|
127
|
+
puzzle,
|
|
128
|
+
currentMoveIndex: 0,
|
|
129
|
+
status: "not-started",
|
|
130
|
+
nextMove: puzzle.moves[0],
|
|
131
|
+
hint: "none",
|
|
132
|
+
cpuMove: null,
|
|
133
|
+
needCpuMove: !!puzzle.makeFirstMove,
|
|
134
|
+
isPlayerTurn: !puzzle.makeFirstMove,
|
|
135
|
+
onSolveInvoked: false,
|
|
136
|
+
onFailInvoked: false
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
var reducer = (state, action) => {
|
|
140
|
+
switch (action.type) {
|
|
141
|
+
case "INITIALIZE":
|
|
142
|
+
return {
|
|
143
|
+
...state,
|
|
144
|
+
...initializePuzzle(action.payload)
|
|
145
|
+
};
|
|
146
|
+
case "RESET":
|
|
147
|
+
return {
|
|
148
|
+
...state,
|
|
149
|
+
...initializePuzzle({
|
|
150
|
+
puzzle: state.puzzle
|
|
151
|
+
})
|
|
152
|
+
};
|
|
153
|
+
case "TOGGLE_HINT":
|
|
154
|
+
if (state.hint === "none") {
|
|
155
|
+
return { ...state, hint: "piece" };
|
|
156
|
+
}
|
|
157
|
+
return { ...state, hint: "move" };
|
|
158
|
+
case "CPU_MOVE":
|
|
159
|
+
if (state.isPlayerTurn) {
|
|
160
|
+
return state;
|
|
161
|
+
}
|
|
162
|
+
if (["solved", "failed"].includes(state.status)) {
|
|
163
|
+
return state;
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
...state,
|
|
167
|
+
currentMoveIndex: state.currentMoveIndex + 1,
|
|
168
|
+
cpuMove: state.puzzle.moves[state.currentMoveIndex],
|
|
169
|
+
nextMove: state.currentMoveIndex < state.puzzle.moves.length - 1 ? state.puzzle.moves[state.currentMoveIndex + 1] : null,
|
|
170
|
+
needCpuMove: false,
|
|
171
|
+
isPlayerTurn: true,
|
|
172
|
+
status: "in-progress"
|
|
173
|
+
};
|
|
174
|
+
case "PLAYER_MOVE": {
|
|
175
|
+
const { move } = action.payload;
|
|
176
|
+
const isMoveRight = [move == null ? void 0 : move.san, move == null ? void 0 : move.lan].includes(
|
|
177
|
+
(state == null ? void 0 : state.nextMove) || ""
|
|
178
|
+
);
|
|
179
|
+
const isPuzzleSolved = state.currentMoveIndex === state.puzzle.moves.length - 1;
|
|
180
|
+
if (!isMoveRight) {
|
|
181
|
+
return {
|
|
182
|
+
...state,
|
|
183
|
+
status: "failed",
|
|
184
|
+
nextMove: null,
|
|
185
|
+
hint: "none",
|
|
186
|
+
isPlayerTurn: false,
|
|
187
|
+
onFailInvoked: false
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
if (isPuzzleSolved) {
|
|
191
|
+
return {
|
|
192
|
+
...state,
|
|
193
|
+
status: "solved",
|
|
194
|
+
nextMove: null,
|
|
195
|
+
hint: "none",
|
|
196
|
+
isPlayerTurn: false,
|
|
197
|
+
onSolveInvoked: false
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
...state,
|
|
202
|
+
hint: "none",
|
|
203
|
+
currentMoveIndex: state.currentMoveIndex + 1,
|
|
204
|
+
nextMove: state.puzzle.moves[state.currentMoveIndex + 1],
|
|
205
|
+
status: "in-progress",
|
|
206
|
+
needCpuMove: true,
|
|
207
|
+
isPlayerTurn: false
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
case "MARK_SOLVE_INVOKED":
|
|
211
|
+
return {
|
|
212
|
+
...state,
|
|
213
|
+
onSolveInvoked: true
|
|
214
|
+
};
|
|
215
|
+
case "MARK_FAIL_INVOKED":
|
|
216
|
+
return {
|
|
217
|
+
...state,
|
|
218
|
+
onFailInvoked: true
|
|
219
|
+
};
|
|
220
|
+
default:
|
|
221
|
+
return state;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// src/hooks/useChessPuzzle.ts
|
|
226
|
+
var import_react_chess_game2 = require("@react-chess-tools/react-chess-game");
|
|
227
|
+
var useChessPuzzle = (puzzle, onSolve, onFail) => {
|
|
228
|
+
var _a;
|
|
229
|
+
const gameContext = (0, import_react_chess_game2.useChessGameContext)();
|
|
230
|
+
const [state, dispatch] = (0, import_react2.useReducer)(reducer, { puzzle }, initializePuzzle);
|
|
231
|
+
const {
|
|
232
|
+
game,
|
|
233
|
+
methods: { makeMove, setPosition }
|
|
234
|
+
} = gameContext;
|
|
235
|
+
const changePuzzle = (0, import_react2.useCallback)(
|
|
236
|
+
(puzzle2) => {
|
|
237
|
+
setPosition(puzzle2.fen, getOrientation(puzzle2));
|
|
238
|
+
dispatch({ type: "INITIALIZE", payload: { puzzle: puzzle2 } });
|
|
239
|
+
},
|
|
240
|
+
[setPosition]
|
|
241
|
+
);
|
|
242
|
+
(0, import_react2.useEffect)(() => {
|
|
243
|
+
changePuzzle(puzzle);
|
|
244
|
+
}, [JSON.stringify(puzzle), changePuzzle]);
|
|
245
|
+
(0, import_react2.useEffect)(() => {
|
|
246
|
+
if (gameContext && game.fen() === puzzle.fen && state.needCpuMove) {
|
|
247
|
+
setTimeout(
|
|
248
|
+
() => dispatch({
|
|
249
|
+
type: "CPU_MOVE"
|
|
250
|
+
}),
|
|
251
|
+
0
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
}, [gameContext, state.needCpuMove]);
|
|
255
|
+
(0, import_react2.useEffect)(() => {
|
|
256
|
+
if (state.cpuMove) {
|
|
257
|
+
makeMove(state.cpuMove);
|
|
258
|
+
}
|
|
259
|
+
}, [state.cpuMove]);
|
|
260
|
+
if (!gameContext) {
|
|
261
|
+
throw new Error("useChessPuzzle must be used within a ChessGameContext");
|
|
262
|
+
}
|
|
263
|
+
const onHint = (0, import_react2.useCallback)(() => {
|
|
264
|
+
dispatch({ type: "TOGGLE_HINT" });
|
|
265
|
+
}, []);
|
|
266
|
+
const resetPuzzle = (0, import_react2.useCallback)(() => {
|
|
267
|
+
changePuzzle(puzzle);
|
|
268
|
+
}, [changePuzzle, puzzle]);
|
|
269
|
+
const puzzleContext = (0, import_react2.useMemo)(
|
|
270
|
+
() => ({
|
|
271
|
+
status: state.status,
|
|
272
|
+
changePuzzle,
|
|
273
|
+
resetPuzzle,
|
|
274
|
+
puzzle,
|
|
275
|
+
hint: state.hint,
|
|
276
|
+
onHint,
|
|
277
|
+
nextMove: state.nextMove,
|
|
278
|
+
isPlayerTurn: state.isPlayerTurn,
|
|
279
|
+
puzzleState: state.status,
|
|
280
|
+
movesPlayed: state.currentMoveIndex,
|
|
281
|
+
totalMoves: puzzle.moves.length
|
|
282
|
+
}),
|
|
283
|
+
[
|
|
284
|
+
state.status,
|
|
285
|
+
changePuzzle,
|
|
286
|
+
resetPuzzle,
|
|
287
|
+
puzzle,
|
|
288
|
+
state.hint,
|
|
289
|
+
onHint,
|
|
290
|
+
state.nextMove,
|
|
291
|
+
state.isPlayerTurn,
|
|
292
|
+
state.currentMoveIndex
|
|
293
|
+
]
|
|
294
|
+
);
|
|
295
|
+
(0, import_react2.useEffect)(() => {
|
|
296
|
+
var _a2, _b, _c;
|
|
297
|
+
if (((_a2 = game == null ? void 0 : game.history()) == null ? void 0 : _a2.length) <= 0 + (puzzle.makeFirstMove ? 1 : 0)) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if (game.history().length % 2 === (puzzle.makeFirstMove ? 0 : 1)) {
|
|
301
|
+
dispatch({
|
|
302
|
+
type: "PLAYER_MOVE",
|
|
303
|
+
payload: {
|
|
304
|
+
move: ((_c = (_b = gameContext == null ? void 0 : gameContext.game) == null ? void 0 : _b.history({ verbose: true })) == null ? void 0 : _c.pop()) ?? null,
|
|
305
|
+
puzzleContext,
|
|
306
|
+
game
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
dispatch({
|
|
310
|
+
type: "CPU_MOVE"
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}, [(_a = game == null ? void 0 : game.history()) == null ? void 0 : _a.length]);
|
|
314
|
+
(0, import_react2.useEffect)(() => {
|
|
315
|
+
if (state.status === "solved" && !state.onSolveInvoked && onSolve) {
|
|
316
|
+
onSolve(puzzleContext);
|
|
317
|
+
dispatch({ type: "MARK_SOLVE_INVOKED" });
|
|
318
|
+
}
|
|
319
|
+
}, [state.status, state.onSolveInvoked]);
|
|
320
|
+
(0, import_react2.useEffect)(() => {
|
|
321
|
+
if (state.status === "failed" && !state.onFailInvoked && onFail) {
|
|
322
|
+
onFail(puzzleContext);
|
|
323
|
+
dispatch({ type: "MARK_FAIL_INVOKED" });
|
|
324
|
+
}
|
|
325
|
+
}, [state.status, state.onFailInvoked]);
|
|
326
|
+
return puzzleContext;
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
// src/components/ChessPuzzle/parts/Root.tsx
|
|
330
|
+
var import_react_chess_game3 = require("@react-chess-tools/react-chess-game");
|
|
331
|
+
|
|
332
|
+
// src/hooks/useChessPuzzleContext.ts
|
|
333
|
+
var import_react3 = __toESM(require("react"), 1);
|
|
334
|
+
var ChessPuzzleContext = import_react3.default.createContext(null);
|
|
335
|
+
var useChessPuzzleContext = () => {
|
|
336
|
+
const context = import_react3.default.useContext(ChessPuzzleContext);
|
|
337
|
+
if (!context) {
|
|
338
|
+
throw new Error(
|
|
339
|
+
`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.`
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
return context;
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
// src/theme/context.tsx
|
|
346
|
+
var import_react4 = __toESM(require("react"), 1);
|
|
347
|
+
var ChessPuzzleThemeContext = (0, import_react4.createContext)(defaultPuzzleTheme);
|
|
348
|
+
var useChessPuzzleTheme = () => {
|
|
349
|
+
return (0, import_react4.useContext)(ChessPuzzleThemeContext);
|
|
350
|
+
};
|
|
351
|
+
var PuzzleThemeProvider = ({
|
|
352
|
+
theme,
|
|
353
|
+
children
|
|
354
|
+
}) => {
|
|
355
|
+
return /* @__PURE__ */ import_react4.default.createElement(ChessPuzzleThemeContext.Provider, { value: theme }, children);
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
// src/theme/utils.ts
|
|
359
|
+
var import_lodash2 = require("lodash");
|
|
360
|
+
var mergePuzzleTheme = (partialTheme) => {
|
|
361
|
+
if (!partialTheme) {
|
|
362
|
+
return { ...defaultPuzzleTheme };
|
|
363
|
+
}
|
|
364
|
+
return (0, import_lodash2.merge)({}, defaultPuzzleTheme, partialTheme);
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
// src/components/ChessPuzzle/parts/Root.tsx
|
|
368
|
+
var PuzzleRootInner = ({
|
|
369
|
+
puzzle,
|
|
370
|
+
onSolve,
|
|
371
|
+
onFail,
|
|
372
|
+
children
|
|
373
|
+
}) => {
|
|
374
|
+
const context = useChessPuzzle(puzzle, onSolve, onFail);
|
|
375
|
+
return /* @__PURE__ */ import_react5.default.createElement(ChessPuzzleContext.Provider, { value: context }, children);
|
|
376
|
+
};
|
|
377
|
+
var Root = ({
|
|
378
|
+
puzzle,
|
|
379
|
+
onSolve,
|
|
380
|
+
onFail,
|
|
381
|
+
theme,
|
|
382
|
+
children
|
|
383
|
+
}) => {
|
|
384
|
+
const mergedTheme = import_react5.default.useMemo(() => mergePuzzleTheme(theme), [theme]);
|
|
385
|
+
return /* @__PURE__ */ import_react5.default.createElement(
|
|
386
|
+
import_react_chess_game3.ChessGame.Root,
|
|
387
|
+
{
|
|
388
|
+
fen: puzzle.fen,
|
|
389
|
+
orientation: getOrientation(puzzle),
|
|
390
|
+
theme: mergedTheme
|
|
391
|
+
},
|
|
392
|
+
/* @__PURE__ */ import_react5.default.createElement(PuzzleThemeProvider, { theme: mergedTheme }, /* @__PURE__ */ import_react5.default.createElement(PuzzleRootInner, { puzzle, onSolve, onFail }, children))
|
|
393
|
+
);
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
// src/components/ChessPuzzle/parts/PuzzleBoard.tsx
|
|
397
|
+
var import_react6 = __toESM(require("react"), 1);
|
|
398
|
+
var import_react_chess_game4 = require("@react-chess-tools/react-chess-game");
|
|
399
|
+
var PuzzleBoard = ({
|
|
400
|
+
options = {},
|
|
401
|
+
...rest
|
|
402
|
+
}) => {
|
|
403
|
+
const puzzleContext = useChessPuzzleContext();
|
|
404
|
+
const gameContext = (0, import_react_chess_game4.useChessGameContext)();
|
|
405
|
+
const theme = useChessPuzzleTheme();
|
|
406
|
+
if (!puzzleContext) {
|
|
407
|
+
throw new Error("PuzzleContext not found");
|
|
408
|
+
}
|
|
409
|
+
if (!gameContext) {
|
|
410
|
+
throw new Error("ChessGameContext not found");
|
|
411
|
+
}
|
|
412
|
+
const { game } = gameContext;
|
|
413
|
+
const { status, hint, isPlayerTurn, nextMove } = puzzleContext;
|
|
414
|
+
const mergedOptions = (0, import_react_chess_game4.deepMergeChessboardOptions)(options, {
|
|
415
|
+
squareStyles: getCustomSquareStyles(
|
|
416
|
+
status,
|
|
417
|
+
hint,
|
|
418
|
+
isPlayerTurn,
|
|
419
|
+
game,
|
|
420
|
+
stringToMove(game, nextMove),
|
|
421
|
+
theme
|
|
422
|
+
)
|
|
423
|
+
});
|
|
424
|
+
return /* @__PURE__ */ import_react6.default.createElement(import_react_chess_game4.ChessGame.Board, { ...rest, options: mergedOptions });
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
// src/components/ChessPuzzle/parts/Reset.tsx
|
|
428
|
+
var import_react7 = __toESM(require("react"), 1);
|
|
429
|
+
var defaultShowOn = ["failed", "solved"];
|
|
430
|
+
var Reset = ({
|
|
431
|
+
children,
|
|
432
|
+
asChild,
|
|
433
|
+
puzzle,
|
|
434
|
+
onReset,
|
|
435
|
+
showOn = defaultShowOn
|
|
436
|
+
}) => {
|
|
437
|
+
const puzzleContext = useChessPuzzleContext();
|
|
438
|
+
if (!puzzleContext) {
|
|
439
|
+
throw new Error("PuzzleContext not found");
|
|
440
|
+
}
|
|
441
|
+
const { changePuzzle, status } = puzzleContext;
|
|
442
|
+
const handleClick = () => {
|
|
443
|
+
changePuzzle(puzzle || puzzleContext.puzzle);
|
|
444
|
+
onReset == null ? void 0 : onReset(puzzleContext);
|
|
445
|
+
};
|
|
446
|
+
if (!showOn.includes(status)) {
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
if (asChild) {
|
|
450
|
+
const child = import_react7.default.Children.only(children);
|
|
451
|
+
if (isClickableElement(child)) {
|
|
452
|
+
return import_react7.default.cloneElement(child, {
|
|
453
|
+
onClick: handleClick
|
|
454
|
+
});
|
|
455
|
+
} else {
|
|
456
|
+
throw new Error("Change child must be a clickable element");
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return /* @__PURE__ */ import_react7.default.createElement("button", { type: "button", onClick: handleClick }, children);
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
// src/components/ChessPuzzle/parts/Hint.tsx
|
|
463
|
+
var import_react8 = __toESM(require("react"), 1);
|
|
464
|
+
var defaultShowOn2 = ["not-started", "in-progress"];
|
|
465
|
+
var Hint = ({
|
|
466
|
+
children,
|
|
467
|
+
asChild,
|
|
468
|
+
showOn = defaultShowOn2
|
|
469
|
+
}) => {
|
|
470
|
+
const puzzleContext = useChessPuzzleContext();
|
|
471
|
+
if (!puzzleContext) {
|
|
472
|
+
throw new Error("PuzzleContext not found");
|
|
473
|
+
}
|
|
474
|
+
const { onHint, status } = puzzleContext;
|
|
475
|
+
const handleClick = () => {
|
|
476
|
+
onHint();
|
|
477
|
+
};
|
|
478
|
+
if (!showOn.includes(status)) {
|
|
479
|
+
return null;
|
|
480
|
+
}
|
|
481
|
+
if (asChild) {
|
|
482
|
+
const child = import_react8.default.Children.only(children);
|
|
483
|
+
if (isClickableElement(child)) {
|
|
484
|
+
return import_react8.default.cloneElement(child, {
|
|
485
|
+
onClick: handleClick
|
|
486
|
+
});
|
|
487
|
+
} else {
|
|
488
|
+
throw new Error("Change child must be a clickable element");
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return /* @__PURE__ */ import_react8.default.createElement("button", { type: "button", onClick: handleClick }, children);
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
// src/components/ChessPuzzle/index.ts
|
|
495
|
+
var ChessPuzzle = {
|
|
496
|
+
Root,
|
|
497
|
+
Board: PuzzleBoard,
|
|
498
|
+
Reset,
|
|
499
|
+
Hint
|
|
500
|
+
};
|
|
501
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
502
|
+
0 && (module.exports = {
|
|
503
|
+
ChessPuzzle,
|
|
504
|
+
ChessPuzzleThemeContext,
|
|
505
|
+
defaultPuzzleTheme,
|
|
506
|
+
mergePuzzleTheme,
|
|
507
|
+
useChessPuzzleContext,
|
|
508
|
+
useChessPuzzleTheme
|
|
509
|
+
});
|
|
510
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../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":["// Components\nexport { ChessPuzzle } from \"./components/ChessPuzzle\";\n\n// Hooks & Context\nexport { useChessPuzzleContext } from \"./hooks/useChessPuzzleContext\";\nexport type { ChessPuzzleContextType } from \"./hooks/useChessPuzzle\";\n\n// Core Types\nexport type { Status, Hint, Puzzle } from \"./utils\";\n\n// Component Props\nexport type { HintProps } from \"./components/ChessPuzzle/parts/Hint\";\nexport type { ResetProps } from \"./components/ChessPuzzle/parts/Reset\";\nexport type { PuzzleBoardProps } from \"./components/ChessPuzzle/parts/PuzzleBoard\";\nexport type { RootProps } from \"./components/ChessPuzzle/parts/Root\";\n\n// Theme - Types\nexport type {\n ChessPuzzleTheme,\n PuzzleStateTheme,\n PartialChessPuzzleTheme,\n} from \"./theme/types\";\n\n// Theme - Values\nexport { defaultPuzzleTheme } from \"./theme/defaults\";\n\n// Theme - Utilities\nexport { mergePuzzleTheme } from \"./theme/utils\";\nexport { useChessPuzzleTheme, ChessPuzzleThemeContext } from \"./theme/context\";\n","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","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\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\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.FC<PuzzleBoardProps> = ({\n options = {},\n ...rest\n}) => {\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 {...rest} options={mergedOptions} />;\n};\n","import React from \"react\";\nimport { isClickableElement, type Puzzle, type Status } from \"../../../utils\";\nimport { useChessPuzzleContext, type ChessPuzzleContextType } from \"../../..\";\n\nexport interface ResetProps {\n asChild?: boolean;\n puzzle?: Puzzle;\n onReset?: (puzzleContext: ChessPuzzleContextType) => 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?.(puzzleContext);\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":["import_react","React","_","import_react","import_react_chess_game","puzzle","_a","import_react_chess_game","import_react","React","import_react","React","import_lodash","React","import_react","import_react_chess_game","React","import_react","React","import_react","defaultShowOn","React"]}
|