@react-chess-tools/react-chess-game 1.0.0 → 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 +6 -0
- package/README.md +399 -0
- package/dist/index.cjs +180 -170
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -3
- package/dist/index.d.ts +17 -3
- package/dist/index.js +180 -170
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/components/ChessGame/Theme.stories.tsx +2 -2
- package/src/components/ChessGame/parts/Board.tsx +214 -205
- package/src/components/ChessGame/parts/KeyboardControls.tsx +9 -0
- package/src/components/ChessGame/parts/Root.tsx +2 -0
- 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/theme/__tests__/context.test.tsx +0 -15
- package/README.MD +0 -190
package/dist/index.cjs
CHANGED
|
@@ -353,6 +353,7 @@ var Root = ({
|
|
|
353
353
|
const mergedTheme = import_react4.default.useMemo(() => mergeTheme(theme), [theme]);
|
|
354
354
|
return /* @__PURE__ */ import_react4.default.createElement(ChessGameContext.Provider, { value: context }, /* @__PURE__ */ import_react4.default.createElement(ThemeProvider, { theme: mergedTheme }, children));
|
|
355
355
|
};
|
|
356
|
+
Root.displayName = "ChessGame.Root";
|
|
356
357
|
|
|
357
358
|
// src/components/ChessGame/parts/Board.tsx
|
|
358
359
|
var import_react5 = __toESM(require("react"), 1);
|
|
@@ -418,192 +419,199 @@ var deepMergeChessboardOptions = (baseOptions, customOptions) => {
|
|
|
418
419
|
};
|
|
419
420
|
|
|
420
421
|
// src/components/ChessGame/parts/Board.tsx
|
|
421
|
-
var Board = (
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
const {
|
|
429
|
-
game,
|
|
430
|
-
currentFen,
|
|
431
|
-
orientation,
|
|
432
|
-
info,
|
|
433
|
-
isLatestMove,
|
|
434
|
-
methods: { makeMove }
|
|
435
|
-
} = gameContext;
|
|
436
|
-
const { turn, isGameOver } = info;
|
|
437
|
-
const [activeSquare, setActiveSquare] = import_react5.default.useState(null);
|
|
438
|
-
const [promotionMove, setPromotionMove] = import_react5.default.useState(null);
|
|
439
|
-
const onSquareClick = (square) => {
|
|
440
|
-
if (isGameOver) {
|
|
441
|
-
return;
|
|
422
|
+
var Board = import_react5.default.forwardRef(
|
|
423
|
+
({ options = {}, className, style: userStyle, ...rest }, ref) => {
|
|
424
|
+
var _a, _b, _c;
|
|
425
|
+
const gameContext = useChessGameContext();
|
|
426
|
+
const theme = useChessGameTheme();
|
|
427
|
+
if (!gameContext) {
|
|
428
|
+
throw new Error("ChessGameContext not found");
|
|
442
429
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
430
|
+
const {
|
|
431
|
+
game,
|
|
432
|
+
currentFen,
|
|
433
|
+
orientation,
|
|
434
|
+
info,
|
|
435
|
+
isLatestMove,
|
|
436
|
+
methods: { makeMove }
|
|
437
|
+
} = gameContext;
|
|
438
|
+
const { turn, isGameOver } = info;
|
|
439
|
+
const [activeSquare, setActiveSquare] = import_react5.default.useState(null);
|
|
440
|
+
const [promotionMove, setPromotionMove] = import_react5.default.useState(null);
|
|
441
|
+
const onSquareClick = (square) => {
|
|
442
|
+
if (isGameOver) {
|
|
443
|
+
return;
|
|
447
444
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
}
|
|
457
|
-
if (requiresPromotion(game, {
|
|
458
|
-
from: activeSquare,
|
|
459
|
-
to: square,
|
|
460
|
-
promotion: "q"
|
|
461
|
-
})) {
|
|
462
|
-
return setPromotionMove({
|
|
445
|
+
if (activeSquare === null) {
|
|
446
|
+
const squadreInfo = game.get(square);
|
|
447
|
+
if (squadreInfo && squadreInfo.color === turn) {
|
|
448
|
+
return setActiveSquare(square);
|
|
449
|
+
}
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
if (!isLegalMove(game, {
|
|
463
453
|
from: activeSquare,
|
|
464
|
-
to: square
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
454
|
+
to: square,
|
|
455
|
+
promotion: "q"
|
|
456
|
+
})) {
|
|
457
|
+
return setActiveSquare(null);
|
|
458
|
+
}
|
|
459
|
+
if (requiresPromotion(game, {
|
|
460
|
+
from: activeSquare,
|
|
461
|
+
to: square,
|
|
462
|
+
promotion: "q"
|
|
463
|
+
})) {
|
|
464
|
+
return setPromotionMove({
|
|
465
|
+
from: activeSquare,
|
|
466
|
+
to: square
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
setActiveSquare(null);
|
|
475
470
|
makeMove({
|
|
476
|
-
from:
|
|
477
|
-
to:
|
|
478
|
-
promotion: piece.toLowerCase()
|
|
471
|
+
from: activeSquare,
|
|
472
|
+
to: square
|
|
479
473
|
});
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
if (typeof document === "undefined") return 80;
|
|
490
|
-
const squareElement = document.querySelector(`[data-square]`);
|
|
491
|
-
return ((_a2 = squareElement == null ? void 0 : squareElement.getBoundingClientRect()) == null ? void 0 : _a2.width) ?? 80;
|
|
492
|
-
}, [promotionMove]);
|
|
493
|
-
const promotionSquareLeft = import_react5.default.useMemo(() => {
|
|
494
|
-
var _a2;
|
|
495
|
-
if (!(promotionMove == null ? void 0 : promotionMove.to)) return 0;
|
|
496
|
-
const column = ((_a2 = promotionMove.to.match(/^[a-h]/)) == null ? void 0 : _a2[0]) ?? "a";
|
|
497
|
-
return squareWidth * (0, import_react_chessboard.chessColumnToColumnIndex)(
|
|
498
|
-
column,
|
|
499
|
-
8,
|
|
500
|
-
orientation === "b" ? "black" : "white"
|
|
501
|
-
);
|
|
502
|
-
}, [promotionMove, squareWidth, orientation]);
|
|
503
|
-
const baseOptions = {
|
|
504
|
-
squareStyles: getCustomSquareStyles(game, info, activeSquare, theme),
|
|
505
|
-
boardOrientation: orientation === "b" ? "black" : "white",
|
|
506
|
-
position: currentFen,
|
|
507
|
-
showNotation: true,
|
|
508
|
-
showAnimations: isLatestMove,
|
|
509
|
-
lightSquareStyle: theme.board.lightSquare,
|
|
510
|
-
darkSquareStyle: theme.board.darkSquare,
|
|
511
|
-
canDragPiece: ({ piece }) => {
|
|
512
|
-
if (isGameOver) return false;
|
|
513
|
-
return piece.pieceType[0] === turn;
|
|
514
|
-
},
|
|
515
|
-
dropSquareStyle: theme.state.dropSquare,
|
|
516
|
-
onPieceDrag: ({ piece, square }) => {
|
|
517
|
-
if (piece.pieceType[0] === turn) {
|
|
518
|
-
setActiveSquare(square);
|
|
474
|
+
};
|
|
475
|
+
const onPromotionPieceSelect = (piece) => {
|
|
476
|
+
if ((promotionMove == null ? void 0 : promotionMove.from) && (promotionMove == null ? void 0 : promotionMove.to)) {
|
|
477
|
+
makeMove({
|
|
478
|
+
from: promotionMove.from,
|
|
479
|
+
to: promotionMove.to,
|
|
480
|
+
promotion: piece.toLowerCase()
|
|
481
|
+
});
|
|
482
|
+
setPromotionMove(null);
|
|
519
483
|
}
|
|
520
|
-
}
|
|
521
|
-
|
|
484
|
+
};
|
|
485
|
+
const onSquareRightClick = () => {
|
|
522
486
|
setActiveSquare(null);
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
if (
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
487
|
+
setPromotionMove(null);
|
|
488
|
+
};
|
|
489
|
+
const squareWidth = import_react5.default.useMemo(() => {
|
|
490
|
+
var _a2;
|
|
491
|
+
if (typeof document === "undefined") return 80;
|
|
492
|
+
const squareElement = document.querySelector(`[data-square]`);
|
|
493
|
+
return ((_a2 = squareElement == null ? void 0 : squareElement.getBoundingClientRect()) == null ? void 0 : _a2.width) ?? 80;
|
|
494
|
+
}, [promotionMove]);
|
|
495
|
+
const promotionSquareLeft = import_react5.default.useMemo(() => {
|
|
496
|
+
var _a2;
|
|
497
|
+
if (!(promotionMove == null ? void 0 : promotionMove.to)) return 0;
|
|
498
|
+
const column = ((_a2 = promotionMove.to.match(/^[a-h]/)) == null ? void 0 : _a2[0]) ?? "a";
|
|
499
|
+
return squareWidth * (0, import_react_chessboard.chessColumnToColumnIndex)(
|
|
500
|
+
column,
|
|
501
|
+
8,
|
|
502
|
+
orientation === "b" ? "black" : "white"
|
|
503
|
+
);
|
|
504
|
+
}, [promotionMove, squareWidth, orientation]);
|
|
505
|
+
const baseOptions = {
|
|
506
|
+
squareStyles: getCustomSquareStyles(game, info, activeSquare, theme),
|
|
507
|
+
boardOrientation: orientation === "b" ? "black" : "white",
|
|
508
|
+
position: currentFen,
|
|
509
|
+
showNotation: true,
|
|
510
|
+
showAnimations: isLatestMove,
|
|
511
|
+
lightSquareStyle: theme.board.lightSquare,
|
|
512
|
+
darkSquareStyle: theme.board.darkSquare,
|
|
513
|
+
canDragPiece: ({ piece }) => {
|
|
514
|
+
if (isGameOver) return false;
|
|
515
|
+
return piece.pieceType[0] === turn;
|
|
550
516
|
},
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
517
|
+
dropSquareStyle: theme.state.dropSquare,
|
|
518
|
+
onPieceDrag: ({ piece, square }) => {
|
|
519
|
+
if (piece.pieceType[0] === turn) {
|
|
520
|
+
setActiveSquare(square);
|
|
521
|
+
}
|
|
522
|
+
},
|
|
523
|
+
onPieceDrop: ({ sourceSquare, targetSquare }) => {
|
|
524
|
+
setActiveSquare(null);
|
|
525
|
+
const moveData = {
|
|
526
|
+
from: sourceSquare,
|
|
527
|
+
to: targetSquare
|
|
528
|
+
};
|
|
529
|
+
if (requiresPromotion(game, { ...moveData, promotion: "q" })) {
|
|
530
|
+
setPromotionMove(moveData);
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
533
|
+
return makeMove(moveData);
|
|
534
|
+
},
|
|
535
|
+
onSquareClick: ({ square }) => {
|
|
536
|
+
if (square.match(/^[a-h][1-8]$/)) {
|
|
537
|
+
onSquareClick(square);
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
onSquareRightClick,
|
|
541
|
+
allowDrawingArrows: true,
|
|
542
|
+
animationDurationInMs: game.history().length === 0 ? 0 : 300
|
|
543
|
+
};
|
|
544
|
+
const mergedOptions = deepMergeChessboardOptions(baseOptions, options);
|
|
545
|
+
const mergedStyle = {
|
|
546
|
+
...userStyle,
|
|
547
|
+
position: "relative"
|
|
548
|
+
};
|
|
549
|
+
return /* @__PURE__ */ import_react5.default.createElement("div", { ref, className, style: mergedStyle, ...rest }, /* @__PURE__ */ import_react5.default.createElement(import_react_chessboard.Chessboard, { options: mergedOptions }), promotionMove && /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement(
|
|
550
|
+
"div",
|
|
579
551
|
{
|
|
580
|
-
|
|
581
|
-
onClick: () => onPromotionPieceSelect(piece),
|
|
552
|
+
onClick: () => setPromotionMove(null),
|
|
582
553
|
onContextMenu: (e) => {
|
|
583
554
|
e.preventDefault();
|
|
555
|
+
setPromotionMove(null);
|
|
584
556
|
},
|
|
585
557
|
style: {
|
|
586
|
-
|
|
587
|
-
|
|
558
|
+
position: "absolute",
|
|
559
|
+
top: 0,
|
|
560
|
+
left: 0,
|
|
561
|
+
right: 0,
|
|
562
|
+
bottom: 0,
|
|
563
|
+
backgroundColor: "rgba(0, 0, 0, 0.1)",
|
|
564
|
+
zIndex: 1e3
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
), /* @__PURE__ */ import_react5.default.createElement(
|
|
568
|
+
"div",
|
|
569
|
+
{
|
|
570
|
+
style: {
|
|
571
|
+
position: "absolute",
|
|
572
|
+
top: ((_b = (_a = promotionMove.to) == null ? void 0 : _a[1]) == null ? void 0 : _b.includes("8")) ? 0 : "auto",
|
|
573
|
+
bottom: ((_c = promotionMove.to) == null ? void 0 : _c[1].includes("1")) ? 0 : "auto",
|
|
574
|
+
left: promotionSquareLeft,
|
|
575
|
+
backgroundColor: "white",
|
|
576
|
+
width: squareWidth,
|
|
577
|
+
zIndex: 1001,
|
|
588
578
|
display: "flex",
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
padding: 0,
|
|
592
|
-
border: "none",
|
|
593
|
-
cursor: "pointer",
|
|
594
|
-
backgroundColor: "white"
|
|
595
|
-
},
|
|
596
|
-
onMouseEnter: (e) => {
|
|
597
|
-
e.currentTarget.style.backgroundColor = "#f0f0f0";
|
|
598
|
-
},
|
|
599
|
-
onMouseLeave: (e) => {
|
|
600
|
-
e.currentTarget.style.backgroundColor = "white";
|
|
579
|
+
flexDirection: "column",
|
|
580
|
+
boxShadow: "0 0 10px 0 rgba(0, 0, 0, 0.5)"
|
|
601
581
|
}
|
|
602
582
|
},
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
583
|
+
["q", "r", "n", "b"].map((piece) => /* @__PURE__ */ import_react5.default.createElement(
|
|
584
|
+
"button",
|
|
585
|
+
{
|
|
586
|
+
key: piece,
|
|
587
|
+
onClick: () => onPromotionPieceSelect(piece),
|
|
588
|
+
onContextMenu: (e) => {
|
|
589
|
+
e.preventDefault();
|
|
590
|
+
},
|
|
591
|
+
style: {
|
|
592
|
+
width: "100%",
|
|
593
|
+
aspectRatio: "1",
|
|
594
|
+
display: "flex",
|
|
595
|
+
alignItems: "center",
|
|
596
|
+
justifyContent: "center",
|
|
597
|
+
padding: 0,
|
|
598
|
+
border: "none",
|
|
599
|
+
cursor: "pointer",
|
|
600
|
+
backgroundColor: "white"
|
|
601
|
+
},
|
|
602
|
+
onMouseEnter: (e) => {
|
|
603
|
+
e.currentTarget.style.backgroundColor = "#f0f0f0";
|
|
604
|
+
},
|
|
605
|
+
onMouseLeave: (e) => {
|
|
606
|
+
e.currentTarget.style.backgroundColor = "white";
|
|
607
|
+
}
|
|
608
|
+
},
|
|
609
|
+
import_react_chessboard.defaultPieces[`${turn}${piece.toUpperCase()}`]()
|
|
610
|
+
))
|
|
611
|
+
)));
|
|
612
|
+
}
|
|
613
|
+
);
|
|
614
|
+
Board.displayName = "ChessGame.Board";
|
|
607
615
|
|
|
608
616
|
// src/components/ChessGame/parts/Sounds.tsx
|
|
609
617
|
var import_react7 = require("react");
|
|
@@ -665,6 +673,7 @@ var Sounds = ({ sounds }) => {
|
|
|
665
673
|
useBoardSounds(customSoundsAudios);
|
|
666
674
|
return null;
|
|
667
675
|
};
|
|
676
|
+
Sounds.displayName = "ChessGame.Sounds";
|
|
668
677
|
|
|
669
678
|
// src/hooks/useKeyboardControls.ts
|
|
670
679
|
var import_react8 = require("react");
|
|
@@ -708,6 +717,7 @@ var KeyboardControls2 = ({
|
|
|
708
717
|
useKeyboardControls(keyboardControls);
|
|
709
718
|
return null;
|
|
710
719
|
};
|
|
720
|
+
KeyboardControls2.displayName = "ChessGame.KeyboardControls";
|
|
711
721
|
|
|
712
722
|
// src/components/ChessGame/index.ts
|
|
713
723
|
var ChessGame = {
|