@react-chess-tools/react-chess-game 0.5.2 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +399 -0
- package/dist/index.cjs +785 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +278 -0
- package/dist/index.d.ts +278 -0
- package/dist/{index.mjs → index.js} +339 -196
- package/dist/index.js.map +1 -0
- package/package.json +19 -9
- package/src/components/ChessGame/Theme.stories.tsx +242 -0
- package/src/components/ChessGame/ThemePresets.stories.tsx +144 -0
- package/src/components/ChessGame/parts/Board.tsx +215 -204
- package/src/components/ChessGame/parts/KeyboardControls.tsx +9 -0
- package/src/components/ChessGame/parts/Root.tsx +13 -1
- package/src/components/ChessGame/parts/Sounds.tsx +9 -0
- package/src/components/ChessGame/parts/__tests__/Board.test.tsx +122 -0
- package/src/components/ChessGame/parts/__tests__/KeyboardControls.test.tsx +34 -0
- package/src/components/ChessGame/parts/__tests__/Root.test.tsx +50 -0
- package/src/components/ChessGame/parts/__tests__/Sounds.test.tsx +22 -0
- package/src/docs/Theming.mdx +281 -0
- package/src/hooks/useChessGame.ts +23 -7
- package/src/index.ts +19 -0
- package/src/theme/__tests__/context.test.tsx +60 -0
- package/src/theme/__tests__/defaults.test.ts +61 -0
- package/src/theme/__tests__/utils.test.ts +106 -0
- package/src/theme/context.tsx +37 -0
- package/src/theme/defaults.ts +22 -0
- package/src/theme/index.ts +36 -0
- package/src/theme/presets.ts +41 -0
- package/src/theme/types.ts +56 -0
- package/src/theme/utils.ts +47 -0
- package/src/utils/__tests__/board.test.ts +118 -0
- package/src/utils/board.ts +18 -9
- package/src/utils/chess.ts +25 -5
- package/README.MD +0 -190
- package/coverage/clover.xml +0 -6
- package/coverage/coverage-final.json +0 -1
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -101
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov.info +0 -0
- package/dist/index.d.mts +0 -158
- package/dist/index.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/components/ChessGame/parts/Root.tsx
|
|
2
|
-
import
|
|
2
|
+
import React4 from "react";
|
|
3
3
|
|
|
4
4
|
// src/hooks/useChessGame.ts
|
|
5
5
|
import React, { useEffect } from "react";
|
|
@@ -9,9 +9,17 @@ import { Chess as Chess2 } from "chess.js";
|
|
|
9
9
|
import { Chess } from "chess.js";
|
|
10
10
|
import _ from "lodash";
|
|
11
11
|
var cloneGame = (game) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
try {
|
|
13
|
+
const copy = new Chess();
|
|
14
|
+
const pgn = game == null ? void 0 : game.pgn();
|
|
15
|
+
if (pgn) {
|
|
16
|
+
copy.loadPgn(pgn);
|
|
17
|
+
}
|
|
18
|
+
return copy;
|
|
19
|
+
} catch (e) {
|
|
20
|
+
console.error("Failed to clone game:", e);
|
|
21
|
+
return new Chess();
|
|
22
|
+
}
|
|
15
23
|
};
|
|
16
24
|
var getGameInfo = (game, orientation) => {
|
|
17
25
|
const turn = game.turn();
|
|
@@ -57,6 +65,9 @@ var isLegalMove = (game, move) => {
|
|
|
57
65
|
}
|
|
58
66
|
};
|
|
59
67
|
var requiresPromotion = (game, move) => {
|
|
68
|
+
if (!game) {
|
|
69
|
+
throw new Error("Game is required");
|
|
70
|
+
}
|
|
60
71
|
try {
|
|
61
72
|
const copy = cloneGame(game);
|
|
62
73
|
const result = copy.move(move);
|
|
@@ -76,12 +87,20 @@ var getCurrentFen = (fen, game, currentMoveIndex) => {
|
|
|
76
87
|
const tempGame = new Chess();
|
|
77
88
|
if (currentMoveIndex === -1) {
|
|
78
89
|
if (fen) {
|
|
79
|
-
|
|
90
|
+
try {
|
|
91
|
+
tempGame.load(fen);
|
|
92
|
+
} catch (e) {
|
|
93
|
+
console.error("Failed to load FEN in getCurrentFen:", fen, e);
|
|
94
|
+
}
|
|
80
95
|
}
|
|
81
96
|
} else {
|
|
82
97
|
const moves = game.history().slice(0, currentMoveIndex + 1);
|
|
83
98
|
if (fen) {
|
|
84
|
-
|
|
99
|
+
try {
|
|
100
|
+
tempGame.load(fen);
|
|
101
|
+
} catch (e) {
|
|
102
|
+
console.error("Failed to load FEN in getCurrentFen:", fen, e);
|
|
103
|
+
}
|
|
85
104
|
}
|
|
86
105
|
moves.forEach((move) => tempGame.move(move));
|
|
87
106
|
}
|
|
@@ -93,9 +112,21 @@ var useChessGame = ({
|
|
|
93
112
|
fen,
|
|
94
113
|
orientation: initialOrientation
|
|
95
114
|
} = {}) => {
|
|
96
|
-
const [game, setGame] = React.useState(
|
|
115
|
+
const [game, setGame] = React.useState(() => {
|
|
116
|
+
try {
|
|
117
|
+
return new Chess2(fen);
|
|
118
|
+
} catch (e) {
|
|
119
|
+
console.error("Invalid FEN:", fen, e);
|
|
120
|
+
return new Chess2();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
97
123
|
useEffect(() => {
|
|
98
|
-
|
|
124
|
+
try {
|
|
125
|
+
setGame(new Chess2(fen));
|
|
126
|
+
} catch (e) {
|
|
127
|
+
console.error("Invalid FEN:", fen, e);
|
|
128
|
+
setGame(new Chess2());
|
|
129
|
+
}
|
|
99
130
|
}, [fen]);
|
|
100
131
|
const [orientation, setOrientation] = React.useState(
|
|
101
132
|
initialOrientation ?? "w"
|
|
@@ -119,11 +150,15 @@ var useChessGame = ({
|
|
|
119
150
|
[game, currentMoveIndex]
|
|
120
151
|
);
|
|
121
152
|
const setPosition = React.useCallback((fen2, orientation2) => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
153
|
+
try {
|
|
154
|
+
const newGame = new Chess2();
|
|
155
|
+
newGame.load(fen2);
|
|
156
|
+
setOrientation(orientation2);
|
|
157
|
+
setGame(newGame);
|
|
158
|
+
setCurrentMoveIndex(-1);
|
|
159
|
+
} catch (e) {
|
|
160
|
+
console.error("Failed to load FEN:", fen2, e);
|
|
161
|
+
}
|
|
127
162
|
}, []);
|
|
128
163
|
const makeMove = React.useCallback(
|
|
129
164
|
(move) => {
|
|
@@ -212,18 +247,69 @@ var useChessGameContext = () => {
|
|
|
212
247
|
return context;
|
|
213
248
|
};
|
|
214
249
|
|
|
250
|
+
// src/theme/context.tsx
|
|
251
|
+
import React3, { createContext, useContext } from "react";
|
|
252
|
+
|
|
253
|
+
// src/theme/defaults.ts
|
|
254
|
+
var defaultGameTheme = {
|
|
255
|
+
board: {
|
|
256
|
+
lightSquare: { backgroundColor: "#f0d9b5" },
|
|
257
|
+
darkSquare: { backgroundColor: "#b58863" }
|
|
258
|
+
},
|
|
259
|
+
state: {
|
|
260
|
+
lastMove: "rgba(255, 255, 0, 0.5)",
|
|
261
|
+
check: "rgba(255, 0, 0, 0.5)",
|
|
262
|
+
activeSquare: "rgba(255, 255, 0, 0.5)",
|
|
263
|
+
dropSquare: { backgroundColor: "rgba(255, 255, 0, 0.4)" }
|
|
264
|
+
},
|
|
265
|
+
indicators: {
|
|
266
|
+
move: "rgba(0, 0, 0, 0.1)",
|
|
267
|
+
capture: "rgba(1, 0, 0, 0.1)"
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
// src/theme/context.tsx
|
|
272
|
+
var ChessGameThemeContext = createContext(defaultGameTheme);
|
|
273
|
+
var useChessGameTheme = () => {
|
|
274
|
+
return useContext(ChessGameThemeContext);
|
|
275
|
+
};
|
|
276
|
+
var ThemeProvider = ({
|
|
277
|
+
theme,
|
|
278
|
+
children
|
|
279
|
+
}) => {
|
|
280
|
+
return /* @__PURE__ */ React3.createElement(ChessGameThemeContext.Provider, { value: theme }, children);
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
// src/theme/utils.ts
|
|
284
|
+
import { merge } from "lodash";
|
|
285
|
+
var mergeTheme = (partialTheme) => {
|
|
286
|
+
if (!partialTheme) {
|
|
287
|
+
return { ...defaultGameTheme };
|
|
288
|
+
}
|
|
289
|
+
return merge({}, defaultGameTheme, partialTheme);
|
|
290
|
+
};
|
|
291
|
+
var mergeThemeWith = (baseTheme, partialTheme) => {
|
|
292
|
+
if (!partialTheme) {
|
|
293
|
+
return { ...baseTheme };
|
|
294
|
+
}
|
|
295
|
+
return merge({}, baseTheme, partialTheme);
|
|
296
|
+
};
|
|
297
|
+
|
|
215
298
|
// src/components/ChessGame/parts/Root.tsx
|
|
216
299
|
var Root = ({
|
|
217
300
|
fen,
|
|
218
301
|
orientation,
|
|
302
|
+
theme,
|
|
219
303
|
children
|
|
220
304
|
}) => {
|
|
221
305
|
const context = useChessGame({ fen, orientation });
|
|
222
|
-
|
|
306
|
+
const mergedTheme = React4.useMemo(() => mergeTheme(theme), [theme]);
|
|
307
|
+
return /* @__PURE__ */ React4.createElement(ChessGameContext.Provider, { value: context }, /* @__PURE__ */ React4.createElement(ThemeProvider, { theme: mergedTheme }, children));
|
|
223
308
|
};
|
|
309
|
+
Root.displayName = "ChessGame.Root";
|
|
224
310
|
|
|
225
311
|
// src/components/ChessGame/parts/Board.tsx
|
|
226
|
-
import
|
|
312
|
+
import React5 from "react";
|
|
227
313
|
import {
|
|
228
314
|
Chessboard,
|
|
229
315
|
defaultPieces,
|
|
@@ -231,23 +317,21 @@ import {
|
|
|
231
317
|
} from "react-chessboard";
|
|
232
318
|
|
|
233
319
|
// src/utils/board.ts
|
|
234
|
-
import { merge } from "lodash";
|
|
235
|
-
var
|
|
236
|
-
var CHECK_COLOR = "rgba(255, 0, 0, 0.5)";
|
|
237
|
-
var getCustomSquareStyles = (game, info, activeSquare) => {
|
|
320
|
+
import { merge as merge2 } from "lodash";
|
|
321
|
+
var getCustomSquareStyles = (game, info, activeSquare, theme = defaultGameTheme) => {
|
|
238
322
|
const customSquareStyles = {};
|
|
239
323
|
const { lastMove, isCheck, turn } = info;
|
|
240
324
|
if (lastMove) {
|
|
241
325
|
customSquareStyles[lastMove.from] = {
|
|
242
|
-
backgroundColor:
|
|
326
|
+
backgroundColor: theme.state.lastMove
|
|
243
327
|
};
|
|
244
328
|
customSquareStyles[lastMove.to] = {
|
|
245
|
-
backgroundColor:
|
|
329
|
+
backgroundColor: theme.state.lastMove
|
|
246
330
|
};
|
|
247
331
|
}
|
|
248
332
|
if (activeSquare) {
|
|
249
333
|
customSquareStyles[activeSquare] = {
|
|
250
|
-
backgroundColor:
|
|
334
|
+
backgroundColor: theme.state.activeSquare
|
|
251
335
|
};
|
|
252
336
|
}
|
|
253
337
|
if (activeSquare) {
|
|
@@ -255,7 +339,7 @@ var getCustomSquareStyles = (game, info, activeSquare) => {
|
|
|
255
339
|
destinationSquares.forEach((square) => {
|
|
256
340
|
var _a;
|
|
257
341
|
customSquareStyles[square] = {
|
|
258
|
-
background: game.get(square) && ((_a = game.get(square)) == null ? void 0 : _a.color) !== turn ?
|
|
342
|
+
background: game.get(square) && ((_a = game.get(square)) == null ? void 0 : _a.color) !== turn ? `radial-gradient(circle, ${theme.indicators.capture} 85%, transparent 85%)` : `radial-gradient(circle, ${theme.indicators.move} 25%, transparent 25%)`
|
|
259
343
|
};
|
|
260
344
|
});
|
|
261
345
|
}
|
|
@@ -264,7 +348,7 @@ var getCustomSquareStyles = (game, info, activeSquare) => {
|
|
|
264
348
|
return row.forEach((square) => {
|
|
265
349
|
if ((square == null ? void 0 : square.type) === "k" && (square == null ? void 0 : square.color) === info.turn) {
|
|
266
350
|
customSquareStyles[square.square] = {
|
|
267
|
-
backgroundColor:
|
|
351
|
+
backgroundColor: theme.state.check
|
|
268
352
|
};
|
|
269
353
|
}
|
|
270
354
|
});
|
|
@@ -276,7 +360,7 @@ var deepMergeChessboardOptions = (baseOptions, customOptions) => {
|
|
|
276
360
|
if (!customOptions) {
|
|
277
361
|
return { ...baseOptions };
|
|
278
362
|
}
|
|
279
|
-
const result =
|
|
363
|
+
const result = merge2({}, baseOptions, customOptions, {
|
|
280
364
|
customizer: (_objValue, srcValue) => {
|
|
281
365
|
if (typeof srcValue === "function") {
|
|
282
366
|
return srcValue;
|
|
@@ -292,191 +376,199 @@ var deepMergeChessboardOptions = (baseOptions, customOptions) => {
|
|
|
292
376
|
};
|
|
293
377
|
|
|
294
378
|
// src/components/ChessGame/parts/Board.tsx
|
|
295
|
-
var Board = (
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
game,
|
|
303
|
-
currentFen,
|
|
304
|
-
orientation,
|
|
305
|
-
info,
|
|
306
|
-
isLatestMove,
|
|
307
|
-
methods: { makeMove }
|
|
308
|
-
} = gameContext;
|
|
309
|
-
const { turn, isGameOver } = info;
|
|
310
|
-
const [activeSquare, setActiveSquare] = React4.useState(null);
|
|
311
|
-
const [promotionMove, setPromotionMove] = React4.useState(null);
|
|
312
|
-
const onSquareClick = (square) => {
|
|
313
|
-
if (isGameOver) {
|
|
314
|
-
return;
|
|
379
|
+
var Board = React5.forwardRef(
|
|
380
|
+
({ options = {}, className, style: userStyle, ...rest }, ref) => {
|
|
381
|
+
var _a, _b, _c;
|
|
382
|
+
const gameContext = useChessGameContext();
|
|
383
|
+
const theme = useChessGameTheme();
|
|
384
|
+
if (!gameContext) {
|
|
385
|
+
throw new Error("ChessGameContext not found");
|
|
315
386
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
387
|
+
const {
|
|
388
|
+
game,
|
|
389
|
+
currentFen,
|
|
390
|
+
orientation,
|
|
391
|
+
info,
|
|
392
|
+
isLatestMove,
|
|
393
|
+
methods: { makeMove }
|
|
394
|
+
} = gameContext;
|
|
395
|
+
const { turn, isGameOver } = info;
|
|
396
|
+
const [activeSquare, setActiveSquare] = React5.useState(null);
|
|
397
|
+
const [promotionMove, setPromotionMove] = React5.useState(null);
|
|
398
|
+
const onSquareClick = (square) => {
|
|
399
|
+
if (isGameOver) {
|
|
400
|
+
return;
|
|
320
401
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
}
|
|
330
|
-
if (requiresPromotion(game, {
|
|
331
|
-
from: activeSquare,
|
|
332
|
-
to: square,
|
|
333
|
-
promotion: "q"
|
|
334
|
-
})) {
|
|
335
|
-
return setPromotionMove({
|
|
402
|
+
if (activeSquare === null) {
|
|
403
|
+
const squadreInfo = game.get(square);
|
|
404
|
+
if (squadreInfo && squadreInfo.color === turn) {
|
|
405
|
+
return setActiveSquare(square);
|
|
406
|
+
}
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
if (!isLegalMove(game, {
|
|
336
410
|
from: activeSquare,
|
|
337
|
-
to: square
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
411
|
+
to: square,
|
|
412
|
+
promotion: "q"
|
|
413
|
+
})) {
|
|
414
|
+
return setActiveSquare(null);
|
|
415
|
+
}
|
|
416
|
+
if (requiresPromotion(game, {
|
|
417
|
+
from: activeSquare,
|
|
418
|
+
to: square,
|
|
419
|
+
promotion: "q"
|
|
420
|
+
})) {
|
|
421
|
+
return setPromotionMove({
|
|
422
|
+
from: activeSquare,
|
|
423
|
+
to: square
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
setActiveSquare(null);
|
|
348
427
|
makeMove({
|
|
349
|
-
from:
|
|
350
|
-
to:
|
|
351
|
-
promotion: piece.toLowerCase()
|
|
428
|
+
from: activeSquare,
|
|
429
|
+
to: square
|
|
352
430
|
});
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
if (typeof document === "undefined") return 80;
|
|
363
|
-
const squareElement = document.querySelector(`[data-square]`);
|
|
364
|
-
return ((_a2 = squareElement == null ? void 0 : squareElement.getBoundingClientRect()) == null ? void 0 : _a2.width) ?? 80;
|
|
365
|
-
}, [promotionMove]);
|
|
366
|
-
const promotionSquareLeft = React4.useMemo(() => {
|
|
367
|
-
var _a2;
|
|
368
|
-
if (!(promotionMove == null ? void 0 : promotionMove.to)) return 0;
|
|
369
|
-
const column = ((_a2 = promotionMove.to.match(/^[a-h]/)) == null ? void 0 : _a2[0]) ?? "a";
|
|
370
|
-
return squareWidth * chessColumnToColumnIndex(
|
|
371
|
-
column,
|
|
372
|
-
8,
|
|
373
|
-
orientation === "b" ? "black" : "white"
|
|
374
|
-
);
|
|
375
|
-
}, [promotionMove, squareWidth, orientation]);
|
|
376
|
-
const baseOptions = {
|
|
377
|
-
squareStyles: getCustomSquareStyles(game, info, activeSquare),
|
|
378
|
-
boardOrientation: orientation === "b" ? "black" : "white",
|
|
379
|
-
position: currentFen,
|
|
380
|
-
showNotation: true,
|
|
381
|
-
showAnimations: isLatestMove,
|
|
382
|
-
canDragPiece: ({ piece }) => {
|
|
383
|
-
if (isGameOver) return false;
|
|
384
|
-
return piece.pieceType[0] === turn;
|
|
385
|
-
},
|
|
386
|
-
dropSquareStyle: {
|
|
387
|
-
backgroundColor: "rgba(255, 255, 0, 0.4)"
|
|
388
|
-
},
|
|
389
|
-
onPieceDrag: ({ piece, square }) => {
|
|
390
|
-
if (piece.pieceType[0] === turn) {
|
|
391
|
-
setActiveSquare(square);
|
|
431
|
+
};
|
|
432
|
+
const onPromotionPieceSelect = (piece) => {
|
|
433
|
+
if ((promotionMove == null ? void 0 : promotionMove.from) && (promotionMove == null ? void 0 : promotionMove.to)) {
|
|
434
|
+
makeMove({
|
|
435
|
+
from: promotionMove.from,
|
|
436
|
+
to: promotionMove.to,
|
|
437
|
+
promotion: piece.toLowerCase()
|
|
438
|
+
});
|
|
439
|
+
setPromotionMove(null);
|
|
392
440
|
}
|
|
393
|
-
}
|
|
394
|
-
|
|
441
|
+
};
|
|
442
|
+
const onSquareRightClick = () => {
|
|
395
443
|
setActiveSquare(null);
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
if (
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
444
|
+
setPromotionMove(null);
|
|
445
|
+
};
|
|
446
|
+
const squareWidth = React5.useMemo(() => {
|
|
447
|
+
var _a2;
|
|
448
|
+
if (typeof document === "undefined") return 80;
|
|
449
|
+
const squareElement = document.querySelector(`[data-square]`);
|
|
450
|
+
return ((_a2 = squareElement == null ? void 0 : squareElement.getBoundingClientRect()) == null ? void 0 : _a2.width) ?? 80;
|
|
451
|
+
}, [promotionMove]);
|
|
452
|
+
const promotionSquareLeft = React5.useMemo(() => {
|
|
453
|
+
var _a2;
|
|
454
|
+
if (!(promotionMove == null ? void 0 : promotionMove.to)) return 0;
|
|
455
|
+
const column = ((_a2 = promotionMove.to.match(/^[a-h]/)) == null ? void 0 : _a2[0]) ?? "a";
|
|
456
|
+
return squareWidth * chessColumnToColumnIndex(
|
|
457
|
+
column,
|
|
458
|
+
8,
|
|
459
|
+
orientation === "b" ? "black" : "white"
|
|
460
|
+
);
|
|
461
|
+
}, [promotionMove, squareWidth, orientation]);
|
|
462
|
+
const baseOptions = {
|
|
463
|
+
squareStyles: getCustomSquareStyles(game, info, activeSquare, theme),
|
|
464
|
+
boardOrientation: orientation === "b" ? "black" : "white",
|
|
465
|
+
position: currentFen,
|
|
466
|
+
showNotation: true,
|
|
467
|
+
showAnimations: isLatestMove,
|
|
468
|
+
lightSquareStyle: theme.board.lightSquare,
|
|
469
|
+
darkSquareStyle: theme.board.darkSquare,
|
|
470
|
+
canDragPiece: ({ piece }) => {
|
|
471
|
+
if (isGameOver) return false;
|
|
472
|
+
return piece.pieceType[0] === turn;
|
|
423
473
|
},
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
474
|
+
dropSquareStyle: theme.state.dropSquare,
|
|
475
|
+
onPieceDrag: ({ piece, square }) => {
|
|
476
|
+
if (piece.pieceType[0] === turn) {
|
|
477
|
+
setActiveSquare(square);
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
onPieceDrop: ({ sourceSquare, targetSquare }) => {
|
|
481
|
+
setActiveSquare(null);
|
|
482
|
+
const moveData = {
|
|
483
|
+
from: sourceSquare,
|
|
484
|
+
to: targetSquare
|
|
485
|
+
};
|
|
486
|
+
if (requiresPromotion(game, { ...moveData, promotion: "q" })) {
|
|
487
|
+
setPromotionMove(moveData);
|
|
488
|
+
return false;
|
|
489
|
+
}
|
|
490
|
+
return makeMove(moveData);
|
|
491
|
+
},
|
|
492
|
+
onSquareClick: ({ square }) => {
|
|
493
|
+
if (square.match(/^[a-h][1-8]$/)) {
|
|
494
|
+
onSquareClick(square);
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
onSquareRightClick,
|
|
498
|
+
allowDrawingArrows: true,
|
|
499
|
+
animationDurationInMs: game.history().length === 0 ? 0 : 300
|
|
500
|
+
};
|
|
501
|
+
const mergedOptions = deepMergeChessboardOptions(baseOptions, options);
|
|
502
|
+
const mergedStyle = {
|
|
503
|
+
...userStyle,
|
|
504
|
+
position: "relative"
|
|
505
|
+
};
|
|
506
|
+
return /* @__PURE__ */ React5.createElement("div", { ref, className, style: mergedStyle, ...rest }, /* @__PURE__ */ React5.createElement(Chessboard, { options: mergedOptions }), promotionMove && /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(
|
|
507
|
+
"div",
|
|
452
508
|
{
|
|
453
|
-
|
|
454
|
-
onClick: () => onPromotionPieceSelect(piece),
|
|
509
|
+
onClick: () => setPromotionMove(null),
|
|
455
510
|
onContextMenu: (e) => {
|
|
456
511
|
e.preventDefault();
|
|
512
|
+
setPromotionMove(null);
|
|
457
513
|
},
|
|
458
514
|
style: {
|
|
459
|
-
|
|
460
|
-
|
|
515
|
+
position: "absolute",
|
|
516
|
+
top: 0,
|
|
517
|
+
left: 0,
|
|
518
|
+
right: 0,
|
|
519
|
+
bottom: 0,
|
|
520
|
+
backgroundColor: "rgba(0, 0, 0, 0.1)",
|
|
521
|
+
zIndex: 1e3
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
), /* @__PURE__ */ React5.createElement(
|
|
525
|
+
"div",
|
|
526
|
+
{
|
|
527
|
+
style: {
|
|
528
|
+
position: "absolute",
|
|
529
|
+
top: ((_b = (_a = promotionMove.to) == null ? void 0 : _a[1]) == null ? void 0 : _b.includes("8")) ? 0 : "auto",
|
|
530
|
+
bottom: ((_c = promotionMove.to) == null ? void 0 : _c[1].includes("1")) ? 0 : "auto",
|
|
531
|
+
left: promotionSquareLeft,
|
|
532
|
+
backgroundColor: "white",
|
|
533
|
+
width: squareWidth,
|
|
534
|
+
zIndex: 1001,
|
|
461
535
|
display: "flex",
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
padding: 0,
|
|
465
|
-
border: "none",
|
|
466
|
-
cursor: "pointer",
|
|
467
|
-
backgroundColor: "white"
|
|
468
|
-
},
|
|
469
|
-
onMouseEnter: (e) => {
|
|
470
|
-
e.currentTarget.style.backgroundColor = "#f0f0f0";
|
|
471
|
-
},
|
|
472
|
-
onMouseLeave: (e) => {
|
|
473
|
-
e.currentTarget.style.backgroundColor = "white";
|
|
536
|
+
flexDirection: "column",
|
|
537
|
+
boxShadow: "0 0 10px 0 rgba(0, 0, 0, 0.5)"
|
|
474
538
|
}
|
|
475
539
|
},
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
540
|
+
["q", "r", "n", "b"].map((piece) => /* @__PURE__ */ React5.createElement(
|
|
541
|
+
"button",
|
|
542
|
+
{
|
|
543
|
+
key: piece,
|
|
544
|
+
onClick: () => onPromotionPieceSelect(piece),
|
|
545
|
+
onContextMenu: (e) => {
|
|
546
|
+
e.preventDefault();
|
|
547
|
+
},
|
|
548
|
+
style: {
|
|
549
|
+
width: "100%",
|
|
550
|
+
aspectRatio: "1",
|
|
551
|
+
display: "flex",
|
|
552
|
+
alignItems: "center",
|
|
553
|
+
justifyContent: "center",
|
|
554
|
+
padding: 0,
|
|
555
|
+
border: "none",
|
|
556
|
+
cursor: "pointer",
|
|
557
|
+
backgroundColor: "white"
|
|
558
|
+
},
|
|
559
|
+
onMouseEnter: (e) => {
|
|
560
|
+
e.currentTarget.style.backgroundColor = "#f0f0f0";
|
|
561
|
+
},
|
|
562
|
+
onMouseLeave: (e) => {
|
|
563
|
+
e.currentTarget.style.backgroundColor = "white";
|
|
564
|
+
}
|
|
565
|
+
},
|
|
566
|
+
defaultPieces[`${turn}${piece.toUpperCase()}`]()
|
|
567
|
+
))
|
|
568
|
+
)));
|
|
569
|
+
}
|
|
570
|
+
);
|
|
571
|
+
Board.displayName = "ChessGame.Board";
|
|
480
572
|
|
|
481
573
|
// src/components/ChessGame/parts/Sounds.tsx
|
|
482
574
|
import { useMemo } from "react";
|
|
@@ -538,6 +630,7 @@ var Sounds = ({ sounds }) => {
|
|
|
538
630
|
useBoardSounds(customSoundsAudios);
|
|
539
631
|
return null;
|
|
540
632
|
};
|
|
633
|
+
Sounds.displayName = "ChessGame.Sounds";
|
|
541
634
|
|
|
542
635
|
// src/hooks/useKeyboardControls.ts
|
|
543
636
|
import { useEffect as useEffect3 } from "react";
|
|
@@ -581,6 +674,7 @@ var KeyboardControls2 = ({
|
|
|
581
674
|
useKeyboardControls(keyboardControls);
|
|
582
675
|
return null;
|
|
583
676
|
};
|
|
677
|
+
KeyboardControls2.displayName = "ChessGame.KeyboardControls";
|
|
584
678
|
|
|
585
679
|
// src/components/ChessGame/index.ts
|
|
586
680
|
var ChessGame = {
|
|
@@ -589,10 +683,59 @@ var ChessGame = {
|
|
|
589
683
|
Sounds,
|
|
590
684
|
KeyboardControls: KeyboardControls2
|
|
591
685
|
};
|
|
686
|
+
|
|
687
|
+
// src/theme/presets.ts
|
|
688
|
+
var lichessTheme = {
|
|
689
|
+
board: {
|
|
690
|
+
lightSquare: { backgroundColor: "#f0d9b5" },
|
|
691
|
+
darkSquare: { backgroundColor: "#b58863" }
|
|
692
|
+
},
|
|
693
|
+
state: {
|
|
694
|
+
lastMove: "rgba(155, 199, 0, 0.41)",
|
|
695
|
+
check: "rgba(255, 0, 0, 0.5)",
|
|
696
|
+
activeSquare: "rgba(20, 85, 30, 0.5)",
|
|
697
|
+
dropSquare: { backgroundColor: "rgba(20, 85, 30, 0.3)" }
|
|
698
|
+
},
|
|
699
|
+
indicators: {
|
|
700
|
+
move: "rgba(20, 85, 30, 0.3)",
|
|
701
|
+
capture: "rgba(20, 85, 30, 0.3)"
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
var chessComTheme = {
|
|
705
|
+
board: {
|
|
706
|
+
lightSquare: { backgroundColor: "#ebecd0" },
|
|
707
|
+
darkSquare: { backgroundColor: "#779556" }
|
|
708
|
+
},
|
|
709
|
+
state: {
|
|
710
|
+
lastMove: "rgba(255, 255, 0, 0.5)",
|
|
711
|
+
check: "rgba(255, 0, 0, 0.7)",
|
|
712
|
+
activeSquare: "rgba(255, 255, 0, 0.5)",
|
|
713
|
+
dropSquare: { backgroundColor: "rgba(255, 255, 0, 0.4)" }
|
|
714
|
+
},
|
|
715
|
+
indicators: {
|
|
716
|
+
move: "rgba(0, 0, 0, 0.1)",
|
|
717
|
+
capture: "rgba(0, 0, 0, 0.1)"
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
// src/theme/index.ts
|
|
722
|
+
var themes = {
|
|
723
|
+
default: defaultGameTheme,
|
|
724
|
+
lichess: lichessTheme,
|
|
725
|
+
chessCom: chessComTheme
|
|
726
|
+
};
|
|
592
727
|
export {
|
|
593
728
|
ChessGame,
|
|
729
|
+
ChessGameThemeContext,
|
|
730
|
+
chessComTheme,
|
|
594
731
|
deepMergeChessboardOptions,
|
|
732
|
+
defaultGameTheme,
|
|
733
|
+
lichessTheme,
|
|
734
|
+
mergeTheme,
|
|
735
|
+
mergeThemeWith,
|
|
736
|
+
themes,
|
|
595
737
|
useChessGame,
|
|
596
|
-
useChessGameContext
|
|
738
|
+
useChessGameContext,
|
|
739
|
+
useChessGameTheme
|
|
597
740
|
};
|
|
598
|
-
//# sourceMappingURL=index.
|
|
741
|
+
//# sourceMappingURL=index.js.map
|